## 経緯
[[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` |
## 人間トリガーのコマンド作成方法
### TODO
タスクが発生したら、以下を行うコマンドを実行する。
1. ワークスペースの作成
2. エージェントの起動 (コマンドによって定義は変わる)
3. sidebarに `TODO` ステータスを設定
コマンド。
- `cc`: [[Claude Code]]
```bash
cc() {
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"
}
```
[[Codex CLI]]の場合は良くも悪くも `chappy` コマンドを使う。あくまでサブとして。
### 完了
```bash
close() {
cmux set-status task "完了" --icon checkmark --color "#34C759"
}
```
## AIトリガーのコマンド実行方法
プロンプトで制御する。たまに動かないけどそこまで重要じゃないのでヨシ。
```markdown
## 基本ルール
- 最初のプロンプトが送信(依頼)されたら `sss "<依頼の要約>"` コマンドを実行
- 『応答』開始前には `ssp <進捗率(0~1)> <応答名>...` コマンドを実行
- 『応答』完了後には `ssw` コマンドを実行
```
### シェルの定義
色々問題があったので
<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.sh`
```bash
claudine() {
chafa --duration 0 --size 30x24 ~/.claude/claudine.gif
GH_TOKEN=$GH_READONLY_TOKEN claude "$@"
}
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"
}
sss() {
cmux workspace-action rename "$1"
}
ssp() {
cmux set-status task "進行中" --icon sparkle --color "#007AFF"
cmux set-progress "$1" --label "$2"
}
ssw() {
cmux set-status task "待ち" --icon clock --color "#FF9500"
cmux clear-progress
}
ssd() {
cmux set-status task "完了" --icon checkmark --color "#34C759"
}
ssc() {
cmux clear-progress
cmux clear-status task
}
```
`~/.claude/settings.json`
```json
{
"includeCoAuthoredBy": false,
"permissions": {
"allow": [
"Bash(sss *)",
"Bash(ssp *)",
"Bash(ssw *)",
"Bash(ssc *)",
]
}
}
```
### 他
progress は `SessionEnd` でクリアできるようにしておけば、残ったままにならない。
```lua
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "cmux clear-progress"
}
]
}
]
},
}
```
## [[GitHub Copilot CLI]]の場合
`~/copilot-instructions.md` の内容は[[Claude Code]]と似ている。
```markdown
## 基本ルール
- 常に日本語でやりとりしてください
- 最初のプロンプトが送信(依頼)されたら `ss start "<依頼の要約>"` コマンドを実行
- 『応答』開始前には `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』中でも進捗率やフェーズに変化があれば `ss progress <進捗率(0~1)> <フェーズ名>...` コマンドを実行
- 『応答』完了後には `ss wait` コマンドを実行
```
`~/.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 " 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
;;
done)
cmux set-status task "完了" --icon checkmark --color "#34C759"
;;
clear)
cmux clear-progress
cmux clear-status task
;;
*)
echo "Unknown command: $command" >&2
usage
;;
esac
```