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,30 +1,52 @@
1
- import { AMBER, BOLD, DIM, GRAY, GREEN, RED, RESET, WHITE, YELLOW } from "../shared.mjs";
2
-
3
- export function ok(msg) { console.log(` ${GREEN}✓${RESET} ${msg}`); }
4
- export function warn(msg) { console.log(` ${YELLOW}⚠${RESET} ${msg}`); }
5
- export function fail(msg) { console.log(` ${RED}✗${RESET} ${msg}`); }
6
-
7
- export function renderTasks(tasks = []) {
8
- if (!tasks.length) {
9
- console.log(`\n ${DIM}태스크 없음${RESET}\n`);
10
- return;
11
- }
12
-
13
- console.log(`\n ${AMBER}${BOLD}⬡ Team Tasks${RESET}\n`);
14
- for (const task of tasks) {
15
- const dep = task.depends_on?.length ? ` ${DIM}(deps: ${task.depends_on.join(",")})${RESET}` : "";
16
- const owner = task.owner ? ` ${GRAY}[${task.owner}]${RESET}` : "";
17
- console.log(` ${WHITE}${task.id}${RESET} ${String(task.status || "").padEnd(11)} ${task.title}${owner}${dep}`);
18
- }
19
- console.log("");
20
- }
21
-
22
- export function formatCompletionSuffix(member) {
23
- if (!member?.completionStatus) return "";
24
- if (member.completionStatus === "abnormal") {
25
- return ` ${RED}[abnormal:${member.completionReason || "unknown"}]${RESET}`;
26
- }
27
- if (member.completionStatus === "normal") return ` ${GREEN}[route-ok]${RESET}`;
28
- if (member.completionStatus === "unchecked") return ` ${GRAY}[route-unchecked]${RESET}`;
29
- return "";
30
- }
1
+ import {
2
+ AMBER,
3
+ BOLD,
4
+ DIM,
5
+ GRAY,
6
+ GREEN,
7
+ RED,
8
+ RESET,
9
+ WHITE,
10
+ YELLOW,
11
+ } from "../shared.mjs";
12
+
13
+ export function ok(msg) {
14
+ console.log(` ${GREEN}✓${RESET} ${msg}`);
15
+ }
16
+ export function warn(msg) {
17
+ console.log(` ${YELLOW}⚠${RESET} ${msg}`);
18
+ }
19
+ export function fail(msg) {
20
+ console.log(` ${RED}✗${RESET} ${msg}`);
21
+ }
22
+
23
+ export function renderTasks(tasks = []) {
24
+ if (!tasks.length) {
25
+ console.log(`\n ${DIM}태스크 없음${RESET}\n`);
26
+ return;
27
+ }
28
+
29
+ console.log(`\n ${AMBER}${BOLD}⬡ Team Tasks${RESET}\n`);
30
+ for (const task of tasks) {
31
+ const dep = task.depends_on?.length
32
+ ? ` ${DIM}(deps: ${task.depends_on.join(",")})${RESET}`
33
+ : "";
34
+ const owner = task.owner ? ` ${GRAY}[${task.owner}]${RESET}` : "";
35
+ console.log(
36
+ ` ${WHITE}${task.id}${RESET} ${String(task.status || "").padEnd(11)} ${task.title}${owner}${dep}`,
37
+ );
38
+ }
39
+ console.log("");
40
+ }
41
+
42
+ export function formatCompletionSuffix(member) {
43
+ if (!member?.completionStatus) return "";
44
+ if (member.completionStatus === "abnormal") {
45
+ return ` ${RED}[abnormal:${member.completionReason || "unknown"}]${RESET}`;
46
+ }
47
+ if (member.completionStatus === "normal")
48
+ return ` ${GREEN}[route-ok]${RESET}`;
49
+ if (member.completionStatus === "unchecked")
50
+ return ` ${GRAY}[route-unchecked]${RESET}`;
51
+ return "";
52
+ }
@@ -1,54 +1,74 @@
1
- import { spawn } from "node:child_process";
2
-
3
- import {
4
- getSessionAttachedCount,
5
- hasWindowsTerminal,
6
- resolveAttachCommand,
7
- } from "../../session.mjs";
8
- import { PKG_ROOT } from "./state-store.mjs";
9
-
10
- export async function launchAttachInWindowsTerminal(sessionName) {
11
- if (!hasWindowsTerminal()) return false;
12
-
13
- let attachSpec;
14
- try {
15
- attachSpec = resolveAttachCommand(sessionName);
16
- } catch {
17
- return false;
18
- }
19
-
20
- const beforeAttached = getSessionAttachedCount(sessionName);
21
- try {
22
- const child = spawn("wt", ["-w", "0", "split-pane", "-V", "-d", PKG_ROOT, attachSpec.command, ...attachSpec.args], {
23
- detached: true,
24
- stdio: "ignore",
25
- windowsHide: false,
26
- });
27
- child.unref();
28
-
29
- if (beforeAttached == null) return true;
30
- const deadline = Date.now() + 3500;
31
- while (Date.now() < deadline) {
32
- await new Promise((resolve) => setTimeout(resolve, 120));
33
- const nowAttached = getSessionAttachedCount(sessionName);
34
- if (typeof nowAttached === "number" && nowAttached > beforeAttached) return true;
35
- }
36
- } catch {}
37
- return false;
38
- }
39
-
40
- export function buildManualAttachCommand(sessionName) {
41
- try {
42
- const spec = resolveAttachCommand(sessionName);
43
- return [spec.command, ...spec.args].map((value) => {
44
- const text = String(value);
45
- return /\s/.test(text) ? `"${text.replace(/"/g, '\\"')}"` : text;
46
- }).join(" ");
47
- } catch {
48
- return `tmux attach-session -t ${sessionName}`;
49
- }
50
- }
51
-
52
- export function wantsWtAttachFallback(args = [], env = process.env) {
53
- return args.includes("--wt") || args.includes("--spawn-wt") || env.TFX_ATTACH_WT_AUTO === "1";
54
- }
1
+ import { spawn } from "node:child_process";
2
+
3
+ import {
4
+ getSessionAttachedCount,
5
+ hasWindowsTerminal,
6
+ resolveAttachCommand,
7
+ } from "../../session.mjs";
8
+ import { PKG_ROOT } from "./state-store.mjs";
9
+
10
+ export async function launchAttachInWindowsTerminal(sessionName) {
11
+ if (!hasWindowsTerminal()) return false;
12
+
13
+ let attachSpec;
14
+ try {
15
+ attachSpec = resolveAttachCommand(sessionName);
16
+ } catch {
17
+ return false;
18
+ }
19
+
20
+ const beforeAttached = getSessionAttachedCount(sessionName);
21
+ try {
22
+ const child = spawn(
23
+ "wt",
24
+ [
25
+ "-w",
26
+ "0",
27
+ "split-pane",
28
+ "-V",
29
+ "-d",
30
+ PKG_ROOT,
31
+ attachSpec.command,
32
+ ...attachSpec.args,
33
+ ],
34
+ {
35
+ detached: true,
36
+ stdio: "ignore",
37
+ windowsHide: false,
38
+ },
39
+ );
40
+ child.unref();
41
+
42
+ if (beforeAttached == null) return true;
43
+ const deadline = Date.now() + 3500;
44
+ while (Date.now() < deadline) {
45
+ await new Promise((resolve) => setTimeout(resolve, 120));
46
+ const nowAttached = getSessionAttachedCount(sessionName);
47
+ if (typeof nowAttached === "number" && nowAttached > beforeAttached)
48
+ return true;
49
+ }
50
+ } catch {}
51
+ return false;
52
+ }
53
+
54
+ export function buildManualAttachCommand(sessionName) {
55
+ try {
56
+ const spec = resolveAttachCommand(sessionName);
57
+ return [spec.command, ...spec.args]
58
+ .map((value) => {
59
+ const text = String(value);
60
+ return /\s/.test(text) ? `"${text.replace(/"/g, '\\"')}"` : text;
61
+ })
62
+ .join(" ");
63
+ } catch {
64
+ return `tmux attach-session -t ${sessionName}`;
65
+ }
66
+ }
67
+
68
+ export function wantsWtAttachFallback(args = [], env = process.env) {
69
+ return (
70
+ args.includes("--wt") ||
71
+ args.includes("--spawn-wt") ||
72
+ env.TFX_ATTACH_WT_AUTO === "1"
73
+ );
74
+ }
@@ -1,10 +1,20 @@
1
- import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
- import { join } from "node:path";
3
1
  import { spawn } from "node:child_process";
