triflux 10.4.0 → 10.7.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.
Files changed (391) hide show
  1. package/.claude-plugin/marketplace.json +34 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/bin/tfx-doctor-tui.mjs +1 -1
  4. package/bin/tfx-doctor.mjs +6 -1
  5. package/bin/tfx-profile.mjs +1 -1
  6. package/bin/tfx-setup-tui.mjs +1 -1
  7. package/bin/tfx-setup.mjs +6 -1
  8. package/bin/triflux.mjs +2396 -1140
  9. package/config/mcp-registry.json +29 -0
  10. package/hooks/agent-route-guard.mjs +12 -8
  11. package/hooks/cross-review-tracker.mjs +21 -8
  12. package/hooks/error-context.mjs +19 -7
  13. package/hooks/hook-adaptive-collector.mjs +18 -16
  14. package/hooks/hook-manager.mjs +93 -32
  15. package/hooks/hook-orchestrator.mjs +108 -24
  16. package/hooks/hook-registry.json +267 -256
  17. package/hooks/keyword-rules.json +6 -10
  18. package/hooks/lib/resolve-root.mjs +1 -1
  19. package/hooks/mcp-config-watcher.mjs +6 -2
  20. package/hooks/pipeline-stop.mjs +3 -6
  21. package/hooks/safety-guard.mjs +99 -28
  22. package/hooks/session-start-fast.mjs +143 -0
  23. package/hooks/subagent-verifier.mjs +5 -4
  24. package/hub/account-broker.mjs +256 -60
  25. package/hub/adaptive-diagnostic.mjs +75 -48
  26. package/hub/adaptive-inject.mjs +96 -58
  27. package/hub/adaptive-memory.mjs +156 -42
  28. package/hub/adaptive.mjs +60 -31
  29. package/hub/assign-callbacks.mjs +163 -126
  30. package/hub/bridge.mjs +0 -1
  31. package/hub/cli-adapter-base.mjs +200 -48
  32. package/hub/codex-adapter.mjs +76 -96
  33. package/hub/codex-compat.mjs +3 -3
  34. package/hub/codex-preflight.mjs +63 -37
  35. package/hub/delegator/contracts.mjs +19 -23
  36. package/hub/delegator/index.mjs +14 -14
  37. package/hub/delegator/service.mjs +88 -64
  38. package/hub/delegator/tool-definitions.mjs +35 -35
  39. package/hub/fullcycle.mjs +33 -17
  40. package/hub/gemini-adapter.mjs +69 -94
  41. package/hub/hitl.mjs +202 -143
  42. package/hub/intent.mjs +161 -38
  43. package/hub/lib/cache-guard.mjs +43 -17
  44. package/hub/lib/mcp-response-cache.mjs +66 -32
  45. package/hub/lib/memory-store.mjs +285 -111
  46. package/hub/lib/path-utils.mjs +35 -37
  47. package/hub/lib/process-utils.mjs +106 -37
  48. package/hub/lib/spawn-trace.mjs +527 -0
  49. package/hub/lib/ssh-command.mjs +34 -4
  50. package/hub/lib/ssh-retry.mjs +5 -1
  51. package/hub/lib/uuidv7.mjs +4 -3
  52. package/hub/memory-doctor.mjs +266 -106
  53. package/hub/middleware/request-logger.mjs +61 -34
  54. package/hub/paths.mjs +9 -9
  55. package/hub/pipeline/gates/confidence.mjs +34 -15
  56. package/hub/pipeline/gates/consensus.mjs +27 -15
  57. package/hub/pipeline/gates/index.mjs +7 -3
  58. package/hub/pipeline/gates/selfcheck.mjs +57 -19
  59. package/hub/pipeline/index.mjs +77 -42
  60. package/hub/pipeline/state.mjs +10 -10
  61. package/hub/pipeline/transitions.mjs +40 -23
  62. package/hub/platform.mjs +57 -48
  63. package/hub/promote-penalties.mjs +25 -7
  64. package/hub/quality/deslop.mjs +70 -49
  65. package/hub/research.mjs +32 -25
  66. package/hub/router.mjs +924 -791
  67. package/hub/routing/complexity.mjs +132 -29
  68. package/hub/routing/index.mjs +17 -12
  69. package/hub/routing/q-learning.mjs +76 -28
  70. package/hub/server.mjs +4 -4
  71. package/hub/session-fingerprint.mjs +127 -61
  72. package/hub/state.mjs +84 -43
  73. package/hub/store-adapter.mjs +59 -26
  74. package/hub/store.mjs +356 -153
  75. package/hub/team/agent-map.json +22 -7
  76. package/hub/team/ansi.mjs +186 -122
  77. package/hub/team/backend.mjs +28 -10
  78. package/hub/team/cli/commands/attach.mjs +57 -37
  79. package/hub/team/cli/commands/control.mjs +29 -8
  80. package/hub/team/cli/commands/debug.mjs +95 -74
  81. package/hub/team/cli/commands/focus.mjs +80 -53
  82. package/hub/team/cli/commands/interrupt.mjs +18 -6
  83. package/hub/team/cli/commands/kill.mjs +16 -5
  84. package/hub/team/cli/commands/list.mjs +31 -24
  85. package/hub/team/cli/commands/send.mjs +19 -6
  86. package/hub/team/cli/commands/start/index.mjs +154 -31
  87. package/hub/team/cli/commands/start/parse-args.mjs +38 -11
  88. package/hub/team/cli/commands/start/start-headless.mjs +112 -36
  89. package/hub/team/cli/commands/start/start-in-process.mjs +50 -40
  90. package/hub/team/cli/commands/start/start-mux.mjs +122 -73
  91. package/hub/team/cli/commands/start/start-wt.mjs +86 -69
  92. package/hub/team/cli/commands/status.mjs +43 -14
  93. package/hub/team/cli/commands/stop.mjs +11 -4
  94. package/hub/team/cli/commands/task.mjs +8 -3
  95. package/hub/team/cli/commands/tasks.mjs +13 -13
  96. package/hub/team/cli/index.mjs +2 -2
  97. package/hub/team/cli/manifest.mjs +38 -8
  98. package/hub/team/cli/render.mjs +52 -30
  99. package/hub/team/cli/services/attach-fallback.mjs +74 -54
  100. package/hub/team/cli/services/hub-client.mjs +42 -14
  101. package/hub/team/cli/services/member-selector.mjs +37 -30
  102. package/hub/team/cli/services/native-control.mjs +143 -116
  103. package/hub/team/cli/services/runtime-mode.mjs +2 -1
  104. package/hub/team/cli/services/state-store.mjs +25 -8
  105. package/hub/team/cli/services/task-model.mjs +40 -30
  106. package/hub/team/conductor-mesh-bridge.mjs +24 -23
  107. package/hub/team/conductor.mjs +8 -4
  108. package/hub/team/dashboard-anchor.mjs +4 -5
  109. package/hub/team/dashboard-layout.mjs +3 -1
  110. package/hub/team/dashboard-open.mjs +41 -21
  111. package/hub/team/dashboard.mjs +76 -28
  112. package/hub/team/event-log.mjs +18 -10
  113. package/hub/team/handoff.mjs +31 -15
  114. package/hub/team/headless.mjs +2 -1
  115. package/hub/team/health-probe.mjs +69 -54
  116. package/hub/team/launcher-template.mjs +16 -13
  117. package/hub/team/native-supervisor.mjs +65 -21
  118. package/hub/team/native.mjs +74 -35
  119. package/hub/team/nativeProxy.mjs +184 -113
  120. package/hub/team/notify.mjs +120 -77
  121. package/hub/team/orchestrator.mjs +166 -161
  122. package/hub/team/pane.mjs +12 -7
  123. package/hub/team/process-cleanup.mjs +25 -16
  124. package/hub/team/psmux.mjs +491 -201
  125. package/hub/team/remote-probe.mjs +68 -52
  126. package/hub/team/remote-session.mjs +117 -59
  127. package/hub/team/remote-watcher.mjs +61 -33
  128. package/hub/team/routing.mjs +51 -25
  129. package/hub/team/runtime-strategy.mjs +3 -1
  130. package/hub/team/session.mjs +675 -611
  131. package/hub/team/shared.mjs +13 -13
  132. package/hub/team/staleState.mjs +72 -30
  133. package/hub/team/swarm-locks.mjs +15 -13
  134. package/hub/team/swarm-planner.mjs +32 -21
  135. package/hub/team/swarm-reconciler.mjs +48 -23
  136. package/hub/team/tui-lite.mjs +266 -68
  137. package/hub/team/tui-remote-adapter.mjs +14 -10
  138. package/hub/team/tui-viewer.mjs +99 -43
  139. package/hub/team/tui.mjs +708 -271
  140. package/hub/team/worktree-lifecycle.mjs +152 -58
  141. package/hub/team/wt-manager.mjs +24 -14
  142. package/hub/token-mode.mjs +71 -71
  143. package/hub/tray.mjs +411 -368
  144. package/hub/workers/claude-worker.mjs +162 -118
  145. package/hub/workers/codex-mcp.mjs +558 -507
  146. package/hub/workers/delegator-mcp.mjs +507 -333
  147. package/hub/workers/factory.mjs +21 -21
  148. package/hub/workers/gemini-worker.mjs +115 -84
  149. package/hub/workers/interface.mjs +6 -1
  150. package/hub/workers/worker-utils.mjs +21 -14
  151. package/hud/colors.mjs +27 -9
  152. package/hud/constants.mjs +162 -26
  153. package/hud/context-monitor.mjs +82 -41
  154. package/hud/hud-qos-status.mjs +129 -49
  155. package/hud/mission-board.mjs +6 -3
  156. package/hud/providers/claude.mjs +226 -115
  157. package/hud/providers/codex.mjs +62 -22
  158. package/hud/providers/gemini.mjs +168 -56
  159. package/hud/renderers.mjs +384 -119
  160. package/hud/terminal.mjs +101 -31
  161. package/hud/utils.mjs +78 -38
  162. package/mesh/index.mjs +11 -5
  163. package/mesh/mesh-budget.mjs +18 -9
  164. package/mesh/mesh-heartbeat.mjs +1 -1
  165. package/mesh/mesh-queue.mjs +3 -5
  166. package/mesh/mesh-router.mjs +5 -4
  167. package/package.json +56 -21
  168. package/scripts/__tests__/gen-skill-docs.test.mjs +36 -7
  169. package/scripts/__tests__/keyword-detector.test.mjs +77 -28
  170. package/scripts/__tests__/mcp-guard-engine.test.mjs +58 -20
  171. package/scripts/__tests__/remote-spawn-transfer.test.mjs +30 -19
  172. package/scripts/__tests__/remote-spawn.test.mjs +10 -4
  173. package/scripts/__tests__/session-start-fast.test.mjs +36 -0
  174. package/scripts/__tests__/skill-template.test.mjs +98 -50
  175. package/scripts/__tests__/smoke.test.mjs +1 -1
  176. package/scripts/__tests__/spawn-trace.test.mjs +102 -0
  177. package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +48 -0
  178. package/scripts/cache-doctor.mjs +11 -4
  179. package/scripts/cache-warmup.mjs +96 -37
  180. package/scripts/claudemd-sync.mjs +27 -17
  181. package/scripts/codex-gateway-preflight.mjs +52 -37
  182. package/scripts/codex-mcp-gateway-sync.mjs +59 -39
  183. package/scripts/config-audit.mjs +232 -0
  184. package/scripts/convert-to-tmpl.mjs +54 -0
  185. package/scripts/cross-review-gate.mjs +35 -12
  186. package/scripts/cross-review-tracker.mjs +21 -8
  187. package/scripts/demo.mjs +35 -17
  188. package/scripts/doctor-diagnose.mjs +284 -0
  189. package/scripts/gen-skill-docs.mjs +7 -2
  190. package/scripts/gen-skill-manifest.mjs +2 -1
  191. package/scripts/headless-guard.mjs +86 -48
  192. package/scripts/hub-ensure.mjs +139 -120
  193. package/scripts/keyword-detector.mjs +293 -272
  194. package/scripts/keyword-rules-expander.mjs +538 -521
  195. package/scripts/lib/claudemd-scanner.mjs +6 -1
  196. package/scripts/lib/context.mjs +3 -3
  197. package/scripts/lib/cross-review-utils.mjs +6 -3
  198. package/scripts/lib/env-probe.mjs +47 -28
  199. package/scripts/lib/gemini-profiles.mjs +44 -10
  200. package/scripts/lib/handoff.mjs +33 -17
  201. package/scripts/lib/hook-utils.mjs +8 -6
  202. package/scripts/lib/keyword-rules.mjs +43 -19
  203. package/scripts/lib/logger.mjs +24 -24
  204. package/scripts/lib/mcp-filter.mjs +377 -239
  205. package/scripts/lib/mcp-guard-engine.mjs +194 -79
  206. package/scripts/lib/mcp-manifest.mjs +23 -13
  207. package/scripts/lib/mcp-server-catalog.mjs +355 -118
  208. package/scripts/lib/psmux-info.mjs +11 -6
  209. package/scripts/lib/remote-spawn-transfer.mjs +44 -14
  210. package/scripts/lib/skill-template.mjs +30 -7
  211. package/scripts/mcp-check.mjs +58 -39
  212. package/scripts/mcp-gateway-config.mjs +83 -39
  213. package/scripts/mcp-gateway-ensure.mjs +43 -35
  214. package/scripts/mcp-gateway-integration-test.mjs +70 -58
  215. package/scripts/mcp-gateway-start.mjs +126 -60
  216. package/scripts/mcp-gateway-verify.mjs +24 -22
  217. package/scripts/mcp-safety-guard.mjs +44 -11
  218. package/scripts/notion-read.mjs +669 -554
  219. package/scripts/pack.mjs +94 -89
  220. package/scripts/preflight-cache.mjs +27 -10
  221. package/scripts/preinstall.mjs +42 -13
  222. package/scripts/remote-spawn.mjs +309 -94
  223. package/scripts/run.cjs +8 -5
  224. package/scripts/session-spawn-helper.mjs +130 -39
  225. package/scripts/session-stale-cleanup.mjs +123 -0
  226. package/scripts/setup.mjs +941 -492
  227. package/scripts/test-lock.mjs +20 -7
  228. package/scripts/test-tfx-route-no-claude-native.mjs +61 -57
  229. package/scripts/tfx-batch-stats.mjs +117 -96
  230. package/scripts/tfx-gate-activate.mjs +11 -4
  231. package/scripts/tfx-route-post.mjs +87 -20
  232. package/scripts/tfx-route-worker.mjs +57 -51
  233. package/scripts/tfx-route.sh +41 -124
  234. package/scripts/tmp-cleanup.mjs +21 -7
  235. package/scripts/token-snapshot.mjs +204 -85
  236. package/skills/.omc/state/idle-notif-cooldown.json +1 -1
  237. package/skills/.omc/state/last-tool-error.json +1 -1
  238. package/skills/.omc/state/subagent-tracking.json +1 -1
  239. package/skills/_templates/base.md +1 -6
  240. package/skills/merge-worktree/SKILL.md.tmpl +144 -0
  241. package/skills/shared/telemetry-segment.md +6 -0
  242. package/skills/star-prompt/SKILL.md.tmpl +222 -0
  243. package/skills/tfx-analysis/SKILL.md.tmpl +107 -0
  244. package/skills/tfx-analysis/skill.json +1 -6
  245. package/skills/tfx-auto/SKILL.md +1 -0
  246. package/skills/{tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md → tfx-auto-codex/SKILL.md.tmpl} +33 -4
  247. package/skills/tfx-auto-codex/skill.json +1 -3
  248. package/skills/tfx-autopilot/SKILL.md.tmpl +116 -0
  249. package/skills/tfx-autopilot/skill.json +1 -5
  250. package/skills/tfx-autoresearch/SKILL.md.tmpl +136 -0
  251. package/skills/tfx-autoroute/SKILL.md.tmpl +189 -0
  252. package/skills/tfx-autoroute/skill.json +1 -7
  253. package/skills/tfx-codex/SKILL.md +1 -0
  254. package/skills/tfx-codex/skill.json +1 -3
  255. package/skills/tfx-codex-swarm/SKILL.md.tmpl +16 -0
  256. package/skills/tfx-codex-swarm/evals/evals.json +1 -1
  257. package/skills/tfx-codex-swarm/skill.json +1 -4
  258. package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +54 -12
  259. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +35 -7
  260. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +35 -7
  261. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +25 -5
  262. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +25 -5
  263. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +20 -4
  264. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +16 -4
  265. package/skills/tfx-consensus/SKILL.md.tmpl +146 -0
  266. package/skills/tfx-debate/SKILL.md.tmpl +192 -0
  267. package/skills/tfx-debate/skill.json +1 -7
  268. package/skills/tfx-deep-analysis/SKILL.md.tmpl +228 -0
  269. package/skills/tfx-deep-analysis/skill.json +1 -5
  270. package/skills/tfx-deep-interview/SKILL.md.tmpl +203 -0
  271. package/skills/tfx-deep-plan/SKILL.md.tmpl +282 -0
  272. package/skills/tfx-deep-qa/SKILL.md.tmpl +165 -0
  273. package/skills/tfx-deep-qa/skill.json +1 -6
  274. package/skills/tfx-deep-research/SKILL.md.tmpl +217 -0
  275. package/skills/tfx-deep-review/SKILL.md.tmpl +179 -0
  276. package/skills/tfx-doctor/SKILL.md +21 -0
  277. package/skills/tfx-doctor/SKILL.md.tmpl +172 -0
  278. package/skills/tfx-doctor/skill.json +1 -3
  279. package/skills/tfx-find/SKILL.md +1 -0
  280. package/skills/tfx-forge/SKILL.md.tmpl +187 -0
  281. package/skills/tfx-fullcycle/SKILL.md.tmpl +286 -0
  282. package/skills/tfx-fullcycle/skill.json +1 -6
  283. package/skills/{tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md → tfx-gemini/SKILL.md.tmpl} +16 -7
  284. package/skills/tfx-gemini/skill.json +1 -3
  285. package/skills/tfx-hooks/SKILL.md.tmpl +216 -0
  286. package/skills/tfx-hooks/skill.json +1 -3
  287. package/skills/tfx-hub/SKILL.md.tmpl +212 -0
  288. package/skills/tfx-hub/skill.json +1 -3
  289. package/skills/tfx-index/SKILL.md +1 -0
  290. package/skills/tfx-index/skill.json +1 -6
  291. package/skills/tfx-interview/SKILL.md.tmpl +285 -0
  292. package/skills/tfx-multi/SKILL.md.tmpl +183 -0
  293. package/skills/tfx-multi/skill.json +1 -3
  294. package/skills/tfx-panel/SKILL.md.tmpl +189 -0
  295. package/skills/tfx-panel/skill.json +1 -7
  296. package/skills/tfx-persist/SKILL.md.tmpl +270 -0
  297. package/skills/tfx-persist/skill.json +1 -7
  298. package/skills/tfx-plan/SKILL.md +1 -0
  299. package/skills/tfx-plan/skill.json +1 -6
  300. package/skills/tfx-profile/SKILL.md.tmpl +239 -0
  301. package/skills/tfx-profile/skill.json +1 -3
  302. package/skills/tfx-prune/SKILL.md.tmpl +200 -0
  303. package/skills/tfx-prune/skill.json +1 -7
  304. package/skills/tfx-psmux-rules/SKILL.md.tmpl +326 -0
  305. package/skills/tfx-psmux-rules/skill.json +1 -4
  306. package/skills/tfx-qa/SKILL.md +1 -0
  307. package/skills/tfx-qa/skill.json +1 -6
  308. package/skills/tfx-ralph/SKILL.md.tmpl +28 -0
  309. package/skills/tfx-ralph/skill.json +1 -4
  310. package/skills/tfx-remote-setup/SKILL.md.tmpl +576 -0
  311. package/skills/tfx-remote-setup/skill.json +1 -3
  312. package/skills/tfx-remote-spawn/SKILL.md.tmpl +263 -0
  313. package/skills/tfx-remote-spawn/references/hosts.json +16 -16
  314. package/skills/tfx-remote-spawn/skill.json +1 -4
  315. package/skills/tfx-research/SKILL.md +1 -0
  316. package/skills/tfx-review/SKILL.md +1 -0
  317. package/skills/tfx-review/skill.json +1 -6
  318. package/skills/tfx-setup/SKILL.md.tmpl +504 -0
  319. package/skills/tfx-setup/skill.json +1 -3
  320. package/skills/tfx-swarm/SKILL.md +22 -0
  321. package/skills/tfx-swarm/SKILL.md.tmpl +218 -0
  322. package/tui/codex-profile.mjs +457 -0
  323. package/tui/core.mjs +266 -0
  324. package/tui/doctor.mjs +375 -0
  325. package/tui/gemini-profile.mjs +299 -0
  326. package/tui/monitor-data.mjs +152 -0
  327. package/tui/monitor.mjs +339 -0
  328. package/tui/setup.mjs +533 -0
  329. package/CLAUDE.md +0 -193
  330. package/references/hosts.json +0 -33
  331. package/skills/tfx-workspace/async-tests/run-tests.sh +0 -203
  332. package/skills/tfx-workspace/evals/evals.json +0 -79
  333. package/skills/tfx-workspace/iteration-1/benchmark.json +0 -162
  334. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +0 -11
  335. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +0 -9
  336. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +0 -154
  337. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +0 -5
  338. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +0 -9
  339. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +0 -126
  340. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +0 -5
  341. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +0 -11
  342. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +0 -9
  343. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +0 -119
  344. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +0 -5
  345. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +0 -9
  346. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +0 -115
  347. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +0 -5
  348. package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +0 -10
  349. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +0 -8
  350. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +0 -86
  351. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +0 -5
  352. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +0 -8
  353. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +0 -81
  354. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +0 -5
  355. package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +0 -12
  356. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +0 -10
  357. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +0 -316
  358. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +0 -5
  359. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +0 -10
  360. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +0 -352
  361. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +0 -5
  362. package/skills/tfx-workspace/iteration-1/review.html +0 -1325
  363. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +0 -12
  364. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +0 -10
  365. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +0 -97
  366. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +0 -5
  367. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +0 -10
  368. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +0 -94
  369. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +0 -5
  370. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +0 -12
  371. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +0 -10
  372. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +0 -209
  373. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +0 -5
  374. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +0 -10
  375. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +0 -193
  376. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +0 -5
  377. package/skills/tfx-workspace/iteration-2/benchmark.json +0 -62
  378. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +0 -13
  379. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +0 -11
  380. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +0 -382
  381. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +0 -5
  382. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +0 -11
  383. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +0 -333
  384. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +0 -5
  385. package/skills/tfx-workspace/iteration-2/review.html +0 -1325
  386. package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +0 -217
  387. package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +0 -65
  388. package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +0 -94
  389. package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +0 -133
  390. package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +0 -426
  391. package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +0 -101
