@geekbeer/minion 3.25.0 → 3.26.0
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/docs/api-reference.md +53 -0
- package/linux/bin/hq +174 -0
- package/linux/routes/chat.js +16 -0
- package/package.json +1 -1
- package/rules/core.md +56 -0
- package/win/routes/chat.js +16 -0
package/docs/api-reference.md
CHANGED
|
@@ -117,6 +117,7 @@ curl http://localhost:8080/api/terminal/wsl/status \
|
|
|
117
117
|
### Files
|
|
118
118
|
|
|
119
119
|
Files are stored in `~/files/`. Max upload size: 50MB.
|
|
120
|
+
**バイナリ成果物(PDF、画像、ZIP等)はここに配置する。** ユーザーがHQダッシュボードからダウンロードできる。
|
|
120
121
|
|
|
121
122
|
| Method | Endpoint | Description |
|
|
122
123
|
|--------|----------|-------------|
|
|
@@ -1448,3 +1449,55 @@ Response:
|
|
|
1448
1449
|
|
|
1449
1450
|
ローカルエージェントの `/api/project-memories` は上記 HQ API へのプロキシ。
|
|
1450
1451
|
詳細なリクエスト/レスポンス仕様はローカル API セクションの「Project Memories」を参照。
|
|
1452
|
+
|
|
1453
|
+
### Notes (HQ, プロジェクトノート)
|
|
1454
|
+
|
|
1455
|
+
プロジェクトに紐づくノート。**テキストベースの成果物(レポート、調査結果、要約等)はノートに保存すること。**
|
|
1456
|
+
ノートはHQダッシュボードでユーザーが即座に閲覧・編集・検索でき、バージョン管理もされる。
|
|
1457
|
+
|
|
1458
|
+
| Method | Endpoint | Description |
|
|
1459
|
+
|--------|----------|-------------|
|
|
1460
|
+
| GET | `/api/minion/projects/:projectId/notes` | プロジェクトのノート一覧。Query: `?status=active&include_content=true` |
|
|
1461
|
+
| POST | `/api/minion/projects/:projectId/notes` | ノートを作成しプロジェクトにリンク |
|
|
1462
|
+
| GET | `/api/minion/projects/:projectId/notes/:noteId` | ノート詳細(全文含む) |
|
|
1463
|
+
| PATCH | `/api/minion/projects/:projectId/notes/:noteId` | ノートを更新(内容変更時にバージョン自動作成) |
|
|
1464
|
+
| GET | `/api/minion/projects/:projectId/notes/search?q=keyword` | ノートを全文検索 |
|
|
1465
|
+
|
|
1466
|
+
POST `/api/minion/projects/:projectId/notes` body:
|
|
1467
|
+
```json
|
|
1468
|
+
{
|
|
1469
|
+
"title": "調査レポート: ユーザー行動分析",
|
|
1470
|
+
"content": "## 概要\n..."
|
|
1471
|
+
}
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
| Field | Type | Required | Description |
|
|
1475
|
+
|-------|------|----------|-------------|
|
|
1476
|
+
| `title` | string | Yes | ノートのタイトル |
|
|
1477
|
+
| `content` | string | No | ノートの本文(Markdown) |
|
|
1478
|
+
|
|
1479
|
+
PATCH `/api/minion/projects/:projectId/notes/:noteId` body:
|
|
1480
|
+
```json
|
|
1481
|
+
{
|
|
1482
|
+
"title": "更新されたタイトル",
|
|
1483
|
+
"content": "更新された本文",
|
|
1484
|
+
"change_summary": "データを追加"
|
|
1485
|
+
}
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
| Field | Type | Required | Description |
|
|
1489
|
+
|-------|------|----------|-------------|
|
|
1490
|
+
| `title` | string | No | 新しいタイトル |
|
|
1491
|
+
| `content` | string | No | 新しい本文 |
|
|
1492
|
+
| `change_summary` | string | No | 変更の要約(バージョン履歴に記録) |
|
|
1493
|
+
|
|
1494
|
+
#### hq CLI ラッパー
|
|
1495
|
+
|
|
1496
|
+
```bash
|
|
1497
|
+
hq note create <project_id> --title "タイトル" --content "本文"
|
|
1498
|
+
hq note create <project_id> --title "タイトル" --file /tmp/report.md
|
|
1499
|
+
hq note update <project_id> <note_id> --content "更新内容" --change-summary "修正理由"
|
|
1500
|
+
hq note list <project_id>
|
|
1501
|
+
hq note get <project_id> <note_id>
|
|
1502
|
+
hq note search <project_id> "キーワード"
|
|
1503
|
+
```
|
package/linux/bin/hq
CHANGED
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
# hq fetch dag-workflow <id> - Get DAG workflow details (graph, version)
|
|
18
18
|
# hq fetch dag-execution <id> - Get DAG execution details (nodes, status)
|
|
19
19
|
# hq list workspaces - List workspaces this minion belongs to
|
|
20
|
+
# hq note create <project_id> --title "Title" --content "Body" [--file path]
|
|
21
|
+
# - Create a note linked to the project
|
|
22
|
+
# hq note update <project_id> <note_id> --content "Body" [--title "Title"] [--file path] [--change-summary "summary"]
|
|
23
|
+
# - Update an existing note
|
|
24
|
+
# hq note list <project_id> - List notes in the project
|
|
25
|
+
# hq note get <project_id> <note_id> - Get a single note with full content
|
|
26
|
+
# hq note search <project_id> <query> - Search notes in the project
|
|
20
27
|
# hq create dag-workflow <body.json> - Create a DAG workflow (PM only). Body: {project_id, name, graph?, ...}
|
|
21
28
|
# hq put dag-workflow <id> <body.json> - Update DAG workflow draft (PM only). Body: {graph?, content?, ...}
|
|
22
29
|
# hq publish dag-workflow <id> - Publish the draft as a new version (PM only, validated)
|
|
@@ -146,6 +153,11 @@ print_usage() {
|
|
|
146
153
|
echo " hq fetch dag-workflow <id> - Get DAG workflow details" >&2
|
|
147
154
|
echo " hq fetch dag-execution <id> - Get DAG execution details" >&2
|
|
148
155
|
echo " hq list workspaces - List workspaces this minion belongs to" >&2
|
|
156
|
+
echo " hq note create <project_id> --title \"Title\" --content \"Body\" [--file path]" >&2
|
|
157
|
+
echo " hq note update <project_id> <note_id> --content \"Body\" [--title \"Title\"] [--file path]" >&2
|
|
158
|
+
echo " hq note list <project_id> - List notes in the project" >&2
|
|
159
|
+
echo " hq note get <project_id> <note_id> - Get a single note" >&2
|
|
160
|
+
echo " hq note search <project_id> <query> - Search notes in the project" >&2
|
|
149
161
|
echo " hq create dag-workflow <body.json> - Create a DAG workflow (PM only)" >&2
|
|
150
162
|
echo " hq put dag-workflow <id> <body.json> - Update DAG workflow draft (PM only)" >&2
|
|
151
163
|
echo " hq publish dag-workflow <id> - Publish the draft as a new version (PM only)" >&2
|
|
@@ -270,6 +282,168 @@ case "${1:-}" in
|
|
|
270
282
|
esac
|
|
271
283
|
;;
|
|
272
284
|
|
|
285
|
+
note)
|
|
286
|
+
action="${2:-}"
|
|
287
|
+
case "$action" in
|
|
288
|
+
create)
|
|
289
|
+
project_id="${3:-}"
|
|
290
|
+
if [ -z "$project_id" ]; then
|
|
291
|
+
echo "Usage: hq note create <project_id> --title \"Title\" --content \"Body\" [--file path]" >&2
|
|
292
|
+
exit 1
|
|
293
|
+
fi
|
|
294
|
+
shift 3
|
|
295
|
+
note_title=""
|
|
296
|
+
note_content=""
|
|
297
|
+
note_file=""
|
|
298
|
+
while [ $# -gt 0 ]; do
|
|
299
|
+
case "$1" in
|
|
300
|
+
--title) note_title="$2"; shift 2 ;;
|
|
301
|
+
--content) note_content="$2"; shift 2 ;;
|
|
302
|
+
--file) note_file="$2"; shift 2 ;;
|
|
303
|
+
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
304
|
+
esac
|
|
305
|
+
done
|
|
306
|
+
if [ -z "$note_title" ]; then
|
|
307
|
+
echo "Error: --title is required" >&2
|
|
308
|
+
exit 1
|
|
309
|
+
fi
|
|
310
|
+
if [ -n "$note_file" ]; then
|
|
311
|
+
if [ ! -f "$note_file" ]; then
|
|
312
|
+
echo "Error: file not found: $note_file" >&2
|
|
313
|
+
exit 1
|
|
314
|
+
fi
|
|
315
|
+
note_content=$(cat "$note_file")
|
|
316
|
+
fi
|
|
317
|
+
if [ -z "$note_content" ]; then
|
|
318
|
+
echo "Error: --content or --file is required" >&2
|
|
319
|
+
exit 1
|
|
320
|
+
fi
|
|
321
|
+
# Build JSON body using jq or python3
|
|
322
|
+
if command -v jq &>/dev/null; then
|
|
323
|
+
body=$(jq -n --arg t "$note_title" --arg c "$note_content" '{title: $t, content: $c}')
|
|
324
|
+
elif command -v python3 &>/dev/null; then
|
|
325
|
+
body=$(python3 -c "import json,sys; print(json.dumps({'title': sys.argv[1], 'content': sys.argv[2]}))" "$note_title" "$note_content")
|
|
326
|
+
else
|
|
327
|
+
echo "Error: jq or python3 is required to build JSON" >&2
|
|
328
|
+
exit 1
|
|
329
|
+
fi
|
|
330
|
+
tmpfile=$(mktemp)
|
|
331
|
+
echo "$body" > "$tmpfile"
|
|
332
|
+
send_json_request POST "$BASE_URL/projects/$project_id/notes" "$tmpfile"
|
|
333
|
+
rm -f "$tmpfile"
|
|
334
|
+
;;
|
|
335
|
+
update)
|
|
336
|
+
project_id="${3:-}"
|
|
337
|
+
note_id="${4:-}"
|
|
338
|
+
if [ -z "$project_id" ] || [ -z "$note_id" ]; then
|
|
339
|
+
echo "Usage: hq note update <project_id> <note_id> --content \"Body\" [--title \"Title\"] [--file path] [--change-summary \"summary\"]" >&2
|
|
340
|
+
exit 1
|
|
341
|
+
fi
|
|
342
|
+
shift 4
|
|
343
|
+
note_title=""
|
|
344
|
+
note_content=""
|
|
345
|
+
note_file=""
|
|
346
|
+
change_summary=""
|
|
347
|
+
while [ $# -gt 0 ]; do
|
|
348
|
+
case "$1" in
|
|
349
|
+
--title) note_title="$2"; shift 2 ;;
|
|
350
|
+
--content) note_content="$2"; shift 2 ;;
|
|
351
|
+
--file) note_file="$2"; shift 2 ;;
|
|
352
|
+
--change-summary) change_summary="$2"; shift 2 ;;
|
|
353
|
+
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
354
|
+
esac
|
|
355
|
+
done
|
|
356
|
+
if [ -n "$note_file" ]; then
|
|
357
|
+
if [ ! -f "$note_file" ]; then
|
|
358
|
+
echo "Error: file not found: $note_file" >&2
|
|
359
|
+
exit 1
|
|
360
|
+
fi
|
|
361
|
+
note_content=$(cat "$note_file")
|
|
362
|
+
fi
|
|
363
|
+
if [ -z "$note_content" ] && [ -z "$note_title" ]; then
|
|
364
|
+
echo "Error: at least --content, --file, or --title is required" >&2
|
|
365
|
+
exit 1
|
|
366
|
+
fi
|
|
367
|
+
# Build JSON body
|
|
368
|
+
if command -v jq &>/dev/null; then
|
|
369
|
+
body="{}"
|
|
370
|
+
[ -n "$note_title" ] && body=$(echo "$body" | jq --arg t "$note_title" '. + {title: $t}')
|
|
371
|
+
[ -n "$note_content" ] && body=$(echo "$body" | jq --arg c "$note_content" '. + {content: $c}')
|
|
372
|
+
[ -n "$change_summary" ] && body=$(echo "$body" | jq --arg s "$change_summary" '. + {change_summary: $s}')
|
|
373
|
+
elif command -v python3 &>/dev/null; then
|
|
374
|
+
body=$(python3 -c "
|
|
375
|
+
import json, sys
|
|
376
|
+
d = {}
|
|
377
|
+
if sys.argv[1]: d['title'] = sys.argv[1]
|
|
378
|
+
if sys.argv[2]: d['content'] = sys.argv[2]
|
|
379
|
+
if sys.argv[3]: d['change_summary'] = sys.argv[3]
|
|
380
|
+
print(json.dumps(d))
|
|
381
|
+
" "$note_title" "$note_content" "$change_summary")
|
|
382
|
+
else
|
|
383
|
+
echo "Error: jq or python3 is required to build JSON" >&2
|
|
384
|
+
exit 1
|
|
385
|
+
fi
|
|
386
|
+
tmpfile=$(mktemp)
|
|
387
|
+
echo "$body" > "$tmpfile"
|
|
388
|
+
# Use PATCH for update
|
|
389
|
+
response=$(curl -s -w "\n%{http_code}" -X PATCH \
|
|
390
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
391
|
+
-H "Content-Type: application/json" \
|
|
392
|
+
--data-binary "@$tmpfile" \
|
|
393
|
+
"$BASE_URL/projects/$project_id/notes/$note_id")
|
|
394
|
+
rm -f "$tmpfile"
|
|
395
|
+
http_code=$(echo "$response" | tail -1)
|
|
396
|
+
body_out=$(echo "$response" | sed '$d')
|
|
397
|
+
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
|
|
398
|
+
echo "$body_out" | format_json
|
|
399
|
+
else
|
|
400
|
+
echo "Error: HQ API returned HTTP $http_code" >&2
|
|
401
|
+
echo "$body_out" >&2
|
|
402
|
+
exit 1
|
|
403
|
+
fi
|
|
404
|
+
;;
|
|
405
|
+
list)
|
|
406
|
+
project_id="${3:-}"
|
|
407
|
+
if [ -z "$project_id" ]; then
|
|
408
|
+
echo "Usage: hq note list <project_id>" >&2
|
|
409
|
+
exit 1
|
|
410
|
+
fi
|
|
411
|
+
fetch_resource "$BASE_URL/projects/$project_id/notes?include_content=false"
|
|
412
|
+
;;
|
|
413
|
+
get)
|
|
414
|
+
project_id="${3:-}"
|
|
415
|
+
note_id="${4:-}"
|
|
416
|
+
if [ -z "$project_id" ] || [ -z "$note_id" ]; then
|
|
417
|
+
echo "Usage: hq note get <project_id> <note_id>" >&2
|
|
418
|
+
exit 1
|
|
419
|
+
fi
|
|
420
|
+
fetch_resource "$BASE_URL/projects/$project_id/notes/$note_id"
|
|
421
|
+
;;
|
|
422
|
+
search)
|
|
423
|
+
project_id="${3:-}"
|
|
424
|
+
query="${4:-}"
|
|
425
|
+
if [ -z "$project_id" ] || [ -z "$query" ]; then
|
|
426
|
+
echo "Usage: hq note search <project_id> <query>" >&2
|
|
427
|
+
exit 1
|
|
428
|
+
fi
|
|
429
|
+
# URL-encode the query
|
|
430
|
+
if command -v jq &>/dev/null; then
|
|
431
|
+
encoded=$(printf '%s' "$query" | jq -sRr @uri)
|
|
432
|
+
elif command -v python3 &>/dev/null; then
|
|
433
|
+
encoded=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$query")
|
|
434
|
+
else
|
|
435
|
+
encoded="$query"
|
|
436
|
+
fi
|
|
437
|
+
fetch_resource "$BASE_URL/projects/$project_id/notes/search?q=$encoded"
|
|
438
|
+
;;
|
|
439
|
+
*)
|
|
440
|
+
echo "Unknown note action: $action" >&2
|
|
441
|
+
echo "Usage: hq note {create|update|list|get|search} ..." >&2
|
|
442
|
+
exit 1
|
|
443
|
+
;;
|
|
444
|
+
esac
|
|
445
|
+
;;
|
|
446
|
+
|
|
273
447
|
*)
|
|
274
448
|
print_usage
|
|
275
449
|
exit 1
|
package/linux/routes/chat.js
CHANGED
|
@@ -337,6 +337,22 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
337
337
|
)
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
+
// File output guidance — always inject on new sessions
|
|
341
|
+
if (!sessionId) {
|
|
342
|
+
parts.push(
|
|
343
|
+
'[ファイル出力ルール]',
|
|
344
|
+
'成果物の保存先は以下のルールに従うこと。`/home/minion/` 直下にファイルを保存しないこと。',
|
|
345
|
+
'',
|
|
346
|
+
'- **テキスト成果物**(レポート、調査結果、要約等)→ ノートに保存: `hq note create <project_id> --title "タイトル" --content "本文"`',
|
|
347
|
+
'- **バイナリファイル**(PDF、画像、ZIP等)→ `~/files/` に配置(ユーザーがHQからダウンロード可能)',
|
|
348
|
+
'- **一時ファイル** → `/tmp/` に配置(作業後に削除)',
|
|
349
|
+
'',
|
|
350
|
+
'プロジェクトコンテキストがない場合、テキスト成果物はローカルメモリ(`POST /api/memory`)に保存する。',
|
|
351
|
+
'詳細は `~/.minion/rules/core.md` の「File Output Rules」セクションを参照。',
|
|
352
|
+
''
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
|
|
340
356
|
if (context) {
|
|
341
357
|
switch (context.type) {
|
|
342
358
|
case 'skill':
|
package/package.json
CHANGED
package/rules/core.md
CHANGED
|
@@ -307,6 +307,62 @@ API詳細は `~/.minion/docs/api-reference.md` の「Todos」セクションを
|
|
|
307
307
|
- **ブロッカーが解決したらスレッドを `resolve` する。** 放置しない。
|
|
308
308
|
- **解決策をプロジェクトメモリーに保存する。** 同じブロッカーに再度遭遇する他のミニオンの助けになる。
|
|
309
309
|
|
|
310
|
+
## File Output Rules (ファイル出力ルール)
|
|
311
|
+
|
|
312
|
+
成果物の保存先は以下のルールに従うこと。**`/home/minion/` 直下にファイルを保存してはならない。** ユーザーがHQダッシュボードからアクセスできない場所にファイルを置いても意味がない。
|
|
313
|
+
|
|
314
|
+
### 保存先の判断基準
|
|
315
|
+
|
|
316
|
+
| 出力タイプ | 保存先 | 理由 |
|
|
317
|
+
|-----------|--------|------|
|
|
318
|
+
| テキスト(レポート、調査結果、要約、分析結果等) | **ノート** (`hq note create`) | HQダッシュボードで即閲覧・編集・検索可能。バージョン管理もされる |
|
|
319
|
+
| バイナリ(PDF、画像、ZIP、Excel等) | **`~/files/`** | Files API経由でユーザーがダウンロード可能 |
|
|
320
|
+
| コード・設定ファイル | **ワークスペース内の適切なディレクトリ** | プロジェクトのリポジトリやワークスペースに配置 |
|
|
321
|
+
| 一時ファイル(中間データ、一時スクリプト等) | **`/tmp/`** | ユーザーに見せる必要なし。作業後に削除 |
|
|
322
|
+
|
|
323
|
+
### ノートへの保存 (`hq note` コマンド)
|
|
324
|
+
|
|
325
|
+
テキストベースの成果物は原則ノートに保存する。ノートはプロジェクトに紐づき、HQダッシュボードで閲覧できる。
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# ノートを作成(プロジェクトに紐づけ)
|
|
329
|
+
hq note create <project_id> --title "レポートタイトル" --content "本文..."
|
|
330
|
+
|
|
331
|
+
# 長い内容はファイルから読み込む
|
|
332
|
+
hq note create <project_id> --title "調査結果" --file /tmp/report.md
|
|
333
|
+
|
|
334
|
+
# 既存ノートを更新
|
|
335
|
+
hq note update <project_id> <note_id> --content "更新された内容"
|
|
336
|
+
|
|
337
|
+
# ノート一覧を確認
|
|
338
|
+
hq note list <project_id>
|
|
339
|
+
|
|
340
|
+
# ノート内容を取得
|
|
341
|
+
hq note get <project_id> <note_id>
|
|
342
|
+
|
|
343
|
+
# ノートを検索
|
|
344
|
+
hq note search <project_id> "キーワード"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### `~/files/` への保存
|
|
348
|
+
|
|
349
|
+
バイナリファイルやユーザーがダウンロードする必要があるファイルは `~/files/` に配置する。
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# ファイルを保存(~/files/ 配下に自動配置)
|
|
353
|
+
cp /tmp/output.pdf ~/files/output.pdf
|
|
354
|
+
|
|
355
|
+
# サブディレクトリで整理も可能
|
|
356
|
+
mkdir -p ~/files/reports/2026-04
|
|
357
|
+
cp /tmp/report.pdf ~/files/reports/2026-04/report.pdf
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### プロジェクトコンテキストがない場合
|
|
361
|
+
|
|
362
|
+
チャットやルーティンなど、プロジェクトに紐づかない作業の場合:
|
|
363
|
+
- テキスト成果物 → ローカルメモリ (`POST /api/memory`) に保存
|
|
364
|
+
- バイナリファイル → `~/files/` に保存
|
|
365
|
+
|
|
310
366
|
## Documentation
|
|
311
367
|
|
|
312
368
|
API仕様やタスク手順の詳細は以下を参照:
|
package/win/routes/chat.js
CHANGED
|
@@ -400,6 +400,22 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
400
400
|
)
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
// File output guidance — always inject on new sessions
|
|
404
|
+
if (!sessionId) {
|
|
405
|
+
parts.push(
|
|
406
|
+
'[ファイル出力ルール]',
|
|
407
|
+
'成果物の保存先は以下のルールに従うこと。`/home/minion/` 直下にファイルを保存しないこと。',
|
|
408
|
+
'',
|
|
409
|
+
'- **テキスト成果物**(レポート、調査結果、要約等)→ ノートに保存: `hq note create <project_id> --title "タイトル" --content "本文"`',
|
|
410
|
+
'- **バイナリファイル**(PDF、画像、ZIP等)→ `~/files/` に配置(ユーザーがHQからダウンロード可能)',
|
|
411
|
+
'- **一時ファイル** → `/tmp/` に配置(作業後に削除)',
|
|
412
|
+
'',
|
|
413
|
+
'プロジェクトコンテキストがない場合、テキスト成果物はローカルメモリ(`POST /api/memory`)に保存する。',
|
|
414
|
+
'詳細は `~/.minion/rules/core.md` の「File Output Rules」セクションを参照。',
|
|
415
|
+
''
|
|
416
|
+
)
|
|
417
|
+
}
|
|
418
|
+
|
|
403
419
|
if (context) {
|
|
404
420
|
switch (context.type) {
|
|
405
421
|
case 'skill':
|