triflux 10.3.4 → 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 (329) hide show
  1. package/LICENSE +21 -21
  2. package/bin/tfx-doctor-tui.mjs +1 -1
  3. package/bin/tfx-doctor.mjs +6 -1
  4. package/bin/tfx-profile.mjs +1 -1
  5. package/bin/tfx-setup-tui.mjs +1 -1
  6. package/bin/tfx-setup.mjs +6 -1
  7. package/bin/triflux.mjs +2396 -1140
  8. package/hooks/agent-route-guard.mjs +12 -8
  9. package/hooks/cross-review-tracker.mjs +21 -8
  10. package/hooks/error-context.mjs +19 -7
  11. package/hooks/hook-adaptive-collector.mjs +18 -16
  12. package/hooks/hook-manager.mjs +93 -32
  13. package/hooks/hook-orchestrator.mjs +108 -24
  14. package/hooks/hook-registry.json +11 -0
  15. package/hooks/keyword-rules.json +6 -10
  16. package/hooks/lib/resolve-root.mjs +1 -1
  17. package/hooks/mcp-config-watcher.mjs +6 -2
  18. package/hooks/pipeline-stop.mjs +3 -6
  19. package/hooks/safety-guard.mjs +99 -28
  20. package/hooks/session-start-fast.mjs +143 -0
  21. package/hooks/subagent-verifier.mjs +5 -4
  22. package/hub/account-broker.mjs +256 -60
  23. package/hub/adaptive-diagnostic.mjs +75 -48
  24. package/hub/adaptive-inject.mjs +95 -57
  25. package/hub/adaptive-memory.mjs +156 -42
  26. package/hub/adaptive.mjs +60 -31
  27. package/hub/assign-callbacks.mjs +67 -30
  28. package/hub/bridge.mjs +0 -1
  29. package/hub/cli-adapter-base.mjs +200 -48
  30. package/hub/codex-adapter.mjs +76 -96
  31. package/hub/codex-compat.mjs +3 -3
  32. package/hub/codex-preflight.mjs +63 -37
  33. package/hub/delegator/contracts.mjs +19 -23
  34. package/hub/delegator/index.mjs +3 -3
  35. package/hub/delegator/service.mjs +88 -64
  36. package/hub/delegator/tool-definitions.mjs +5 -5
  37. package/hub/fullcycle.mjs +33 -17
  38. package/hub/gemini-adapter.mjs +69 -94
  39. package/hub/hitl.mjs +89 -30
  40. package/hub/intent.mjs +161 -38
  41. package/hub/lib/cache-guard.mjs +43 -17
  42. package/hub/lib/mcp-response-cache.mjs +66 -32
  43. package/hub/lib/memory-store.mjs +285 -111
  44. package/hub/lib/path-utils.mjs +35 -37
  45. package/hub/lib/process-utils.mjs +106 -37
  46. package/hub/lib/spawn-trace.mjs +527 -0
  47. package/hub/lib/ssh-command.mjs +34 -4
  48. package/hub/lib/ssh-retry.mjs +5 -1
  49. package/hub/lib/uuidv7.mjs +4 -3
  50. package/hub/memory-doctor.mjs +266 -106
  51. package/hub/middleware/request-logger.mjs +61 -34
  52. package/hub/paths.mjs +9 -9
  53. package/hub/pipeline/gates/confidence.mjs +34 -15
  54. package/hub/pipeline/gates/consensus.mjs +27 -15
  55. package/hub/pipeline/gates/index.mjs +7 -3
  56. package/hub/pipeline/gates/selfcheck.mjs +57 -19
  57. package/hub/pipeline/index.mjs +77 -42
  58. package/hub/pipeline/state.mjs +10 -10
  59. package/hub/pipeline/transitions.mjs +40 -23
  60. package/hub/platform.mjs +57 -48
  61. package/hub/promote-penalties.mjs +25 -7
  62. package/hub/quality/deslop.mjs +70 -49
  63. package/hub/research.mjs +32 -25
  64. package/hub/router.mjs +240 -107
  65. package/hub/routing/complexity.mjs +132 -29
  66. package/hub/routing/index.mjs +17 -12
  67. package/hub/routing/q-learning.mjs +76 -28
  68. package/hub/server.mjs +4 -4
  69. package/hub/session-fingerprint.mjs +126 -60
  70. package/hub/state.mjs +84 -43
  71. package/hub/store-adapter.mjs +59 -26
  72. package/hub/store.mjs +356 -153
  73. package/hub/team/agent-map.json +22 -7
  74. package/hub/team/ansi.mjs +186 -122
  75. package/hub/team/backend.mjs +28 -10
  76. package/hub/team/cli/commands/attach.mjs +29 -9
  77. package/hub/team/cli/commands/control.mjs +29 -8
  78. package/hub/team/cli/commands/debug.mjs +32 -11
  79. package/hub/team/cli/commands/focus.mjs +38 -11
  80. package/hub/team/cli/commands/interrupt.mjs +18 -6
  81. package/hub/team/cli/commands/kill.mjs +16 -5
  82. package/hub/team/cli/commands/list.mjs +11 -4
  83. package/hub/team/cli/commands/send.mjs +19 -6
  84. package/hub/team/cli/commands/start/index.mjs +154 -31
  85. package/hub/team/cli/commands/start/parse-args.mjs +38 -11
  86. package/hub/team/cli/commands/start/start-headless.mjs +112 -36
  87. package/hub/team/cli/commands/start/start-in-process.mjs +12 -2
  88. package/hub/team/cli/commands/start/start-mux.mjs +70 -21
  89. package/hub/team/cli/commands/start/start-wt.mjs +29 -12
  90. package/hub/team/cli/commands/status.mjs +43 -14
  91. package/hub/team/cli/commands/stop.mjs +11 -4
  92. package/hub/team/cli/commands/task.mjs +8 -3
  93. package/hub/team/cli/commands/tasks.mjs +1 -1
  94. package/hub/team/cli/index.mjs +2 -2
  95. package/hub/team/cli/manifest.mjs +38 -8
  96. package/hub/team/cli/render.mjs +30 -8
  97. package/hub/team/cli/services/attach-fallback.mjs +31 -11
  98. package/hub/team/cli/services/hub-client.mjs +42 -14
  99. package/hub/team/cli/services/member-selector.mjs +11 -4
  100. package/hub/team/cli/services/native-control.mjs +48 -21
  101. package/hub/team/cli/services/runtime-mode.mjs +2 -1
  102. package/hub/team/cli/services/state-store.mjs +25 -8
  103. package/hub/team/cli/services/task-model.mjs +16 -6
  104. package/hub/team/conductor-mesh-bridge.mjs +24 -23
  105. package/hub/team/conductor.mjs +8 -4
  106. package/hub/team/dashboard-anchor.mjs +4 -5
  107. package/hub/team/dashboard-layout.mjs +3 -1
  108. package/hub/team/dashboard-open.mjs +41 -21
  109. package/hub/team/dashboard.mjs +76 -28
  110. package/hub/team/event-log.mjs +18 -10
  111. package/hub/team/handoff.mjs +31 -15
  112. package/hub/team/headless.mjs +2 -1
  113. package/hub/team/health-probe.mjs +69 -54
  114. package/hub/team/launcher-template.mjs +16 -13
  115. package/hub/team/native-supervisor.mjs +65 -21
  116. package/hub/team/native.mjs +74 -35
  117. package/hub/team/nativeProxy.mjs +184 -113
  118. package/hub/team/notify.mjs +119 -76
  119. package/hub/team/orchestrator.mjs +9 -4
  120. package/hub/team/pane.mjs +12 -7
  121. package/hub/team/process-cleanup.mjs +25 -16
  122. package/hub/team/psmux.mjs +491 -201
  123. package/hub/team/remote-probe.mjs +68 -52
  124. package/hub/team/remote-session.mjs +117 -59
  125. package/hub/team/remote-watcher.mjs +61 -33
  126. package/hub/team/routing.mjs +51 -25
  127. package/hub/team/runtime-strategy.mjs +3 -1
  128. package/hub/team/session.mjs +98 -34
  129. package/hub/team/staleState.mjs +72 -30
  130. package/hub/team/swarm-locks.mjs +15 -13
  131. package/hub/team/swarm-planner.mjs +32 -21
  132. package/hub/team/swarm-reconciler.mjs +48 -23
  133. package/hub/team/tui-lite.mjs +266 -68
  134. package/hub/team/tui-remote-adapter.mjs +14 -10
  135. package/hub/team/tui-viewer.mjs +99 -43
  136. package/hub/team/tui.mjs +708 -271
  137. package/hub/team/worktree-lifecycle.mjs +152 -58
  138. package/hub/team/wt-manager.mjs +24 -14
  139. package/hub/token-mode.mjs +71 -71
  140. package/hub/tray.mjs +66 -23
  141. package/hub/workers/claude-worker.mjs +162 -118
  142. package/hub/workers/codex-mcp.mjs +192 -141
  143. package/hub/workers/delegator-mcp.mjs +507 -333
  144. package/hub/workers/factory.mjs +8 -8
  145. package/hub/workers/gemini-worker.mjs +115 -84
  146. package/hub/workers/interface.mjs +6 -1
  147. package/hub/workers/worker-utils.mjs +21 -14
  148. package/hud/colors.mjs +27 -9
  149. package/hud/constants.mjs +162 -26
  150. package/hud/context-monitor.mjs +82 -41
  151. package/hud/hud-qos-status.mjs +129 -49
  152. package/hud/mission-board.mjs +6 -3
  153. package/hud/providers/claude.mjs +226 -115
  154. package/hud/providers/codex.mjs +62 -22
  155. package/hud/providers/gemini.mjs +168 -56
  156. package/hud/renderers.mjs +384 -119
  157. package/hud/terminal.mjs +101 -31
  158. package/hud/utils.mjs +78 -38
  159. package/mesh/index.mjs +11 -5
  160. package/mesh/mesh-budget.mjs +18 -9
  161. package/mesh/mesh-heartbeat.mjs +1 -1
  162. package/mesh/mesh-queue.mjs +3 -5
  163. package/mesh/mesh-router.mjs +5 -4
  164. package/package.json +2 -1
  165. package/scripts/__tests__/gen-skill-docs.test.mjs +36 -7
  166. package/scripts/__tests__/keyword-detector.test.mjs +77 -28
  167. package/scripts/__tests__/mcp-guard-engine.test.mjs +58 -20
  168. package/scripts/__tests__/remote-spawn-transfer.test.mjs +30 -19
  169. package/scripts/__tests__/remote-spawn.test.mjs +10 -4
  170. package/scripts/__tests__/session-start-fast.test.mjs +36 -0
  171. package/scripts/__tests__/skill-template.test.mjs +98 -50
  172. package/scripts/__tests__/smoke.test.mjs +1 -1
  173. package/scripts/__tests__/spawn-trace.test.mjs +102 -0
  174. package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +48 -0
  175. package/scripts/cache-doctor.mjs +11 -4
  176. package/scripts/cache-warmup.mjs +96 -37
  177. package/scripts/claudemd-sync.mjs +27 -17
  178. package/scripts/codex-gateway-preflight.mjs +52 -37
  179. package/scripts/codex-mcp-gateway-sync.mjs +59 -39
  180. package/scripts/completions/tfx.bash +47 -47
  181. package/scripts/completions/tfx.fish +44 -44
  182. package/scripts/completions/tfx.zsh +83 -83
  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 +45 -26
  193. package/scripts/keyword-detector.mjs +41 -20
  194. package/scripts/keyword-rules-expander.mjs +47 -30
  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 +300 -63
  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 +199 -84
  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 +16 -12
  229. package/scripts/tfx-batch-stats.mjs +32 -11
  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/agent-replay-8f0e10a9-9693-4410-96f5-a6b07e8ed995.jsonl +1 -0
  237. package/skills/.omc/state/idle-notif-cooldown.json +3 -0
  238. package/skills/.omc/state/last-tool-error.json +7 -0
  239. package/skills/.omc/state/subagent-tracking.json +7 -0
  240. package/skills/_templates/base.md +1 -6
  241. package/skills/merge-worktree/SKILL.md.tmpl +144 -0
  242. package/skills/shared/telemetry-segment.md +6 -0
  243. package/skills/star-prompt/SKILL.md.tmpl +222 -0
  244. package/skills/tfx-analysis/SKILL.md.tmpl +107 -0
  245. package/skills/tfx-analysis/skill.json +1 -6
  246. package/skills/tfx-auto/SKILL.md +1 -0
  247. package/skills/tfx-auto-codex/SKILL.md.tmpl +106 -0
  248. package/skills/tfx-auto-codex/skill.json +1 -3
  249. package/skills/tfx-autopilot/SKILL.md.tmpl +116 -0
  250. package/skills/tfx-autopilot/skill.json +1 -5
  251. package/skills/tfx-autoresearch/SKILL.md.tmpl +136 -0
  252. package/skills/tfx-autoroute/SKILL.md.tmpl +189 -0
  253. package/skills/tfx-autoroute/skill.json +1 -7
  254. package/skills/tfx-codex/SKILL.md +1 -0
  255. package/skills/tfx-codex/skill.json +1 -3
  256. package/skills/tfx-codex-swarm/SKILL.md.tmpl +16 -0
  257. package/skills/tfx-codex-swarm/evals/evals.json +1 -1
  258. package/skills/tfx-codex-swarm/skill.json +1 -4
  259. package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +54 -12
  260. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +35 -7
  261. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +35 -7
  262. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +25 -5
  263. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +25 -5
  264. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +20 -4
  265. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +16 -4
  266. package/skills/tfx-consensus/SKILL.md.tmpl +146 -0
  267. package/skills/tfx-debate/SKILL.md.tmpl +192 -0
  268. package/skills/tfx-debate/skill.json +1 -7
  269. package/skills/tfx-deep-analysis/SKILL.md.tmpl +228 -0
  270. package/skills/tfx-deep-analysis/skill.json +1 -5
  271. package/skills/tfx-deep-interview/SKILL.md.tmpl +203 -0
  272. package/skills/tfx-deep-plan/SKILL.md.tmpl +282 -0
  273. package/skills/tfx-deep-qa/SKILL.md.tmpl +165 -0
  274. package/skills/tfx-deep-qa/skill.json +1 -6
  275. package/skills/tfx-deep-research/SKILL.md.tmpl +217 -0
  276. package/skills/tfx-deep-review/SKILL.md.tmpl +179 -0
  277. package/skills/tfx-doctor/SKILL.md +21 -0
  278. package/skills/tfx-doctor/SKILL.md.tmpl +172 -0
  279. package/skills/tfx-doctor/skill.json +1 -3
  280. package/skills/tfx-find/SKILL.md +1 -0
  281. package/skills/tfx-forge/SKILL.md.tmpl +187 -0
  282. package/skills/tfx-fullcycle/SKILL.md.tmpl +286 -0
  283. package/skills/tfx-fullcycle/skill.json +1 -6
  284. package/skills/tfx-gemini/SKILL.md.tmpl +91 -0
  285. package/skills/tfx-gemini/skill.json +1 -3
  286. package/skills/tfx-hooks/SKILL.md.tmpl +216 -0
  287. package/skills/tfx-hooks/skill.json +1 -3
  288. package/skills/tfx-hub/SKILL.md.tmpl +212 -0
  289. package/skills/tfx-hub/skill.json +1 -3
  290. package/skills/tfx-index/SKILL.md +1 -0
  291. package/skills/tfx-index/skill.json +1 -6
  292. package/skills/tfx-interview/SKILL.md.tmpl +285 -0
  293. package/skills/tfx-multi/SKILL.md.tmpl +183 -0
  294. package/skills/tfx-multi/skill.json +1 -3
  295. package/skills/tfx-panel/SKILL.md.tmpl +189 -0
  296. package/skills/tfx-panel/skill.json +1 -7
  297. package/skills/tfx-persist/SKILL.md.tmpl +270 -0
  298. package/skills/tfx-persist/skill.json +1 -7
  299. package/skills/tfx-plan/SKILL.md +1 -0
  300. package/skills/tfx-plan/skill.json +1 -6
  301. package/skills/tfx-profile/SKILL.md.tmpl +239 -0
  302. package/skills/tfx-profile/skill.json +1 -3
  303. package/skills/tfx-prune/SKILL.md.tmpl +200 -0
  304. package/skills/tfx-prune/skill.json +1 -7
  305. package/skills/tfx-psmux-rules/SKILL.md.tmpl +326 -0
  306. package/skills/tfx-psmux-rules/skill.json +1 -4
  307. package/skills/tfx-qa/SKILL.md +1 -0
  308. package/skills/tfx-qa/skill.json +1 -6
  309. package/skills/tfx-ralph/SKILL.md.tmpl +28 -0
  310. package/skills/tfx-ralph/skill.json +1 -4
  311. package/skills/tfx-remote-setup/SKILL.md.tmpl +576 -0
  312. package/skills/tfx-remote-setup/skill.json +1 -3
  313. package/skills/tfx-remote-spawn/SKILL.md.tmpl +263 -0
  314. package/skills/tfx-remote-spawn/references/hosts.json +16 -0
  315. package/skills/tfx-remote-spawn/skill.json +1 -4
  316. package/skills/tfx-research/SKILL.md +1 -0
  317. package/skills/tfx-review/SKILL.md +1 -0
  318. package/skills/tfx-review/skill.json +1 -6
  319. package/skills/tfx-setup/SKILL.md.tmpl +504 -0
  320. package/skills/tfx-setup/skill.json +1 -3
  321. package/skills/tfx-swarm/SKILL.md +22 -0
  322. package/skills/tfx-swarm/SKILL.md.tmpl +218 -0
  323. package/tui/codex-profile.mjs +88 -33
  324. package/tui/core.mjs +45 -15
  325. package/tui/doctor.mjs +75 -28
  326. package/tui/gemini-profile.mjs +74 -29
  327. package/tui/monitor-data.mjs +8 -4
  328. package/tui/monitor.mjs +71 -27
  329. package/tui/setup.mjs +133 -42
