kenaz 0.3.17 → 0.3.19

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.
Files changed (316) hide show
  1. package/core/.claude/commands/agent-worker.md +1 -1
  2. package/core/.claude/commands/architect.md +1 -2
  3. package/core/.claude/commands/spec.md +1 -1
  4. package/core/.claude/commands//347/224/242/345/223/201.md +1 -1
  5. package/core/.claude/hooks/__tests__/task-1977-dedupe-guard.test.js +8 -8
  6. package/core/.claude/hooks/synapse-first-investigation.js +15 -0
  7. package/core/.claude/skills/architect_agent/SKILL.md +11 -92
  8. package/core/.claude/skills/assessment_agent/SKILL.md +0 -1
  9. package/core/.claude/skills/backend_engineer/SKILL.md +3 -6
  10. package/core/.claude/skills/code_reviewer/SKILL.md +1 -1
  11. package/core/.claude/skills/code_reviewer/patterns.yaml +1 -1
  12. package/core/.claude/skills/designer/SKILL.md +3 -6
  13. package/core/.claude/skills/dev_agent/SKILL.md +30 -491
  14. package/core/.claude/skills/developer/SKILL.md +3 -6
  15. package/core/.claude/skills/feature_agent/SKILL.md +3 -17
  16. package/core/.claude/skills/product_manager/SKILL.md +29 -1064
  17. package/core/.claude/skills/qa_engineer/SKILL.md +12 -17
  18. package/core/.claude/skills/spec_optimizer/SKILL.md +25 -275
  19. package/core/.claude/skills/sre_agent/SKILL.md +3 -6
  20. package/core/.collaboration/README.md +2 -3
  21. package/core/.collaboration/core/task-api.js +5 -138
  22. package/core/.collaboration/docs/CLI.md +0 -2
  23. package/core/.failure/INDEX.yaml +6 -40
  24. package/core/.failure/agent-execution/FAIL-013-search-cwd-drift-and-case-mismatch.yaml +1 -1
  25. package/core/.failure/tools/README.md +9 -227
  26. package/core/.formation/bifrost/exec.js +29 -4
  27. package/core/.formation/bifrost/launch.js +1 -6
  28. package/core/.formation/bifrost/launch.test.js +1 -1
  29. package/core/.formation/bifrost/provider-launch.js +18 -11
  30. package/core/.formation/bifrost/provider-launch.test.js +26 -2
  31. package/core/.formation/bifrost/shared/ansuz-boot-policy.js +3 -3
  32. package/core/.formation/bifrost/shared/ansuz-boot-policy.test.js +1 -2
  33. package/core/.formation/tools/__tests__/dispatch-cwd-project.test.js +42 -0
  34. package/core/.formation/tools/__tests__/m1-hmap-convid.test.js +1 -124
  35. package/core/.formation/tools/__tests__/subagent-executor.test.js +3 -2
  36. package/core/.formation/tools/dispatch.js +15 -2
  37. package/core/.formation/tools/loader.js +17 -140
  38. package/core/.formation/tools/post-complete.js +0 -31
  39. package/core/.rule/INDEX.yaml +0 -18
  40. package/core/.rule/general/agent-workflow.yaml +14 -164
  41. package/core/.rule/general/project-self-containment.yaml +8 -19
  42. package/core/.rule/general/rust-verify-target.yaml +6 -5
  43. package/core/.rule/general/synapse-code-intelligence.yaml +3 -3
  44. package/core/.specialist/Amelia/capability.yaml +12 -12
  45. package/core/.specialist/Amelia/workflow.yaml +2 -2
  46. package/core/.specialist/Ansuz/SYSTEM_DOC.md +20 -578
  47. package/core/.specialist/Ansuz/cognitive_principles.yaml +2 -3
  48. package/core/.specialist/Ansuz/concepts/boot_rules_summary.yaml +0 -1
  49. package/core/.specialist/Ansuz/concepts/deep_knowledge_pointers.yaml +1 -2
  50. package/core/.specialist/Ansuz/core.yaml +6 -108
  51. package/core/.specialist/Ansuz/guards/lesson_guards.yaml +0 -3
  52. package/core/.specialist/Ansuz/identity_contract.yaml +0 -1
  53. package/core/.specialist/Ansuz/knowledge.yaml +0 -4
  54. package/core/.specialist/Ansuz/rule.yaml +0 -1
  55. package/core/.specialist/Ansuz/tools/handoff-session-identity.test.js +6 -150
  56. package/core/.specialist/tests/runtime-discovery/README.md +1 -1
  57. package/core/.specialist/tools/__tests__/task-2374-usage-counter.test.js +1 -12
  58. package/core/.specialist/tools/prompt-files.test.js +1 -0
  59. package/core/.specialist/tools/task-bridge.js +1 -66
  60. package/core/.system/README.md +11 -552
  61. package/core/.system/collaboration/README.md +10 -174
  62. package/core/CLAUDE.md +1 -6
  63. package/core/KENAZ_CORE_VERSION +1 -1
  64. package/core/dev/scripts/js-yaml-resolution.test.js +1 -1
  65. package/core/dev/scripts/run-rust-tests.js +30 -46
  66. package/core/dev/scripts/run-rust-tests.test.js +17 -0
  67. package/core/dev/scripts/rust-verify-worktree.js +4 -4
  68. package/core/dev/scripts/verify-target-dir.js +6 -6
  69. package/core/plugins/kenaz/INVENTORY.md +8 -8
  70. package/core/plugins/kenaz/commands/architect.md +1 -2
  71. package/core/plugins/kenaz/commands/spec.md +1 -1
  72. package/core/plugins/kenaz/commands//347/224/242/345/223/201.md +1 -1
  73. package/core/plugins/kenaz/guidance.md +1 -1
  74. package/core/plugins/kenaz/scripts/sync.js +1 -1
  75. package/core/plugins/kenaz/scripts/ygg.js +6 -0
  76. package/core/plugins/kenaz/skills/architect_agent/SKILL.md +11 -92
  77. package/core/plugins/kenaz/skills/assessment_agent/SKILL.md +0 -1
  78. package/core/plugins/kenaz/skills/backend_engineer/SKILL.md +3 -6
  79. package/core/plugins/kenaz/skills/code_reviewer/SKILL.md +1 -1
  80. package/core/plugins/kenaz/skills/code_reviewer/patterns.yaml +1 -1
  81. package/core/plugins/kenaz/skills/designer/SKILL.md +3 -6
  82. package/core/plugins/kenaz/skills/dev_agent/SKILL.md +30 -491
  83. package/core/plugins/kenaz/skills/developer/SKILL.md +3 -6
  84. package/core/plugins/kenaz/skills/feature_agent/SKILL.md +3 -17
  85. package/core/plugins/kenaz/skills/product_manager/SKILL.md +29 -1064
  86. package/core/plugins/kenaz/skills/qa_engineer/SKILL.md +12 -17
  87. package/core/plugins/kenaz/skills/spec_optimizer/SKILL.md +25 -275
  88. package/core/plugins/kenaz/skills/sre_agent/SKILL.md +3 -6
  89. package/package.json +6 -6
  90. package/core/.claude/commands/archive.md +0 -24
  91. package/core/.claude/commands/init.md +0 -112
  92. package/core/.claude/commands/legacy_dev.md +0 -18
  93. package/core/.claude/commands/product-review.md +0 -131
  94. package/core/.claude/commands/strategy.md +0 -141
  95. package/core/.claude/commands/sunny.md +0 -1
  96. package/core/.claude/commands//347/224/242/345/223/201/346/252/242/350/246/226.md +0 -129
  97. package/core/.claude/commands//351/200/262/345/272/246.md +0 -15
  98. package/core/.claude/hooks/__tests__/substrate.test.js +0 -122
  99. package/core/.claude/hooks/_substrate-paths.js +0 -95
  100. package/core/.claude/hooks/context-check.js +0 -51
  101. package/core/.claude/hooks/fatigue-check.js +0 -52
  102. package/core/.claude/hooks/handoff-snapshot-on-commit.js +0 -154
  103. package/core/.claude/hooks/handoff-snapshot-on-question.js +0 -158
  104. package/core/.claude/hooks/handoff-staleness.js +0 -197
  105. package/core/.claude/hooks/jev-thalamus-context.js +0 -17
  106. package/core/.claude/hooks/jev-thalamus-context.test.js +0 -41
  107. package/core/.claude/hooks/lease-release.js +0 -119
  108. package/core/.claude/hooks/lease-touch.js +0 -96
  109. package/core/.claude/hooks/reflex-feedback.js +0 -5
  110. package/core/.claude/hooks/session-init.ps1 +0 -49
  111. package/core/.claude/hooks/sound-event.js +0 -70
  112. package/core/.claude/hooks/sound-event.sh +0 -37
  113. package/core/.claude/hooks/stream-delta.js +0 -169
  114. package/core/.claude/no-hooks.settings.json +0 -3
  115. package/core/.claude/skills/legacy_dev/SKILL.md +0 -202
  116. package/core/.claude/skills/sunny/SKILL.md +0 -74
  117. package/core/.collaboration/cli/commands/assign.js +0 -39
  118. package/core/.collaboration/cli/commands/claim.js +0 -33
  119. package/core/.collaboration/cli/commands/complete.js +0 -44
  120. package/core/.collaboration/cli/commands/create.js +0 -110
  121. package/core/.collaboration/cli/commands/get.js +0 -83
  122. package/core/.collaboration/cli/commands/index.js +0 -52
  123. package/core/.collaboration/cli/commands/list.js +0 -51
  124. package/core/.collaboration/cli/commands/lock.js +0 -45
  125. package/core/.collaboration/cli/commands/rebuild.js +0 -39
  126. package/core/.collaboration/cli/commands/search.js +0 -61
  127. package/core/.collaboration/cli/commands/stats.js +0 -61
  128. package/core/.collaboration/cli/commands/transfer.js +0 -41
  129. package/core/.collaboration/cli/commands/unlock.js +0 -48
  130. package/core/.collaboration/cli/formatters/help-formatter.js +0 -70
  131. package/core/.collaboration/cli/formatters/index.js +0 -7
  132. package/core/.collaboration/cli/task-cli.js +0 -46
  133. package/core/.collaboration/cli/utils/arg-parser.js +0 -74
  134. package/core/.collaboration/cli/utils/git-user.js +0 -25
  135. package/core/.collaboration/cli/utils/index.js +0 -9
  136. package/core/.collaboration/cli/utils/output.js +0 -10
  137. package/core/.collaboration/config/default.yaml +0 -189
  138. package/core/.collaboration/core/conflict-resolver.js +0 -461
  139. package/core/.collaboration/core/conflict-resolver.test.js +0 -389
  140. package/core/.collaboration/core/migrate-legacy.js +0 -260
  141. package/core/.collaboration/docs/API.md +0 -787
  142. package/core/.collaboration/docs/ARCHITECTURE.md +0 -596
  143. package/core/.collaboration/docs/FAQ.md +0 -695
  144. package/core/.collaboration/docs/MIGRATION.md +0 -804
  145. package/core/.collaboration/docs/examples/README.md +0 -320
  146. package/core/.collaboration/docs/examples/advanced-queries.js +0 -261
  147. package/core/.collaboration/docs/examples/basic-usage.js +0 -184
  148. package/core/.collaboration/docs/examples/team-workflow.js +0 -352
  149. package/core/.failure/agent-execution/FAIL-001-agent-no-output.yaml +0 -391
  150. package/core/.failure/agent-execution/FAIL-007-pm-lead-wrong-team-invocation.yaml +0 -0
  151. package/core/.failure/agent-execution/FAIL-010-phase0-poem-format-skipped.yaml +0 -28
  152. package/core/.failure/agent-execution/FAIL-010-skipping-cognitive-checkpoint-after-verification.yaml +0 -59
  153. package/core/.failure/agent-execution/FAIL-012-grep-shortcut-during-investigation.yaml +0 -85
  154. package/core/.failure/architecture/FAIL-006-python-version-compatibility.yaml +0 -445
  155. package/core/.failure/pipeline/FAIL-003-queue-pollution.yaml +0 -335
  156. package/core/.failure/pipeline/README.md +0 -95
  157. package/core/.failure/retired/FAIL-009-skipping-synapse-pulse-before-code-change.yaml +0 -49
  158. package/core/.failure/tools/USAGE_GUIDE.md +0 -323
  159. package/core/.failure/tools/check_failures.ps1 +0 -387
  160. package/core/.failure/tools/log_failure.ps1 +0 -474
  161. package/core/.formation/.episode-input.json +0 -10
  162. package/core/.formation/.merge-lock +0 -1
  163. package/core/.formation/lead.yaml +0 -118
  164. package/core/.formation/legacy.bak/designer.yaml +0 -57
  165. package/core/.formation/legacy.bak/pm.yaml +0 -57
  166. package/core/.formation/legacy.bak/qa.yaml +0 -57
  167. package/core/.formation/legacy.bak/review.yaml +0 -62
  168. package/core/.formation/legacy.bak/scheduler.yaml +0 -129
  169. package/core/.formation/legacy.bak/sre.yaml +0 -57
  170. package/core/.formation/role-map.yaml +0 -274
  171. package/core/.formation/roles/_shared/modules/code_review.yaml +0 -98
  172. package/core/.formation/roles/_shared/modules/security.yaml +0 -103
  173. package/core/.formation/roles/_shared/modules/testing.yaml +0 -14
  174. package/core/.formation/roles/backend/role.yaml +0 -93
  175. package/core/.formation/roles/code_reviewer/role.yaml +0 -102
  176. package/core/.formation/roles/database_optimizer/role.yaml +0 -107
  177. package/core/.formation/roles/designer/role.yaml +0 -66
  178. package/core/.formation/roles/developer/role.yaml +0 -75
  179. package/core/.formation/roles/frontend/role.yaml +0 -134
  180. package/core/.formation/roles/incident_response/role.yaml +0 -89
  181. package/core/.formation/roles/qa/role.yaml +0 -89
  182. package/core/.formation/roles/security/role.yaml +0 -87
  183. package/core/.formation/roles/sre/role.yaml +0 -66
  184. package/core/.formation/skills/coordinator.yaml +0 -52
  185. package/core/.formation/solo/diagnosis.yaml +0 -78
  186. package/core/.formation/solo/strategy.yaml +0 -121
  187. package/core/.formation/tests/hello.txt +0 -2
  188. package/core/.formation/tools/coordinator.js +0 -350
  189. package/core/.formation/tools/jev-correction.js +0 -214
  190. package/core/.formation/tools/jev-correction.test.js +0 -178
  191. package/core/.formation/tools/log-reader.js +0 -232
  192. package/core/.formation/tools/revert-daemon-state.js +0 -162
  193. package/core/.formation/tools/test-drift.js +0 -148
  194. package/core/.formation/unit/heimdall.yaml +0 -96
  195. package/core/.formation/unit/plan.yaml +0 -67
  196. package/core/.formation/unit/think.yaml +0 -58
  197. package/core/.kenaz/MUNINN_SNAPSHOT9_EPISODE.json +0 -32
  198. package/core/.kenaz/MUNINN_SNAPSHOT9_RUNE.json +0 -23
  199. package/core/.kenaz/MUNINN_SNAPSHOT9_SUMMARY.md +0 -89
  200. package/core/.kenaz/ash_TASK_1428-20260507.json +0 -14
  201. package/core/.kenaz/muninn_episode_write.ps1 +0 -17
  202. package/core/.kenaz/muninn_snapshot11_rune_candidates.md +0 -63
  203. package/core/.kenaz/muninn_snapshot1_rune_candidates.md +0 -49
  204. package/core/.kenaz/runes_TASK_1428.json +0 -57
  205. package/core/.kenaz/tmp_heimdall_proposal_8d3e392.json +0 -13
  206. package/core/.kenaz/tmp_props.json +0 -1
  207. package/core/.kenaz/tmp_sounddrop_t1_prompt.txt +0 -371
  208. package/core/.rule/MECHANIZED.md +0 -61
  209. package/core/.rule/general/cortex-memory-recall.yaml +0 -446
  210. package/core/.rule/general/pipeline.yaml +0 -246
  211. package/core/.rule/general/sunny-access-control.yaml +0 -60
  212. package/core/.rule/general/system-invariants.yaml +0 -231
  213. package/core/.rule/pipeline/PPL-002-completed-task-archival.yaml +0 -528
  214. package/core/.rule/pipeline/auto-update.yaml +0 -282
  215. package/core/.rule/pipeline/task-execution.yaml +0 -365
  216. package/core/.specialist/Ansuz/concepts/phase_protocol.yaml +0 -65
  217. package/core/.specialist/Ansuz/experiments/boot_ablation_replay.js +0 -197
  218. package/core/.specialist/Ansuz/tools/bootstrap-anchors.js +0 -289
  219. package/core/.specialist/Ansuz/workflow.yaml +0 -1225
  220. package/core/.specialist/experiments/rg_benchmark.js +0 -523
  221. package/core/.specialist/experiments/rg_benchmark_results.json +0 -27
  222. package/core/.specialist/tools/jev-optional-context.js +0 -107
  223. package/core/.specialist/tools/jev-optional-context.test.js +0 -152
  224. package/core/.specialist/tools/memory-action-log.js +0 -839
  225. package/core/.specialist/tools/phase-gate.js +0 -3534
  226. package/core/.specialist/tools/phase-gate.test.js +0 -85
  227. package/core/.specialist/tools/precompute-runner.js +0 -444
  228. package/core/.specialist/tools/rule-engine.js +0 -621
  229. package/core/.specialist/tools/task-bridge-jev.test.js +0 -170
  230. package/core/.synapse/memory-shared.json.sync +0 -1
  231. package/core/.system/agent-skills/README.md +0 -724
  232. package/core/.system/cli-tools/README.md +0 -724
  233. package/core/.system/cortex/MODULES.md +0 -1046
  234. package/core/.system/dashboard/FRONTEND.md +0 -812
  235. package/core/.system/dashboard/README.md +0 -737
  236. package/core/.system/failure/README.md +0 -723
  237. package/core/.system/formation/LEGACY_SKILLS.md +0 -974
  238. package/core/.system/formation/POST_COMPLETE.md +0 -602
  239. package/core/.system/formation/README.md +0 -1094
  240. package/core/.system/formation/TOOLS_REFERENCE.md +0 -1145
  241. package/core/.system/kenaz/README.md +0 -787
  242. package/core/.system/memory/README.md +0 -719
  243. package/core/.system/pipeline/README.md +0 -712
  244. package/core/.system/rule/README.md +0 -794
  245. package/core/.system/sunny/README.md +0 -476
  246. package/core/.system/sunny/RULES.json +0 -89
  247. package/core/.system/sunny/knowledge/INDEX.md +0 -37
  248. package/core/.system/sunny/knowledge/agent-teams-api.md +0 -0
  249. package/core/.system/sunny/knowledge/ansuz-specialist.md +0 -500
  250. package/core/.system/sunny/knowledge/claude-cli-spawn.md +0 -177
  251. package/core/.system/sunny/knowledge/collaboration-api.md +0 -925
  252. package/core/.system/sunny/teammates/README.md +0 -107
  253. package/core/.system/sunny/teammates/how_to_use.yaml +0 -101
  254. package/core/.system/sunny/teammates/tools/headless/launcher.js +0 -318
  255. package/core/.system/sunny/teammates/tools/powershell/launcher.js +0 -241
  256. package/core/.system/sunny/teammates/tools/powershell/start.bat +0 -50
  257. package/core/.system/sunny/teammates/tools/utils/env.js +0 -96
  258. package/core/.system/sunny/teammates/tools/utils/format-output.js +0 -329
  259. package/core/.system/sunny/tools.json +0 -101
  260. package/core/dev/scripts/cleanup-queue.js +0 -184
  261. package/core/dev/scripts/cleanup_queue.js +0 -86
  262. package/core/dev/scripts/legacy/README.md +0 -39
  263. package/core/dev/scripts/legacy/dev_agent_scheduler.ps1.bak +0 -536
  264. package/core/dev/scripts/legacy/multi_agent_scheduler.ps1.bak +0 -1978
  265. package/core/dev/scripts/matrix/CLI_README.md +0 -214
  266. package/core/dev/scripts/matrix/README.md +0 -310
  267. package/core/dev/scripts/matrix/package-lock.json +0 -4266
  268. package/core/dev/scripts/matrix/package.json +0 -55
  269. package/core/dev/scripts/matrix/src/abbreviations.ts +0 -295
  270. package/core/dev/scripts/matrix/src/cli/commands/convert.ts +0 -211
  271. package/core/dev/scripts/matrix/src/cli/commands/create.ts +0 -95
  272. package/core/dev/scripts/matrix/src/cli/commands/delete.ts +0 -102
  273. package/core/dev/scripts/matrix/src/cli/commands/list-tags.ts.wip +0 -140
  274. package/core/dev/scripts/matrix/src/cli/commands/manage-tags.ts.wip +0 -173
  275. package/core/dev/scripts/matrix/src/cli/commands/query.ts +0 -261
  276. package/core/dev/scripts/matrix/src/cli/commands/read.ts +0 -77
  277. package/core/dev/scripts/matrix/src/cli/commands/stats.ts.wip +0 -168
  278. package/core/dev/scripts/matrix/src/cli/commands/tokens.ts.wip +0 -126
  279. package/core/dev/scripts/matrix/src/cli/commands/update.ts +0 -147
  280. package/core/dev/scripts/matrix/src/cli/commands/validate.ts +0 -275
  281. package/core/dev/scripts/matrix/src/cli/index.ts +0 -350
  282. package/core/dev/scripts/matrix/src/cli/utils/file-handler.ts +0 -72
  283. package/core/dev/scripts/matrix/src/cli/utils/logger.ts +0 -65
  284. package/core/dev/scripts/matrix/src/index.ts +0 -62
  285. package/core/dev/scripts/matrix/src/indexer/tag-indexer.ts +0 -165
  286. package/core/dev/scripts/matrix/src/parser.ts +0 -281
  287. package/core/dev/scripts/matrix/src/serializer.ts +0 -151
  288. package/core/dev/scripts/matrix/src/validator.ts +0 -301
  289. package/core/dev/scripts/matrix/tests/abbreviations.test.ts +0 -122
  290. package/core/dev/scripts/matrix/tests/cli.test.ts +0 -177
  291. package/core/dev/scripts/matrix/tests/convert.test.ts +0 -143
  292. package/core/dev/scripts/matrix/tests/parser.test.ts +0 -203
  293. package/core/dev/scripts/matrix/tests/query.test.ts +0 -85
  294. package/core/dev/scripts/matrix/tests/serializer.test.ts +0 -197
  295. package/core/dev/scripts/matrix/tests/validate.test.ts +0 -141
  296. package/core/dev/scripts/matrix/tests/validator.test.ts +0 -167
  297. package/core/dev/scripts/matrix/tsconfig.json +0 -20
  298. package/core/dev/scripts/matrix/types/index.d.ts +0 -111
  299. package/core/dev/scripts/matrix/types/index.d.ts.map +0 -1
  300. package/core/dev/scripts/matrix/types/index.js +0 -8
  301. package/core/dev/scripts/matrix/types/index.js.map +0 -1
  302. package/core/dev/scripts/matrix/types/index.ts +0 -124
  303. package/core/dev/scripts/memory-usage-report.js +0 -152
  304. package/core/dev/scripts/probe/ansuz-scaffold-ablation.js +0 -579
  305. package/core/dev/scripts/probe/ansuz-scaffold-ablation.test.js +0 -244
  306. package/core/dev/scripts/probe/hook-latency-probe.js +0 -315
  307. package/core/dev/scripts/probe/hook-latency-probe.test.js +0 -105
  308. package/core/dev/scripts/probe/prediction-signal-auc.js +0 -483
  309. package/core/dev/scripts/probe/prediction-signal-auc.test.js +0 -200
  310. package/core/dev/scripts/test-pty-ws-tunnel.js +0 -229
  311. package/core/dev/scripts/validate_pipeline.js +0 -197
  312. package/core/dev/spikes/task2145-evidence-20261004/backend-log-excerpt.txt +0 -56
  313. package/core/dev/spikes/task2145-evidence-20261004/graph.shadow +0 -0
  314. package/core/dev/spikes/task2145-evidence-20261004/graph.wal +0 -0
  315. package/core/dev/spikes/task2145-evidence-20261004/graph_corrupt_suspect.marker +0 -1
  316. package/core/plugins/kenaz/commands/strategy.md +0 -141