@@ -1,31 +1,63 @@
1
1
  import { decomposeTask } from "../../../orchestrator.mjs";
2
- import { hasWindowsTerminal, hasWindowsTerminalSession } from "../../../session.mjs";
3
- import { AMBER, BOLD, DIM, GREEN, RED, RESET, WHITE } from "../../../shared.mjs";
4
- import { getDefaultHubUrl, getHubInfo, startHubDaemon } from "../../services/hub-client.mjs";
2
+ import {
3
+ hasWindowsTerminal,
4
+ hasWindowsTerminalSession,
5
+ } from "../../../session.mjs";
6
+ import {
7
+ AMBER,
8
+ BOLD,
9
+ DIM,
10
+ GREEN,
11
+ RED,
12
+ RESET,
13
+ WHITE,
14
+ } from "../../../shared.mjs";
15
+ import { fail, ok, warn } from "../../render.mjs";
16
+ import {
17
+ getDefaultHubUrl,
18
+ getHubInfo,
19
+ startHubDaemon,
20
+ } from "../../services/hub-client.mjs";
5
21
  import { ensureTmuxOrExit } from "../../services/runtime-mode.mjs";
6
22
  import { saveTeamState } from "../../services/state-store.mjs";
7
- import { fail, ok, warn } from "../../render.mjs";
8
23
  import { parseTeamArgs } from "./parse-args.mjs";
