@geekbeer/minion 2.10.3 → 2.16.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/bin/hq ADDED
@@ -0,0 +1,108 @@
1
+ #!/bin/bash
2
+ # HQ API helper for minion chat context
3
+ #
4
+ # Fetches resource details from the HQ server API.
5
+ # Used by Claude CLI during chat to retrieve information about
6
+ # skills, workflows, and projects that the user is viewing on the dashboard.
7
+ #
8
+ # Environment variables (inherited from minion server):
9
+ # HQ_URL - HQ server URL (e.g., https://minion-agent.com)
10
+ # API_TOKEN - Minion API token for authentication
11
+ #
12
+ # Usage:
13
+ # hq fetch skill <name> - Get skill details (content, description, files)
14
+ # hq fetch workflow <name> - Get workflow details (pipeline, cron, etc.)
15
+ # hq fetch project <id> - Get project info (name, description, role)
16
+ # hq fetch project-context <id> - Get project context (shared Markdown document)
17
+
18
+ set -euo pipefail
19
+
20
+ # Validate required environment variables
21
+ if [ -z "${HQ_URL:-}" ]; then
22
+ echo "Error: HQ_URL is not set" >&2
23
+ exit 1
24
+ fi
25
+
26
+ if [ -z "${API_TOKEN:-}" ]; then
27
+ echo "Error: API_TOKEN is not set" >&2
28
+ exit 1
29
+ fi
30
+
31
+ BASE_URL="${HQ_URL}/api/minion"
32
+
33
+ # Pretty-print JSON if jq is available, otherwise output raw
34
+ format_json() {
35
+ if command -v jq &>/dev/null; then
36
+ jq .
37
+ else
38
+ cat
39
+ fi
40
+ }
41
+
42
+ fetch_resource() {
43
+ local url="$1"
44
+ local response
45
+ local http_code
46
+
47
+ # Fetch with HTTP status code
48
+ response=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer $API_TOKEN" "$url")
49
+ http_code=$(echo "$response" | tail -1)
50
+ body=$(echo "$response" | sed '$d')
51
+
52
+ if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
53
+ echo "$body" | format_json
54
+ else
55
+ echo "Error: HQ API returned HTTP $http_code" >&2
56
+ echo "$body" >&2
57
+ exit 1
58
+ fi
59
+ }
60
+
61
+ # Main command dispatch
62
+ case "${1:-}" in
63
+ fetch)
64
+ resource="${2:-}"
65
+ identifier="${3:-}"
66
+
67
+ if [ -z "$resource" ] || [ -z "$identifier" ]; then
68
+ echo "Usage: hq fetch {skill|workflow|project|project-context} <identifier>" >&2
69
+ exit 1
70
+ fi
71
+
72
+ case "$resource" in
73
+ skill)
74
+ fetch_resource "$BASE_URL/skills/$identifier"
75
+ ;;
76
+ workflow)
77
+ fetch_resource "$BASE_URL/workflows/$identifier"
78
+ ;;
79
+ project)
80
+ # Fetch all projects and filter by ID
81
+ response=$(curl -s -H "Authorization: Bearer $API_TOKEN" "$BASE_URL/me/projects")
82
+ if command -v jq &>/dev/null; then
83
+ echo "$response" | jq --arg id "$identifier" '.projects[] | select(.id == $id)'
84
+ else
85
+ echo "$response" | format_json
86
+ fi
87
+ ;;
88
+ project-context)
89
+ fetch_resource "$BASE_URL/me/project/$identifier/context"
90
+ ;;
91
+ *)
92
+ echo "Unknown resource: $resource" >&2
93
+ echo "Usage: hq fetch {skill|workflow|project|project-context} <identifier>" >&2
94
+ exit 1
95
+ ;;
96
+ esac
97
+ ;;
98
+ *)
99
+ echo "HQ API helper for minion chat" >&2
100
+ echo "" >&2
101
+ echo "Usage:" >&2
102
+ echo " hq fetch skill <name> - Get skill details" >&2
103
+ echo " hq fetch workflow <name> - Get workflow details" >&2
104
+ echo " hq fetch project <id> - Get project info" >&2
105
+ echo " hq fetch project-context <id> - Get project context" >&2
106
+ exit 1
107
+ ;;
108
+ esac
package/chat-store.js ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Chat Session Store
3
+ * Persists the active chat session (session_id + messages) to local JSON file.
4
+ * One active session per minion. Claude CLI manages conversation context via --resume.
5
+ */
6
+
7
+ const fs = require('fs').promises
8
+ const path = require('path')
9
+
10
+ const { config } = require('./config')
11
+
12
+ const MAX_MESSAGES = 100
13
+
14
+ /**
15
+ * Get chat session file path
16
+ * Uses /opt/minion-agent/ if available, otherwise home dir
17
+ */
18
+ function getFilePath() {
19
+ const optPath = '/opt/minion-agent/chat-session.json'
20
+ try {
21
+ require('fs').accessSync(path.dirname(optPath))
22
+ return optPath
23
+ } catch {
24
+ return path.join(config.HOME_DIR, 'chat-session.json')
25
+ }
26
+ }
27
+
28
+ const SESSION_FILE = getFilePath()
29
+
30
+ /**
31
+ * Load the active chat session
32
+ * @returns {Promise<object|null>} Session object or null if none exists
33
+ */
34
+ async function load() {
35
+ try {
36
+ const data = await fs.readFile(SESSION_FILE, 'utf-8')
37
+ return JSON.parse(data)
38
+ } catch (err) {
39
+ if (err.code === 'ENOENT') {
40
+ return null
41
+ }
42
+ console.error(`[ChatStore] Failed to load session: ${err.message}`)
43
+ return null
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Save the active chat session
49
+ * @param {object} session - Session object
50
+ */
51
+ async function save(session) {
52
+ try {
53
+ await fs.writeFile(SESSION_FILE, JSON.stringify(session, null, 2), 'utf-8')
54
+ } catch (err) {
55
+ console.error(`[ChatStore] Failed to save session: ${err.message}`)
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Add a message to the active session
61
+ * Creates a new session if none exists
62
+ * @param {string} sessionId - Claude CLI session ID
63
+ * @param {{ role: string, content: string }} msg - Message to add
64
+ */
65
+ async function addMessage(sessionId, msg) {
66
+ let session = await load()
67
+
68
+ // If session_id changed, start a new session
69
+ if (!session || session.session_id !== sessionId) {
70
+ session = {
71
+ session_id: sessionId,
72
+ messages: [],
73
+ created_at: Date.now(),
74
+ updated_at: Date.now(),
75
+ }
76
+ }
77
+
78
+ session.messages.push({
79
+ role: msg.role,
80
+ content: msg.content,
81
+ timestamp: Date.now(),
82
+ })
83
+ session.updated_at = Date.now()
84
+
85
+ // Prune old messages
86
+ if (session.messages.length > MAX_MESSAGES) {
87
+ session.messages = session.messages.slice(-MAX_MESSAGES)
88
+ }
89
+
90
+ await save(session)
91
+ }
92
+
93
+ /**
94
+ * Clear the active session
95
+ */
96
+ async function clear() {
97
+ try {
98
+ await fs.unlink(SESSION_FILE)
99
+ } catch (err) {
100
+ if (err.code !== 'ENOENT') {
101
+ console.error(`[ChatStore] Failed to clear session: ${err.message}`)
102
+ }
103
+ }
104
+ }
105
+
106
+ module.exports = { load, save, addMessage, clear }
@@ -1,67 +1,9 @@
1
- # Minion Agent Environment
1
+ # Minion API Reference
2
2
 
3
- You are running on a Minion VPS managed by the @geekbeer/minion package.
4
- A local Agent API server runs at `http://localhost:3001` and a CLI tool `minion-cli` is available.
3
+ このドキュメントはミニオンが利用可能なAPIの全仕様です。
4
+ HQのソースコードを読む必要はありません 必要な情報はすべてここに記載されています。
5
5
 
6
- ## Architecture: Project / Workflow / Routine
7
-
8
- ```
9
- Project (組織・課金単位)
10
- ├── Context (markdown, PMが更新)
11
- ├── Members (minion + role: pm | engineer)
12
- └── Workflows (何をするか + オプションのcronスケジュール)
13
- ├── Versions (pipeline の不変スナップショット)
14
- └── Executions (実行履歴, ステップごとの進捗)
15
-
16
- Minion
17
- └── Routines (いつ・何を, cron付き, ミニオンローカルのタスク)
18
- ```
19
-
20
- - **Workflow** はプロジェクトスコープ。バージョン管理されたパイプライン(スキル列)を持つ。オプションで `cron_expression` によるスケジュール実行が可能。HQ UIからワンショット実行もできる。
21
- - **Routine** はミニオンスコープ。ミニオンローカルの定期タスク。cron_expression を持ち自律トリガーする。
22
- - ミニオンは複数プロジェクトに `pm` または `engineer` として参加できる。
23
- - ワークフローの各ステップには `assigned_role`(pm/engineer)と `requires_review` フラグがある。
24
-
25
- ## Workflow Execution Model (DB ステートマシン)
26
-
27
- ワークフロー実行はHQのDBがステートマシンとして管理する。ミニオン間通信は不要。
28
-
29
- ```
30
- 1. Execution 作成 (HQ UIのRunボタン or cronスケジュール)
31
- → workflow_execution (status='pending')
32
- → workflow_step_executions (全ステップ status='pending')
33
-
34
- 2. ミニオンエージェントが GET /api/minion/pending-steps をポーリング
35
- → 自分のロールに該当 & 前ステップ完了済みのステップを取得
36
-
37
- 3. ミニオンがステップを実行し完了を報告
38
- → POST /api/minion/execution で status/outcome を更新
39
-
40
- 4. 次ステップが eligible に → 別のミニオンが検知して実行
41
- → requires_review=true の場合はHQでレビュー承認後に次へ
42
-
43
- 5. 全ステップ完了 → execution 全体を completed に
44
- ```
45
-
46
- **ポイント:**
47
- - HQの責務は「executionレコードを作る(指示書発行)」だけ
48
- - 各ミニオンは自分の担当ステップだけをポーリングして実行
49
- - ミニオンエージェント(Port 3001)が軽量HTTPポーリングを行い、pending検知時のみClaude Codeを起動(トークン節約)
50
-
51
- ## CLI Commands
52
-
53
- ```bash
54
- minion-cli status # Get current status (online/offline/busy)
55
- minion-cli health # Health check
56
- minion-cli set-status <status> [task] # Set status and optional task description
57
- minion-cli skill push <name> # Push local skill to HQ
58
- minion-cli skill fetch <name> # Fetch skill from HQ to local
59
- minion-cli skill list # List skills on HQ
60
- minion-cli skill list --local # List local deployed skills
61
- minion-cli --version # Show package version
62
- # Service management (requires sudo):
63
- # sudo minion-cli start | stop | restart
64
- ```
6
+ ---
65
7
 
66
8
  ## Agent API Endpoints (http://localhost:3001)
67
9
 
@@ -142,6 +84,8 @@ Files are stored in `~/files/`. Max upload size: 50MB.
142
84
 
143
85
  Available commands: `restart-agent`, `update-agent`, `restart-display`, `status-services`
144
86
 
87
+ ---
88
+
145
89
  ## HQ API Endpoints (https://<HQ_URL>)
146
90
 
147
91
  Authentication: `Authorization: Bearer $API_TOKEN` header.
@@ -230,6 +174,60 @@ POST body (push):
230
174
 
231
175
  push するとパイプライン内のスキル名が `skill_version_id` に解決され、新バージョンが自動作成される。
232
176
 
177
+ ### Workflow Structure
178
+
179
+ ```json
180
+ {
181
+ "name": "my-workflow",
182
+ "pipeline_skill_names": ["skill-1", "skill-2", "execution-report"],
183
+ "pipeline": [
184
+ {
185
+ "skill_version_id": "uuid",
186
+ "skill_name": "skill-1",
187
+ "skill_display_name": "Skill One",
188
+ "skill_version": 2,
189
+ "assigned_role": "engineer",
190
+ "requires_review": false,
191
+ "is_my_step": true
192
+ }
193
+ ],
194
+ "content": "Markdown description of the workflow",
195
+ "version": 2,
196
+ "cron_expression": "0 9 * * *",
197
+ "project_id": "uuid"
198
+ }
199
+ ```
200
+
201
+ | Field | Type | Description |
202
+ |-------|------|-------------|
203
+ | `name` | string | Slug identifier (`/^[a-z0-9-]+$/`) |
204
+ | `pipeline_skill_names` | string[] | Ordered skill names (for display/push) |
205
+ | `pipeline` | PipelineStep[] | Resolved pipeline with version IDs and roles |
206
+ | `content` | string | Markdown body describing the workflow |
207
+ | `version` | number | Current version number (auto-incremented on push) |
208
+ | `cron_expression` | string\|null | Cron schedule (null = manual/one-shot only) |
209
+ | `project_id` | string | UUID of the parent project |
210
+
211
+ ### Pipeline Step Fields
212
+
213
+ | Field | Type | Description |
214
+ |-------|------|-------------|
215
+ | `skill_version_id` | string | UUID of the specific skill version |
216
+ | `skill_name` | string | Skill slug name |
217
+ | `skill_display_name` | string | Human-readable skill name |
218
+ | `skill_version` | number | Skill version number |
219
+ | `assigned_role` | string | `"pm"` or `"engineer"` — who executes this step |
220
+ | `requires_review` | boolean | If true, human review required after completion |
221
+ | `is_my_step` | boolean | Whether this minion's role matches assigned_role |
222
+
223
+ ### Syncing Workflows with HQ
224
+
225
+ - `POST /api/workflows/push/:name` — Push local workflow to HQ. Pipeline skills are auto-pushed first.
226
+ - `POST /api/workflows/fetch/:name` — Fetch workflow from HQ. Missing pipeline skills are auto-fetched.
227
+ - `GET /api/workflows/remote` — List workflows available on HQ.
228
+
229
+ Pipeline skills must be deployed locally (in `~/.claude/skills/`) before pushing a workflow.
230
+
233
231
  ### Pending Steps (軽量ポーリング)
234
232
 
235
233
  | Method | Endpoint | Description |
@@ -237,7 +235,6 @@ push するとパイプライン内のスキル名が `skill_version_id` に解
237
235
  | GET | `/api/minion/pending-steps` | 自分が実行すべき pending ステップ一覧 |
238
236
 
239
237
  **このエンドポイントはミニオンエージェント(非AI)による高頻度ポーリング用。**
240
- Claude Code(AIスキル実行)はステップ検知時のみ起動する。
241
238
 
242
239
  Response:
243
240
  ```json
@@ -329,7 +326,7 @@ Response:
329
326
 
330
327
  使用可能なラベル: `bug`, `enhancement`, `critical`, `minor`
331
328
 
332
- **使い方:** サービスのバグや改善点を発見したら、このエンドポイントで GitHub Issue を起票する。報告者のミニオン名と ID が自動で本文に付記される。
329
+ 報告者のミニオン名と ID が自動で本文に付記される。
333
330
 
334
331
  ### Routines (minion-scoped)
335
332
 
@@ -355,127 +352,7 @@ Response:
355
352
  ]
356
353
  ```
357
354
 
358
- ### Skills
359
-
360
- | Method | Endpoint | Description |
361
- |--------|----------|-------------|
362
- | GET | `/api/minion/skills` | HQ に登録されたスキル一覧 |
363
- | GET | `/api/minion/skills/[name]` | スキル詳細取得(content, files 含む) |
364
- | POST | `/api/minion/skills` | スキル登録/更新(新バージョン自動作成) |
365
-
366
- スキルはバージョン管理される。push ごとに新バージョンが作成され、ファイルは Supabase Storage に保存される。
367
-
368
- ## Environment Variables
369
-
370
- | Variable | Description |
371
- |----------|-------------|
372
- | `HQ_URL` | HQ server URL (empty = standalone mode) |
373
- | `API_TOKEN` | Bearer token for HQ and local API auth |
374
- | `MINION_ID` | UUID assigned by HQ |
375
- | `AGENT_PORT` | Agent HTTP port (default: 3001) |
376
- | `MINION_USER` | System user running the agent |
377
-
378
- ## Skills Directory Structure
379
-
380
- Skills are stored in `~/.claude/skills/<name>/`:
381
-
382
- ```
383
- ~/.claude/skills/<name>/
384
- SKILL.md # Skill definition (YAML frontmatter + markdown body)
385
- references/ # Optional supporting files
386
- ```
387
-
388
- SKILL.md format:
389
- ```markdown
390
- ---
391
- name: my-skill
392
- description: What this skill does
393
- ---
394
-
395
- Skill instructions here...
396
- ```
397
-
398
- ## HQ Connection
399
-
400
- When `HQ_URL` and `API_TOKEN` are set, the agent sends heartbeats and syncs with HQ.
401
- Use `minion-cli skill push/fetch` to sync skills between local and HQ.
402
- Use the workflow API endpoints (`/api/workflows/push/:name`, `/api/workflows/fetch/:name`) to sync workflows.
403
- When not configured, the agent runs in standalone mode and HQ-dependent features return errors.
404
-
405
- ## Workflow Structure
406
-
407
- Workflows are project-scoped and versioned. Each version is an immutable snapshot of the pipeline.
408
- Fetched from HQ via `GET /api/minion/workflows`. Also stored locally in `workflows.json`.
409
-
410
- ```json
411
- {
412
- "name": "my-workflow",
413
- "pipeline_skill_names": ["skill-1", "skill-2", "execution-report"],
414
- "pipeline": [
415
- {
416
- "skill_version_id": "uuid",
417
- "skill_name": "skill-1",
418
- "skill_display_name": "Skill One",
419
- "skill_version": 2,
420
- "assigned_role": "engineer",
421
- "requires_review": false,
422
- "is_my_step": true
423
- }
424
- ],
425
- "content": "Markdown description of the workflow",
426
- "version": 2,
427
- "cron_expression": "0 9 * * *",
428
- "project_id": "uuid"
429
- }
430
- ```
431
-
432
- | Field | Type | Description |
433
- |-------|------|-------------|
434
- | `name` | string | Slug identifier (`/^[a-z0-9-]+$/`) |
435
- | `pipeline_skill_names` | string[] | Ordered skill names (for display/push) |
436
- | `pipeline` | PipelineStep[] | Resolved pipeline with version IDs and roles |
437
- | `content` | string | Markdown body describing the workflow |
438
- | `version` | number | Current version number (auto-incremented on push) |
439
- | `cron_expression` | string\|null | Cron schedule (null = manual/one-shot only) |
440
- | `project_id` | string | UUID of the parent project |
441
-
442
- ### Pipeline Step Fields
443
-
444
- | Field | Type | Description |
445
- |-------|------|-------------|
446
- | `skill_version_id` | string | UUID of the specific skill version |
447
- | `skill_name` | string | Skill slug name |
448
- | `skill_display_name` | string | Human-readable skill name |
449
- | `skill_version` | number | Skill version number |
450
- | `assigned_role` | string | `"pm"` or `"engineer"` — who executes this step |
451
- | `requires_review` | boolean | If true, human review required after completion |
452
- | `is_my_step` | boolean | Whether this minion's role matches assigned_role |
453
-
454
- ### Syncing workflows with HQ
455
-
456
- - `POST /api/workflows/push/:name` — Push local workflow to HQ. Pipeline skills are auto-pushed first.
457
- - `POST /api/workflows/fetch/:name` — Fetch workflow from HQ. Missing pipeline skills are auto-fetched.
458
- - `GET /api/workflows/remote` — List workflows available on HQ.
459
-
460
- Pipeline skills must be deployed locally (in `~/.claude/skills/`) before pushing a workflow.
461
-
462
- ## Routine Structure
463
-
464
- Routines are minion-scoped and fetched from HQ via `GET /api/minion/routines`.
465
- They are also stored locally in `routines.json`. Each routine object:
466
-
467
- ```json
468
- {
469
- "id": "uuid",
470
- "name": "morning-work",
471
- "pipeline_skill_names": ["project-workflow-check", "execution-report"],
472
- "content": "Markdown description of the routine",
473
- "cron_expression": "0 9 * * 1-5",
474
- "is_active": true,
475
- "last_run": "2026-02-10T09:00:00.000Z",
476
- "next_run": "2026-02-11T09:00:00.000Z"
477
- }
478
- ```
355
+ ### Routine Structure
479
356
 
480
357
  | Field | Type | Description |
481
358
  |-------|------|-------------|
@@ -488,44 +365,12 @@ They are also stored locally in `routines.json`. Each routine object:
488
365
  | `last_run` | string\|null | ISO timestamp of last execution |
489
366
  | `next_run` | string\|null | ISO timestamp of next scheduled run |
490
367
 
491
- ## Routine Execution
492
-
493
- Routines run on cron schedules. Each execution:
494
- 1. Creates a tmux session
495
- 2. Runs skills in pipeline order via `claude --dangerously-skip-permissions`
496
- 3. Appends `execution-report` skill to report outcome
497
- 4. Environment variables `MINION_EXECUTION_ID`, `MINION_ROUTINE_ID`, `MINION_ROUTINE_NAME` are available during execution
498
-
499
- ## Workflow Step Execution via Pending Steps
500
-
501
- ミニオンエージェントは `GET /api/minion/pending-steps` を定期ポーリングし、
502
- 自分の担当ステップを検知したら Claude Code を起動してスキルを実行する。
503
-
504
- ```
505
- ミニオンエージェント (Port 3001, 常駐, トークン不要)
506
-
507
- ├── 軽量ポーリング: N秒ごとに GET /api/minion/pending-steps
508
- │ → HTTPのみ、AIなし、コストゼロ
509
- │ → pendingステップがなければ何もしない
510
-
511
- └── ステップ検知時のみ:
512
- 1. Claude Code 起動 → 該当スキルを実行
513
- 2. POST /api/minion/execution → ステップ完了を報告
514
- 3. Claude Code 終了 → トークン消費はここだけ
515
- ```
516
-
517
- ### Workflow Execution via Routine (従来方式)
368
+ ### Skills
518
369
 
519
- ワークフローは `project-workflow-check` システムスキルを通じてルーティンからも実行可能:
370
+ | Method | Endpoint | Description |
371
+ |--------|----------|-------------|
372
+ | GET | `/api/minion/skills` | HQ に登録されたスキル一覧 |
373
+ | GET | `/api/minion/skills/[name]` | スキル詳細取得(content, files 含む) |
374
+ | POST | `/api/minion/skills` | スキル登録/更新(新バージョン自動作成) |
520
375
 
521
- ```
522
- ルーティン: "morning-work" (cron: 0 9 * * 1-5)
523
- pipeline: [project-workflow-check, execution-report]
524
-
525
- project-workflow-check:
526
- 1. GET /api/minion/me/projects → 参加プロジェクト一覧
527
- 2. GET /api/minion/workflows → active なワークフロー一覧
528
- 3. 各ワークフローの pipeline を順に実行
529
-
530
- execution-report → HQ に結果報告
531
- ```
376
+ スキルはバージョン管理される。push ごとに新バージョンが作成され、ファイルは Supabase Storage に保存される。