2
+ import {
3
+ existsSync,
4
+ mkdirSync,
5
+ readFileSync,
6
+ unlinkSync,
7
+ writeFileSync,
8
+ } from "node:fs";
9
+ import { join } from "node:path";
4
10
 
5
11
  import { publishLeadControl as publishLeadControlBridge } from "../../lead-control.mjs";
6
- import { getTeamStatus as fetchTeamStatus, subscribeToLeadCommands as pullLeadCommands } from "../../session-sync.mjs";
12
+ import {
13
+ getTeamStatus as fetchTeamStatus,
14
+ subscribeToLeadCommands as pullLeadCommands,
15
+ } from "../../session-sync.mjs";
7
16
  import { HUB_PID_DIR, PKG_ROOT } from "./state-store.mjs";
17
+
8
18
  export { nativeGetStatus } from "./native-control.mjs";
9
19
 
10
20
  const HUB_PID_FILE = join(HUB_PID_DIR, "hub.pid");
@@ -67,7 +77,9 @@ export async function getHubInfo() {
67
77
  ...(status ? {} : { degraded: true }),
68
78
  };
69
79
  } catch {
70
- try { unlinkSync(HUB_PID_FILE); } catch {}
80
+ try {
81
+ unlinkSync(HUB_PID_FILE);
82
+ } catch {}
71
83
  }