24
+ import { startHeadlessTeam } from "./start-headless.mjs";
9
25
  import { startInProcessTeam } from "./start-in-process.mjs";
10
26
  import { startMuxTeam } from "./start-mux.mjs";
11
- import { startHeadlessTeam } from "./start-headless.mjs";
12
27
  import { startWtTeam } from "./start-wt.mjs";
13
28
 
14
29
  function printStartUsage() {
15
30
  console.log(`\n ${AMBER}${BOLD}⬡ tfx multi${RESET}\n`);
16
31
  console.log(` 사용법: ${WHITE}tfx multi "작업 설명"${RESET}`);
17
- console.log(` ${WHITE}tfx multi --agents codex,gemini --lead claude "작업"${RESET}`);
18
- console.log(` ${WHITE}tfx multi --teammate-mode headless "작업"${RESET} ${DIM}(psmux 헤드리스, 기본)${RESET}`);
19
- console.log(` ${WHITE}tfx multi --dashboard-layout lite "작업"${RESET} ${DIM}(dashboard-lite 기본 뷰)${RESET}`);
20
- console.log(` ${WHITE}tfx multi --dashboard-layout auto "작업"${RESET} ${DIM}(dashboard viewer 레이아웃 자동)${RESET}`);
21
- console.log(` ${WHITE}tfx multi --dashboard-anchor window "작업"${RESET} ${DIM}(dashboard anchor: window|tab, 기본 window)${RESET}`);
22
- console.log(` ${WHITE}tfx multi --teammate-mode wt "작업"${RESET} ${DIM}(Windows Terminal split-pane)${RESET}`);
23
- console.log(` ${WHITE}tfx multi --teammate-mode in-process "작업"${RESET} ${DIM}(mux 불필요)${RESET}\n`);
32
+ console.log(
33
+ ` ${WHITE}tfx multi --agents codex,gemini --lead claude "작업"${RESET}`,
34
+ );
35
+ console.log(
36
+ ` ${WHITE}tfx multi --teammate-mode headless "작업"${RESET} ${DIM}(psmux 헤드리스, 기본)${RESET}`,
37
+ );
38
+ console.log(
39
+ ` ${WHITE}tfx multi --dashboard-layout lite "작업"${RESET} ${DIM}(dashboard-lite 기본 뷰)${RESET}`,
40
+ );
41
+ console.log(
42
+ ` ${WHITE}tfx multi --dashboard-layout auto "작업"${RESET} ${DIM}(dashboard viewer 레이아웃 자동)${RESET}`,
43
+ );
44
+ console.log(
45
+ ` ${WHITE}tfx multi --dashboard-anchor window "작업"${RESET} ${DIM}(dashboard anchor: window|tab, 기본 window)${RESET}`,
46
+ );
47
+ console.log(
48
+ ` ${WHITE}tfx multi --teammate-mode wt "작업"${RESET} ${DIM}(Windows Terminal split-pane)${RESET}`,
49
+ );
50
+ console.log(
51
+ ` ${WHITE}tfx multi --teammate-mode in-process "작업"${RESET} ${DIM}(mux 불필요)${RESET}\n`,
52
+ );
24
53
  }