@@ -1,1145 +0,0 @@
1
- # Formation 工具鏈完整參考
2
-
3
- **版本**: v2.0
4
- **最後更新**: 2026-02-20
5
-
6
- 本文檔詳細說明 `.formation/tools/` 下所有模組的函數簽名、參數、呼叫關係與設計意圖。
7
-
8
- ---
9
-
10
- ## 目錄
11
-
12
- 1. [系統架構總覽](#系統架構總覽)
13
- 2. [headless.js — Dispatch 入口](#headlessjs--dispatch-入口)
14
- 3. [prompt.js — Prompt 組裝 + Principles 注入](#promptjs--prompt-組裝--principles-注入)
15
- 4. [runner.js — Subagent 執行](#runnerjs--subagent-執行)
16
- 5. [logger.js — Log 管理](#loggerjs--log-管理)
17
- 6. [utils.js — 工具函數](#utilsjs--工具函數)
18
- 7. [loader.js — 任務載入三層 Fallback](#loaderjs--任務載入三層-fallback)
19
- 8. [呼叫關係圖](#呼叫關係圖)
20
- 9. [關鍵流程範例](#關鍵流程範例)
21
-
22
- ---
23
-
24
- ## 系統架構總覽
25
-
26
- Formation 工具鏈採用**分層架構**,各模組職責清晰:
27
-
28
- ```
29
- ┌──────────────────────────────────────────────────────────┐
30
- │ L5: headless.js — 陣型編排層(5 種陣型的執行邏輯) │
31
- │ launch() → launchUnit/Solo/Squad/Legion/Legacy │
32
- └────────────────────┬─────────────────────────────────────┘
33
- ↓
34
- ┌──────────────────────────────────────────────────────────┐
35
- │ L4: runner.js — 進程啟動層(統一的 claude 進程管理) │
36
- │ runSingle / runHeadless / runLegionLead / runParallel │
37
- └────────────────────┬─────────────────────────────────────┘
38
- ↓
39
- ┌──────────────────────────────────────────────────────────┐
40
- │ L3: prompt.js — Prompt 組裝層(針對不同陣型組裝 prompt) │
41
- │ buildPrompt → Unit/Solo/Squad/Legion/Legacy builders │
42
- └────────────────────┬─────────────────────────────────────┘
43
- ↓
44
- ┌──────────────────────────────────────────────────────────┐
45
- │ L2: loader.js — 資料載入層(skill YAML + 任務三層查詢) │
46
- │ loadSkill / loadTask │
47
- └────────────────────┬─────────────────────────────────────┘
48
- ↓
49
- ┌──────────────────────────────────────────────────────────┐
50
- │ L1: logger.js + utils.js — 基礎設施層 │
51
- │ createLogWriter / formatEntry / generateSessionId │
52
- └──────────────────────────────────────────────────────────┘
53
- ```
54
-
55
- **設計原則**:
56
- - **單一職責**:每個模組只負責一件事(編排 / 進程 / prompt / 載入 / 日誌)
57
- - **依賴單向**:L5 依賴 L4,L4 依賴 L3,依此類推,無循環依賴
58
- - **可測試性**:每層可獨立測試,dry-run 可在 prompt 層停下
59
-
60
- ---
61
-
62
- ## headless.js — Dispatch 入口
63
-
64
- **職責**:根據 `--formation` 參數分發到 5 種陣型的執行邏輯
65
-
66
- ### 主入口
67
-
68
- #### `launch(options)`
69
-
70
- 陣型編排的總調度器。
71
-
72
- **參數**:
73
- ```js
74
- {
75
- formation: 'unit' | 'solo' | 'squad' | 'legion' | 'legacy',
76
- skill: string, // 技能名稱(YAML 檔名,不含 .yaml)
77
- task: string | null, // TASK_ID 或任務描述(null 則自動尋找)
78
- dryRun: boolean, // true=只印 prompt,不啟動進程
79
- mode: string | null // 分析模式(squad 用),如 'optimization', 'innovation'
80
- }
81
- ```
82
-
83
- **回傳**:
84
- - `unit/solo`: `ChildProcess`(單一進程)
85
- - `squad`: `ChildProcess[]`(並行進程陣列)
86
- - `legion`: `ChildProcess`(lead 進程)
87
- - `legacy`: `null`(scheduler loop 在 legacy-scheduler.js)
88
-
89
- **流程**:
90
- 1. 若 `task` 為空且非 legacy → 呼叫 `findNextTask()` 自動選擇任務
91
- 2. 載入 skill YAML (`loadSkill`) 和任務資料 (`loadTask`)
92
- 3. 組裝 prompt (`buildPrompt`)
93
- 4. 若 `dryRun=true` → 印出 prompt,結束
94
- 5. 分發到對應陣型的 launcher 函數
95
-
96
- ---
97
-
98
- ### 陣型 Launchers
99
-
100
- #### `launchUnit(opts)`
101
-
102
- **單一 agent 直接執行**(最簡單的模式)
103
-
104
- **參數**:
105
- ```js
106
- {
107
- rawPrompt: string, // 組裝好的 prompt
108
- skill: string,
109
- sessionId: string
110
- }
111
- ```
112
-
113
- **行為**:
114
- - 呼叫 `runHeadless({ prompt: HEADLESS_PREFIX + rawPrompt, ... })`
115
- - 輸出壓縮、原始 stdout 直通
116
-
117
- ---
118
-
119
- #### `launchSolo(opts)`
120
-
121
- **單一 agent 多視角分析**(agent 自主切換視角)
122
-
123
- **參數** / **行為**:與 `launchUnit` 相同,差異在 prompt 結構(含 perspectives)
124
-
125
- ---
126
-
127
- #### `launchSquad(opts)`
128
-
129
- **多 agent 並行 + 辯論 + 整合**(複雜度最高的陣型)
130
-
131
- **參數**:
132
- ```js
133
- {
134
- rawPrompt: Array<{ memberId, prompt, skill }>, // 成員 prompt 陣列
135
- skill: string,
136
- sessionId: string,
137
- skillDef: object // 完整的 skill YAML(含 debate/merge 設定)
138
- }
139
- ```
140
-
141
- **執行流程**:
142
- 1. **Round 1**:並行啟動所有成員 (`runHeadless` × N),各自獨立分析
143
- 2. 等待所有成員完成 (`waitAll`)
144
- 3. 若啟用 debate → **Round 2**:每個成員讀取其他人的報告,寫反駁
145
- 4. **Synthesis**:整合者讀取所有報告,產出最終報告
146
-
147
- **關鍵函數**:
148
- - `waitAll(children)`: 等待所有進程完成,回傳 `Promise<{ memberId, exitCode, logPath }[]>`
149
- - `printResults(label, results, total)`: 格式化輸出進程執行結果
150
- - `hasSuccess(results)`: 檢查是否有至少一個成功
151
- - `squadSynthesis(opts)`: 啟動整合 agent
152
-
153
- ---
154
-
155
- #### `launchLegion(opts)`
156
-
157
- **Agent Teams 啟動**(使用 Claude Code 官方 teammate 功能)
158
-
159
- **參數**:
160
- ```js
161
- {
162
- rawPrompt: { // buildLegionPrompts 的輸出
163
- teamName: string,
164
- teamDesc: string,
165
- lead: { prompt },
166
- members: [{ name, agentType, prompt }]
167
- },
168
- skill: string,
169
- sessionId: string
170
- }
171
- ```
172
-
173
- **行為**:
174
- - 用 `buildLegionLeadPrompt(legionConfig)` 組裝 lead prompt
175
- - 呼叫 `runLegionLead({ prompt, ... })` 啟動 lead agent
176
- - Lead agent 用 `Task` 工具 spawn teammates(進程內並行)
177
-
178
- ---
179
-
180
- #### `launchLegacy(opts)`
181
-
182
- **連續排程器**(Rust SingleAgentScheduler 對等實作)
183
-
184
- **參數**:
185
- ```js
186
- {
187
- skillDef: object // legacy skill YAML(含 config 設定)
188
- }
189
- ```
190
-
191
- **行為**:
192
- - 從 `skillDef.config` 提取參數(initial_delay_secs, interval_minutes 等)
193
- - 呼叫 `legacy-scheduler.js` 的 `start(overrides)`
194
- - 回傳 `null`(scheduler loop 不是 child process)
195
-
196
- ---
197
-
198
- ### 自動任務選擇
199
-
200
- #### `findNextTask()`
201
-
202
- 從 `.collaboration/tasks/backlog/` 中找出最高優先級的任務。
203
-
204
- **回傳**:
205
- ```js
206
- {
207
- id: 'TASK_XXX',
208
- title: string,
209
- priority: number // 0=P0, 1=P1, 2=P2, 3=P3
210
- } | null
211
- ```
212
-
213
- **排序規則**:
214
- 1. 優先級排序(P0 > P1 > P2 > P3)
215
- 2. 同優先級按 ID 數字排序(TASK_150 > TASK_151)
216
- 3. 跳過有未完成依賴的任務(檢查 dependencies 是否都在 done/)
217
-
218
- ---
219
-
220
- ### Dry Run
221
-
222
- #### `printDryRun(formation, rawPrompt, skillDef, skill)`
223
-
224
- 列印 prompt 但不執行,用於偵錯。
225
-
226
- **行為**:
227
- - `legion`: 印 lead prompt
228
- - `squad`: 印 R1 所有成員 prompt + R2 debate prompts + synthesis prompt
229
- - 其他: 直接印 `HEADLESS_PREFIX + rawPrompt`
230
-
231
- ---
232
-
233
- ## prompt.js — Prompt 組裝 + Principles 注入
234
-
235
- **職責**:根據 skill YAML 和陣型,組裝出符合格式的 prompt
236
-
237
- ### 主入口
238
-
239
- #### `buildPrompt(skillDef, taskInput, taskData, options)`
240
-
241
- 根據陣型分發到對應的 prompt builder。
242
-
243
- **參數**:
244
- ```js
245
- skillDef: object, // loadSkill 回傳的 YAML 解析結果
246
- taskInput: string, // TASK_ID 或任務描述
247
- taskData: string | null, // loadTask 回傳的 YAML 文本(或 null)
248
- options: {
249
- analysisMode?: string // 'optimization' | 'innovation'(squad 用)
250
- }
251
- ```
252
-
253
- **回傳**:
254
- - `unit/solo/legacy`: `string`(單一 prompt)
255
- - `squad`: `Array<{ memberId, prompt, skill }>`
256
- - `legion`: `{ teamName, teamDesc, lead, members }`
257
-
258
- ---
259
-
260
- ### 陣型 Builders
261
-
262
- #### `buildUnitPrompt(skillDef, taskInput, taskData)`
263
-
264
- 組裝單一 agent 的 prompt(最簡單結構)
265
-
266
- **Prompt 結構**:
267
- ```
268
- ## Role
269
- {role.identity}
270
- Priority: {role.priority}
271
-
272
- ## Behavior
273
- - {behavior[0]}
274
- - {behavior[1]}
275
- ...
276
-
277
- ## Task
278
- {taskInput 或 taskData}
279
-
280
- ## Workflow
281
- ### {workflow[0].step}
282
- ...
283
-
284
- ## Expected Output
285
- Primary: {output.primary}
286
- Secondary: {output.secondary}
287
- ```
288
-
289
- ---
290
-
291
- #### `buildSoloPrompt(skillDef, taskInput, taskData)`
292
-
293
- 在 unit 基礎上加入**可用視角 (perspectives)** 和**分析原則 (analysis_principles)**
294
-
295
- **額外區塊**:
296
- ```
297
- ## Analysis Principles
298
- ### {principle.name}
299
- {principle.description}
300
-
301
- ## Available Perspectives
302
- ### {perspective.name}
303
- - 關注:{perspective.lens}
304
- - 何時切換:{perspective.trigger}
305
- ```
306
-
307
- ---
308
-
309
- #### `buildSquadPrompts(skillDef, taskInput, taskData, options)`
310
-
311
- 為每個成員分別組裝 prompt(**最複雜的 builder**)
312
-
313
- **成員 Prompt 結構**:
314
- ```
315
- ## Role
316
- {member.role}
317
-
318
- ## Analysis Mode: {analysisMode}
319
- {modeConfig.description}
320
- **你在此模式下的立場調整**:
321
- {member.mode_behavior[analysisMode]}
322
-
323
- ## Principles (絕對遵守)
324
- {skillDef.principles.focus}
325
- **禁止 (違反即失敗)**:
326
- - ❌ {forbidden[0]}
327
- ...
328
- **必須遵守**:
329
- - ✅ {required[0]}
330
- ...
331
-
332
- ## Identity
333
- 你是 Squad 的成員 **{member.name}** (id: {member.id})。
334
- 你與其他成員並行工作,各自獨立,不能互相通訊。
335
- 完成你負責的部分後回報結果,Lead 會負責整合。
336
-
337
- ## Scope (你只能碰這些檔案)
338
- Include:
339
- - {scope.include[0]}
340
- - ...
341
- Exclude:
342
- - {scope.exclude[0]}
343
- - ...
344
-
345
- ## Shared Context (所有成員共享的約定)
346
- {skillDef.shared_context.description}
347
- ### {key}
348
- {value}
349
-
350
- ## Behavior
351
- - {skillDef.behavior[0]}
352
- - {member.behavior[0]}
353
- ...
354
-
355
- ## Task
356
- {taskInput 或 taskData}
357
-
358
- ## Workflow
359
- {member.workflow 或 skillDef.collaboration.workflow}
360
-
361
- ## Expected Output
362
- {member.output 或 skillDef.output}
363
- ```
364
-
365
- **關鍵函數**:
366
- - `buildSharedContextBlock(skillDef)`: 組裝 shared_context 區塊(成員共用的約定)
367
-
368
- ---
369
-
370
- #### `buildLegionPrompts(skillDef, taskInput, taskData)`
371
-
372
- 組裝 team lead 和每個成員的 prompt。
373
-
374
- **回傳結構**:
375
- ```js
376
- {
377
- teamName: string, // 團隊名稱(自動轉 kebab-case)
378
- teamDesc: string, // 團隊描述
379
- lead: {
380
- prompt: string // Lead agent 的 prompt
381
- },
382
- members: [
383
- {
384
- name: string, // 成員名稱
385
- agentType: string, // 'general-purpose' 等
386
- prompt: string // 成員的 prompt
387
- }
388
- ]
389
- }
390
- ```
391
-
392
- **Lead Prompt 結構**:
393
- ```
394
- ## Role
395
- 你是 {teamName} 的 Team Lead。
396
- {role.identity}
397
-
398
- ## Team Members
399
- - **{member.name}**: {member.role}
400
-
401
- ## Communication Rules
402
- ### Principles
403
- - {comm.principles[0]}
404
- ...
405
- ### Patterns
406
- - **{pattern.name}**: {pattern.who} — {pattern.content}
407
- ...
408
- ### Broadcast Policy
409
- {comm.broadcast_policy}
410
-
411
- ## Task
412
- {taskInput}
413
-
414
- ## Lifecycle
415
- ### {phase}
416
- {description}
417
- Lead actions:
418
- - {lead_actions[0]}
419
- Exit criteria:
420
- - {exit_criteria[0]}
421
-
422
- ## Expected Output
423
- ...
424
- ```
425
-
426
- **Member Prompt**:
427
- - 優先使用 `skillDef.member_prompts[member.id]`(如 forge 的 designer/implementer)
428
- - 否則自動生成(Role + Responsibilities + Skills + Scope + Team Context)
429
-
430
- ---
431
-
432
- #### `buildLegacyPrompt(skillDef)`
433
-
434
- 回傳 scheduler 配置摘要(供 dry-run 顯示)
435
-
436
- ---
437
-
438
- ### Squad 專用:Synthesis 與 Debate
439
-
440
- #### `buildSquadSynthesisPrompt(skillDef, reportDir)`
441
-
442
- 組裝整合 agent 的 prompt,讀取所有成員報告並整合。
443
-
444
- **Prompt 結構**:
445
- ```
446
- ## Role
447
- 你是 Squad Synthesis Agent(整合者)。
448
- 你不偏袒任何一方。
449
-
450
- ## Principles (整合時也必須遵守)
451
- {skillDef.principles.focus}
452
- **禁止**: {forbidden}
453
- **必須遵守**: {required}
454
-
455
- ## Merge Strategy: {merge.strategy}
456
- {merge.description}
457
-
458
- ## Merge Steps (按順序執行)
459
- ### Step: {step.step}
460
- {step.action}
461
- **Partial Failure Handling**: {step.on_partial_failure}
462
-
463
- ## Reports Location
464
- 所有成員報告位於 `.formation/reports/{reportDir}/` 目錄。
465
- **執行步驟**:
466
- 1. 用 Glob 工具掃描 `.formation/reports/{reportDir}/*.md`
467
- 2. 排除 synthesis.md
468
- 3. 用 Read 工具逐一讀取每份報告
469
- 4. 按照上述 Merge Steps 逐步整合
470
-
471
- ## Squad Members(供參考)
472
- - **{member.name}** ({member.id}): {roleFirstLine}
473
-
474
- ## Output
475
- 將整合報告寫入 `.formation/reports/{reportDir}/synthesis.md`
476
- ```
477
-
478
- ---
479
-
480
- #### `buildSquadDebatePrompts(skillDef, reportDir)`
481
-
482
- 組裝 Round 2 交叉辯論的 prompts(每個成員讀其他人的報告)
483
-
484
- **回傳**:`Array<{ memberId, prompt, skill }>`(格式與 buildSquadPrompts 相同)
485
-
486
- **Prompt 結構**:
487
- ```
488
- ## Role
489
- 你是 **{member.name}**,這是你的第二輪分析(辯論回合)。
490
-
491
- ## 你的立場(簡要提醒)
492
- {roleFirstLine}
493
-
494
- ## Debate Instructions
495
- {member.debate_instructions}
496
-
497
- ## Debate Rules
498
- - {debate.rules[0]}
499
- ...
500
-
501
- ## Reports to Read
502
- - **{other.name}**: `.formation/reports/{reportDir}/{other.id}.md`
503
-
504
- 用 Read 工具讀取上述報告,然後寫出你的回應。
505
-
506
- ## Output
507
- 將反駁報告寫入 `.formation/reports/{reportDir}/{member.id}-r2.md`
508
- ```
509
-
510
- ---
511
-
512
- ### Legion 專用
513
-
514
- #### `buildLegionLeadPrompt(config)`
515
-
516
- 組裝 Legion lead 的完整 headless prompt(複製 Sunny teammate 成功模式)
517
-
518
- **結構**:
519
- ```
520
- {LEGION_SYSTEM_PREFIX}
521
- Create an agent team with {members.length} teammates:
522
- 1. "{name}" - {desc}
523
- 2. ...
524
-
525
- Task: {taskMatch}
526
-
527
- {LEGION_AUTO_EXECUTE}
528
- ```
529
-
530
- **常數定義**:
531
- - `LEGION_SYSTEM_PREFIX`: 定義 Team Lead 的角色與責任
532
- - `LEGION_AUTO_EXECUTE`: 強制執行規則(立即建 teammates,進入 polling loop,等所有人完成)
533
-
534
- ---
535
-
536
- ### 共用片段
537
-
538
- #### `appendBehavior(lines, skillDef)`
539
-
540
- 將 `skillDef.behavior` 陣列附加到 lines。
541
-
542
- #### `appendTask(lines, taskInput, taskData)`
543
-
544
- 組裝 Task 區塊:
545
- - 若有 taskData → 用 ` ``` ` 包起來顯示
546
- - 否則直接顯示 taskInput
547
-
548
- #### `appendWorkflow(lines, skillDef)`
549
-
550
- 組裝 Workflow 區塊(從 `skillDef.collaboration.workflow`)
551
-
552
- #### `appendOutput(lines, skillDef)`
553
-
554
- 組裝 Output 區塊(`primary` + `secondary`)
555
-
556
- ---
557
-
558
- ### Headless 常數
559
-
560
- #### `HEADLESS_PREFIX`
561
-
562
- 強制規則:
563
- 1. 直接執行,不要提問
564
- 2. 不要讀取 CLAUDE.md
565
- 3. 完成後輸出結構化結果
566
- 4. 遇到無法執行的問題,輸出錯誤描述後結束
567
- 5. **禁止執行任何 git 操作**(Git 由 Formation Lead 統一管理)
568
-
569
- ---
570
-
571
- ## runner.js — Subagent 執行
572
-
573
- **職責**:統一的 `claude` 進程啟動與輸出收集
574
-
575
- ### 內部:進程管理
576
-
577
- #### `spawnClaude(opts)`
578
-
579
- 所有 `run*` 函數的底層實作。
580
-
581
- **參數**:
582
- ```js
583
- {
584
- prompt: string, // 完整 prompt(已包含 HEADLESS_PREFIX)
585
- formation: string, // 陣型名稱(用於 log 目錄)
586
- skill: string, // 技能名稱
587
- sessionId: string, // session ID
588
- memberId?: string, // 成員 ID(squad/legion 用)
589
- silent?: boolean, // 不輸出到 console
590
- outputPath?: string, // 自訂 log 路徑
591
- cleanPrompt?: boolean, // true=壓縮 prompt(移除換行、多餘空格)
592
- allowedTools?: string, // 允許的工具清單(逗號分隔)
593
- extraArgs?: string[], // 額外的 claude CLI 參數
594
- pipeRaw?: boolean, // true=原始 stdout 直通,false=格式化輸出
595
- onLog?: (formatted: string) => void // 自訂 log handler
596
- }
597
- ```
598
-
599
- **回傳**:`ChildProcess`(附加 `_formation` 屬性)
600
-
601
- **流程**:
602
- 1. 建立 log writer (`createLogWriter`)
603
- 2. 啟動 `claude.cmd -p - --dangerously-skip-permissions --output-format stream-json ...`
604
- 3. 將 prompt 透過 stdin 傳入
605
- 4. 呼叫 `collectOutput(child, log, opts)` 收集輸出
606
- 5. 附加 `_formation` 屬性到 child process
607
-
608
- **`_formation` 屬性**:
609
- ```js
610
- {
611
- logPath: string, // log 檔案路徑
612
- memberId: string, // 成員 ID
613
- log: object // log writer 實例
614
- }
615
- ```
616
-
617
- ---
618
-
619
- #### `collectOutput(child, log, opts)`
620
-
621
- 收集 `claude` 進程的 stdout/stderr,寫入 log。
622
-
623
- **參數**:
624
- ```js
625
- child: ChildProcess,
626
- log: LogWriter,
627
- opts: {
628
- silent?: boolean, // 不輸出到 console
629
- memberId?: string, // 成員 ID(顯示用)
630
- pipeRaw?: boolean, // true=直通,false=格式化
631
- onLog?: (line) => void // 自訂 handler
632
- }
633
- ```
634
-
635
- **行為**:
636
- 1. 監聽 `stdout.data` 事件,解析 stream-json 格式
637
- 2. 用 `formatEntry(entry)` 格式化每條 entry
638
- 3. 寫入 log 檔案
639
- 4. 若 `!silent && !pipeRaw` → 輸出到 console
640
- 5. 偵測到 `type: 'result'` → emit `formation:done` 並延遲 kill(Windows fix)
641
- 6. 監聽 `close/exit/formation:done` → 呼叫 `log.writeFooter(code)`
642
-
643
- **Windows 特殊處理**:
644
- - `claude.cmd` 有時進程不 exit,偵測到 `result` 就 emit 完成信號並延遲 kill
645
-
646
- ---
647
-
648
- ### 公開 API
649
-
650
- #### `runSingle(opts)`
651
-
652
- 啟動單一 claude subagent(**格式化輸出**)
653
-
654
- **用途**:dispatch.js 用(一般模式)
655
-
656
- ---
657
-
658
- #### `runHeadless(opts)`
659
-
660
- 無頭模式:**壓縮 prompt + 原始 stdout 直通**
661
-
662
- **用途**:Unit / Solo / Squad 成員
663
-
664
- ---
665
-
666
- #### `runLegionLead(opts)`
667
-
668
- Agent Teams 模式:啟用 `--teammate-mode in-process` + `Task` 工具
669
-
670
- **預設參數覆蓋**:
671
- ```js
672
- {
673
- cleanPrompt: true,
674
- pipeRaw: true,
675
- allowedTools: 'Bash,Read,Edit,Write,Glob,Grep,Task',
676
- extraArgs: ['--teammate-mode', 'in-process']
677
- }
678
- ```
679
-
680
- ---
681
-
682
- #### `runParallel(opts)`
683
-
684
- 並行啟動多個 claude subagent(**dispatch 用**)
685
-
686
- **參數**:
687
- ```js
688
- {
689
- members: Array<{ memberId, prompt, skill }>,
690
- formation: string,
691
- sessionId: string
692
- }
693
- ```
694
-
695
- **回傳**:`Promise<Array<{ memberId, exitCode, logPath }>>`
696
-
697
- **行為**:
698
- 1. 用 `runSingle` 並行啟動所有成員
699
- 2. 用 `Promise.all` 等待所有進程完成
700
- 3. 輸出執行結果摘要
701
-
702
- ---
703
-
704
- ## logger.js — Log 管理
705
-
706
- **職責**:Claude subagent 的 stream-json 格式化與 log 寫入
707
-
708
- ### Log Writer
709
-
710
- #### `createLogWriter(opts)`
711
-
712
- 建立 log writer 實例。
713
-
714
- **參數**:
715
- ```js
716
- {
717
- formation: string, // 陣型(決定 log 目錄)
718
- skill: string, // 技能名稱
719
- sessionId: string, // session ID
720
- outputPath?: string, // 自訂輸出路徑
721
- memberId?: string // Squad 成員 ID
722
- }
723
- ```
724
-
725
- **回傳**:
726
- ```js
727
- {
728
- stream: WriteStream, // fs.createWriteStream 實例
729
- path: string, // log 檔案絕對路徑
730
- writeHeader: () => void, // 寫入 header(formation, skill, session, 時間)
731
- writeFooter: (code) => void // 寫入 footer(finished, exit code)
732
- }
733
- ```
734
-
735
- **Log 目錄結構**:
736
- ```
737
- .formation/logs/{formation}/{skill}_{memberId?}_{sessionId}.log
738
- ```
739
-
740
- ---
741
-
742
- ### Entry 格式化
743
-
744
- #### `formatEntry(entry)`
745
-
746
- 格式化 stream-json 的一條 entry。
747
-
748
- **參數**:
749
- ```js
750
- entry: {
751
- type: 'system' | 'assistant' | 'user' | 'result',
752
- subtype?: string,
753
- message?: { content: [...] },
754
- ...
755
- }
756
- ```
757
-
758
- **回傳**:`string | null`(格式化後的文本,或 null 表示跳過)
759
-
760
- **支援的 entry types**:
761
-
762
- 1. **system**:
763
- - `init`: `[SYSTEM][INIT] model=... cwd=...`
764
- - `hook_started`: `[SYSTEM][HOOK] {hook_name} started`
765
- - `hook_response`: `[SYSTEM][HOOK] {hook_name} OK/FAILED`
766
-
767
- 2. **assistant**(agent 輸出 + 工具呼叫):
768
- - `text` block → 移除 markdown 格式,分行輸出 `[Agent] ...`
769
- - `tool_use` block → `[Agent][{tool}] {detail}`
770
-
771
- 3. **user**(tool results、teammate 訊息):
772
- - `tool_use_result.status === 'teammate_spawned'` → `[SYSTEM][Spawned] ...`
773
- - `message.content` 包含 "Message from" → `[Teammate:{name}] | ...`
774
-
775
- 4. **result**(session 結束摘要):
776
- - `[RESULT] {subtype}`
777
- - `Duration: {duration_ms/1000}s`
778
- - `Cost: ${total_cost_usd}`
779
- - `Turns: {num_turns}`
780
- - 摘要前 10 行
781
-
782
- ---
783
-
784
- #### `formatToolUse(ts, block)`
785
-
786
- 格式化 tool_use block。
787
-
788
- **工具清單**:
789
- - `Bash`: 顯示 `description` 或 `command` 前 60 字元
790
- - `Read/Write/Edit`: 顯示 `file_path`
791
- - `Glob/Grep`: 顯示 `pattern`
792
- - `TeamCreate`: 顯示 `team_name`
793
- - `Task`: 顯示 `name` 和 `subagent_type`
794
- - `SendMessage`: 顯示 `recipient` 和 `type`,並附加完整訊息內容
795
-
796
- **格式**:
797
- ```
798
- [HH:MM:SS][Agent][{tool}] {detail}
799
- | {message line 1}
800
- | {message line 2}
801
- | ...
802
- ```
803
-
804
- ---
805
-
806
- #### `formatUser(ts, entry)`
807
-
808
- 格式化 user events(tool results、teammate 訊息)
809
-
810
- **格式**:
811
- ```
812
- [HH:MM:SS][SYSTEM][Spawned] Teammate "{name}" model=...
813
- [HH:MM:SS][Teammate:{name}]
814
- | {message line 1}
815
- | {message line 2}
816
- | ...
817
- ```
818
-
819
- ---
820
-
821
- #### `formatResult(ts, entry)`
822
-
823
- 格式化 session 結束摘要。
824
-
825
- **格式**:
826
- ```
827
- [HH:MM:SS][RESULT] {subtype}
828
- Duration: {seconds}s
829
- Cost: ${usd}
830
- Turns: {num_turns}
831
- {result line 1}
832
- {result line 2}
833
- ...
834
- ```
835
-
836
- ---
837
-
838
- ## utils.js — 工具函數
839
-
840
- **職責**:路徑常數、Session ID 生成、Git Bash 偵測、環境變數設定
841
-
842
- ### 路徑常數
843
-
844
- ```js
845
- ROOT // D:\repo\side\ava\KenazAI
846
- FORMATION_DIR // {ROOT}/.formation
847
- COLLABORATION_API // {ROOT}/.collaboration/core/task-api.js
848
- LOG_DIR // {ROOT}/.formation/logs
849
- ```
850
-
851
- ---
852
-
853
- ### Session ID
854
-
855
- #### `generateSessionId()`
856
-
857
- 生成唯一的 session ID。
858
-
859
- **格式**:`YYYYMMDD-HHMMSS-{4 位隨機 hex}`
860
-
861
- **範例**:`20260220-123045-a3f9`
862
-
863
- ---
864
-
865
- ### Git Bash 偵測
866
-
867
- #### `detectGitBash()`
868
-
869
- Windows 專用:自動偵測 Git Bash 路徑。
870
-
871
- **回傳**:`string | null`(bash.exe 的絕對路徑)
872
-
873
- **偵測順序**:
874
- 1. 從 `where git` 找到 git.exe 路徑
875
- 2. 往上找包含 `bin/bash.exe` 的 Git 根目錄
876
- 3. Fallback 到固定路徑清單:
877
- - `C:\Program Files\Git\bin\bash.exe`
878
- - `C:\Program Files (x86)\Git\bin\bash.exe`
879
- - `D:\Program Files\Git\bin\bash.exe`
880
-
881
- ---
882
-
883
- ### 環境變數
884
-
885
- #### `getClaudeEnv()`
886
-
887
- 建立 claude 進程的環境變數。
888
-
889
- **回傳**:`object`(繼承 `process.env` 並修改)
890
-
891
- **變更**:
892
- 1. 設定 `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`(啟用 agent teams)
893
- 2. 刪除 `CLAUDECODE`(避免 nested session 錯誤)
894
- 3. Windows: 設定 `CLAUDE_CODE_GIT_BASH_PATH`(若未設定)
895
-
896
- ---
897
-
898
- ## loader.js — 任務載入三層 Fallback
899
-
900
- **職責**:載入 skill YAML + 任務資料(支援新舊兩套任務系統)
901
-
902
- ### Skill 載入
903
-
904
- #### `loadSkill(formation, skill)`
905
-
906
- 載入 skill YAML 定義。
907
-
908
- **參數**:
909
- ```js
910
- formation: string, // 陣型名稱(決定子目錄)
911
- skill: string // 技能名稱(YAML 檔名,不含 .yaml)
912
- ```
913
-
914
- **回傳**:`object`(YAML 解析結果)
915
-
916
- **路徑**:`.formation/{formation}/{skill}.yaml`
917
-
918
- **錯誤處理**:檔案不存在 → `console.error` + `process.exit(1)`
919
-
920
- ---
921
-
922
- #### `listSkills(formation)`
923
-
924
- 列出某個陣型下所有可用的 skill。
925
-
926
- **回傳**:`string[]`(skill 名稱列表,不含 .yaml)
927
-
928
- ---
929
-
930
- ### 任務載入(三層 Fallback)
931
-
932
- #### `loadTask(taskId)`
933
-
934
- 載入任務資料,支援新舊兩套任務系統。
935
-
936
- **參數**:
937
- ```js
938
- taskId: string // TASK_XXX 格式(若不符合或為 null 則回傳 null)
939
- ```
940
-
941
- **回傳**:`string | null`(YAML 或 JSON 文本)
942
-
943
- **查詢順序**:
944
-
945
- 1. **新系統** (`.collaboration/tasks/`)
946
- - 呼叫 `node .collaboration/core/task-api.js get {taskId}`
947
- - 目錄結構:`{status}/{taskId}_{git_user}.yaml`(status = backlog/active/done/blocked)
948
-
949
- 2. **舊系統 YAML** (`dev/pipeline/completed/` + `tasks/`)
950
- - 掃描兩個目錄,找到以 `{taskId}` 開頭且 `.yaml` 結尾的檔案
951
- - 讀取並回傳檔案內容
952
-
953
- 3. **舊系統 JSON** (`dev/pipeline/TASK_QUEUE.json`)
954
- - 解析 JSON 檔案
955
- - 從 `tasks` 陣列找到 `id === taskId` 的任務
956
- - 用 `yaml.dump` 轉為 YAML 格式回傳
957
-
958
- **錯誤處理**:
959
- - 所有層都失敗 → `console.warn` + 回傳 `null`(不中斷執行)
960
-
961
- ---
962
-
963
- ### 實作細節
964
-
965
- #### `loadTaskFromCollaboration(taskId)`
966
-
967
- 新系統載入邏輯。
968
-
969
- **實作**:
970
- ```js
971
- const result = execSync(
972
- `node "${COLLABORATION_API}" get ${taskId}`,
973
- { encoding: 'utf8', cwd: ROOT, timeout: 10000 }
974
- );
975
- ```
976
-
977
- **錯誤處理**:捕捉 exception 並回傳 `null`
978
-
979
- ---
980
-
981
- #### `loadTaskFromLegacyYaml(taskId)`
982
-
983
- 舊系統 YAML 檔載入。
984
-
985
- **實作**:
986
- ```js
987
- const dirs = ['completed', 'tasks'];
988
- for (const dir of dirs) {
989
- const files = fs.readdirSync(dirPath);
990
- const match = files.find(f => f.startsWith(taskId) && f.endsWith('.yaml'));
991
- if (match) return fs.readFileSync(...);
992
- }
993
- ```
994
-
995
- ---
996
-
997
- #### `loadTaskFromLegacyQueue(taskId)`
998
-
999
- 舊系統 JSON 索引載入。
1000
-
1001
- **實作**:
1002
- ```js
1003
- const queue = JSON.parse(fs.readFileSync(LEGACY_TASK_QUEUE, 'utf8'));
1004
- const task = queue.tasks.find(t => t.id === taskId);
1005
- if (task) return yaml.dump(task, { lineWidth: -1 });
1006
- ```
1007
-
1008
- ---
1009
-
1010
- ## 呼叫關係圖
1011
-
1012
- ```
1013
- CLI (node .formation/tools/headless.js --formation=squad --skill=blitz)
1014
- ↓
1015
- headless.js:launch()
1016
- ↓
1017
- ├─→ loader.js:loadSkill(formation, skill) → 載入 YAML
1018
- ├─→ loader.js:loadTask(taskId) → 三層 fallback 載入任務
1019
- ├─→ prompt.js:buildPrompt(skillDef, taskInput) → 組裝 prompt
1020
- ↓
1021
- ├── formation='squad' → headless.js:launchSquad()
1022
- │ ↓
1023
- │ ├─→ runner.js:runHeadless() × N (Round 1)
1024
- │ │ ↓
1025
- │ │ ├─→ runner.js:spawnClaude()
1026
- │ │ │ ↓
1027
- │ │ │ ├─→ logger.js:createLogWriter()
1028
- │ │ │ ├─→ utils.js:getClaudeEnv()
1029
- │ │ │ └─→ runner.js:collectOutput()
1030
- │ │ │ ↓
1031
- │ │ │ └─→ logger.js:formatEntry() → log 寫入
1032
- │ │ └─→ waitAll() → 等待所有進程完成
1033
- │ ↓
1034
- │ ├─→ prompt.js:buildSquadDebatePrompts() (Round 2)
1035
- │ ├─→ runner.js:runHeadless() × N (Round 2)
1036
- │ └─→ headless.js:squadSynthesis()
1037
- │ ↓
1038
- │ └─→ prompt.js:buildSquadSynthesisPrompt()
1039
- │ ↓
1040
- │ └─→ runner.js:runHeadless()
1041
- │
1042
- ├── formation='legion' → headless.js:launchLegion()
1043
- │ ↓
1044
- │ ├─→ prompt.js:buildLegionLeadPrompt()
1045
- │ └─→ runner.js:runLegionLead()
1046
- │ ↓
1047
- │ └─→ runner.js:spawnClaude(extraArgs: ['--teammate-mode', ...])
1048
- │
1049
- ├── formation='unit' → headless.js:launchUnit()
1050
- │ ↓
1051
- │ └─→ runner.js:runHeadless()
1052
- │
1053
- ├── formation='solo' → headless.js:launchSolo()
1054
- │ ↓
1055
- │ └─→ runner.js:runHeadless()
1056
- │
1057
- └── formation='legacy' → headless.js:launchLegacy()
1058
- ↓
1059
- └─→ legacy-scheduler.js:start()
1060
- ```
1061
-
1062
- ---
1063
-
1064
- ## 關鍵流程範例
1065
-
1066
- ### 範例 1:Unit 執行流程
1067
-
1068
- **命令**:
1069
- ```bash
1070
- node .formation/tools/headless.js --skill=do --task="修正按鈕顏色"
1071
- ```
1072
-
1073
- **流程**:
1074
- 1. `headless.launch()` 解析參數:`formation='unit', skill='do', task='修正按鈕顏色'`
1075
- 2. `loader.loadSkill('unit', 'do')` → 讀取 `.formation/unit/do.yaml`
1076
- 3. `prompt.buildPrompt()` → 呼叫 `buildUnitPrompt()` 組裝 prompt
1077
- 4. `headless.launchUnit()` → 呼叫 `runner.runHeadless()`
1078
- 5. `runner.spawnClaude()` 啟動 `claude.cmd -p - ...`
1079
- 6. `collectOutput()` 收集輸出,`formatEntry()` 格式化每條 entry
1080
- 7. 寫入 `.formation/logs/unit/do_{sessionId}.log`
1081
-
1082
- ---
1083
-
1084
- ### 範例 2:Squad 執行流程(含 Debate)
1085
-
1086
- **命令**:
1087
- ```bash
1088
- node .formation/tools/headless.js --formation=squad --skill=blitz --task=TASK_201
1089
- ```
1090
-
1091
- **流程**:
1092
- 1. `headless.launch()` 解析參數:`formation='squad', skill='blitz', task='TASK_201'`
1093
- 2. `loader.loadTask('TASK_201')` → 三層 fallback 載入任務 YAML
1094
- 3. `prompt.buildSquadPrompts()` → 回傳 `[{ memberId, prompt, skill }, ...]`
1095
- 4. `headless.launchSquad()`:
1096
- - **Round 1**:`runHeadless()` × N,並行啟動所有成員
1097
- - `waitAll()` 等待所有進程完成
1098
- - 若 `skillDef.debate.enabled=true`:
1099
- - **Round 2**:`buildSquadDebatePrompts()` 組裝辯論 prompts
1100
- - `runHeadless()` × N,成員互相讀取報告
1101
- - **Synthesis**:`buildSquadSynthesisPrompt()` + `runHeadless()`
1102
- 5. 每個成員的輸出分別寫入:
1103
- - R1: `.formation/logs/squad/{member.id}_{sessionId}.log`
1104
- - R2: `.formation/logs/squad/{member.id}-r2_{sessionId}.log`
1105
- - Synthesis: `.formation/logs/squad/{skill}-synthesis_{sessionId}.log`
1106
-
1107
- ---
1108
-
1109
- ### 範例 3:Legion 執行流程
1110
-
1111
- **命令**:
1112
- ```bash
1113
- node .formation/tools/headless.js --formation=legion --skill=forge --task=TASK_202
1114
- ```
1115
-
1116
- **流程**:
1117
- 1. `prompt.buildLegionPrompts()` → 回傳 `{ teamName, lead, members }`
1118
- 2. `prompt.buildLegionLeadPrompt()` → 組裝 lead prompt(含 `LEGION_AUTO_EXECUTE`)
1119
- 3. `runner.runLegionLead()` → 啟動 lead agent(`--teammate-mode in-process`)
1120
- 4. Lead agent 用 `Task` 工具 spawn teammates(進程內並行)
1121
- 5. Lead agent 進入 polling loop(`sleep 5` + check messages)
1122
- 6. 等待所有 teammates 回報 → 整合結果 → 結束
1123
-
1124
- ---
1125
-
1126
- ## 總結
1127
-
1128
- Formation 工具鏈設計遵循以下核心原則:
1129
-
1130
- 1. **分層架構**:L1 基礎設施 → L2 載入 → L3 prompt → L4 進程 → L5 編排
1131
- 2. **單一職責**:每個模組只做一件事,介面清晰
1132
- 3. **可測試性**:dry-run 可在 prompt 層停下,不啟動進程
1133
- 4. **統一進程管理**:所有陣型的 subagent 啟動都經過 `runner.js`
1134
- 5. **統一日誌格式**:所有 log 都經過 `logger.js` 格式化
1135
- 6. **雙系統相容**:任務載入支援新舊兩套系統(三層 fallback)
1136
-
1137
- **擴展建議**:
1138
- - 新增陣型:在 `.formation/{formation}/` 建立 YAML,在 `headless.js` 新增 launcher
1139
- - 新增工具支援:在 `logger.js:formatToolUse()` 新增格式化規則
1140
- - 調整 prompt 結構:修改 `prompt.js` 對應的 builder 函數
1141
-
1142
- **維護要點**:
1143
- - 修改 prompt 結構時,同步更新 `.formation/{formation}/` 下的 YAML 範例
1144
- - 新增環境變數時,在 `utils.js:getClaudeEnv()` 統一設定
1145
- - 修改 log 格式時,確保與 Sunny 的 `format-output.js` 保持一致