@geekbeer/minion 3.30.0 → 3.34.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/core/lib/dag-step-poller.js +2 -1
- package/core/llm-plugins/claude/stream.js +1 -1
- package/docs/api-reference.md +39 -1
- package/linux/minion-cli.sh +18 -3
- package/linux/routes/chat.js +34 -3
- package/linux/workflow-runner.js +4 -2
- package/package.json +1 -1
- package/rules/core.md +4 -0
- package/win/minion-cli.ps1 +15 -1
- package/win/routes/chat.js +34 -3
- package/win/workflow-runner.js +4 -2
- package/win/wsl-session-server.js +1 -1
|
@@ -385,7 +385,8 @@ function buildTransformSkillContent(instruction, inputData, outputContracts) {
|
|
|
385
385
|
lines.push('| Field | Type | Required | Description |')
|
|
386
386
|
lines.push('|-------|------|----------|-------------|')
|
|
387
387
|
for (const f of oc.contract.fields || []) {
|
|
388
|
-
|
|
388
|
+
const typeDisplay = f.type === 'array' && f.items ? `array<${f.items}>` : f.type
|
|
389
|
+
lines.push(`| ${f.key} | ${typeDisplay} | ${f.required ? 'Yes' : 'No'} | ${f.description || ''} |`)
|
|
389
390
|
}
|
|
390
391
|
}
|
|
391
392
|
}
|
|
@@ -35,7 +35,7 @@ function streamClaude(input, onEvent, ctx = {}) {
|
|
|
35
35
|
const child = spawn(bin, args, {
|
|
36
36
|
cwd: config.HOME_DIR,
|
|
37
37
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
38
|
-
timeout: input.timeoutMs ||
|
|
38
|
+
timeout: input.timeoutMs || 3600000, // 60 min default
|
|
39
39
|
env: {
|
|
40
40
|
...process.env,
|
|
41
41
|
HOME: config.HOME_DIR,
|
package/docs/api-reference.md
CHANGED
|
@@ -1048,8 +1048,13 @@ PUT `/api/minion/dag-workflows/:id` body(全フィールド optional、省略
|
|
|
1048
1048
|
}
|
|
1049
1049
|
```
|
|
1050
1050
|
|
|
1051
|
-
- `graph` を渡すと draft_graph
|
|
1051
|
+
- `graph` を渡すと draft_graph が上書きされる(構造チェック + structural validation: contract参照の型整合性チェックは実行、ノード完全性チェックは `publish` 時のみ)
|
|
1052
1052
|
- `content` / `change_summary` は `graph` と併せて draft スロットに保存される
|
|
1053
|
+
- **推奨**: graph 全文PUTは**原則使用しない**。代わりに個別APIの `/nodes` `/edges` `/contracts` を使ってインクリメンタルに編集すること。全文PUTは型の取り違え(例: `edge.contract` に配列を渡す)が発生しやすく、バリデーションエラーで400が返る
|
|
1054
|
+
- 具体的な制約:
|
|
1055
|
+
- `edge.contract` は**単一の**Contract名(string)。配列は不可
|
|
1056
|
+
- `contract.fields[].items` は Contract名(string)で、`graph.contracts` 内に存在するものを参照
|
|
1057
|
+
- 不整合があると `{ "error": "...", "details": [...] }` の形式で400エラー
|
|
1053
1058
|
|
|
1054
1059
|
POST `/api/minion/dag-workflows/:id/publish` (body なし):
|
|
1055
1060
|
- 現在の draft_graph を `validateDagGraph` でフル検証
|
|
@@ -1206,15 +1211,48 @@ POST `/api/minion/dag-workflows/:id/publish` (body なし):
|
|
|
1206
1211
|
type: "string" | "number" | "boolean" | "url" | "array" | "object" // フィールド型
|
|
1207
1212
|
description: string // フィールドの説明
|
|
1208
1213
|
required?: boolean // 必須フラグ (省略時 false)
|
|
1214
|
+
items?: string // type='array' 時のみ。要素の型を表す別Contract名
|
|
1209
1215
|
}]
|
|
1210
1216
|
}
|
|
1211
1217
|
```
|
|
1212
1218
|
|
|
1213
1219
|
**注意:**
|
|
1214
1220
|
- エッジに設定する `contract` は `graph.contracts` に存在する名前でなければならない(存在しない名前を指定すると 400 エラー)
|
|
1221
|
+
- **エッジが参照できる Contract は 1 つのみ**。`edge.contract` に配列を渡すことは不可(400エラー)。複数の型構造を束ねたい場合は、それらを束ねた複合Contractを1つ定義してから参照すること
|
|
1215
1222
|
- contract を削除すると、参照しているエッジの `contract` フィールドが自動でクリアされる(DELETE / PUT 共通)
|
|
1216
1223
|
- `validate` エンドポイントはダングリング参照(存在しない contract への参照)をエラーとして報告する
|
|
1217
1224
|
|
|
1225
|
+
**Contract内で List<別Contract> を表現する方法 (items):**
|
|
1226
|
+
|
|
1227
|
+
`type: 'array'` のフィールドに `items` プロパティを設定すると、配列要素の型を別Contractで記述できる。`items` の値は `graph.contracts` 内のContract名。
|
|
1228
|
+
|
|
1229
|
+
```json
|
|
1230
|
+
{
|
|
1231
|
+
"contracts": {
|
|
1232
|
+
"Article": {
|
|
1233
|
+
"description": "個別の記事",
|
|
1234
|
+
"fields": [
|
|
1235
|
+
{ "key": "title", "type": "string", "required": true, "description": "タイトル" },
|
|
1236
|
+
{ "key": "url", "type": "url", "description": "記事URL" }
|
|
1237
|
+
]
|
|
1238
|
+
},
|
|
1239
|
+
"NewsCollection": {
|
|
1240
|
+
"description": "収集されたニュース全体",
|
|
1241
|
+
"fields": [
|
|
1242
|
+
{ "key": "articles", "type": "array", "items": "Article", "required": true, "description": "記事リスト" },
|
|
1243
|
+
{ "key": "collected_at", "type": "string", "required": true, "description": "収集日時" },
|
|
1244
|
+
{ "key": "count", "type": "number", "required": true, "description": "件数" }
|
|
1245
|
+
]
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
"edges": [
|
|
1249
|
+
{ "id": "edge_1", "source": "a", "target": "b", "contract": "NewsCollection" }
|
|
1250
|
+
]
|
|
1251
|
+
}
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
この構造で「エッジは単一Contract (`NewsCollection`) を参照し、その内部で `articles` フィールドが `Article[]` 型」という意味になる。
|
|
1255
|
+
|
|
1218
1256
|
##### GET `/api/minion/dag-workflows/:id/contracts` — 全contracts取得
|
|
1219
1257
|
|
|
1220
1258
|
レスポンス: `{ "contracts": { "name": { "description": "...", "fields": [...] }, ... } }`
|
package/linux/minion-cli.sh
CHANGED
|
@@ -1096,13 +1096,28 @@ SUPEOF
|
|
|
1096
1096
|
HOSTNAME_VAL=$(hostname 2>/dev/null || echo "")
|
|
1097
1097
|
LAN_IP=$(detect_lan_ip)
|
|
1098
1098
|
|
|
1099
|
+
# Collect machine specs
|
|
1100
|
+
local CPU_MODEL CPU_CORES MEMORY_MB DISK_GB OS_INFO ARCH_INFO
|
|
1101
|
+
CPU_MODEL=$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ //' || echo "unknown")
|
|
1102
|
+
CPU_CORES=$(nproc 2>/dev/null || grep -c '^processor' /proc/cpuinfo 2>/dev/null || echo "0")
|
|
1103
|
+
MEMORY_MB=$(awk '/MemTotal/ {printf "%.0f", $2/1024}' /proc/meminfo 2>/dev/null || echo "0")
|
|
1104
|
+
DISK_GB=$(df -BG / 2>/dev/null | awk 'NR==2 {gsub("G",""); print $2}' || echo "0")
|
|
1105
|
+
OS_INFO=$(. /etc/os-release 2>/dev/null && echo "${PRETTY_NAME}" || uname -s 2>/dev/null || echo "unknown")
|
|
1106
|
+
ARCH_INFO=$(uname -m 2>/dev/null || echo "unknown")
|
|
1107
|
+
|
|
1108
|
+
local MACHINE_SPECS
|
|
1109
|
+
MACHINE_SPECS=$(cat <<SPECEOF
|
|
1110
|
+
{"cpu_model":"${CPU_MODEL}","cpu_cores":${CPU_CORES},"memory_mb":${MEMORY_MB},"disk_gb":${DISK_GB},"os":"${OS_INFO}","arch":"${ARCH_INFO}"}
|
|
1111
|
+
SPECEOF
|
|
1112
|
+
)
|
|
1113
|
+
|
|
1099
1114
|
local BODY
|
|
1100
1115
|
if [ -f /.dockerenv ]; then
|
|
1101
|
-
BODY="{\"internal_ip_address\":\"${HOSTNAME_VAL}\"}"
|
|
1116
|
+
BODY="{\"internal_ip_address\":\"${HOSTNAME_VAL}\",\"machine_specs\":${MACHINE_SPECS}}"
|
|
1102
1117
|
elif [ -n "$LAN_IP" ]; then
|
|
1103
|
-
BODY="{\"internal_ip_address\":\"${LAN_IP}\",\"ip_address\":\"${LAN_IP}\"}"
|
|
1118
|
+
BODY="{\"internal_ip_address\":\"${LAN_IP}\",\"ip_address\":\"${LAN_IP}\",\"machine_specs\":${MACHINE_SPECS}}"
|
|
1104
1119
|
else
|
|
1105
|
-
BODY="{\"internal_ip_address\":\"${HOSTNAME_VAL}\"}"
|
|
1120
|
+
BODY="{\"internal_ip_address\":\"${HOSTNAME_VAL}\",\"machine_specs\":${MACHINE_SPECS}}"
|
|
1106
1121
|
fi
|
|
1107
1122
|
|
|
1108
1123
|
NOTIFY_RESPONSE=$(curl -sfL -X POST "${HQ_URL}/api/minion/setup-complete" \
|
package/linux/routes/chat.js
CHANGED
|
@@ -353,6 +353,36 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
353
353
|
)
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
+
// Task planning guidance — instruct Claude to create TODOs before starting work
|
|
357
|
+
if (!sessionId) {
|
|
358
|
+
const port = require('../../core/config').config.AGENT_PORT
|
|
359
|
+
parts.push(
|
|
360
|
+
'[作業手順 — 必ず守ること]',
|
|
361
|
+
'依頼された作業に着手する**前に**、以下の手順を踏むこと:',
|
|
362
|
+
'',
|
|
363
|
+
'1. 依頼内容を分析し、必要なステップをToDoとして登録する',
|
|
364
|
+
'2. 各ステップを完了するたびに、ToDoのstatusを `done` に更新する',
|
|
365
|
+
'3. すべてのToDoが完了したら、ユーザーに完了報告する',
|
|
366
|
+
'',
|
|
367
|
+
'ToDo APIの使い方:',
|
|
368
|
+
'```bash',
|
|
369
|
+
'# ToDo作成(session_idは後でセッションIDが判明してから設定)',
|
|
370
|
+
`curl -X POST http://localhost:${port}/api/todos \\`,
|
|
371
|
+
' -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \\',
|
|
372
|
+
' -d \'{"title": "ステップの説明", "session_id": "SESSION_ID", "priority": "normal"}\'',
|
|
373
|
+
'',
|
|
374
|
+
'# ToDo完了',
|
|
375
|
+
`curl -X PUT http://localhost:${port}/api/todos/{id} \\`,
|
|
376
|
+
' -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \\',
|
|
377
|
+
' -d \'{"status": "done"}\'',
|
|
378
|
+
'```',
|
|
379
|
+
'',
|
|
380
|
+
'ToDoを先に作成する理由: チャットのコンテキストが圧縮されても、未完了のToDoは次のターンで自動的に再表示されます。',
|
|
381
|
+
'これにより、長時間の作業でも途中で何をすべきか見失うことがありません。',
|
|
382
|
+
''
|
|
383
|
+
)
|
|
384
|
+
}
|
|
385
|
+
|
|
356
386
|
if (context) {
|
|
357
387
|
switch (context.type) {
|
|
358
388
|
case 'skill':
|
|
@@ -403,7 +433,7 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
403
433
|
` hq fetch dag-workflow ${context.dagWorkflowId}`,
|
|
404
434
|
`プロジェクトコンテキスト:`,
|
|
405
435
|
` hq fetch project-context ${context.projectId}`,
|
|
406
|
-
`PMロールの場合、ノード/エッジ操作API
|
|
436
|
+
`PMロールの場合、ノード/エッジ操作APIでインクリメンタルに編集してください(**強く推奨**、全文PUTは型取り違えが起きやすいためエラーになりがち):`,
|
|
407
437
|
` hq dag add-node ${context.dagWorkflowId} <body.json> # ノード追加`,
|
|
408
438
|
` hq dag update-node ${context.dagWorkflowId} <node-id> <body.json> # ノード更新`,
|
|
409
439
|
` hq dag remove-node ${context.dagWorkflowId} <node-id> # ノード削除`,
|
|
@@ -411,7 +441,8 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
411
441
|
` hq dag remove-edge ${context.dagWorkflowId} <edge-id> # エッジ削除`,
|
|
412
442
|
` hq dag validate ${context.dagWorkflowId} # ドラフト検証(公開せず)`,
|
|
413
443
|
` hq publish dag-workflow ${context.dagWorkflowId} # 公開`,
|
|
414
|
-
`
|
|
444
|
+
`Contract編集時の重要な規則: edge.contract は単一Contract名(string)のみ、配列不可。List<X> は type:"array" + items:"X" で表現。詳細は ~/.minion/docs/api-reference.md の「Contracts API」参照。`,
|
|
445
|
+
`graph JSON 全文PUTは非推奨: hq put dag-workflow ${context.dagWorkflowId} <body.json>`,
|
|
415
446
|
`新規作成は: hq create dag-workflow <body.json>`,
|
|
416
447
|
`プロジェクト内の DAG ワークフロー一覧: hq list dag-workflows ${context.projectId}`,
|
|
417
448
|
`DAG の構造(nodes/edges/node types/scope_path 等)や実行フローの詳細は ~/.minion/docs/api-reference.md の「DAG Workflows」セクション、および ~/.minion/docs/task-guides.md の「DAG ワークフロー」セクションを参照してください。`,
|
|
@@ -568,7 +599,7 @@ function streamViaLegacyLlmCommand(res, prompt, sessionId, workspaceId, original
|
|
|
568
599
|
const child = spawn(binary, args, {
|
|
569
600
|
cwd: config.HOME_DIR,
|
|
570
601
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
571
|
-
timeout:
|
|
602
|
+
timeout: 3600000, // 60 min — allow long-running tasks to complete
|
|
572
603
|
})
|
|
573
604
|
|
|
574
605
|
// Track active child process for abort
|
package/linux/workflow-runner.js
CHANGED
|
@@ -106,7 +106,8 @@ async function executeWorkflowSession(workflow, executionId, skillNames, options
|
|
|
106
106
|
contractContext += `### ${ic.contract_name}\n${ic.contract.description || ''}\n`
|
|
107
107
|
contractContext += '| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n'
|
|
108
108
|
for (const f of ic.contract.fields || []) {
|
|
109
|
-
|
|
109
|
+
const typeDisplay = f.type === 'array' && f.items ? `array<${f.items}>` : f.type
|
|
110
|
+
contractContext += `| ${f.key} | ${typeDisplay} | ${f.required ? 'Yes' : 'No'} | ${f.description || ''} |\n`
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
contractContext += '\n'
|
|
@@ -117,7 +118,8 @@ async function executeWorkflowSession(workflow, executionId, skillNames, options
|
|
|
117
118
|
contractContext += `### ${oc.contract_name}\n${oc.contract.description || ''}\n`
|
|
118
119
|
contractContext += '| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n'
|
|
119
120
|
for (const f of oc.contract.fields || []) {
|
|
120
|
-
|
|
121
|
+
const typeDisplay = f.type === 'array' && f.items ? `array<${f.items}>` : f.type
|
|
122
|
+
contractContext += `| ${f.key} | ${typeDisplay} | ${f.required ? 'Yes' : 'No'} | ${f.description || ''} |\n`
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
contractContext += '\n'
|
package/package.json
CHANGED
package/rules/core.md
CHANGED
|
@@ -28,6 +28,10 @@ Minion
|
|
|
28
28
|
|
|
29
29
|
- **Workflow**: プロジェクトスコープ。線形パイプライン形式のバージョン管理ワークフロー。ミニオンAPIで push/fetch 可能。
|
|
30
30
|
- **DAG Workflow**: プロジェクトスコープ。ノード/エッジで依存関係を表現する新方式。fan-out / join / conditional / transform / review をサポート。作成・編集はHQダッシュボードのみ、ミニオンは `dag-step-poller` で自動実行。詳細は `~/.minion/docs/api-reference.md` の「DAG Workflows」と `~/.minion/docs/task-guides.md` の「DAG ワークフロー」を参照。
|
|
31
|
+
- **PMロールで編集する場合の重要な規則**:
|
|
32
|
+
- ノード/エッジ/contract の追加・更新は**個別API** (`/nodes` `/edges` `/contracts`) を使うこと。`PUT /dag-workflows/:id` による graph 全文PUTは型の取り違えが起きやすく、バリデーションエラーで 400 が返る
|
|
33
|
+
- `edge.contract` は**単一のContract名(string)**のみ。配列は不可。複数の型構造を束ねたい場合は、それらを内包する複合Contractを1つ定義する
|
|
34
|
+
- Contract内で `List<別Contract>` を表現するには `type: 'array'` + `items: "別Contract名"` を使う(詳細は `~/.minion/docs/api-reference.md` の「Contracts API」を参照)
|
|
31
35
|
- **Routine**: ミニオンスコープ。ミニオンローカルの定期タスク。
|
|
32
36
|
- **Workspace**: ミニオンは複数のワークスペースに所属でき、スキルやプロジェクトはワークスペース単位でスコープされる。チャットセッションもワークスペース別に分離される。所属ワークスペースはハートビートで自動同期され、`hq list workspaces` で確認できる。
|
|
33
37
|
- ミニオンは複数プロジェクトに `pm`、`engineer`、`accountant` として参加できる。
|
package/win/minion-cli.ps1
CHANGED
|
@@ -1522,7 +1522,21 @@ function Invoke-Configure {
|
|
|
1522
1522
|
$bodyHash = @{}
|
|
1523
1523
|
if ($lanIp) { $bodyHash['ip_address'] = $lanIp; $bodyHash['internal_ip_address'] = $lanIp }
|
|
1524
1524
|
else { $bodyHash['internal_ip_address'] = [System.Net.Dns]::GetHostName() }
|
|
1525
|
-
|
|
1525
|
+
|
|
1526
|
+
# Collect machine specs
|
|
1527
|
+
$cpuInfo = Get-CimInstance Win32_Processor -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
1528
|
+
$osInfo = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue
|
|
1529
|
+
$diskInfo = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'" -ErrorAction SilentlyContinue
|
|
1530
|
+
$bodyHash['machine_specs'] = @{
|
|
1531
|
+
cpu_model = if ($cpuInfo) { $cpuInfo.Name } else { 'unknown' }
|
|
1532
|
+
cpu_cores = if ($cpuInfo) { $cpuInfo.NumberOfLogicalProcessors } else { 0 }
|
|
1533
|
+
memory_mb = if ($osInfo) { [math]::Round($osInfo.TotalVisibleMemorySize / 1024) } else { 0 }
|
|
1534
|
+
disk_gb = if ($diskInfo) { [math]::Round($diskInfo.Size / 1GB) } else { 0 }
|
|
1535
|
+
os = if ($osInfo) { $osInfo.Caption } else { 'Windows' }
|
|
1536
|
+
arch = $env:PROCESSOR_ARCHITECTURE
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
$body = $bodyHash | ConvertTo-Json -Depth 3
|
|
1526
1540
|
Invoke-RestMethod -Uri "$HqUrl/api/minion/setup-complete" -Method Post -Headers $headers -Body $body -ErrorAction Stop | Out-Null
|
|
1527
1541
|
Write-Detail "HQ notified"
|
|
1528
1542
|
}
|
package/win/routes/chat.js
CHANGED
|
@@ -416,6 +416,36 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
416
416
|
)
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
// Task planning guidance — instruct Claude to create TODOs before starting work
|
|
420
|
+
if (!sessionId) {
|
|
421
|
+
const port = require('../../core/config').config.AGENT_PORT
|
|
422
|
+
parts.push(
|
|
423
|
+
'[作業手順 — 必ず守ること]',
|
|
424
|
+
'依頼された作業に着手する**前に**、以下の手順を踏むこと:',
|
|
425
|
+
'',
|
|
426
|
+
'1. 依頼内容を分析し、必要なステップをToDoとして登録する',
|
|
427
|
+
'2. 各ステップを完了するたびに、ToDoのstatusを `done` に更新する',
|
|
428
|
+
'3. すべてのToDoが完了したら、ユーザーに完了報告する',
|
|
429
|
+
'',
|
|
430
|
+
'ToDo APIの使い方:',
|
|
431
|
+
'```bash',
|
|
432
|
+
'# ToDo作成(session_idは後でセッションIDが判明してから設定)',
|
|
433
|
+
`curl -X POST http://localhost:${port}/api/todos \\`,
|
|
434
|
+
' -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \\',
|
|
435
|
+
' -d \'{"title": "ステップの説明", "session_id": "SESSION_ID", "priority": "normal"}\'',
|
|
436
|
+
'',
|
|
437
|
+
'# ToDo完了',
|
|
438
|
+
`curl -X PUT http://localhost:${port}/api/todos/{id} \\`,
|
|
439
|
+
' -H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \\',
|
|
440
|
+
' -d \'{"status": "done"}\'',
|
|
441
|
+
'```',
|
|
442
|
+
'',
|
|
443
|
+
'ToDoを先に作成する理由: チャットのコンテキストが圧縮されても、未完了のToDoは次のターンで自動的に再表示されます。',
|
|
444
|
+
'これにより、長時間の作業でも途中で何をすべきか見失うことがありません。',
|
|
445
|
+
''
|
|
446
|
+
)
|
|
447
|
+
}
|
|
448
|
+
|
|
419
449
|
if (context) {
|
|
420
450
|
switch (context.type) {
|
|
421
451
|
case 'skill':
|
|
@@ -464,7 +494,7 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
464
494
|
` hq fetch dag-workflow ${context.dagWorkflowId}`,
|
|
465
495
|
`プロジェクトコンテキスト:`,
|
|
466
496
|
` hq fetch project-context ${context.projectId}`,
|
|
467
|
-
`PMロールの場合、ノード/エッジ操作API
|
|
497
|
+
`PMロールの場合、ノード/エッジ操作APIでインクリメンタルに編集してください(**強く推奨**、全文PUTは型取り違えが起きやすいためエラーになりがち):`,
|
|
468
498
|
` hq dag add-node ${context.dagWorkflowId} <body.json> # ノード追加`,
|
|
469
499
|
` hq dag update-node ${context.dagWorkflowId} <node-id> <body.json> # ノード更新`,
|
|
470
500
|
` hq dag remove-node ${context.dagWorkflowId} <node-id> # ノード削除`,
|
|
@@ -472,7 +502,8 @@ async function buildContextPrefix(message, context, sessionId, workspaceId) {
|
|
|
472
502
|
` hq dag remove-edge ${context.dagWorkflowId} <edge-id> # エッジ削除`,
|
|
473
503
|
` hq dag validate ${context.dagWorkflowId} # ドラフト検証(公開せず)`,
|
|
474
504
|
` hq publish dag-workflow ${context.dagWorkflowId} # 公開`,
|
|
475
|
-
`
|
|
505
|
+
`Contract編集時の重要な規則: edge.contract は単一Contract名(string)のみ、配列不可。List<X> は type:"array" + items:"X" で表現。詳細は ~/.minion/docs/api-reference.md の「Contracts API」参照。`,
|
|
506
|
+
`graph JSON 全文PUTは非推奨: hq put dag-workflow ${context.dagWorkflowId} <body.json>`,
|
|
476
507
|
`新規作成は: hq create dag-workflow <body.json>`,
|
|
477
508
|
`プロジェクト内の DAG ワークフロー一覧: hq list dag-workflows ${context.projectId}`,
|
|
478
509
|
`DAG の構造(nodes/edges/node types/scope_path 等)や実行フローの詳細は ~/.minion/docs/api-reference.md の「DAG Workflows」セクション、および ~/.minion/docs/task-guides.md の「DAG ワークフロー」セクションを参照してください。`,
|
|
@@ -602,7 +633,7 @@ function streamViaLegacyLlmCommand(res, prompt, sessionId, workspaceId, original
|
|
|
602
633
|
const child = spawn(binary, args, {
|
|
603
634
|
cwd: config.HOME_DIR,
|
|
604
635
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
605
|
-
timeout:
|
|
636
|
+
timeout: 3600000, // 60 min — allow long-running tasks to complete
|
|
606
637
|
shell: true, // Required on Windows to resolve .cmd shims (e.g. claude.cmd)
|
|
607
638
|
})
|
|
608
639
|
|
package/win/workflow-runner.js
CHANGED
|
@@ -113,7 +113,8 @@ async function executeWorkflowSession(workflow, executionId, skillNames, options
|
|
|
113
113
|
contractContext += `### ${ic.contract_name}\n${ic.contract.description || ''}\n`
|
|
114
114
|
contractContext += '| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n'
|
|
115
115
|
for (const f of ic.contract.fields || []) {
|
|
116
|
-
|
|
116
|
+
const typeDisplay = f.type === 'array' && f.items ? `array<${f.items}>` : f.type
|
|
117
|
+
contractContext += `| ${f.key} | ${typeDisplay} | ${f.required ? 'Yes' : 'No'} | ${f.description || ''} |\n`
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
contractContext += '\n'
|
|
@@ -124,7 +125,8 @@ async function executeWorkflowSession(workflow, executionId, skillNames, options
|
|
|
124
125
|
contractContext += `### ${oc.contract_name}\n${oc.contract.description || ''}\n`
|
|
125
126
|
contractContext += '| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n'
|
|
126
127
|
for (const f of oc.contract.fields || []) {
|
|
127
|
-
|
|
128
|
+
const typeDisplay = f.type === 'array' && f.items ? `array<${f.items}>` : f.type
|
|
129
|
+
contractContext += `| ${f.key} | ${typeDisplay} | ${f.required ? 'Yes' : 'No'} | ${f.description || ''} |\n`
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
contractContext += '\n'
|
|
@@ -187,7 +187,7 @@ function streamLlmResponse(res, prompt, sessionId) {
|
|
|
187
187
|
const child = spawn(binary, args, {
|
|
188
188
|
cwd: HOME_DIR,
|
|
189
189
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
190
|
-
timeout:
|
|
190
|
+
timeout: 3600000, // 60 min — allow long-running tasks to complete
|
|
191
191
|
shell: true,
|
|
192
192
|
})
|
|
193
193
|
|