25
54
 
26
55
  function printWorkerPreview(agents, subtasks) {
27
56
  for (let index = 0; index < subtasks.length; index += 1) {
28
- const preview = subtasks[index].length > 44 ? `${subtasks[index].slice(0, 44)}…` : subtasks[index];
57
+ const preview =
58
+ subtasks[index].length > 44
59
+ ? `${subtasks[index].slice(0, 44)}…`
60
+ : subtasks[index];
29
61
  console.log(` ${DIM}[${agents[index]}-${index + 1}] ${preview}${RESET}`);
30
62
  }
31
63
  console.log("");
@@ -34,16 +66,40 @@ function printWorkerPreview(agents, subtasks) {
34
66
  function renderTmuxInstallHelp() {
35
67
  console.log(`\n ${RED}${BOLD}tmux 미발견${RESET}\n`);
36
68
  console.log(" 현재 선택한 모드는 tmux 기반 팀세션이 필요합니다.\n");
37
- console.log(` 설치:\n WSL2: ${WHITE}wsl sudo apt install tmux${RESET}\n macOS: ${WHITE}brew install tmux${RESET}\n Linux: ${WHITE}apt install tmux${RESET}\n`);
38
- console.log(` Windows에서는 WSL2를 권장합니다:\n 1. ${WHITE}wsl --install${RESET}\n 2. ${WHITE}wsl sudo apt install tmux${RESET}\n 3. ${WHITE}tfx multi "작업"${RESET}\n`);
69
+ console.log(
70
+ ` 설치:\n WSL2: ${WHITE}wsl sudo apt install tmux${RESET}\n macOS: ${WHITE}brew install tmux${RESET}\n Linux: ${WHITE}apt install tmux${RESET}\n`,
71
+ );
72
+ console.log(
73
+ ` Windows에서는 WSL2를 권장합니다:\n 1. ${WHITE}wsl --install${RESET}\n 2. ${WHITE}wsl sudo apt install tmux${RESET}\n 3. ${WHITE}tfx multi "작업"${RESET}\n`,
74
+ );
39
75
  }
40
76
 
41
77
  export { parseTeamArgs };
42
78
 
43
79
  export async function teamStart(args = []) {
44
- const { agents, lead, layout, teammateMode, task: rawTask, assigns, autoAttach, progressive, timeoutSec, verbose, dashboard, dashboardLayout, dashboardSize, dashboardAnchor, mcpProfile, model, cwd } = parseTeamArgs(args);
80
+ const {
81
+ agents,
82
+ lead,
83
+ layout,
84
+ teammateMode,
85
+ task: rawTask,
86
+ assigns,
87
+ autoAttach,
88
+ progressive,
89
+ timeoutSec,
90
+ verbose,
91
+ dashboard,
92
+ dashboardLayout,
93
+ dashboardSize,
94
+ dashboardAnchor,
95
+ mcpProfile,
96
+ model,
97
+ cwd,
98
+ } = parseTeamArgs(args);
45
99
  // --assign 사용 시 task를 자동 생성
46
- const task = rawTask || (assigns.length > 0 ? assigns.map(a => a.prompt).join(" + ") : "");
100
+ const task =
101
+ rawTask ||
102
+ (assigns.length > 0 ? assigns.map((a) => a.prompt).join(" + ") : "");
47
103
  if (!task) return printStartUsage();
48
104
 
49
105
  console.log(`\n ${AMBER}${BOLD}⬡ tfx multi${RESET}\n`);
@@ -57,7 +113,12 @@ export async function teamStart(args = []) {
57
113
  hub = await getHubInfo();
58
114
  if (!hub) {
59
115
  process.stdout.write(" Hub 시작 중...");
60
- try { hub = await startHubDaemon(); } catch (error) { if (error?.code === "HUB_SERVER_MISSING") fail("hub/server.mjs 없음 — hub 모듈이 설치되지 않음"); }
116
+ try {
117
+ hub = await startHubDaemon();
118
+ } catch (error) {
119
+ if (error?.code === "HUB_SERVER_MISSING")
120
+ fail("hub/server.mjs 없음 — hub 모듈이 설치되지 않음");
121
+ }
61
122
  console.log(` ${hub ? `${GREEN}✓${RESET}` : `${RED}✗${RESET}`}`);
62
123
  if (!hub) warn("Hub 시작 실패 — 수동으로 실행: tfx hub start");
63
124
  } else ok(`Hub: ${DIM}${hub.url}${RESET}`);
@@ -69,26 +130,84 @@ export async function teamStart(args = []) {
69
130
  const subtasks = decomposeTask(task, agents.length);
70
131
  const hubUrl = hub?.url || getDefaultHubUrl();
71
132
  let effectiveMode = teammateMode;
72
- if (effectiveMode === "wt" && !hasWindowsTerminal()) { warn("wt.exe 미발견 — in-process 모드로 자동 fallback"); effectiveMode = "in-process"; }
73
- if (effectiveMode === "wt" && !hasWindowsTerminalSession()) { warn("WT_SESSION 미감지(Windows Terminal 외부) — in-process 모드로 자동 fallback"); effectiveMode = "in-process"; }
133
+ if (effectiveMode === "wt" && !hasWindowsTerminal()) {
134
+ warn("wt.exe 미발견 — in-process 모드로 자동 fallback");
135
+ effectiveMode = "in-process";
136
+ }
137
+ if (effectiveMode === "wt" && !hasWindowsTerminalSession()) {
138
+ warn(
139
+ "WT_SESSION 미감지(Windows Terminal 외부) — in-process 모드로 자동 fallback",
140
+ );
141
+ effectiveMode = "in-process";
142
+ }
74
143
 
75
144
  console.log(` 세션: ${WHITE}${sessionId}${RESET}`);
76
145
  console.log(` 모드: ${effectiveMode}`);
77
146
  console.log(` 리드: ${AMBER}${lead}${RESET}`);
78
- console.log(` 워커: ${agents.map((agent) => `${AMBER}${agent}${RESET}`).join(", ")}`);
147
+ console.log(
148
+ ` 워커: ${agents.map((agent) => `${AMBER}${agent}${RESET}`).join(", ")}`,
149
+ );
79
150
  printWorkerPreview(agents, subtasks);
80
151
 
81
152
  if (effectiveMode === "tmux") {
82
- try { ensureTmuxOrExit(); } catch { return renderTmuxInstallHelp(); }
153
+ try {
154
+ ensureTmuxOrExit();
155
+ } catch {
156
+ return renderTmuxInstallHelp();
157
+ }
83
158
  }
84
159
 
85
- const state = effectiveMode === "in-process"
86
- ? await startInProcessTeam({ sessionId, task, lead, agents, subtasks, hubUrl })
87
- : effectiveMode === "headless"
88
- ? await startHeadlessTeam({ sessionId, task, lead, agents, subtasks, layout, assigns, autoAttach, progressive, timeoutSec, verbose, dashboard, dashboardLayout, dashboardSize, dashboardAnchor, mcpProfile, model, cwd })
89
- : effectiveMode === "wt"
90
- ? await startWtTeam({ sessionId, task, lead, agents, subtasks, layout, hubUrl })
91
- : await startMuxTeam({ sessionId, task, lead, agents, subtasks, layout, hubUrl, teammateMode: effectiveMode });
160
+ const state =
161
+ effectiveMode === "in-process"
162
+ ? await startInProcessTeam({
163
+ sessionId,
164
+ task,
165
+ lead,
166
+ agents,
167
+ subtasks,
168
+ hubUrl,
169
+ })
170
+ : effectiveMode === "headless"
171
+ ? await startHeadlessTeam({
172
+ sessionId,
173
+ task,
174
+ lead,
175
+ agents,
176
+ subtasks,
177
+ layout,
178
+ assigns,
179
+ autoAttach,
180
+ progressive,
181
+ timeoutSec,
182
+ verbose,
183
+ dashboard,
184
+ dashboardLayout,
185
+ dashboardSize,
186
+ dashboardAnchor,
187
+ mcpProfile,
188
+ model,
189
+ cwd,
190
+ })
191
+ : effectiveMode === "wt"
192
+ ? await startWtTeam({
193
+ sessionId,
194
+ task,
195
+ lead,
196
+ agents,
197
+ subtasks,
198
+ layout,
199
+ hubUrl,
200
+ })
201
+ : await startMuxTeam({
202
+ sessionId,
203
+ task,
204
+ lead,
205
+ agents,
206
+ subtasks,
207
+ layout,
208
+ hubUrl,
209
+ teammateMode: effectiveMode,
210
+ });
92
211
 
93
212
  if (!state) return fail("in-process supervisor 시작 실패");
94
213
  state.sessionId = sessionId;
@@ -100,7 +219,11 @@ export async function teamStart(args = []) {
100
219
  console.log(` ${DIM}제어: tfx multi send/control/tasks/status${RESET}\n`);
101
220
  } else if (effectiveMode === "wt") {
102
221
  ok("Windows Terminal wt 팀 시작 완료");
103
- console.log(` ${DIM}현재 pane 기준으로 ${state.layout} 분할 생성됨${RESET}`);
104
- console.log(` ${DIM}wt 모드는 자동 프롬프트 주입/Hub direct 제어(send/control)가 제한됩니다.${RESET}\n`);
222
+ console.log(
223
+ ` ${DIM}현재 pane 기준으로 ${state.layout} 분할 생성됨${RESET}`,
224
+ );
225
+ console.log(
226
+ ` ${DIM}wt 모드는 자동 프롬프트 주입/Hub direct 제어(send/control)가 제한됩니다.${RESET}\n`,
227
+ );
105
228
  }
106
229
  }
@@ -1,14 +1,29 @@
1
1
  import { resolve } from "node:path";
2
- import { normalizeLayout, normalizeTeammateMode } from "../../services/runtime-mode.mjs";
3
- import { parseDashboardLayout } from "../../../dashboard-layout.mjs";
4
2
  import { parseDashboardAnchor } from "../../../dashboard-anchor.mjs";
3
+ import { parseDashboardLayout } from "../../../dashboard-layout.mjs";
4
+ import {
5
+ normalizeLayout,
6
+ normalizeTeammateMode,
7
+ } from "../../services/runtime-mode.mjs";
5
8
 
6
9
  // --assign 파싱 시 마지막 콜론 뒤를 role로 인식할 알려진 역할/CLI 이름
7
10
  const KNOWN_ROLES = new Set([
8
- "codex", "gemini", "claude",
9
- "executor", "architect", "planner", "analyst", "critic",
10
- "debugger", "verifier", "code-reviewer", "security-reviewer",
11
- "test-engineer", "designer", "writer", "scientist",
11
+ "codex",
12
+ "gemini",
13
+ "claude",
14
+ "executor",
15
+ "architect",
16
+ "planner",
17
+ "analyst",
18
+ "critic",
19
+ "debugger",
20
+ "verifier",
21
+ "code-reviewer",
22
+ "security-reviewer",
23
+ "test-engineer",
24
+ "designer",
25
+ "writer",
26
+ "scientist",
12
27
  ]);
13
28
 
14
29
  /**
@@ -29,7 +44,10 @@ function parseAssignValue(raw) {
29
44
 
30
45
  const lastColon = rest.lastIndexOf(":");
31
46
  if (lastColon > 0) {
32
- const candidate = rest.slice(lastColon + 1).trim().toLowerCase();
47
+ const candidate = rest
48
+ .slice(lastColon + 1)
49
+ .trim()
50
+ .toLowerCase();
33
51
  if (KNOWN_ROLES.has(candidate)) {
34
52
  return { cli, prompt: rest.slice(0, lastColon).trim(), role: candidate };
35
53
  }
@@ -51,7 +69,7 @@ export function parseTeamArgs(args = []) {
51
69
  let verbose = false;
52
70
  let dashboard = true;
53
71
  let dashboardLayout = "lite";
54
- let dashboardSize = 0.40;
72
+ let dashboardSize = 0.4;
55
73
  let dashboardAnchor = "window";
56
74
  let mcpProfile = "";
57
75
  let model = "";
@@ -60,12 +78,18 @@ export function parseTeamArgs(args = []) {
60
78
  for (let index = 0; index < args.length; index += 1) {
61
79
  const current = args[index];
62
80
  if (current === "--agents" && args[index + 1]) {
63
- agents = args[++index].split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
81
+ agents = args[++index]
82
+ .split(",")
83
+ .map((value) => value.trim().toLowerCase())
84
+ .filter(Boolean);
64
85
  } else if (current === "--lead" && args[index + 1]) {
65
86
  lead = args[++index].trim().toLowerCase();
66
87
  } else if (current === "--layout" && args[index + 1]) {
67
88
  layout = args[++index];
68
- } else if ((current === "--teammate-mode" || current === "--mode") && args[index + 1]) {
89
+ } else if (
90
+ (current === "--teammate-mode" || current === "--mode") &&
91
+ args[index + 1]
92
+ ) {
69
93
  teammateMode = args[++index];
70
94
  } else if (current === "--assign" && args[index + 1]) {
71
95
  const parsed = parseAssignValue(args[++index]);
@@ -83,7 +107,10 @@ export function parseTeamArgs(args = []) {
83
107
  } else if (current === "--dashboard-layout" && args[index + 1]) {
84
108
  dashboardLayout = parseDashboardLayout(args[++index]);
85
109
  } else if (current === "--dashboard-size" && args[index + 1]) {
86
- dashboardSize = Math.min(0.8, Math.max(0.2, parseFloat(args[++index]) || 0.50));
110
+ dashboardSize = Math.min(
111
+ 0.8,
112
+ Math.max(0.2, parseFloat(args[++index]) || 0.5),
113
+ );
87
114
  } else if (current === "--dashboard-anchor" && args[index + 1]) {
88
115
  dashboardAnchor = parseDashboardAnchor(args[++index]);
89
116
  } else if (current === "--no-progressive") {
@@ -1,14 +1,45 @@
1
- import { DIM, GREEN, RESET, AMBER } from "../../../shared.mjs";
2
- import { runHeadlessInteractive, resolveCliType } from "../../../headless.mjs";
3
- import { ok, } from "../../render.mjs";
4
- import { buildTasks } from "../../services/task-model.mjs";
1
+ import { resolveCliType, runHeadlessInteractive } from "../../../headless.mjs";
2
+ import { AMBER, DIM, GREEN, RESET } from "../../../shared.mjs";
3
+ import { ok } from "../../render.mjs";
5
4
  import { clearTeamState } from "../../services/state-store.mjs";
5
+ import { buildTasks } from "../../services/task-model.mjs";
6
6
 
7
- export async function startHeadlessTeam({ sessionId, task, lead, agents, subtasks, layout, assigns, autoAttach, progressive, timeoutSec, verbose, dashboard, dashboardLayout, dashboardSize, dashboardAnchor, mcpProfile, model }) {
7
+ export async function startHeadlessTeam({
8
+ sessionId,
9
+ task,
10
+ lead,
11
+ agents,
12
+ subtasks,
13
+ layout,
14
+ assigns,
15
+ autoAttach,
16
+ progressive,
17
+ timeoutSec,
18
+ verbose,
19
+ dashboard,
20
+ dashboardLayout,
21
+ dashboardSize,
22
+ dashboardAnchor,
23
+ mcpProfile,
24
+ model,
25
+ }) {
8
26
  // --assign이 있으면 그것을 사용, 없으면 agents+subtasks 조합
9
- const assignments = assigns && assigns.length > 0
10
- ? assigns.map((a, i) => ({ cli: resolveCliType(a.cli), prompt: a.prompt, role: a.role || `worker-${i + 1}`, mcp: mcpProfile, model }))
11
- : subtasks.map((subtask, i) => ({ cli: resolveCliType(agents[i] || agents[0]), prompt: subtask, role: `worker-${i + 1}`, mcp: mcpProfile, model }));
27
+ const assignments =
28
+ assigns && assigns.length > 0
29
+ ? assigns.map((a, i) => ({
30
+ cli: resolveCliType(a.cli),
31
+ prompt: a.prompt,
32
+ role: a.role || `worker-${i + 1}`,
33
+ mcp: mcpProfile,
34
+ model,
35
+ }))
36
+ : subtasks.map((subtask, i) => ({
37
+ cli: resolveCliType(agents[i] || agents[0]),
38
+ prompt: subtask,
39
+ role: `worker-${i + 1}`,
40
+ mcp: mcpProfile,
41
+ model,
42
+ }));
12
43
 
13
44
  const _startedAt = Date.now();
14
45
  ok(`headless ${assignments.length}워커 시작`);
@@ -19,25 +50,41 @@ export async function startHeadlessTeam({ sessionId, task, lead, agents, subtask
19
50
  autoAttach: !!autoAttach,
20
51
  dashboard: !!dashboard,
21
52
  dashboardLayout,
22
- dashboardSize: dashboardSize ?? 0.50,
53
+ dashboardSize: dashboardSize ?? 0.5,
23
54
  dashboardAnchor,
24
55
  progressive: progressive !== false,
25
56
  progressIntervalSec: verbose ? 10 : 0,
26
- onProgress: verbose ? function onProgress(event) {
27
- if (event.type === "session_created") {
28
- console.log(` ${DIM}세션: ${event.sessionName}${RESET}`);
29
- } else if (event.type === "worker_added") {
30
- console.log(` ${DIM}[+] ${event.paneTitle}${RESET}`);
31
- } else if (event.type === "dispatched") {
32
- console.log(` ${DIM}[${event.paneName}] ${event.cli} dispatch${RESET}`);
33
- } else if (event.type === "progress") {
34
- const last = (event.snapshot || "").split("\n").filter(l => l.trim()).pop() || "";
35
- if (last) console.log(` ${DIM}[${event.paneName}] ${last.slice(0, 60)}${RESET}`);
36
- } else if (event.type === "completed") {
37
- const icon = event.matched && event.exitCode === 0 ? `${GREEN}✓${RESET}` : `${AMBER}✗${RESET}`;
38
- console.log(` ${icon} [${event.paneName}] ${event.cli} exit=${event.exitCode}${event.sessionDead ? " (dead)" : ""}`);
39
- }
40
- } : undefined,
57
+ onProgress: verbose
58
+ ? function onProgress(event) {
59
+ if (event.type === "session_created") {
60
+ console.log(` ${DIM}세션: ${event.sessionName}${RESET}`);
61
+ } else if (event.type === "worker_added") {
62
+ console.log(` ${DIM}[+] ${event.paneTitle}${RESET}`);
63
+ } else if (event.type === "dispatched") {
64
+ console.log(
65
+ ` ${DIM}[${event.paneName}] ${event.cli} dispatch${RESET}`,
66
+ );
67
+ } else if (event.type === "progress") {
68
+ const last =
69
+ (event.snapshot || "")
70
+ .split("\n")
71
+ .filter((l) => l.trim())
72
+ .pop() || "";
73
+ if (last)
74
+ console.log(
75
+ ` ${DIM}[${event.paneName}] ${last.slice(0, 60)}${RESET}`,
76
+ );
77
+ } else if (event.type === "completed") {
78
+ const icon =
79
+ event.matched && event.exitCode === 0
80
+ ? `${GREEN}✓${RESET}`
81
+ : `${AMBER}✗${RESET}`;
82
+ console.log(
83
+ ` ${icon} [${event.paneName}] ${event.cli} exit=${event.exitCode}${event.sessionDead ? " (dead)" : ""}`,
84
+ );
85
+ }
86
+ }
87
+ : undefined,
41
88
  });
42
89
 
43
90
  // 최소 결과 요약
@@ -45,17 +92,25 @@ export async function startHeadlessTeam({ sessionId, task, lead, agents, subtask
45
92
  const succeeded = results.filter((r) => r.matched && r.exitCode === 0);
46
93
  const failed = results.filter((r) => !r.matched || r.exitCode !== 0);
47
94
 
48
- ok(`헤드리스 완료: ${succeeded.length}성공 / ${failed.length}실패 / ${results.length}전체`);
95
+ ok(
96
+ `헤드리스 완료: ${succeeded.length}성공 / ${failed.length}실패 / ${results.length}전체`,
97
+ );
49
98
  // 머신 파싱용 완료 마커 — background task에서 결과 회수 시점 판단에 사용
50
- console.log(`=== HEADLESS_COMPLETE succeeded=${succeeded.length} failed=${failed.length} total=${results.length} ===`);
99
+ console.log(
100
+ `=== HEADLESS_COMPLETE succeeded=${succeeded.length} failed=${failed.length} total=${results.length} ===`,
101
+ );
51
102
 
52
103
  if (failed.length > 0) {
53
- for (const r of failed) console.log(` ${AMBER}✗${RESET} ${r.paneName} (${r.cli}) exit=${r.exitCode}`);
104
+ for (const r of failed)
105
+ console.log(
106
+ ` ${AMBER}✗${RESET} ${r.paneName} (${r.cli}) exit=${r.exitCode}`,
107
+ );
54
108
  }
55
109
 
56
110
  // handoff 요약 (Lead 토큰 절약 포맷)
57
111
  for (const r of results) {
58
- const icon = r.matched && r.exitCode === 0 ? `${GREEN}✓${RESET}` : `${AMBER}✗${RESET}`;
112
+ const icon =
113
+ r.matched && r.exitCode === 0 ? `${GREEN}✓${RESET}` : `${AMBER}✗${RESET}`;
59
114
  if (r.handoffFormatted) {
60
115
  const tag = r.handoffFallback ? `${DIM}(fallback)${RESET}` : "";
61
116
  console.log(` ${icon} ${r.paneName} ${tag}`);
@@ -71,8 +126,11 @@ export async function startHeadlessTeam({ sessionId, task, lead, agents, subtask
71
126
  if (verbose) {
72
127
  for (const r of results) {
73
128
  if (r.output) {
74
- const preview = r.output.length > 200 ? `${r.output.slice(0, 200)}…` : r.output;
75
- console.log(`\n ${DIM}── ${r.paneName} (${r.cli}${r.role ? `, ${r.role}` : ""}) ──${RESET}`);
129
+ const preview =
130
+ r.output.length > 200 ? `${r.output.slice(0, 200)}…` : r.output;
131
+ console.log(
132
+ `\n ${DIM}── ${r.paneName} (${r.cli}${r.role ? `, ${r.role}` : ""}) ──${RESET}`,
133
+ );
76
134
  console.log(` ${preview}`);
77
135
  }
78
136
  }
@@ -80,28 +138,46 @@ export async function startHeadlessTeam({ sessionId, task, lead, agents, subtask
80
138
 
81
139
  // dashboard 모드: tui-viewer가 최종 상태를 렌더링할 시간 확보
82
140
  // WT pane spawn (~1s) + node 기동 (~500ms) + 첫 폴링 (~500ms) + 렌더 여유
83
- if (dashboard) await new Promise(r => setTimeout(r, 5000));
141
+ if (dashboard) await new Promise((r) => setTimeout(r, 5000));
84
142
 
85
143
  // 세션 정리
86
144
  handle.kill();
87
145
 
88
146
  const members = [
89
- { role: "lead", name: "lead", cli: lead, pane: `${handle.sessionName}:0.0` },
90
- ...results.map((r, i) => ({ role: "worker", name: r.paneName, cli: r.cli, pane: r.paneId || "", subtask: assignments[i]?.prompt })),
147
+ {
148
+ role: "lead",
149
+ name: "lead",
150
+ cli: lead,
151
+ pane: `${handle.sessionName}:0.0`,
152
+ },
153
+ ...results.map((r, i) => ({
154
+ role: "worker",
155
+ name: r.paneName,
156
+ cli: r.cli,
157
+ pane: r.paneId || "",
158
+ subtask: assignments[i]?.prompt,
159
+ })),
91
160
  ];
92
161
 
93
162
  return {
94
163
  sessionName: handle.sessionName,
95
164
  task,
96
165
  lead,
97
- agents: assignments.map(a => a.cli),
166
+ agents: assignments.map((a) => a.cli),
98
167
  layout,
99
168
  teammateMode: "headless",
100
169
  startedAt: Date.now(),
101
170
  members,
102
171
  headlessResults: results,
103
- handoffs: results.map((r) => ({ paneName: r.paneName, cli: r.cli, ...r.handoff })),
104
- tasks: buildTasks(assignments.map(a => a.prompt), members.filter((m) => m.role === "worker")),
172
+ handoffs: results.map((r) => ({
173
+ paneName: r.paneName,
174
+ cli: r.cli,
175
+ ...r.handoff,
176
+ })),
177
+ tasks: buildTasks(
178
+ assignments.map((a) => a.prompt),
179
+ members.filter((m) => m.role === "worker"),
180
+ ),
105
181
  postSave() {
106
182
  // headless는 실행 완료 후 즉시 정리 — HUD에 잔존 방지
107
183
  clearTeamState(sessionId);
@@ -1,40 +1,50 @@
1
- import { startNativeSupervisor } from "../../services/native-control.mjs";
2
- import { buildTasks } from "../../services/task-model.mjs";
3
-
4
- export async function startInProcessTeam({ sessionId, task, lead, agents, subtasks, hubUrl }) {
5
- const { runtime, members } = await startNativeSupervisor({
6
- sessionId,
7
- task,
8
- lead,
9
- agents,
10
- subtasks,
11
- hubUrl,
12
- });
13
-
14
- if (!runtime?.controlUrl) return null;
15
-
16
- return {
17
- sessionName: sessionId,
18
- task,
19
- lead,
20
- agents,
21
- layout: "native",
22
- teammateMode: "in-process",
23
- startedAt: Date.now(),
24
- hubUrl,
25
- members: members.map((member, index) => ({
26
- role: member.role,
27
- name: member.name,
28
- cli: member.cli,
29
- agentId: member.agentId,
30
- pane: `native:${index}`,
31
- subtask: member.subtask || null,
32
- })),
33
- panes: {},
34
- tasks: buildTasks(subtasks, members.filter((member) => member.role === "worker")),
35
- native: {
36
- controlUrl: runtime.controlUrl,
37
- supervisorPid: runtime.supervisorPid,
38
- },
39
- };
40
- }
1
+ import { startNativeSupervisor } from "../../services/native-control.mjs";
2
+ import { buildTasks } from "../../services/task-model.mjs";
3
+
4
+ export async function startInProcessTeam({
5
+ sessionId,
6
+ task,
7
+ lead,
8
+ agents,
9
+ subtasks,
10
+ hubUrl,
11
+ }) {
12
+ const { runtime, members } = await startNativeSupervisor({
13
+ sessionId,
14
+ task,
15
+ lead,
16
+ agents,
17
+ subtasks,
18
+ hubUrl,
19
+ });
20
+
21
+ if (!runtime?.controlUrl) return null;
22
+
23
+ return {
24
+ sessionName: sessionId,
25
+ task,
26
+ lead,
27
+ agents,
28
+ layout: "native",
29
+ teammateMode: "in-process",
30
+ startedAt: Date.now(),
31
+ hubUrl,
32
+ members: members.map((member, index) => ({
33
+ role: member.role,
34
+ name: member.name,
35
+ cli: member.cli,
36
+ agentId: member.agentId,
37
+ pane: `native:${index}`,
38
+ subtask: member.subtask || null,
39
+ })),
40
+ panes: {},
41
+ tasks: buildTasks(
42
+ subtasks,
43
+ members.filter((member) => member.role === "worker"),
44
+ ),
45
+ native: {
46
+ controlUrl: runtime.controlUrl,
47
+ supervisorPid: runtime.supervisorPid,
48
+ },
49
+ };
50
+ }