72
84
  }
73
85
 
@@ -86,7 +98,10 @@ export async function getHubInfo() {
86
98
  if (Number.isFinite(recovered.pid) && recovered.pid > 0) {
87
99
  try {
88
100
  mkdirSync(HUB_PID_DIR, { recursive: true });
89
- writeFileSync(HUB_PID_FILE, JSON.stringify({ ...recovered, started: Date.now() }));
101
+ writeFileSync(
102
+ HUB_PID_FILE,
103
+ JSON.stringify({ ...recovered, started: Date.now() }),
104
+ );
90
105
  } catch {}
91
106
  }
92
107
  return recovered;
@@ -159,7 +174,9 @@ export async function ensureHubAlive(maxRetries = 3) {
159
174
  }
160
175
  }
161
176
 
162
- const error = new Error(`Hub 재시작 ${maxRetries}회 모두 실패${lastError ? `: ${lastError.message}` : ""}`);
177
+ const error = new Error(
178
+ `Hub 재시작 ${maxRetries}회 모두 실패${lastError ? `: ${lastError.message}` : ""}`,
179
+ );
163
180
  error.code = "HUB_RESTART_FAILED";
164
181
  error.cause = lastError;
165
182
  throw error;
@@ -178,16 +195,24 @@ export async function fetchHubTaskList(state) {
178
195
  signal: AbortSignal.timeout(2000),
179
196
  });
180
197
  const data = await res.json();
181
- return data?.ok ? (data.data?.tasks || []) : [];
198
+ return data?.ok ? data.data?.tasks || [] : [];
182
199
  } catch {
183
200
  return [];
184
201
  }
185
202
  }
186
203
 
