@geekbeer/minion 2.68.5 → 2.70.2

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/api.js CHANGED
@@ -88,75 +88,75 @@ async function sendHeartbeat(data) {
88
88
 
89
89
  /**
90
90
  * Create a project thread (help or discussion) on HQ.
91
- * @param {object} data - { project_id, title, description, thread_type?, mentions?, context? }
91
+ * @param {object} data - { project_id, title, content, thread_type?, mentions?, context? }
92
92
  * @returns {Promise<{ thread: object }>}
93
93
  */
94
- async function createHelpThread(data) {
95
- return request('/help-threads', {
94
+ async function createThread(data) {
95
+ return request('/threads', {
96
96
  method: 'POST',
97
97
  body: JSON.stringify(data),
98
98
  })
99
99
  }
100
100
 
101
101
  /**
102
- * Get open help threads in this minion's projects.
102
+ * Get open threads in this minion's projects.
103
103
  * @returns {Promise<{ threads: object[] }>}
104
104
  */
105
- async function getOpenHelpThreads() {
106
- return request('/help-threads/open')
105
+ async function getOpenThreads() {
106
+ return request('/threads/open')
107
107
  }
108
108
 
109
109
  /**
110
- * Get a help thread by ID with messages.
110
+ * Get a thread by ID with messages.
111
111
  * @param {string} threadId
112
112
  * @returns {Promise<{ thread: object, messages: object[] }>}
113
113
  */
114
- async function getHelpThread(threadId) {
115
- return request(`/help-threads/${threadId}`)
114
+ async function getThread(threadId) {
115
+ return request(`/threads/${threadId}`)
116
116
  }
117
117
 
118
118
  /**
119
- * Post a message to a help thread.
119
+ * Post a message to a thread.
120
120
  * @param {string} threadId
121
121
  * @param {object} data - { content, attachments?, mentions? }
122
122
  */
123
- async function postHelpMessage(threadId, data) {
124
- return request(`/help-threads/${threadId}/messages`, {
123
+ async function postThreadMessage(threadId, data) {
124
+ return request(`/threads/${threadId}/messages`, {
125
125
  method: 'POST',
126
126
  body: JSON.stringify(data),
127
127
  })
128
128
  }
129
129
 
130
130
  /**
131
- * Resolve a help thread.
131
+ * Resolve a thread.
132
132
  * @param {string} threadId
133
133
  * @param {string} resolution
134
134
  */
135
- async function resolveHelpThread(threadId, resolution) {
136
- return request(`/help-threads/${threadId}/resolve`, {
135
+ async function resolveThread(threadId, resolution) {
136
+ return request(`/threads/${threadId}/resolve`, {
137
137
  method: 'PATCH',
138
138
  body: JSON.stringify({ resolution }),
139
139
  })
140
140
  }
141
141
 
142
142
  /**
143
- * Cancel a help thread.
143
+ * Cancel a thread.
144
144
  * @param {string} threadId
145
145
  * @param {string} [reason]
146
146
  */
147
- async function cancelHelpThread(threadId, reason) {
148
- return request(`/help-threads/${threadId}/cancel`, {
147
+ async function cancelThread(threadId, reason) {
148
+ return request(`/threads/${threadId}/cancel`, {
149
149
  method: 'PATCH',
150
150
  body: JSON.stringify({ reason: reason || null }),
151
151
  })
152
152
  }
153
153
 
154
154
  /**
155
- * Permanently delete a help thread (PM only).
155
+ * Permanently delete a thread (PM only).
156
156
  * @param {string} threadId
157
157
  */
158
- async function deleteHelpThread(threadId) {
159
- return request(`/help-threads/${threadId}`, {
158
+ async function deleteThread(threadId) {
159
+ return request(`/threads/${threadId}`, {
160
160
  method: 'DELETE',
161
161
  })
162
162
  }
@@ -192,14 +192,13 @@ module.exports = {
192
192
  reportStepComplete,
193
193
  reportIssue,
194
194
  sendHeartbeat,
195
- createHelpThread,
196
- getOpenHelpThreads,
197
- getHelpThread,
198
- postHelpMessage,
199
- resolveHelpThread,
200
-
201
- cancelHelpThread,
202
- deleteHelpThread,
195
+ createThread,
196
+ getOpenThreads,
197
+ getThread,
198
+ postThreadMessage,
199
+ resolveThread,
200
+ cancelThread,
201
+ deleteThread,
203
202
  createProjectMemory,
204
203
  searchProjectMemories,
205
204
  }
@@ -10,7 +10,7 @@
10
10
  * 3. Rate limiting: max 1 LLM evaluation per thread per 5 minutes
11
11
  *
12
12
  * Flow per poll cycle:
13
- * 1. GET /api/minion/help-threads/open → list of open threads
13
+ * 1. GET /api/minion/threads/open → list of open threads
14
14
  * 2. For each thread with new activity:
15
15
  * a. Check mentions → if mentioned, must evaluate
16
16
  * b. Check read state → skip if no new messages
@@ -98,7 +98,7 @@ async function pollOnce() {
98
98
 
99
99
  polling = true
100
100
  try {
101
- const data = await api.request('/help-threads/open')
101
+ const data = await api.request('/threads/open')
102
102
 
103
103
  if (!data.threads || data.threads.length === 0) {
104
104
  return
@@ -139,7 +139,7 @@ async function processThread(thread, myProjects, now) {
139
139
  // Fetch thread detail to get message count and check for new messages
140
140
  let detail
141
141
  try {
142
- detail = await api.request(`/help-threads/${thread.id}`)
142
+ detail = await api.request(`/threads/${thread.id}`)
143
143
  } catch {
144
144
  return
145
145
  }
@@ -155,6 +155,13 @@ async function processThread(thread, myProjects, now) {
155
155
  // New messages detected
156
156
  const newMessages = messages.slice(state.lastMessageCount)
157
157
 
158
+ // Skip if all new messages are from self (avoid re-triggering on own posts)
159
+ const newFromOthers = newMessages.filter(m => m.sender_minion_id !== config.MINION_ID)
160
+ if (newFromOthers.length === 0) {
161
+ readState.set(thread.id, { ...state, lastMessageCount: messageCount })
162
+ return
163
+ }
164
+
158
165
  // Update read state (message count only — eval timestamp updated after LLM call)
159
166
  readState.set(thread.id, { ...state, lastMessageCount: messageCount })
160
167
 
@@ -194,9 +201,9 @@ async function evaluateWithLlm(threadSummary, threadDetail, allMessages, newMess
194
201
  .join('\n')
195
202
 
196
203
  const threadType = threadDetail.thread_type || 'help'
197
- const mentionNote = mentioned
198
- ? '\n\nあなたはこのスレッドでメンションされています。必ず返信してください。'
199
- : ''
204
+ const isRequester = threadDetail.requester_minion_id === config.MINION_ID
205
+ const mentions = threadDetail.mentions || []
206
+ const mentionsSummary = mentions.length > 0 ? mentions.join(', ') : 'なし(全員に向けた投稿)'
200
207
 
201
208
  // Extract optional context metadata
202
209
  const ctx = threadDetail.context || {}
@@ -205,13 +212,14 @@ async function evaluateWithLlm(threadSummary, threadDetail, allMessages, newMess
205
212
  ctx.attempted_resolution ? `試行済み: ${ctx.attempted_resolution}` : '',
206
213
  ].filter(Boolean).join('\n')
207
214
 
208
- const prompt = `あなたはプロジェクト「${myProject.name}」のチームメンバー(ロール: ${myProject.role})です。
215
+ const prompt = `あなたはプロジェクト「${myProject.name}」のチームメンバー(ロール: ${myProject.role}、ID: ${config.MINION_ID})です。
209
216
  以下のスレッドに対して、あなたが返信すべきかどうかを判断し、返信する場合はその内容を生成してください。
210
217
 
211
218
  スレッドタイプ: ${threadType}
212
219
  タイトル: ${threadDetail.title}
213
- 説明: ${threadDetail.description}
214
- ${contextInfo}${mentionNote}
220
+ 起票者: ${isRequester ? 'あなた自身' : `他のミニオン(${threadDetail.requester_minion_id?.slice(0, 8)})`}
221
+ メンション対象: ${mentionsSummary}
222
+ ${contextInfo}
215
223
 
216
224
  --- メッセージ履歴 ---
217
225
  ${messageHistory || '(メッセージなし)'}
@@ -225,11 +233,15 @@ ${messageHistory || '(メッセージなし)'}
225
233
  }
226
234
 
227
235
  判断基準:
236
+ - 自分が起票したスレッドの場合、他のメンバーの回答を待つべき(追加情報がある場合を除く)
237
+ - メンション対象が特定のロールやミニオンに限定されている場合、自分が対象でなければ静観する
228
238
  - 自分のロール(${myProject.role})に関連する話題か
229
239
  - 自分が貢献できる知見や意見があるか
230
240
  - 既に十分な回答がある場合は重複を避ける
231
- - メンションされている場合は必ず返信する
232
- - 人間に聞くべき場合は @user メンションを含めて返信する`
241
+ - 人間に聞くべき場合は @user メンションを含めて返信する
242
+
243
+ フォーマットルール:
244
+ - 他のミニオンに言及する場合は必ず Minion(IDの先頭8文字) の形式を使うこと(例: メッセージ履歴中の Minion(abc12345) をそのまま使用)`
233
245
 
234
246
  try {
235
247
  const result = await llmCallFn(prompt)
@@ -251,7 +263,7 @@ ${messageHistory || '(メッセージなし)'}
251
263
  mentions.push('user')
252
264
  }
253
265
 
254
- await api.request(`/help-threads/${threadSummary.id}/messages`, {
266
+ await api.request(`/threads/${threadSummary.id}/messages`, {
255
267
  method: 'POST',
256
268
  body: JSON.stringify({
257
269
  content: parsed.response,
@@ -281,7 +293,7 @@ async function fallbackMemoryMatch(thread) {
281
293
 
282
294
  if (!memData.memories || memData.memories.length === 0) return
283
295
 
284
- const keywords = (thread.title + ' ' + thread.description)
296
+ const keywords = thread.title
285
297
  .toLowerCase()
286
298
  .split(/[\s,.\-_/]+/)
287
299
  .filter(w => w.length >= 3)
@@ -301,7 +313,7 @@ async function fallbackMemoryMatch(thread) {
301
313
  .map(m => `[${m.title}] ${m.content}`)
302
314
  .join('\n\n')
303
315
 
304
- await api.request(`/help-threads/${thread.id}/messages`, {
316
+ await api.request(`/threads/${thread.id}/messages`, {
305
317
  method: 'POST',
306
318
  body: JSON.stringify({
307
319
  content: `関連するプロジェクトメモリーが見つかりました:\n\n${knowledgeSummary}`,
@@ -2,13 +2,13 @@
2
2
  * Project thread routes (local API on minion)
3
3
  *
4
4
  * Endpoints:
5
- * - GET /api/help-threads - List open threads in minion's projects
6
- * - POST /api/help-threads - Create a new thread (proxied to HQ)
7
- * - GET /api/help-threads/:id - Get thread detail with messages
8
- * - POST /api/help-threads/:id/messages - Post a message to a thread
9
- * - POST /api/help-threads/:id/resolve - Resolve a thread
10
- * - POST /api/help-threads/:id/cancel - Cancel a thread
11
- * - DELETE /api/help-threads/:id - Permanently delete a thread (PM only)
5
+ * - GET /api/threads - List open threads in minion's projects
6
+ * - POST /api/threads - Create a new thread (proxied to HQ)
7
+ * - GET /api/threads/:id - Get thread detail with messages
8
+ * - POST /api/threads/:id/messages - Post a message to a thread
9
+ * - POST /api/threads/:id/resolve - Resolve a thread
10
+ * - POST /api/threads/:id/cancel - Cancel a thread
11
+ * - DELETE /api/threads/:id - Permanently delete a thread (PM only)
12
12
  * - GET /api/project-memories - Search project memories
13
13
  * - POST /api/project-memories - Create a project memory
14
14
  */
@@ -19,77 +19,77 @@ const api = require('../api')
19
19
  /**
20
20
  * @param {import('fastify').FastifyInstance} fastify
21
21
  */
22
- async function helpThreadRoutes(fastify) {
22
+ async function threadRoutes(fastify) {
23
23
  // List open threads
24
- fastify.get('/api/help-threads', async (request, reply) => {
24
+ fastify.get('/api/threads', async (request, reply) => {
25
25
  if (!verifyToken(request)) {
26
26
  reply.code(401)
27
27
  return { success: false, error: 'Unauthorized' }
28
28
  }
29
29
 
30
30
  try {
31
- const data = await api.getOpenHelpThreads()
31
+ const data = await api.getOpenThreads()
32
32
  return { success: true, threads: data.threads || [] }
33
33
  } catch (error) {
34
- console.error(`[HelpThreads] List error: ${error.message}`)
34
+ console.error(`[Threads] List error: ${error.message}`)
35
35
  reply.code(500)
36
36
  return { success: false, error: error.message }
37
37
  }
38
38
  })
39
39
 
40
40
  // Create thread
41
- fastify.post('/api/help-threads', async (request, reply) => {
41
+ fastify.post('/api/threads', async (request, reply) => {
42
42
  if (!verifyToken(request)) {
43
43
  reply.code(401)
44
44
  return { success: false, error: 'Unauthorized' }
45
45
  }
46
46
 
47
47
  try {
48
- const data = await api.createHelpThread(request.body)
48
+ const data = await api.createThread(request.body)
49
49
  return { success: true, thread: data.thread }
50
50
  } catch (error) {
51
- console.error(`[HelpThreads] Create error: ${error.message}`)
51
+ console.error(`[Threads] Create error: ${error.message}`)
52
52
  reply.code(error.statusCode || 500)
53
53
  return { success: false, error: error.message }
54
54
  }
55
55
  })
56
56
 
57
57
  // Get thread detail
58
- fastify.get('/api/help-threads/:id', async (request, reply) => {
58
+ fastify.get('/api/threads/:id', async (request, reply) => {
59
59
  if (!verifyToken(request)) {
60
60
  reply.code(401)
61
61
  return { success: false, error: 'Unauthorized' }
62
62
  }
63
63
 
64
64
  try {
65
- const data = await api.getHelpThread(request.params.id)
65
+ const data = await api.getThread(request.params.id)
66
66
  return { success: true, thread: data.thread, messages: data.messages }
67
67
  } catch (error) {
68
- console.error(`[HelpThreads] Get error: ${error.message}`)
68
+ console.error(`[Threads] Get error: ${error.message}`)
69
69
  reply.code(error.statusCode || 500)
70
70
  return { success: false, error: error.message }
71
71
  }
72
72
  })
73
73
 
74
74
  // Post message
75
- fastify.post('/api/help-threads/:id/messages', async (request, reply) => {
75
+ fastify.post('/api/threads/:id/messages', async (request, reply) => {
76
76
  if (!verifyToken(request)) {
77
77
  reply.code(401)
78
78
  return { success: false, error: 'Unauthorized' }
79
79
  }
80
80
 
81
81
  try {
82
- const data = await api.postHelpMessage(request.params.id, request.body)
82
+ const data = await api.postThreadMessage(request.params.id, request.body)
83
83
  return { success: true, message: data.message }
84
84
  } catch (error) {
85
- console.error(`[HelpThreads] Message error: ${error.message}`)
85
+ console.error(`[Threads] Message error: ${error.message}`)
86
86
  reply.code(error.statusCode || 500)
87
87
  return { success: false, error: error.message }
88
88
  }
89
89
  })
90
90
 
91
91
  // Resolve thread
92
- fastify.post('/api/help-threads/:id/resolve', async (request, reply) => {
92
+ fastify.post('/api/threads/:id/resolve', async (request, reply) => {
93
93
  if (!verifyToken(request)) {
94
94
  reply.code(401)
95
95
  return { success: false, error: 'Unauthorized' }
@@ -97,34 +97,34 @@ async function helpThreadRoutes(fastify) {
97
97
 
98
98
  try {
99
99
  const { resolution } = request.body || {}
100
- const data = await api.resolveHelpThread(request.params.id, resolution)
100
+ const data = await api.resolveThread(request.params.id, resolution)
101
101
  return { success: true, thread: data.thread }
102
102
  } catch (error) {
103
- console.error(`[HelpThreads] Resolve error: ${error.message}`)
103
+ console.error(`[Threads] Resolve error: ${error.message}`)
104
104
  reply.code(error.statusCode || 500)
105
105
  return { success: false, error: error.message }
106
106
  }
107
107
  })
108
108
 
109
109
  // Permanently delete thread (PM only)
110
- fastify.delete('/api/help-threads/:id', async (request, reply) => {
110
+ fastify.delete('/api/threads/:id', async (request, reply) => {
111
111
  if (!verifyToken(request)) {
112
112
  reply.code(401)
113
113
  return { success: false, error: 'Unauthorized' }
114
114
  }
115
115
 
116
116
  try {
117
- const data = await api.deleteHelpThread(request.params.id)
117
+ const data = await api.deleteThread(request.params.id)
118
118
  return { success: true, deleted: data.deleted }
119
119
  } catch (error) {
120
- console.error(`[HelpThreads] Delete error: ${error.message}`)
120
+ console.error(`[Threads] Delete error: ${error.message}`)
121
121
  reply.code(error.statusCode || 500)
122
122
  return { success: false, error: error.message }
123
123
  }
124
124
  })
125
125
 
126
126
  // Cancel thread
127
- fastify.post('/api/help-threads/:id/cancel', async (request, reply) => {
127
+ fastify.post('/api/threads/:id/cancel', async (request, reply) => {
128
128
  if (!verifyToken(request)) {
129
129
  reply.code(401)
130
130
  return { success: false, error: 'Unauthorized' }
@@ -132,10 +132,10 @@ async function helpThreadRoutes(fastify) {
132
132
 
133
133
  try {
134
134
  const { reason } = request.body || {}
135
- const data = await api.cancelHelpThread(request.params.id, reason)
135
+ const data = await api.cancelThread(request.params.id, reason)
136
136
  return { success: true, thread: data.thread }
137
137
  } catch (error) {
138
- console.error(`[HelpThreads] Cancel error: ${error.message}`)
138
+ console.error(`[Threads] Cancel error: ${error.message}`)
139
139
  reply.code(error.statusCode || 500)
140
140
  return { success: false, error: error.message }
141
141
  }
@@ -186,4 +186,4 @@ async function helpThreadRoutes(fastify) {
186
186
  })
187
187
  }
188
188
 
189
- module.exports = { helpThreadRoutes }
189
+ module.exports = { threadRoutes }
@@ -281,21 +281,21 @@ GET `/api/daemons/status` response:
281
281
 
282
282
  | Method | Endpoint | Description |
283
283
  |--------|----------|-------------|
284
- | GET | `/api/help-threads` | 参加プロジェクトのオープンスレッド一覧 |
285
- | POST | `/api/help-threads` | スレッドを起票 |
286
- | GET | `/api/help-threads/:id` | スレッド詳細 + メッセージ一覧 |
287
- | POST | `/api/help-threads/:id/messages` | スレッドにメッセージを投稿 |
288
- | POST | `/api/help-threads/:id/resolve` | スレッドを解決済みにする |
289
- | POST | `/api/help-threads/:id/cancel` | スレッドをキャンセル |
290
- | DELETE | `/api/help-threads/:id` | スレッドを完全削除(PMのみ) |
291
-
292
- POST `/api/help-threads` body (ヘルプスレッド起票):
284
+ | GET | `/api/threads` | 参加プロジェクトのオープンスレッド一覧 |
285
+ | POST | `/api/threads` | スレッドを起票(初回メッセージを同時作成) |
286
+ | GET | `/api/threads/:id` | スレッド詳細 + メッセージ一覧 |
287
+ | POST | `/api/threads/:id/messages` | スレッドにメッセージを投稿 |
288
+ | POST | `/api/threads/:id/resolve` | スレッドを解決済みにする |
289
+ | POST | `/api/threads/:id/cancel` | スレッドをキャンセル |
290
+ | DELETE | `/api/threads/:id` | スレッドを完全削除(PMのみ) |
291
+
292
+ POST `/api/threads` body (ヘルプスレッド起票):
293
293
  ```json
294
294
  {
295
295
  "project_id": "uuid",
296
296
  "thread_type": "help",
297
297
  "title": "ランサーズの2FA認証コードが必要",
298
- "description": "ログイン時に2段階認証を要求された。メールで届く6桁コードの入力が必要。",
298
+ "content": "ログイン時に2段階認証を要求された。メールで届く6桁コードの入力が必要。",
299
299
  "mentions": ["role:pm"],
300
300
  "context": {
301
301
  "category": "auth",
@@ -304,13 +304,13 @@ POST `/api/help-threads` body (ヘルプスレッド起票):
304
304
  }
305
305
  ```
306
306
 
307
- POST `/api/help-threads` body (ディスカッションスレッド起票):
307
+ POST `/api/threads` body (ディスカッションスレッド起票):
308
308
  ```json
309
309
  {
310
310
  "project_id": "uuid",
311
311
  "thread_type": "discussion",
312
312
  "title": "デプロイ手順の確認",
313
- "description": "本番デプロイ前にステージングで確認するフローに変えたい。意見ある?",
313
+ "content": "本番デプロイ前にステージングで確認するフローに変えたい。意見ある?",
314
314
  "mentions": ["role:engineer"]
315
315
  }
316
316
  ```
@@ -320,7 +320,7 @@ POST `/api/help-threads` body (ディスカッションスレッド起票):
320
320
  | `project_id` | string | Yes | プロジェクト UUID |
321
321
  | `thread_type` | string | No | `help`(デフォルト)or `discussion` |
322
322
  | `title` | string | Yes | スレッドの要約 |
323
- | `description` | string | Yes | 詳細説明 |
323
+ | `content` | string | Yes | スレッド本文(thread_messagesの最初のメッセージとして保存) |
324
324
  | `mentions` | string[] | No | メンション対象。形式: `role:engineer`, `role:pm`, `minion:<minion_id>`, `user` |
325
325
  | `context` | object | No | 任意のメタデータ(category, urgency, workflow_execution_id等) |
326
326
 
@@ -334,7 +334,7 @@ POST `/api/help-threads` body (ディスカッションスレッド起票):
334
334
  - トークン消費を抑えるため、当事者が明確な場合はメンションを推奨
335
335
  - ミニオンが自力で解決できない場合、`@user` メンション付きで返信して人間に助けを求める
336
336
 
337
- POST `/api/help-threads/:id/messages` body:
337
+ POST `/api/threads/:id/messages` body:
338
338
  ```json
339
339
  {
340
340
  "content": "関連するプロジェクトメモリーが見つかりました: ...",
@@ -348,14 +348,14 @@ POST `/api/help-threads/:id/messages` body:
348
348
  | `attachments` | object | No | 添付ファイル情報(JSON) |
349
349
  | `mentions` | string[] | No | メンション対象 |
350
350
 
351
- POST `/api/help-threads/:id/resolve` body:
351
+ POST `/api/threads/:id/resolve` body:
352
352
  ```json
353
353
  {
354
354
  "resolution": "ユーザーから2FAコード(123456)を受け取りログイン成功"
355
355
  }
356
356
  ```
357
357
 
358
- POST `/api/help-threads/:id/cancel` body (optional):
358
+ POST `/api/threads/:id/cancel` body (optional):
359
359
  ```json
360
360
  {
361
361
  "reason": "誤って起票したため取り消し"
@@ -409,7 +409,7 @@ POST `/api/project-memories` body:
409
409
  **推奨ワークフロー:**
410
410
  1. ブロッカー発生 → `GET /api/project-memories?project_id=...&category=auth&search=2fa` で既知の知見を検索
411
411
  2. 該当あり → 知見に基づいて自己解決 or 即エスカレーション
412
- 3. 該当なし → `POST /api/help-threads` でブロッカー起票
412
+ 3. 該当なし → `POST /api/threads` でブロッカー起票
413
413
  4. 解決後 → `POST /api/project-memories` で知見を蓄積
414
414
 
415
415
  ### Commands
@@ -770,21 +770,20 @@ Response:
770
770
 
771
771
  スキルはバージョン管理される。push ごとに新バージョンが作成され、ファイルは Supabase Storage に保存される。
772
772
 
773
- ### Help Threads (HQ)
773
+ ### Project Threads (HQ)
774
774
 
775
775
  | Method | Endpoint | Description |
776
776
  |--------|----------|-------------|
777
- | POST | `/api/minion/help-threads` | ブロッカースレッドを起票 |
778
- | GET | `/api/minion/help-threads/open` | 参加プロジェクトの未解決スレッド一覧 |
779
- | GET | `/api/minion/help-threads/:id` | スレッド詳細 + メッセージ一覧 |
780
- | POST | `/api/minion/help-threads/:id/messages` | スレッドにメッセージを投稿 |
781
- | PATCH | `/api/minion/help-threads/:id/resolve` | スレッドを解決済みにする。Body: `{resolution}` |
782
- | PATCH | `/api/minion/help-threads/:id/cancel` | スレッドをキャンセル。Body: `{reason?}` |
783
- | DELETE | `/api/minion/help-threads/:id` | スレッドを完全削除(PMのみ)。メッセージもCASCADE削除 |
784
- | PATCH | `/api/minion/help-threads/:id/escalate` | スレッドを手動エスカレーション |
785
-
786
- ローカルエージェントの `/api/help-threads` は上記 HQ API へのプロキシ。
787
- 詳細なリクエスト/レスポンス仕様はローカル API セクションの「Help Threads」を参照。
777
+ | POST | `/api/minion/threads` | スレッドを起票(初回メッセージを同時作成) |
778
+ | GET | `/api/minion/threads/open` | 参加プロジェクトの未解決スレッド一覧 |
779
+ | GET | `/api/minion/threads/:id` | スレッド詳細 + メッセージ一覧 |
780
+ | POST | `/api/minion/threads/:id/messages` | スレッドにメッセージを投稿 |
781
+ | PATCH | `/api/minion/threads/:id/resolve` | スレッドを解決済みにする。Body: `{resolution}` |
782
+ | PATCH | `/api/minion/threads/:id/cancel` | スレッドをキャンセル。Body: `{reason?}` |
783
+ | DELETE | `/api/minion/threads/:id` | スレッドを完全削除(PMのみ)。メッセージもCASCADE削除 |
784
+
785
+ ローカルエージェントの `/api/threads` は上記 HQ API へのプロキシ。
786
+ 詳細なリクエスト/レスポンス仕様はローカル API セクションの「Project Threads」を参照。
788
787
 
789
788
  ### Project Memories (HQ)
790
789
 
package/linux/server.js CHANGED
@@ -73,7 +73,7 @@ const { memoryRoutes } = require('../core/routes/memory')
73
73
  const { dailyLogRoutes } = require('../core/routes/daily-logs')
74
74
  const { sudoersRoutes } = require('../core/routes/sudoers')
75
75
  const { permissionRoutes } = require('../core/routes/permissions')
76
- const { helpThreadRoutes } = require('../core/routes/help-threads')
76
+ const { threadRoutes } = require('../core/routes/threads')
77
77
  const { daemonRoutes } = require('../core/routes/daemons')
78
78
 
79
79
  // Linux-specific routes
@@ -278,7 +278,7 @@ async function registerAllRoutes(app) {
278
278
  await app.register(dailyLogRoutes)
279
279
  await app.register(sudoersRoutes)
280
280
  await app.register(permissionRoutes)
281
- await app.register(helpThreadRoutes)
281
+ await app.register(threadRoutes)
282
282
  await app.register(daemonRoutes, { heartbeatStatus: () => ({ running: !!heartbeatTimer, last_beat_at: lastBeatAt }) })
283
283
 
284
284
  // Linux-specific routes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekbeer/minion",
3
- "version": "2.68.5",
3
+ "version": "2.70.2",
4
4
  "description": "AI Agent runtime for Minion - manages status and skill deployment on VPS",
5
5
  "main": "linux/server.js",
6
6
  "bin": {
package/win/server.js CHANGED
@@ -57,7 +57,7 @@ const { variableRoutes } = require('../core/routes/variables')
57
57
  const { memoryRoutes } = require('../core/routes/memory')
58
58
  const { dailyLogRoutes } = require('../core/routes/daily-logs')
59
59
  const { permissionRoutes } = require('../core/routes/permissions')
60
- const { helpThreadRoutes } = require('../core/routes/help-threads')
60
+ const { threadRoutes } = require('../core/routes/threads')
61
61
  const { daemonRoutes } = require('../core/routes/daemons')
62
62
 
63
63
  // Validate configuration
@@ -212,7 +212,7 @@ async function registerRoutes(app) {
212
212
  await app.register(memoryRoutes)
213
213
  await app.register(dailyLogRoutes)
214
214
  await app.register(permissionRoutes)
215
- await app.register(helpThreadRoutes)
215
+ await app.register(threadRoutes)
216
216
  await app.register(daemonRoutes, { heartbeatStatus: () => ({ running: !!heartbeatTimer, last_beat_at: lastBeatAt }) })
217
217
 
218
218
  // Shutdown endpoint — allows detached restart/update scripts to trigger