@geekbeer/minion 3.59.4 → 3.59.8
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.
- package/core/meetings/meeting-mcp-server.js +40 -3
- package/core/meetings/meeting-prompt.js +8 -0
- package/docs/api-reference.md +7 -3
- package/docs/task-guides.md +32 -0
- package/linux/meeting-runner.js +1 -0
- package/package.json +1 -1
- package/rules/core.md +6 -1
- package/win/meeting-runner.js +1 -0
- package/win/minion-cli.ps1 +19 -5
|
@@ -17,7 +17,15 @@
|
|
|
17
17
|
*
|
|
18
18
|
* meeting_leave()
|
|
19
19
|
* Records left_at for this minion. Returns { ok: true }; claude should
|
|
20
|
-
* exit its participation loop after this call.
|
|
20
|
+
* exit its participation loop after this call. **Does NOT delete the
|
|
21
|
+
* meeting room** — only this minion's own departure is recorded.
|
|
22
|
+
*
|
|
23
|
+
* meeting_end()
|
|
24
|
+
* End and delete the meeting room (host minion only). Cascades to
|
|
25
|
+
* participants/messages and pushes end-notices to all other minions
|
|
26
|
+
* so their tmux sessions terminate. Returns { ok: true } or 403 if
|
|
27
|
+
* the calling minion is not the host. Use this when YOU created the
|
|
28
|
+
* meeting (via POST /api/minion/meetings) and the discussion is over.
|
|
21
29
|
*
|
|
22
30
|
* Environment (passed by meeting-runner):
|
|
23
31
|
* MINION_MEETING_ID - meeting UUID
|
|
@@ -105,6 +113,22 @@ async function leave() {
|
|
|
105
113
|
return { ok: true }
|
|
106
114
|
}
|
|
107
115
|
|
|
116
|
+
async function endMeeting() {
|
|
117
|
+
const { resp, data } = await hqFetch(`/api/minion/meetings/${MEETING_ID}`, {
|
|
118
|
+
method: 'DELETE',
|
|
119
|
+
})
|
|
120
|
+
if (resp.status === 404 || data.meeting_ended) {
|
|
121
|
+
return { ok: true, meeting_ended: true }
|
|
122
|
+
}
|
|
123
|
+
if (resp.status === 403) {
|
|
124
|
+
throw new Error(data.error || 'Only the host minion can end this meeting')
|
|
125
|
+
}
|
|
126
|
+
if (!resp.ok) {
|
|
127
|
+
throw new Error(data.error || `end failed: ${resp.status}`)
|
|
128
|
+
}
|
|
129
|
+
return { ok: true }
|
|
130
|
+
}
|
|
131
|
+
|
|
108
132
|
// --- Tool definitions --------------------------------------------------------
|
|
109
133
|
|
|
110
134
|
function toolsList() {
|
|
@@ -143,8 +167,19 @@ function toolsList() {
|
|
|
143
167
|
{
|
|
144
168
|
name: 'meeting_leave',
|
|
145
169
|
description:
|
|
146
|
-
'Leave the meeting
|
|
147
|
-
'
|
|
170
|
+
'Leave the meeting (depart, do NOT delete the room). Records your left_at. ' +
|
|
171
|
+
'Use this when you have been excused but the meeting continues without you. ' +
|
|
172
|
+
'If you are the host and the discussion is over, call meeting_end instead.',
|
|
173
|
+
inputSchema: { type: 'object', properties: {} },
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'meeting_end',
|
|
177
|
+
description:
|
|
178
|
+
'End and delete the meeting room (host minion only). Cascades to participants ' +
|
|
179
|
+
'and messages and shuts down every other minion in the room. Call this when ' +
|
|
180
|
+
'YOU created the meeting and the discussion is concluded — meeting_leave only ' +
|
|
181
|
+
'records your own departure and leaves the room hanging. Fails with 403 if you ' +
|
|
182
|
+
'are not the host.',
|
|
148
183
|
inputSchema: { type: 'object', properties: {} },
|
|
149
184
|
},
|
|
150
185
|
]
|
|
@@ -160,6 +195,8 @@ async function handleToolCall(name, args) {
|
|
|
160
195
|
return getState()
|
|
161
196
|
case 'meeting_leave':
|
|
162
197
|
return leave()
|
|
198
|
+
case 'meeting_end':
|
|
199
|
+
return endMeeting()
|
|
163
200
|
default:
|
|
164
201
|
throw new Error(`Unknown tool: ${name}`)
|
|
165
202
|
}
|
|
@@ -34,6 +34,14 @@ function buildMeetingKickoffPrompt({ meetingId, title, purpose, host, selfName,
|
|
|
34
34
|
'5. `meeting_wait_for_next_message` の戻り値が `{ meeting_ended: true }` になったら',
|
|
35
35
|
' `meeting_leave` を呼んでループを終了する',
|
|
36
36
|
'',
|
|
37
|
+
'## ミーティングの終了 (leave と end の使い分け)',
|
|
38
|
+
'',
|
|
39
|
+
'- **`meeting_leave`**: 自分だけ退席する。ルームは残り、他参加者は続行可能。',
|
|
40
|
+
' 「あなただけ退席してOK」と明示された時のみ使う。',
|
|
41
|
+
'- **`meeting_end`**: ルームを削除して全員を解散する。**ホストのみ呼び出せる** (403になる)。',
|
|
42
|
+
' あなたが招集したミーティングで議論が終わったら `meeting_end` を呼ぶこと。',
|
|
43
|
+
' `meeting_leave` だけだとルームが孤児として残り続けるので注意。',
|
|
44
|
+
'',
|
|
37
45
|
'## 発言ガイドライン',
|
|
38
46
|
'- 1回の発言は **2-3 文以内** を基本とする (会議でだらだら話さない)',
|
|
39
47
|
'- 議論を前進させる発言を優先する (賛否・確認・代替案・質問)',
|
package/docs/api-reference.md
CHANGED
|
@@ -1989,13 +1989,17 @@ hq note search <project_id> "キーワード"
|
|
|
1989
1989
|
|
|
1990
1990
|
### Meeting Rooms 🧪 (HQ, experimental, v3.59.0〜)
|
|
1991
1991
|
|
|
1992
|
-
ミーティング機能はミニオン上の `meeting` MCP サーバーが叩く HQ
|
|
1992
|
+
ミーティング機能はミニオン上の `meeting` MCP サーバーが叩く HQ エンドポイント。**参加中**の操作は MCP ツール経由で自動的に叩かれるが、**自分で会議を招集する**場合 (例: PMミニオンが朝会を主催) は `POST /api/minion/meetings` をルーティン/スキルから直接叩く。
|
|
1993
1993
|
|
|
1994
1994
|
| Method | Endpoint | Description |
|
|
1995
1995
|
|--------|----------|-------------|
|
|
1996
|
+
| POST | `/api/minion/meetings` | **会議室を作成して参加者を招待する。** Body: `{project_id, title, purpose?, invitees?: [{type: 'user'\|'minion', id}]}`。呼び出し元ミニオンは自動でホスト+参加者になる。プロジェクトメンバーかつ `experimental_meetings` 有効ワークスペースで動作 |
|
|
1996
1997
|
| GET | `/api/minion/meetings/:id` | ミーティングのメタデータ + 参加者一覧。`meeting_get_state` ツールから呼ばれる |
|
|
1997
1998
|
| GET | `/api/minion/meetings/:id/messages?after=<iso>&wait=true` | long-poll で次の発言を待機 (最大 ~25秒)。404 = 会議終了 |
|
|
1998
1999
|
| POST | `/api/minion/meetings/:id/messages` | 発言。Body: `{text}` |
|
|
1999
|
-
| POST | `/api/minion/meetings/:id` | アクション。Body: `{action: 'leave' \| 'heartbeat'}` |
|
|
2000
|
+
| POST | `/api/minion/meetings/:id` | アクション。Body: `{action: 'leave' \| 'heartbeat'}`。`leave` は自分の `left_at` を記録するだけでルームは残る |
|
|
2001
|
+
| DELETE | `/api/minion/meetings/:id` | **ルームを削除して会議を終了する** (ホストミニオン限定、403 if not host)。CASCADE で participants/messages 削除 + 他参加ミニオンに終了通知 push |
|
|
2000
2002
|
|
|
2001
|
-
|
|
2003
|
+
参加中の操作 (GET state / long-poll messages / speak / leave / end / heartbeat) は MCP ツール (`meeting_get_state`, `meeting_wait_for_next_message`, `meeting_speak`, `meeting_leave`, `meeting_end`) として claude に公開されるため、直接叩く必要はない。会議の**作成**だけはルーティン/スキルから明示的に叩く必要がある (作成後は HQ がプッシュした招待で各ミニオンに mt-* tmux セッションが立ち上がる)。
|
|
2004
|
+
|
|
2005
|
+
**leave と end の違い**: `meeting_leave` は自分だけ退席するアクション (ルームは残る)、`meeting_end` (DELETE) はルームごと削除して全員解散させるアクション (ホストミニオン限定)。自分が招集した会議が終わったら必ず `meeting_end` を呼ばないとルームが孤児として残る。
|
package/docs/task-guides.md
CHANGED
|
@@ -821,6 +821,38 @@ curl -H "Authorization: Bearer $API_TOKEN" http://localhost:8080/api/meetings/ac
|
|
|
821
821
|
|
|
822
822
|
セッション復帰機構は未実装。tmux/claude が落ちた場合は再起動されず、新しい招待を待つ。
|
|
823
823
|
|
|
824
|
+
### ミーティングを自分で招集する (v3.59.6〜)
|
|
825
|
+
|
|
826
|
+
PMロール等で「自分が会議を主催したい」場合は HQ の `POST /api/minion/meetings` を直接叩く。呼び出し元ミニオンは自動でホスト + 参加者になり、`invitees` で指定した他ミニオン・人間が `meeting_participants` に挿入される。他ミニオンへの招待は HQ がプッシュするので、こちら側で追加処理は不要。
|
|
827
|
+
|
|
828
|
+
```bash
|
|
829
|
+
curl -X POST "$HQ_URL/api/minion/meetings" \
|
|
830
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
831
|
+
-H "Content-Type: application/json" \
|
|
832
|
+
-d '{
|
|
833
|
+
"project_id": "<project-uuid>",
|
|
834
|
+
"title": "朝会 2026-05-15",
|
|
835
|
+
"purpose": "前日進捗の共有とブロッカーの洗い出し",
|
|
836
|
+
"invitees": [
|
|
837
|
+
{"type": "minion", "id": "<other-minion-uuid>"},
|
|
838
|
+
{"type": "user", "id": "<user-uuid>"}
|
|
839
|
+
]
|
|
840
|
+
}'
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
**前提条件:**
|
|
844
|
+
- 自分がそのプロジェクトの `project_members` に登録されていること (403 が返るならPMに依頼)
|
|
845
|
+
- プロジェクトが所属する workspace の `feature_flags.experimental_meetings = true` (人間管理者しか有効化できない)
|
|
846
|
+
- 作成成功後、自分自身のミニオンにも招待が届き `mt-{id8}` tmux セッションが起動する
|
|
847
|
+
|
|
848
|
+
**会議の終了 (ホストの責務):**
|
|
849
|
+
自分が招集した会議で議論が終わったら、MCP ツール `meeting_end` を呼んでルームを削除する。`meeting_leave` は自分が退席するだけでルームは残るため、ホストが leave で抜けるとルームが孤児になり HQ ダッシュボードのアクティブ会議室一覧に居座り続ける。`meeting_end` は ホストミニオン限定 (それ以外は 403)。
|
|
850
|
+
|
|
851
|
+
```
|
|
852
|
+
meeting_end() # DELETE /api/minion/meetings/:id を裏で叩く
|
|
853
|
+
# → 全参加ミニオンに終了通知が push され、各 mt-* tmux が終了する
|
|
854
|
+
```
|
|
855
|
+
|
|
824
856
|
## ツール・MCPサーバーのインストール
|
|
825
857
|
|
|
826
858
|
スキルが `requires` で宣言している MCP サーバーや CLI ツールが不足している場合は、`~/.minion/docs/environment-setup.md` の手順に従ってインストールする。
|
package/linux/meeting-runner.js
CHANGED
|
@@ -165,6 +165,7 @@ async function runMeeting({ meetingId, title, purpose, host, hqUrl, selfName, ro
|
|
|
165
165
|
'mcp__meeting__meeting_speak',
|
|
166
166
|
'mcp__meeting__meeting_get_state',
|
|
167
167
|
'mcp__meeting__meeting_leave',
|
|
168
|
+
'mcp__meeting__meeting_end',
|
|
168
169
|
].join(',')
|
|
169
170
|
const llmCommand = `${claudeBin} -p --mcp-config "${mcpConfigFile}" --allowedTools "${allowedTools}" < "${promptFile}"`
|
|
170
171
|
|
package/package.json
CHANGED
package/rules/core.md
CHANGED
|
@@ -279,7 +279,7 @@ Routine 実行中は以下もtmuxセッション環境で利用可能:
|
|
|
279
279
|
|
|
280
280
|
## Meeting Participation (ミーティング参加, experimental, v3.59.0〜)
|
|
281
281
|
|
|
282
|
-
HQ からミーティング招待 (`POST /api/meetings/invitations`) を受け取ると、専用 tmux セッション `mt-{meetingId8}` で claude が起動し、`meeting` MCP
|
|
282
|
+
HQ からミーティング招待 (`POST /api/meetings/invitations`) を受け取ると、専用 tmux セッション `mt-{meetingId8}` で claude が起動し、`meeting` MCP サーバー経由で会議に参加する。**自分から会議を招集する** (`POST $HQ_URL/api/minion/meetings`) ことも可能 (v3.59.6〜、PMロール推奨)。詳細は `~/.minion/docs/task-guides.md` の「ミーティングを自分で招集する」を参照。
|
|
283
283
|
|
|
284
284
|
**基本ループ:**
|
|
285
285
|
1. `meeting_get_state` で参加者・目的・タイトルを把握
|
|
@@ -291,6 +291,11 @@ HQ からミーティング招待 (`POST /api/meetings/invitations`) を受け
|
|
|
291
291
|
4. 応答すべきなら `meeting_speak` で **1-3 文程度** の発言を送信
|
|
292
292
|
5. 戻り値が `{ meeting_ended: true }` になったら `meeting_leave` を呼んで終了
|
|
293
293
|
|
|
294
|
+
**`meeting_leave` と `meeting_end` の使い分け** (v3.59.7〜):
|
|
295
|
+
- `meeting_leave` = 自分だけ退席。ルームは残り議論は続行
|
|
296
|
+
- `meeting_end` = ルームごと削除して全員解散 (**ホストミニオンのみ**、403になる)
|
|
297
|
+
- 自分が招集した会議で議論が終わったら **必ず `meeting_end`** を呼ぶこと。`meeting_leave` だけだとルームが孤児として残る
|
|
298
|
+
|
|
294
299
|
**振る舞いのルール:**
|
|
295
300
|
- 発言は短く保つ (会議でだらだら話さない)
|
|
296
301
|
- 他のミニオンの発言と重複しない (既に同じ趣旨を誰かが言っていたら追従しない)
|
package/win/meeting-runner.js
CHANGED
|
@@ -130,6 +130,7 @@ async function runMeeting({ meetingId, title, purpose, host, hqUrl, selfName, ro
|
|
|
130
130
|
'mcp__meeting__meeting_speak',
|
|
131
131
|
'mcp__meeting__meeting_get_state',
|
|
132
132
|
'mcp__meeting__meeting_leave',
|
|
133
|
+
'mcp__meeting__meeting_end',
|
|
133
134
|
].join(',')
|
|
134
135
|
|
|
135
136
|
await fs.writeFile(
|
package/win/minion-cli.ps1
CHANGED
|
@@ -48,10 +48,15 @@ $needsAdmin = $Command -in $adminRequired
|
|
|
48
48
|
# `stop --force` rewrites NSSM AppExit config and may need to kill processes
|
|
49
49
|
# owned by the service account → requires Administrator.
|
|
50
50
|
if ($Command -eq 'stop' -and $Force) { $needsAdmin = $true }
|
|
51
|
+
# `restart --all` triggers the MinionVNC schtask which is registered with
|
|
52
|
+
# /RL HIGHEST, so schtasks /Run requires Administrator.
|
|
53
|
+
if ($Command -eq 'restart' -and $All) { $needsAdmin = $true }
|
|
51
54
|
if ($needsAdmin) {
|
|
52
55
|
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
|
|
53
56
|
if (-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
54
|
-
$label = if ($Command -eq 'stop' -and $Force) { 'stop --force' }
|
|
57
|
+
$label = if ($Command -eq 'stop' -and $Force) { 'stop --force' }
|
|
58
|
+
elseif ($Command -eq 'restart' -and $All) { 'restart --all' }
|
|
59
|
+
else { $Command }
|
|
55
60
|
Write-Host "ERROR: '$label' requires Administrator privileges." -ForegroundColor Red
|
|
56
61
|
Write-Host " Right-click PowerShell and select 'Run as administrator'." -ForegroundColor Yellow
|
|
57
62
|
exit 1
|
|
@@ -614,9 +619,17 @@ function Restart-AllMinionServices {
|
|
|
614
619
|
}
|
|
615
620
|
|
|
616
621
|
# Step 5: Re-trigger user-session logon tasks. schtasks /Run is a no-op if
|
|
617
|
-
# the task is already running
|
|
618
|
-
|
|
619
|
-
|
|
622
|
+
# the task is already running. MinionVNC is /RL HIGHEST so we require
|
|
623
|
+
# Administrator at the entry point (see needsAdmin check above), which
|
|
624
|
+
# is what allows this /Run to succeed.
|
|
625
|
+
foreach ($task in @('MinionVNC', 'MinionWSL')) {
|
|
626
|
+
$output = & schtasks /Run /TN $task 2>&1
|
|
627
|
+
if ($LASTEXITCODE -eq 0) {
|
|
628
|
+
Write-Host "Triggered logon task: $task"
|
|
629
|
+
} else {
|
|
630
|
+
Write-Warn "Logon task '$task' could not be triggered: $output"
|
|
631
|
+
}
|
|
632
|
+
}
|
|
620
633
|
|
|
621
634
|
Write-Host "All minion services restarted"
|
|
622
635
|
}
|
|
@@ -1874,7 +1887,7 @@ switch ($Command) {
|
|
|
1874
1887
|
Write-Host " stop Stop the minion-agent service (graceful)"
|
|
1875
1888
|
Write-Host " stop --force Force-stop all minion services & processes (admin required)"
|
|
1876
1889
|
Write-Host " restart Restart the minion-agent service"
|
|
1877
|
-
Write-Host " restart --all Restart all minion services
|
|
1890
|
+
Write-Host " restart --all Restart all minion services + logon tasks (admin required)"
|
|
1878
1891
|
Write-Host " status Show agent service status"
|
|
1879
1892
|
Write-Host " health Check agent health endpoint"
|
|
1880
1893
|
Write-Host " daemons Show all daemon service status"
|
|
@@ -1902,5 +1915,6 @@ switch ($Command) {
|
|
|
1902
1915
|
Write-Host " minion-cloudflared, then re-trigger MinionVNC/MinionWSL"
|
|
1903
1916
|
Write-Host " logon tasks. Use after Windows Update or when only"
|
|
1904
1917
|
Write-Host " some services came back online."
|
|
1918
|
+
Write-Host " Requires Administrator (MinionVNC schtask is /RL HIGHEST)."
|
|
1905
1919
|
}
|
|
1906
1920
|
}
|