## 経緯
[[cmux]]を使って複数[[ワークスペース (cmux)|ワークスペース]]、複数[[エージェント]]を立ち上げるようになって、各タスク/[[エージェント]]の状態を把握するのが大変になったので検討してみた。
## 前提
ある意味[[Jira]]みたいなものだ。
- タスクの発生と共に[[ワークスペース (cmux)|ワークスペース]]をつくる
- [[ワークスペース (cmux)|ワークスペース]]作成後は必ず[[エージェント]]を起動する
- [[Claude Code]]、[[Codex CLI]]、[[GitHub Copilot CLI]]を想定
- 対応優先度は
1. [[Claude Code]]
2. [[GitHub Copilot CLI]]
3. [[Codex CLI]]
- 完了後は[[エージェント]]を破棄する
- 後処理がある場合は残しておく必要あり
- **1つの[[ワークスペース (cmux)|ワークスペース]]には1つの[[エージェント]]しか起動しない**
- 少し強い制約なので今後変わる可能性は高い
- ただ、この前提でやらないとサイドバーの表示制御が厳しいので...
## ステータス定義
| ステータス | 説明 | トリガー |
| -------- | ----------------------------------- | ---- |
| **TODO** | **エージェントを**起動した状態 (人間待ち) | 人間 |
| **進行中** | **エージェントが**作業を進めている状態 | AI |
| **待機** | **人間の**作業待ち or 作業中 ([[エージェント]]は待機中) | AI |
| **完了** | **エージェントの**タスクは完了したが、**後始末が必要**な場合 | 人間 |
- エージェントの**作業終了**はあくまで『待機』
- **完了**かどうかを判断するのは人間
- **後始末** はコミット/pushなどのこと
`cmux` コマンドの例。
| 状態 | コマンド |
| ------ | -------------------------------------------------------------- |
| 🔵 進行中 | `cmux set-status task "進行中" --icon sparkle --color "#007AFF"` |
| 🟡 待ち | `cmux set-status task "待ち" --icon clock --color "#FF9500"` |
| 🟢 完了 | `cmux set-status task "完了" --icon checkmark --color "#34C759"` |
| クリア | `cmux clear-status task` |
## ssコマンド
`~/.zshrc` で定義した関数は[[GitHub Copilot CLI]]が認識しなかったので、`~/bin` のようにPATHが通っている箇所に `ss` として切り出し。
`~/bin/ss`
```bash
#!/bin/bash
set -euo pipefail
usage() {
echo "Usage: ss <command> [args...]"
echo ""
echo "Commands:"
echo " start <name> ワークスペースをリネーム"
echo " progress <rate> <label> 進行中ステータスに設定 (rate: 0~1)"
echo " wait 人間待ちステータスに設定"
echo " block <note> ブロックステータスに設定 (note省略時は『動作確認待ち』)"
echo " done 完了ステータスに設定"
echo " clear ステータスとプログレスをクリア"
exit 1
}
if [[ $# -lt 1 ]]; then
usage
fi
command="$1"
shift
case "$command" in
start)
cmux workspace-action rename "$1"
;;
progress)
cmux set-status task "進行中" --icon sparkle --color "#007AFF"
cmux set-progress "$1" --label "$2"
;;
wait)
cmux set-status task "人間待ち" --icon clock --color "#FF9500"
cmux clear-progress
;;
block)
cmux set-status task "ブロック: ${1:-動作確認待ち}" --icon exclamationmark.triangle --color "#FF3B30"
cmux clear-progress
;;
done)
cmux set-status task "完了" --icon checkmark --color "#34C759"
;;
clear)
cmux clear-progress
cmux clear-status task
;;
*)
echo "Unknown command: $command" >&2
usage
;;
esac
```
[[CLI]]として切り出した発端は以下。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📝Claude Codeでシャープを含むシェルコマンドを実行するとpermissionのallowリストに設定していても必ず確認されてしまう
</div>
<div class="link-card-v2-content">Claude Code 2.1.7.6で`~/.claude/settings.json`のpermissions.allowに`Bash(cmux set-status:*)`を設定したが、`cmux set-status task "待ち" --icon clock --color "#FF9500"`のように`#`を含むコマンドを実行した際、allowリストが効かず毎回permission確認が発生した事象である</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/troubleshooting.webp" />
<a data-href="📝Claude Codeでシャープを含むシェルコマンドを実行するとpermissionのallowリストに設定していても必ず確認されてしまう" class="internal-link"></a>
</div>
%%[[📝Claude Codeでシャープを含むシェルコマンドを実行するとpermissionのallowリストに設定していても必ず確認されてしまう]]%%
[[Claude Code]]のパーミッション。
`~/.claude/settings.json`
```json
{
"includeCoAuthoredBy": false,
"permissions": {
"allow": [
"Bash(ss *)",
]
}
}
```
[[GitHub Copilot CLI]]のパーミッション。
```bash
copilot \
--allow-tool "shell(ss:*)"
```
## ステータス変更
### TODO
タスクが発生したら、以下を行うコマンドを実行する。
1. ワークスペースの作成
2. エージェントの起動 (コマンドによって定義は変わる)
3. sidebarに `TODO` ステータスを設定
#### [[Claude Code]]
`~/.claude.sh`
```bash
# 現在のワークスペースで
cc() {
cmux set-status task 'TODO' --icon sparkle --color '#ff77ff'
claudine "$@"
}
# 新しいワークスペースで
ccnew() {
ws_id=$(cmux new-workspace | awk '/^OK /{print $2}')
cmux set-status task 'TODO' --icon sparkle --color '#ff77ff' \
--workspace "$ws_id"
cmux send 'claudine\n' \
--workspace "$ws_id"
cmux select-workspace \
--workspace "$ws_id"
}
```
#### [[GitHub Copilot CLI]]
`~/.copilot.sh`
```bash
# 現在のワークスペースで
gc() {
cmux set-status task 'TODO' --icon sparkle --color '#ff77ff'
colot "$@"
}
# 新しいワークスペースで
gcnew() {
ws_id=$(cmux new-workspace | awk '/^OK /{print $2}')
cmux set-status task 'TODO' --icon sparkle --color '#ff77ff' \
--workspace "$ws_id"
cmux send 'colot\n' \
--workspace "$ws_id"
cmux select-workspace \
--workspace "$ws_id"
}
```
### 進行中・人間待ち
#### [[Claude Code]]
`~/.claude/CLAUDE.md`
```markdown
## 基本ルール
- 常に日本語でやりとりしてください
- 最初のプロンプトが送信(依頼)されたら `ss start "<依頼の要約>"` コマンドを実行
- `<依頼の要約>`: 先頭に依頼のタイプを現す絵文字をつける
- 『応答』開始前には `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』中でも進捗率やフェーズに変化があれば `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』完了後には `ss wait` コマンドを実行
```
#### [[GitHub Copilot CLI]]
`~/.copilot/copilot-instructions.md`
```markdown
## 基本ルール
- 常に日本語でやりとりしてください
- 最初のプロンプトが送信(依頼)されたら `ss start "<依頼の要約>"` コマンドを実行
- `<依頼の要約>`: 先頭に依頼のタイプを現す絵文字をつける
- 『応答』開始前には `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』中でも進捗率やフェーズに変化があれば `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』完了後には `ss wait` コマンドを実行
```
### 完了
手動で `ss done`。完了してたらワークスペースごと閉じていい。
### 他
progress は `SessionEnd` でクリアできるようにしておけば、残ったままにならない。
```lua
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "cmux clear-progress"
}
]
}
]
},
}
```