@@ -10,42 +10,126 @@ const COMPLEXITY_INDICATORS = {
10
10
  // 높은 복잡도 (0.7-1.0)
11
11
  high: {
12
12
  keywords: [
13
- 'refactor', 'architecture', 'security', 'migration', 'distributed',
14
- 'concurrent', 'parallel', 'optimization', 'performance', 'scalability',
15
- 'cryptograph', 'encryption', 'authentication', 'authorization',
16
- 'database schema', 'data model', 'state machine', 'event-driven',
17
- 'microservice', 'orchestrat', 'pipeline', 'workflow',
13
+ "refactor",
14
+ "architecture",
15
+ "security",
16
+ "migration",
17
+ "distributed",
18
+ "concurrent",
19
+ "parallel",
20
+ "optimization",
21
+ "performance",
22
+ "scalability",
23
+ "cryptograph",
24
+ "encryption",
25
+ "authentication",
26
+ "authorization",
27
+ "database schema",
28
+ "data model",
29
+ "state machine",
30
+ "event-driven",
31
+ "microservice",
32
+ "orchestrat",
33
+ "pipeline",
34
+ "workflow",
18
35
  // 한국어
19
- '리팩터링', '리팩토링', '아키텍처', '보안', '마이그레이션', '분산',
20
- '동시성', '병렬', '최적화', '성능', '확장성',
21
- '암호화', '인증', '인가', '데이터베이스 스키마', '데이터 모델',
22
- '상태 머신', '이벤트 드리븐', '마이크로서비스', '오케스트레이션',
36
+ "리팩터링",
37
+ "리팩토링",
38
+ "아키텍처",
39
+ "보안",
40
+ "마이그레이션",
41
+ "분산",
42
+ "동시성",
43
+ "병렬",
44
+ "최적화",
45
+ "성능",
46
+ "확장성",
47
+ "암호화",
48
+ "인증",
49
+ "인가",
50
+ "데이터베이스 스키마",
51
+ "데이터 모델",
52
+ "상태 머신",
53
+ "이벤트 드리븐",
54
+ "마이크로서비스",
55
+ "오케스트레이션",
23
56
  ],
24
57
  weight: 0.85,
25
58
  },
26
59
  // 중간 복잡도 (0.4-0.7)
27
60
  medium: {
28
61
  keywords: [
29
- 'implement', 'integrate', 'api', 'endpoint', 'middleware',
30
- 'validation', 'error handling', 'testing', 'debug', 'fix bug',
31
- 'configuration', 'deploy', 'ci/cd', 'docker', 'container',
32
- 'cache', 'queue', 'webhook', 'notification', 'logging',
62
+ "implement",
63
+ "integrate",
64
+ "api",
65
+ "endpoint",
66
+ "middleware",
67
+ "validation",
68
+ "error handling",
69
+ "testing",
70
+ "debug",
71
+ "fix bug",
72
+ "configuration",
73
+ "deploy",
74
+ "ci/cd",
75
+ "docker",
76
+ "container",
77
+ "cache",
78
+ "queue",
79
+ "webhook",
80
+ "notification",
81
+ "logging",
33
82
  // 한국어
34
- '구현', '통합', '엔드포인트', '미들웨어', '유효성 검사',
35
- '에러 처리', '오류 처리', '테스트', '디버깅', '버그 수정',
36
- '설정', '배포', '컨테이너', '캐시', '알림', '로깅',
83
+ "구현",
84
+ "통합",
85
+ "엔드포인트",
86
+ "미들웨어",
87
+ "유효성 검사",
88
+ "에러 처리",
89
+ "오류 처리",
90
+ "테스트",
91
+ "디버깅",
92
+ "버그 수정",
93
+ "설정",
94
+ "배포",
95
+ "컨테이너",
96
+ "캐시",
97
+ "알림",
98
+ "로깅",
37
99
  ],
38
100
  weight: 0.55,
39
101
  },
40
102
  // 낮은 복잡도 (0.1-0.4)
41
103
  low: {
42
104
  keywords: [
43
- 'readme', 'comment', 'typo', 'rename', 'format', 'lint',
44
- 'update version', 'bump', 'add dependency', 'install',
45
- 'simple', 'trivial', 'minor', 'small change', 'one-liner',
105
+ "readme",
106
+ "comment",
107
+ "typo",
108
+ "rename",
109
+ "format",
110
+ "lint",
111
+ "update version",
112
+ "bump",
113
+ "add dependency",
114
+ "install",
115
+ "simple",
116
+ "trivial",
117
+ "minor",
118
+ "small change",
119
+ "one-liner",
46
120
  // 한국어
47
- '문서화', '주석', '오타', '이름 변경', '포맷', '버전 업데이트',
48
- '의존성 추가', '설치', '간단', '사소한', '소규모', '한 줄',
121
+ "문서화",
122
+ "주석",
123
+ "오타",
124
+ "이름 변경",
125
+ "포맷",
126
+ "버전 업데이트",
127
+ "의존성 추가",
128
+ "설치",
129
+ "간단",
130
+ "사소한",
131
+ "소규모",
132
+ "한 줄",
49
133
  ],
50
134
  weight: 0.2,
51
135
  },
@@ -98,7 +182,7 @@ function semanticDepth(text) {
98
182
  * @returns {number} 0-1
99
183
  */
100
184
  function taskScope(text) {
101
- const lines = text.split('\n').filter((l) => l.trim().length > 0);
185
+ const lines = text.split("\n").filter((l) => l.trim().length > 0);
102
186
  const sentences = text.split(/[.!?]+/).filter((s) => s.trim().length > 0);
103
187
  const fileRefs = (text.match(/[\w\-/]+\.\w{1,5}/g) || []).length;
104
188
 
@@ -118,9 +202,22 @@ function taskScope(text) {
118
202
  function uncertainty(text) {
119
203
  const lower = text.toLowerCase();
120
204
  const uncertainWords = [
121
- 'maybe', 'perhaps', 'might', 'could', 'possibly', 'unclear',
122
- 'not sure', 'investigate', 'explore', 'research', 'try',
123
- 'consider', 'evaluate', 'assess', 'determine', 'figure out',
205
+ "maybe",
206
+ "perhaps",
207
+ "might",
208
+ "could",
209
+ "possibly",
210
+ "unclear",
211
+ "not sure",
212
+ "investigate",
213
+ "explore",
214
+ "research",
215
+ "try",
216
+ "consider",
217
+ "evaluate",
218
+ "assess",
219
+ "determine",
220
+ "figure out",
124
221
  ];
125
222
  let count = 0;
126
223
  for (const w of uncertainWords) {
@@ -138,11 +235,17 @@ function uncertainty(text) {
138
235
  * @returns {{ score: number, breakdown: { lexical: number, semantic: number, scope: number, uncertainty: number } }}
139
236
  */
140
237
  export function scoreComplexity(taskDescription) {
141
- if (!taskDescription || typeof taskDescription !== 'string') {
142
- return { score: 0, breakdown: { lexical: 0, semantic: 0, scope: 0, uncertainty: 0 } };
238
+ if (!taskDescription || typeof taskDescription !== "string") {
239
+ return {
240
+ score: 0,
241
+ breakdown: { lexical: 0, semantic: 0, scope: 0, uncertainty: 0 },
242
+ };
143
243
  }
144
244
 
145
- const words = taskDescription.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
245
+ const words = taskDescription
246
+ .toLowerCase()
247
+ .split(/\s+/)
248
+ .filter((w) => w.length > 0);
146
249
  const lexical = lexicalComplexity(words);
147
250
  const semantic = semanticDepth(taskDescription);
148
251
  const scope = taskScope(taskDescription);
@@ -150,7 +253,7 @@ export function scoreComplexity(taskDescription) {
150
253
 
151
254
  // 가중 합산: 어휘(20%) + 시맨틱(35%) + 범위(25%) + 불확실성(20%)
152
255
  const score = Math.min(
153
- lexical * 0.20 + semantic * 0.35 + scope * 0.25 + uncertain * 0.20,
256
+ lexical * 0.2 + semantic * 0.35 + scope * 0.25 + uncertain * 0.2,
154
257
  1,
155
258
  );
156
259
 
@@ -2,16 +2,16 @@
2
2
  // Q-Learning 동적 라우팅 + agent-map.json 정적 폴백
3
3
  // 환경변수 TRIFLUX_DYNAMIC_ROUTING=true 로 옵트인 (기본 false)
4
4
 
5
- import { createRequire } from 'node:module';
6
- import { QLearningRouter } from './q-learning.mjs';
7
- import { scoreComplexity } from './complexity.mjs';
5
+ import { createRequire } from "node:module";
6
+ import { scoreComplexity } from "./complexity.mjs";
7
+ import { QLearningRouter } from "./q-learning.mjs";
8
8
 
9
9
  const _require = createRequire(import.meta.url);
10
10
 
11
11
  /** agent-map.json 정적 매핑 */
12
12
  let AGENT_MAP;
13
13
  try {
14
- AGENT_MAP = _require('../team/agent-map.json');
14
+ AGENT_MAP = _require("../team/agent-map.json");
15
15
  } catch {
16
16
  AGENT_MAP = {};
17
17
  }
@@ -37,7 +37,7 @@ function getRouter() {
37
37
  */
38
38
  function isDynamicRoutingEnabled() {
39
39
  const env = process.env.TRIFLUX_DYNAMIC_ROUTING;
40
- return env === 'true' || env === '1';
40
+ return env === "true" || env === "1";
41
41
  }
42
42
 
43
43
  /**
@@ -48,19 +48,19 @@ function isDynamicRoutingEnabled() {
48
48
  * @param {string} [taskDescription=''] — 작업 설명 (동적 라우팅용)
49
49
  * @returns {{ cliType: string, source: 'dynamic' | 'static', confidence: number, complexity: number }}
50
50
  */
51
- export function resolveRoute(agentType, taskDescription = '') {
51
+ export function resolveRoute(agentType, taskDescription = "") {
52
52
  // 정적 기본값
53
53
  const staticCli = AGENT_MAP[agentType] || agentType;
54
54
  const { score: complexity } = scoreComplexity(taskDescription);
55
55
 
56
56
  // 동적 라우팅 비활성화 시 정적 매핑 반환
57
57
  if (!isDynamicRoutingEnabled()) {
58
- return { cliType: staticCli, source: 'static', confidence: 1, complexity };
58
+ return { cliType: staticCli, source: "static", confidence: 1, complexity };
59
59
  }
60
60
 
61
61
  // 작업 설명 없으면 정적 폴백
62
62
  if (!taskDescription || taskDescription.trim().length === 0) {
63
- return { cliType: staticCli, source: 'static', confidence: 1, complexity };
63
+ return { cliType: staticCli, source: "static", confidence: 1, complexity };
64
64
  }
65
65
 
66
66
  const router = getRouter();
@@ -68,12 +68,17 @@ export function resolveRoute(agentType, taskDescription = '') {
68
68
 
69
69
  // 신뢰도 기준 미달 시 정적 폴백
70
70
  if (prediction.confidence < 0.6) {
71
- return { cliType: staticCli, source: 'static', confidence: prediction.confidence, complexity };
71
+ return {
72
+ cliType: staticCli,
73
+ source: "static",
74
+ confidence: prediction.confidence,
75
+ complexity,
76
+ };
72
77
  }
73
78
 
74
79
  return {
75
80
  cliType: prediction.action,
76
- source: 'dynamic',
81
+ source: "dynamic",
77
82
  confidence: prediction.confidence,
78
83
  complexity,
79
84
  };
@@ -113,5 +118,5 @@ export function routerStatus() {
113
118
  }
114
119
 
115
120
  // re-export for convenience
116
- export { scoreComplexity } from './complexity.mjs';
117
- export { QLearningRouter, ACTIONS } from './q-learning.mjs';
121
+ export { scoreComplexity } from "./complexity.mjs";
122
+ export { ACTIONS, QLearningRouter } from "./q-learning.mjs";
@@ -2,44 +2,84 @@
2
2
  // agent-map.json 폴백을 유지하면서, 작업 결과 피드백으로 가중치를 학습한다.
3
3
  // 외부 의존성 없음 (fs, path, crypto만 사용)
4
4
 
5
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
6
- import { join } from 'node:path';
7
- import { createHash } from 'node:crypto';
8
- import { createRequire } from 'node:module';
9
- import { homedir } from 'node:os';
10
- import { scoreComplexity } from './complexity.mjs';
5
+ import { createHash } from "node:crypto";
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+ import { homedir } from "node:os";
9
+ import { join } from "node:path";
10
+ import { scoreComplexity } from "./complexity.mjs";
11
11
 
12
12
  const _require = createRequire(import.meta.url);
13
13
 
14
14
  /** agent-map.json 정적 매핑 (폴백용) */
15
15
  let AGENT_MAP;
16
16
  try {
17
- AGENT_MAP = _require('../team/agent-map.json');
17
+ AGENT_MAP = _require("../team/agent-map.json");
18
18
  } catch {
19
19
  AGENT_MAP = {};
20
20
  }
21
21
 
22
22
  /** 사용 가능한 CLI 액션 */
23
- const ACTIONS = ['codex', 'gemini', 'claude', 'haiku', 'sonnet'];
23
+ const ACTIONS = ["codex", "gemini", "claude", "haiku", "sonnet"];
24
24
 
25
25
  /** 특성 벡터 키워드 (48차원, 에이전트 타입 기반) */
26
26
  const FEATURE_KEYWORDS = [
27
27
  // 실행/구현 (codex 친화)
28
- 'implement', 'execute', 'build', 'fix', 'debug', 'code', 'refactor', 'test',
28
+ "implement",
29
+ "execute",
30
+ "build",
31
+ "fix",
32
+ "debug",
33
+ "code",
34
+ "refactor",
35
+ "test",
29
36
  // 분석/설계 (claude/sonnet 친화)
30
- 'analyze', 'architect', 'plan', 'review', 'security', 'optimize', 'research', 'evaluate',
37
+ "analyze",
38
+ "architect",
39
+ "plan",
40
+ "review",
41
+ "security",
42
+ "optimize",
43
+ "research",
44
+ "evaluate",
31
45
  // 디자인/문서 (gemini 친화)
32
- 'design', 'ui', 'ux', 'frontend', 'visual', 'document', 'write', 'explain',
46
+ "design",
47
+ "ui",
48
+ "ux",
49
+ "frontend",
50
+ "visual",
51
+ "document",
52
+ "write",
53
+ "explain",
33
54
  // 간단/빠른 (haiku 친화)
34
- 'simple', 'quick', 'trivial', 'rename', 'format', 'lint', 'typo', 'minor',
55
+ "simple",
56
+ "quick",
57
+ "trivial",
58
+ "rename",
59
+ "format",
60
+ "lint",
61
+ "typo",
62
+ "minor",
35
63
  // 한국어 — 실행/구현 (codex 친화)
36
- '구현', '빌드', '수정', '디버깅', '리팩터링', '테스트',
64
+ "구현",
65
+ "빌드",
66
+ "수정",
67
+ "디버깅",
68
+ "리팩터링",
69
+ "테스트",
37
70
  // 한국어 — 분석/설계 (claude/sonnet 친화)
38
- '분석', '아키텍처', '설계', '검토', '보안', '최적화',
71
+ "분석",
72
+ "아키텍처",
73
+ "설계",
74
+ "검토",
75
+ "보안",
76
+ "최적화",
39
77
  // 한국어 — 디자인/문서 (gemini 친화)
40
- '디자인', '문서화',
78
+ "디자인",
79
+ "문서화",
41
80
  // 한국어 — 간단/빠른 (haiku 친화)
42
- '간단', '사소한',
81
+ "간단",
82
+ "사소한",
43
83
  ];
44
84
 
45
85
  /**
@@ -66,7 +106,7 @@ function extractFeatures(text) {
66
106
  * @returns {string}
67
107
  */
68
108
  function stateKey(features) {
69
- const hash = createHash('sha256').update(features.join(',')).digest('hex');
109
+ const hash = createHash("sha256").update(features.join(",")).digest("hex");
70
110
  return hash.slice(0, 16);
71
111
  }
72
112
 
@@ -131,9 +171,11 @@ export class QLearningRouter {
131
171
  this._epsilon = opts.epsilon ?? 0.3;
132
172
  this._epsilonDecay = opts.epsilonDecay ?? 0.995;
133
173
  // epsilon=0 시에도 최소 탐색 보장 (pure-exploit 방지)
134
- this._epsilonMin = opts.epsilonMin ?? Math.max(0.01, Math.min(0.05, this._epsilon));
174
+ this._epsilonMin =
175
+ opts.epsilonMin ?? Math.max(0.01, Math.min(0.05, this._epsilon));
135
176
  this._minConfidence = opts.minConfidence ?? 0.6;
136
- this._modelPath = opts.modelPath ?? join(homedir(), '.omc', 'routing-model.json');
177
+ this._modelPath =
178
+ opts.modelPath ?? join(homedir(), ".omc", "routing-model.json");
137
179
 
138
180
  /** @type {Map<string, Map<string, number>>} state -> (action -> Q-value) */
139
181
  this._qTable = new Map();
@@ -200,13 +242,16 @@ export class QLearningRouter {
200
242
  }
201
243
 
202
244
  // 신뢰도 계산: 방문 횟수 기반 (최소 10회 이상이면 안정)
203
- const confidence = visits >= 10
204
- ? Math.min(visits / 50, 1)
205
- : visits / 10;
245
+ const confidence = visits >= 10 ? Math.min(visits / 50, 1) : visits / 10;
206
246
 
207
247
  const { score: complexity } = scoreComplexity(taskDescription);
208
248
 
209
- const result = { action, confidence, exploration: isExploration, complexity };
249
+ const result = {
250
+ action,
251
+ confidence,
252
+ exploration: isExploration,
253
+ complexity,
254
+ };
210
255
  // 탐색(랜덤) 결과는 캐싱하지 않음 — 매번 새로운 랜덤 액션 생성
211
256
  if (!isExploration) this._cache.set(state, result);
212
257
  return result;
@@ -241,7 +286,10 @@ export class QLearningRouter {
241
286
  this._totalUpdates++;
242
287
 
243
288
  // 엡실론 감쇠
244
- this._epsilon = Math.max(this._epsilonMin, this._epsilon * this._epsilonDecay);
289
+ this._epsilon = Math.max(
290
+ this._epsilonMin,
291
+ this._epsilon * this._epsilonDecay,
292
+ );
245
293
 
246
294
  // 캐시 무효화 (해당 상태)
247
295
  this._cache.clear();
@@ -251,7 +299,7 @@ export class QLearningRouter {
251
299
  * Q-table을 JSON 파일로 영속화
252
300
  */
253
301
  save() {
254
- const dir = join(this._modelPath, '..');
302
+ const dir = join(this._modelPath, "..");
255
303
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
256
304
 
257
305
  const data = {
@@ -269,7 +317,7 @@ export class QLearningRouter {
269
317
  data.visitCounts[state] = count;
270
318
  }
271
319
 
272
- writeFileSync(this._modelPath, JSON.stringify(data, null, 2), 'utf8');
320
+ writeFileSync(this._modelPath, JSON.stringify(data, null, 2), "utf8");
273
321
  }
274
322
 
275
323
  /**
@@ -280,7 +328,7 @@ export class QLearningRouter {
280
328
  if (!existsSync(this._modelPath)) return false;
281
329
 
282
330
  try {
283
- const raw = readFileSync(this._modelPath, 'utf8');
331
+ const raw = readFileSync(this._modelPath, "utf8");
284
332
  const data = JSON.parse(raw);
285
333
  if (data.version !== 1) return false;
286
334
 
@@ -333,4 +381,4 @@ export class QLearningRouter {
333
381
  }
334
382
 
335
383
  // 모듈 레벨 export
336
- export { ACTIONS, FEATURE_KEYWORDS, extractFeatures, stateKey, LRUCache };
384
+ export { ACTIONS, extractFeatures, FEATURE_KEYWORDS, LRUCache, stateKey };
package/hub/server.mjs CHANGED
@@ -1534,11 +1534,11 @@ export async function startHub({
1534
1534
  { port, host },
1535
1535
  "hub.port_in_use: port already occupied — check for existing hub or other service",
1536
1536
  );
1537
- reject(
1538
- new Error(
1539
- `Hub 포트 ${port}이(가) 이미 사용 중입니다. 기존 Hub 프로세스를 확인하세요. (PID file: ${PID_FILE})`,
1540
- ),
1537
+ const wrapped = new Error(
1538
+ `Hub 포트 ${port}이(가) 이미 사용 중입니다. 기존 Hub 프로세스를 확인하세요. (PID file: ${PID_FILE})`,
1541
1539
  );
1540
+ wrapped.code = "EADDRINUSE";
1541
+ reject(wrapped);
1542
1542
  } else {
1543
1543
  reject(err);
1544
1544
  }