187
- export async function publishLeadControl(state, targetMember, command, reason = "") {
204
+ export async function publishLeadControl(
205
+ state,
206
+ targetMember,
207
+ command,
208
+ reason = "",
209
+ ) {
188
210
  const hubBase = (state?.hubUrl || getDefaultHubUrl()).replace(/\/mcp$/, "");
189
- const leadAgent = (state?.members || []).find((member) => member.role === "lead")?.agentId || "lead";
190
- const targetAgent = typeof targetMember === "string" ? targetMember : targetMember?.agentId;
211
+ const leadAgent =
212
+ (state?.members || []).find((member) => member.role === "lead")?.agentId ||
213
+ "lead";
214
+ const targetAgent =
215
+ typeof targetMember === "string" ? targetMember : targetMember?.agentId;
191
216
 
192
217
  const result = await publishLeadControlBridge({
193
218
  hubUrl: hubBase,
@@ -206,10 +231,13 @@ export async function publishLeadControl(state, targetMember, command, reason =
206
231
 
207
232
  export async function subscribeToLeadCommands(state, member, options = {}) {
208
233
  const hubBase = (state?.hubUrl || getDefaultHubUrl()).replace(/\/mcp$/, "");
209
- const fallbackAgentId = (state?.members || []).find((candidate) => candidate.role === "lead")?.agentId || null;
210
- const agentId = typeof member === "string"
211
- ? member
212
- : member?.agentId || options?.agentId || fallbackAgentId;
234
+ const fallbackAgentId =
235
+ (state?.members || []).find((candidate) => candidate.role === "lead")
236
+ ?.agentId || null;
237
+ const agentId =
238
+ typeof member === "string"
239
+ ? member
240
+ : member?.agentId || options?.agentId || fallbackAgentId;
213
241
 
214
242
  return await pullLeadCommands({
215
243
  hubUrl: hubBase,
@@ -1,30 +1,37 @@
1
- export function resolveMember(state, selector) {
2
- const members = state?.members || [];
3
- if (!selector) return null;
4
-
5
- const direct = members.find((member) => (
6
- member.name === selector || member.role === selector || member.agentId === selector
7
- ));
8
- if (direct) return direct;
9
-
10
- const workerAlias = /^worker-(\d+)$/i.exec(selector);
11
- if (workerAlias) {
12
- const index = parseInt(workerAlias[1], 10) - 1;
13
- const workers = members.filter((member) => member.role === "worker");
14
- if (index >= 0 && index < workers.length) return workers[index];
15
- }
16
-
17
- const numeric = parseInt(selector, 10);
18
- if (!Number.isNaN(numeric)) {
19
- const byPane = members.find((member) => member.pane?.endsWith(`.${numeric}`) || member.pane?.endsWith(`:${numeric}`));
20
- if (byPane) return byPane;
21
- if (numeric >= 1 && numeric <= members.length) return members[numeric - 1];
22
- }
23
-
24
- return null;
25
- }
26
-
27
- export function toAgentId(cli, target) {
28
- const suffix = String(target).split(/[:.]/).pop();
29
- return `${cli}-${suffix}`;
30
- }
1
+ export function resolveMember(state, selector) {
2
+ const members = state?.members || [];
3
+ if (!selector) return null;
4
+
5
+ const direct = members.find(
6
+ (member) =>
7
+ member.name === selector ||
8
+ member.role === selector ||
9
+ member.agentId === selector,
10
+ );
11
+ if (direct) return direct;
12
+
13
+ const workerAlias = /^worker-(\d+)$/i.exec(selector);
14
+ if (workerAlias) {
15
+ const index = parseInt(workerAlias[1], 10) - 1;
16
+ const workers = members.filter((member) => member.role === "worker");
17
+ if (index >= 0 && index < workers.length) return workers[index];
18
+ }
19
+
20
+ const numeric = parseInt(selector, 10);
21
+ if (!Number.isNaN(numeric)) {
22
+ const byPane = members.find(
23
+ (member) =>
24
+ member.pane?.endsWith(`.${numeric}`) ||
25
+ member.pane?.endsWith(`:${numeric}`),
26
+ );
27
+ if (byPane) return byPane;
28
+ if (numeric >= 1 && numeric <= members.length) return members[numeric - 1];
29
+ }
30
+
31
+ return null;
32
+ }
33
+
34
+ export function toAgentId(cli, target) {
35
+ const suffix = String(target).split(/[:.]/).pop();
36
+ return `${cli}-${suffix}`;
37
+ }
@@ -1,117 +1,144 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { join } from "node:path";
3
- import { spawn } from "node:child_process";
4
-
5
- import { buildLeadPrompt, buildPrompt } from "../../orchestrator.mjs";
6
- import { HUB_PID_DIR, PKG_ROOT } from "./state-store.mjs";
7
-
8
- import { buildExecArgs } from "../../../codex-adapter.mjs";
9
-
10
- export function buildNativeCliCommand(cli) {
11
- switch (cli) {
12
- case "codex":
13
- return buildExecArgs({});
14
- case "gemini":
15
- return "gemini";
16
- case "claude":
17
- return "claude";
18
- default:
19
- return cli;
20
- }
21
- }
22
-
23
- export async function startNativeSupervisor({ sessionId, task, lead, agents, subtasks, hubUrl }) {
24
- const configPath = join(HUB_PID_DIR, `team-native-${sessionId}.config.json`);
25
- const runtimePath = join(HUB_PID_DIR, `team-native-${sessionId}.runtime.json`);
26
- const logsDir = join(HUB_PID_DIR, "team-logs", sessionId);
27
- mkdirSync(logsDir, { recursive: true });
28
-
29
- const leadMember = {
30
- role: "lead",
31
- name: "lead",
32
- cli: lead,
33
- agentId: `${lead}-lead`,
34
- command: buildNativeCliCommand(lead),
35
- };
36
- const workers = agents.map((cli, index) => ({
37
- role: "worker",
38
- name: `${cli}-${index + 1}`,
39
- cli,
40
- agentId: `${cli}-w${index + 1}`,
41
- command: buildNativeCliCommand(cli),
42
- subtask: subtasks[index],
43
- }));
44
- const members = [
45
- {
46
- ...leadMember,
47
- prompt: buildLeadPrompt(task, {
48
- agentId: leadMember.agentId,
49
- hubUrl,
50
- teammateMode: "in-process",
51
- workers: workers.map((worker) => ({
52
- agentId: worker.agentId,
53
- cli: worker.cli,
54
- subtask: worker.subtask,
55
- })),
56
- }),
57
- },
58
- ...workers.map((worker) => ({
59
- ...worker,
60
- prompt: buildPrompt(worker.subtask, { cli: worker.cli, agentId: worker.agentId, hubUrl }),
61
- })),
62
- ];
63
-
64
- writeFileSync(configPath, JSON.stringify({
65
- sessionName: sessionId,
66
- hubUrl,
67
- startupDelayMs: 3000,
68
- logsDir,
69
- runtimeFile: runtimePath,
70
- members,
71
- }, null, 2) + "\n");
72
-
73
- const child = spawn(process.execPath, [join(PKG_ROOT, "hub", "team", "native-supervisor.mjs"), "--config", configPath], {
74
- detached: true,
75
- stdio: "ignore",
76
- env: { ...process.env },
77
- windowsHide: true,
78
- });
79
- child.unref();
80
-
81
- const deadline = Date.now() + 5000;
82
- while (Date.now() < deadline) {
83
- if (existsSync(runtimePath)) {
84
- try {
85
- const runtime = JSON.parse(readFileSync(runtimePath, "utf8"));
86
- return { runtime, members };
87
- } catch {}
88
- }
89
- await new Promise((resolve) => setTimeout(resolve, 100));
90
- }
91
-
92
- return { runtime: null, members };
93
- }
94
-
95
- export async function nativeRequest(state, path, body = {}) {
96
- if (!state?.native?.controlUrl) return null;
97
- try {
98
- const res = await fetch(`${state.native.controlUrl}${path}`, {
99
- method: "POST",
100
- headers: { "Content-Type": "application/json" },
101
- body: JSON.stringify(body),
102
- });
103
- return await res.json();
104
- } catch {
105
- return null;
106
- }
107
- }
108
-
109
- export async function nativeGetStatus(state) {
110
- if (!state?.native?.controlUrl) return null;
111
- try {
112
- const res = await fetch(`${state.native.controlUrl}/status`);
113
- return await res.json();
114
- } catch {
115
- return null;
116
- }
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { buildExecArgs } from "../../../codex-adapter.mjs";
5
+ import { buildLeadPrompt, buildPrompt } from "../../orchestrator.mjs";
6
+ import { HUB_PID_DIR, PKG_ROOT } from "./state-store.mjs";
7
+
8
+ export function buildNativeCliCommand(cli) {
9
+ switch (cli) {
10
+ case "codex":
11
+ return buildExecArgs({});
12
+ case "gemini":
13
+ return "gemini";
14
+ case "claude":
15
+ return "claude";
16
+ default:
17
+ return cli;
18
+ }
19
+ }
20
+
21
+ export async function startNativeSupervisor({
22
+ sessionId,
23
+ task,
24
+ lead,
25
+ agents,
26
+ subtasks,
27
+ hubUrl,
28
+ }) {
29
+ const configPath = join(HUB_PID_DIR, `team-native-${sessionId}.config.json`);
30
+ const runtimePath = join(
31
+ HUB_PID_DIR,
32
+ `team-native-${sessionId}.runtime.json`,
33
+ );
34
+ const logsDir = join(HUB_PID_DIR, "team-logs", sessionId);
35
+ mkdirSync(logsDir, { recursive: true });
36
+
37
+ const leadMember = {
38
+ role: "lead",
39
+ name: "lead",
40
+ cli: lead,
41
+ agentId: `${lead}-lead`,
42
+ command: buildNativeCliCommand(lead),
43
+ };
44
+ const workers = agents.map((cli, index) => ({
45
+ role: "worker",
46
+ name: `${cli}-${index + 1}`,
47
+ cli,
48
+ agentId: `${cli}-w${index + 1}`,
49
+ command: buildNativeCliCommand(cli),
50
+ subtask: subtasks[index],
51
+ }));
52
+ const members = [
53
+ {
54
+ ...leadMember,
55
+ prompt: buildLeadPrompt(task, {
56
+ agentId: leadMember.agentId,
57
+ hubUrl,
58
+ teammateMode: "in-process",
59
+ workers: workers.map((worker) => ({
60
+ agentId: worker.agentId,
61
+ cli: worker.cli,
62
+ subtask: worker.subtask,
63
+ })),
64
+ }),
65
+ },
66
+ ...workers.map((worker) => ({
67
+ ...worker,
68
+ prompt: buildPrompt(worker.subtask, {
69
+ cli: worker.cli,
70
+ agentId: worker.agentId,
71
+ hubUrl,
72
+ }),
73
+ })),
74
+ ];
75
+
76
+ writeFileSync(
77
+ configPath,
78
+ JSON.stringify(
79
+ {
80
+ sessionName: sessionId,
81
+ hubUrl,
82
+ startupDelayMs: 3000,
83
+ logsDir,
84
+ runtimeFile: runtimePath,
85
+ members,
86
+ },
87
+ null,
88
+ 2,
89
+ ) + "\n",
90
+ );
91
+
92
+ const child = spawn(
93
+ process.execPath,
94
+ [
95
+ join(PKG_ROOT, "hub", "team", "native-supervisor.mjs"),
96
+ "--config",
97
+ configPath,
98
+ ],
99
+ {
100
+ detached: true,
101
+ stdio: "ignore",
102
+ env: { ...process.env },
103
+ windowsHide: true,
104
+ },
105
+ );
106
+ child.unref();
107
+
108
+ const deadline = Date.now() + 5000;
109
+ while (Date.now() < deadline) {
110
+ if (existsSync(runtimePath)) {
111
+ try {
112
+ const runtime = JSON.parse(readFileSync(runtimePath, "utf8"));
113
+ return { runtime, members };
114
+ } catch {}
115
+ }
116
+ await new Promise((resolve) => setTimeout(resolve, 100));
117
+ }
118
+
119
+ return { runtime: null, members };
120
+ }
121
+
122
+ export async function nativeRequest(state, path, body = {}) {
123
+ if (!state?.native?.controlUrl) return null;
124
+ try {
125
+ const res = await fetch(`${state.native.controlUrl}${path}`, {
126
+ method: "POST",
127
+ headers: { "Content-Type": "application/json" },
128
+ body: JSON.stringify(body),
129
+ });
130
+ return await res.json();
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+
136
+ export async function nativeGetStatus(state) {
137
+ if (!state?.native?.controlUrl) return null;
138
+ try {
139
+ const res = await fetch(`${state.native.controlUrl}/status`);
140
+ return await res.json();
141
+ } catch {
142
+ return null;
143
+ }
117
144
  }
@@ -22,7 +22,8 @@ export function normalizeTeammateMode(mode = "auto") {
22
22
  export function normalizeLayout(layout = "2x2") {
23
23
  const raw = String(layout).toLowerCase();
24
24
  if (raw === "2x2" || raw === "grid") return "2x2";
25
- if (raw === "1xn" || raw === "1x3" || raw === "vertical" || raw === "columns") return "1xN";
25
+ if (raw === "1xn" || raw === "1x3" || raw === "vertical" || raw === "columns")
26
+ return "1xN";
26
27
  if (raw === "nx1" || raw === "horizontal" || raw === "rows") return "Nx1";
27
28
  return "2x2";
28
29
  }