triflux 10.9.8 → 10.9.10

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 (83) hide show
  1. package/.claude-plugin/marketplace.json +34 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/config/mcp-registry.json +29 -0
  4. package/hooks/keyword-rules.json +104 -38
  5. package/hub/public/dashboard.html +61 -0
  6. package/package.json +56 -21
  7. package/scripts/tfx-route-worker.mjs +6 -0
  8. package/scripts/tfx-route.sh +125 -188
  9. package/scripts/wt-cli.mjs +57 -0
  10. package/skills/tfx-deep-analysis/SKILL.md +1 -7
  11. package/skills/tfx-deep-analysis/SKILL.md.tmpl +0 -1
  12. package/tui/codex-profile.mjs +457 -0
  13. package/tui/core.mjs +266 -0
  14. package/tui/doctor.mjs +375 -0
  15. package/tui/gemini-profile.mjs +299 -0
  16. package/tui/monitor-data.mjs +152 -0
  17. package/tui/monitor.mjs +339 -0
  18. package/tui/setup.mjs +598 -0
  19. package/CLAUDE.md +0 -212
  20. package/references/hosts.json +0 -46
  21. package/skills/tfx-workspace/async-tests/run-tests.sh +0 -203
  22. package/skills/tfx-workspace/evals/evals.json +0 -79
  23. package/skills/tfx-workspace/iteration-1/benchmark.json +0 -524
  24. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +0 -11
  25. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +0 -25
  26. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +0 -154
  27. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +0 -5
  28. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +0 -25
  29. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +0 -126
  30. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +0 -5
  31. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +0 -11
  32. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +0 -25
  33. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +0 -119
  34. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +0 -5
  35. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +0 -25
  36. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +0 -115
  37. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +0 -5
  38. package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +0 -10
  39. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +0 -20
  40. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +0 -86
  41. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +0 -5
  42. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +0 -20
  43. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +0 -81
  44. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +0 -5
  45. package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +0 -12
  46. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +0 -30
  47. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +0 -316
  48. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +0 -5
  49. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +0 -30
  50. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +0 -352
  51. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +0 -5
  52. package/skills/tfx-workspace/iteration-1/review.html +0 -1325
  53. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +0 -12
  54. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +0 -30
  55. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +0 -97
  56. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +0 -5
  57. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +0 -30
  58. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +0 -94
  59. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +0 -5
  60. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +0 -12
  61. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +0 -30
  62. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +0 -209
  63. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +0 -5
  64. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +0 -30
  65. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +0 -193
  66. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +0 -5
  67. package/skills/tfx-workspace/iteration-2/benchmark.json +0 -144
  68. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +0 -13
  69. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +0 -35
  70. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +0 -382
  71. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +0 -5
  72. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +0 -35
  73. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +0 -333
  74. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +0 -5
  75. package/skills/tfx-workspace/iteration-2/review.html +0 -1325
  76. package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +0 -217
  77. package/skills/tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md +0 -77
  78. package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +0 -65
  79. package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +0 -94
  80. package/skills/tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md +0 -82
  81. package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +0 -133
  82. package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +0 -426
  83. package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +0 -101
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "triflux",
4
+ "description": "CLI-first multi-model orchestrator — Codex/Gemini/Claude routing with DAG execution, auto-triage, and cost optimization",
5
+ "owner": {
6
+ "name": "tellang"
7
+ },
8
+ "plugins": [
9
+ {
10
+ "name": "triflux",
11
+ "description": "Tri-CLI orchestrator for Claude Code. Routes tasks across Claude + Codex + Gemini with consensus intelligence, natural language routing, 42 skills, and cross-model review.",
12
+ "version": "10.9.6",
13
+ "author": {
14
+ "name": "tellang"
15
+ },
16
+ "source": {
17
+ "source": "npm",
18
+ "package": "triflux"
19
+ },
20
+ "category": "productivity",
21
+ "homepage": "https://github.com/tellang/triflux",
22
+ "tags": [
23
+ "multi-model",
24
+ "codex",
25
+ "gemini",
26
+ "cli-routing",
27
+ "orchestration",
28
+ "cost-optimization",
29
+ "dag-execution"
30
+ ]
31
+ }
32
+ ],
33
+ "version": "10.9.9"
34
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "triflux",
3
+ "version": "10.3.4",
4
+ "description": "CLI-first multi-model orchestrator for Claude Code — route tasks to Codex, Gemini, and Claude",
5
+ "author": {
6
+ "name": "tellang"
7
+ },
8
+ "repository": "https://github.com/tellang/triflux",
9
+ "homepage": "https://github.com/tellang/triflux",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "claude-code",
13
+ "plugin",
14
+ "codex",
15
+ "gemini",
16
+ "cli-routing",
17
+ "orchestration",
18
+ "multi-model"
19
+ ],
20
+ "skills": "./skills/",
21
+ "hooks": "./hooks/hooks.json"
22
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "mcp-registry-schema",
3
+ "version": 1,
4
+ "description": "MCP 서버 중앙 레지스트리 — 진실의 원천",
5
+ "defaults": {
6
+ "transport": "hub-url",
7
+ "hub_base": "http://127.0.0.1:27888"
8
+ },
9
+ "servers": {
10
+ "tfx-hub": {
11
+ "transport": "hub-url",
12
+ "url": "http://127.0.0.1:27888/mcp",
13
+ "safe": true,
14
+ "targets": ["claude", "gemini", "codex"],
15
+ "description": "triflux Hub MCP 서버"
16
+ }
17
+ },
18
+ "policies": {
19
+ "stdio_action": "replace-with-hub",
20
+ "unknown_server_action": "warn",
21
+ "watched_paths": [
22
+ "~/.gemini/settings.json",
23
+ "~/.codex/config.toml",
24
+ "~/.claude/settings.json",
25
+ "~/.claude/settings.local.json",
26
+ ".mcp.json"
27
+ ]
28
+ }
29
+ }
@@ -11,7 +11,12 @@
11
11
  "skill": null,
12
12
  "action": "suppress_all",
13
13
  "priority": 0,
14
- "supersedes": ["tfx-multi", "tfx-unified", "tfx-codex", "tfx-gemini"],
14
+ "supersedes": [
15
+ "tfx-multi",
16
+ "tfx-unified",
17
+ "tfx-codex",
18
+ "tfx-gemini"
19
+ ],
15
20
  "exclusive": true,
16
21
  "state": null,
17
22
  "mcp_route": null
@@ -57,7 +62,9 @@
57
62
  ],
58
63
  "skill": "tfx-swarm",
59
64
  "priority": 1,
60
- "supersedes": ["tfx-codex"],
65
+ "supersedes": [
66
+ "tfx-codex"
67
+ ],
61
68
  "exclusive": false,
62
69
  "state": null,
63
70
  "mcp_route": null
@@ -65,14 +72,38 @@
65
72
  {
66
73
  "id": "tfx-unified",
67
74
  "patterns": [
68
- { "source": "\\btfx[\\s-]?auto\\b", "flags": "i" },
69
- { "source": "\\btfx[\\s-]?auto[\\s-]?codex\\b", "flags": "i" },
70
- { "source": "(?:만들어|고쳐|구현해|짜줘|수정해|바꿔)", "flags": "i" },
71
- { "source": "(?:리뷰해|검토해|봐줘|괜찮아)", "flags": "i" },
72
- { "source": "(?:테스트|검증|돌려봐|QA)", "flags": "i" },
73
- { "source": "(?:분석해|계획|설계해)", "flags": "i" },
74
- { "source": "(?:찾아봐|조사해|검색해)", "flags": "i" },
75
- { "source": "(?:정리해|슬롭|클린업)", "flags": "i" },
75
+ {
76
+ "source": "\\btfx[\\s-]?auto\\b",
77
+ "flags": "i"
78
+ },
79
+ {
80
+ "source": "\\btfx[\\s-]?auto[\\s-]?codex\\b",
81
+ "flags": "i"
82
+ },
83
+ {
84
+ "source": "(?:만들어|고쳐|구현해|짜줘|수정해|바꿔)",
85
+ "flags": "i"
86
+ },
87
+ {
88
+ "source": "(?:리뷰해|검토해|봐줘|괜찮아)",
89
+ "flags": "i"
90
+ },
91
+ {
92
+ "source": "(?:테스트|검증|돌려봐|QA)",
93
+ "flags": "i"
94
+ },
95
+ {
96
+ "source": "(?:분석해|계획|설계해)",
97
+ "flags": "i"
98
+ },
99
+ {
100
+ "source": "(?:찾아봐|조사해|검색해)",
101
+ "flags": "i"
102
+ },
103
+ {
104
+ "source": "(?:정리해|슬롭|클린업)",
105
+ "flags": "i"
106
+ },
76
107
  {
77
108
  "source": "\\b(?:implement|build|fix|review|test|plan|analyze)\\b",
78
109
  "flags": "i"
@@ -80,7 +111,9 @@
80
111
  ],
81
112
  "skill": "tfx-auto",
82
113
  "priority": 2,
83
- "supersedes": ["tfx-auto-codex"],
114
+ "supersedes": [
115
+ "tfx-auto-codex"
116
+ ],
84
117
  "exclusive": false,
85
118
  "state": null,
86
119
  "mcp_route": null
@@ -193,17 +226,32 @@
193
226
  {
194
227
  "id": "wt-tab-route",
195
228
  "patterns": [
196
- { "source": "(?:새\\s*탭|탭\\s*(?:새로|추가|생성|열|띄|파|만들))", "flags": "i" },
197
- { "source": "(?:패인|화면|pane)\\s*(?:분할|나눠|스플릿|split)", "flags": "i" },
198
- { "source": "\\bwt\\b\\s*(?:에\\s*)?(?:탭|tab|열|띄|새)", "flags": "i" },
199
- { "source": "(?:터미널|terminal)\\s*(?:탭|새\\s*탭)", "flags": "i" },
200
- { "source": "\\b(?:new\\s+tab|split\\s+pane|open\\s+(?:new\\s+)?tab)\\b", "flags": "i" }
229
+ {
230
+ "source": "(?:새\\s*탭|탭\\s*(?:새로|추가|생성|열|띄|파|만들))",
231
+ "flags": "i"
232
+ },
233
+ {
234
+ "source": "(?:패인|화면|pane)\\s*(?:분할|나눠|스플릿|split)",
235
+ "flags": "i"
236
+ },
237
+ {
238
+ "source": "\\bwt\\b\\s*(?:에\\s*)?(?:탭|tab|열|띄|새)",
239
+ "flags": "i"
240
+ },
241
+ {
242
+ "source": "(?:터미널|terminal)\\s*(?:탭|새\\s*탭)",
243
+ "flags": "i"
244
+ },
245
+ {
246
+ "source": "\\b(?:new\\s+tab|split\\s+pane|open\\s+(?:new\\s+)?tab)\\b",
247
+ "flags": "i"
248
+ }
201
249
  ],
202
- "skill": null,
203
- "action": "context_hint",
204
- "hint": "WT 탭/패인 생성 요청입니다. wt.exe 직접 호출은 safety-guard가 차단합니다.\n\nhub/team/wt-manager.mjs의 createWtManager() 팩토리로 인스턴스를 만든 뒤 API를 호출하세요:\n- wt.createTab({ title, command, profile, cwd }) — 새 탭\n- wt.splitPane({ direction: 'H'|'V', title, command }) — 패인 분할\n- wt.applySplitLayout([{ title, command, direction }]) — 다중 배치\n- wt.closeTab(title) — 탭 닫기\n\n사용법:\nnode -e \"import('./hub/team/wt-manager.mjs').then(m => { const wt = m.createWtManager(); wt.createTab({ title: 'MyTab', command: 'pwsh' }); })\"",
250
+ "skill": "tfx-wt",
205
251
  "priority": 1,
206
- "supersedes": ["tfx-unified"],
252
+ "supersedes": [
253
+ "tfx-unified"
254
+ ],
207
255
  "exclusive": false,
208
256
  "state": null,
209
257
  "mcp_route": null
@@ -211,14 +259,20 @@
211
259
  {
212
260
  "id": "wt-tab-rename",
213
261
  "patterns": [
214
- { "source": "(?:탭\\s*(?:이름|제목)\\s*(?:바꿔|변경|rename))", "flags": "i" },
215
- { "source": "(?:rename\\s+tab|tab\\s+rename)", "flags": "i" }
262
+ {
263
+ "source": "(?:탭\\s*(?:이름|제목)\\s*(?:바꿔|변경|rename))",
264
+ "flags": "i"
265
+ },
266
+ {
267
+ "source": "(?:rename\\s+tab|tab\\s+rename)",
268
+ "flags": "i"
269
+ }
216
270
  ],
217
- "skill": null,
218
- "action": "context_hint",
219
- "hint": "WT 탭 이름 변경 요청입니다. wt.exe 직접 호출은 safety-guard가 차단합니다.\n\nhub/team/wt-manager.mjs의 createWtManager() 팩토리로 인스턴스를 만든 뒤 API를 호출하세요:\n- wt.renameTab({ oldTitle, newTitle }) — 탭 이름 변경\n\n사용법:\nnode -e \"import('./hub/team/wt-manager.mjs').then(m => { const wt = m.createWtManager(); wt.renameTab({ oldTitle: 'OldName', newTitle: 'NewName' }); })\"",
271
+ "skill": "tfx-wt",
220
272
  "priority": 1,
221
- "supersedes": ["tfx-unified"],
273
+ "supersedes": [
274
+ "tfx-unified"
275
+ ],
222
276
  "exclusive": false,
223
277
  "state": null,
224
278
  "mcp_route": null
@@ -226,14 +280,20 @@
226
280
  {
227
281
  "id": "wt-tab-list",
228
282
  "patterns": [
229
- { "source": "(?:탭\\s*(?:목록|리스트|열린|현재))", "flags": "i" },
230
- { "source": "(?:list\\s+tabs|tab\\s+list|열린\\s*탭)", "flags": "i" }
283
+ {
284
+ "source": "(?:탭\\s*(?:목록|리스트|열린|현재))",
285
+ "flags": "i"
286
+ },
287
+ {
288
+ "source": "(?:list\\s+tabs|tab\\s+list|열린\\s*탭)",
289
+ "flags": "i"
290
+ }
231
291
  ],
232
- "skill": null,
233
- "action": "context_hint",
234
- "hint": "WT 탭 목록 조회 요청입니다. wt.exe 직접 호출은 safety-guard가 차단합니다.\n\nhub/team/wt-manager.mjs의 createWtManager() 팩토리로 인스턴스를 만든 뒤 API를 호출하세요:\n- wt.listTabs() — 현재 열린 탭 목록 (pid 파일 기반)\n\n사용법:\nnode -e \"import('./hub/team/wt-manager.mjs').then(m => { const wt = m.createWtManager(); console.log(wt.listTabs()); })\"",
292
+ "skill": "tfx-wt",
235
293
  "priority": 1,
236
- "supersedes": ["tfx-unified"],
294
+ "supersedes": [
295
+ "tfx-unified"
296
+ ],
237
297
  "exclusive": false,
238
298
  "state": null,
239
299
  "mcp_route": null
@@ -241,14 +301,20 @@
241
301
  {
242
302
  "id": "wt-tab-close",
243
303
  "patterns": [
244
- { "source": "(?:탭\\s*(?:닫아|닫기|종료|정리|close))", "flags": "i" },
245
- { "source": "(?:close\\s+tab|tab\\s+close|탭\\s*정리)", "flags": "i" }
304
+ {
305
+ "source": "(?:탭\\s*(?:닫아|닫기|종료|정리|close))",
306
+ "flags": "i"
307
+ },
308
+ {
309
+ "source": "(?:close\\s+tab|tab\\s+close|탭\\s*정리)",
310
+ "flags": "i"
311
+ }
246
312
  ],
247
- "skill": null,
248
- "action": "context_hint",
249
- "hint": "WT 탭 닫기 요청입니다. wt.exe 직접 호출은 safety-guard가 차단합니다.\n\nhub/team/wt-manager.mjs의 createWtManager() 팩토리로 인스턴스를 만든 뒤 API를 호출하세요:\n- wt.closeTab(title) — 제목으로 탭 닫기\n- wt.closeStale({ olderThanMs, titlePattern }) — 오래된/패턴 매칭 탭 정리\n\n사용법:\nnode -e \"import('./hub/team/wt-manager.mjs').then(m => { const wt = m.createWtManager(); wt.closeTab('MyTab'); })\"",
313
+ "skill": "tfx-wt",
250
314
  "priority": 1,
251
- "supersedes": ["tfx-unified"],
315
+ "supersedes": [
316
+ "tfx-unified"
317
+ ],
252
318
  "exclusive": false,
253
319
  "state": null,
254
320
  "mcp_route": null
@@ -47,6 +47,17 @@ body{background:#0d1117;color:#c9d1d9;font-family:system-ui,-apple-system,sans-s
47
47
  .legend-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:4px;vertical-align:middle}
48
48
 
49
49
  .placeholder{text-align:center;padding:24px;color:#8b949e;font-size:.85rem}
50
+ .btn{background:#21262d;border:1px solid #30363d;color:#c9d1d9;padding:4px 12px;border-radius:6px;font-size:.78rem;cursor:pointer;transition:background .2s}
51
+ .btn:hover{background:#30363d}
52
+ .btn:active{background:#3b414a}
53
+ .btn.ok{border-color:#3fb950;color:#3fb950}
54
+ .guide{display:none;max-width:1200px;margin:0 auto 16px;background:#161b22;border:1px solid #30363d;border-radius:8px;padding:16px;font-size:.82rem;line-height:1.7;color:#8b949e}
55
+ .guide.open{display:block}
56
+ .guide h3{color:#c9d1d9;font-size:.9rem;margin:12px 0 6px}
57
+ .guide h3:first-child{margin-top:0}
58
+ .guide code{background:#0d1117;padding:1px 5px;border-radius:3px;font-size:.78rem;color:#d19a66}
59
+ .guide ul{padding-left:18px;margin:4px 0}
60
+ .actions{display:flex;gap:8px;align-items:center}
50
61
  </style>
51
62
  </head>
52
63
  <body>
@@ -57,9 +68,35 @@ body{background:#0d1117;color:#c9d1d9;font-family:system-ui,-apple-system,sans-s
57
68
  <span class="status-dot" id="statusDot"></span>
58
69
  <span id="statusText">연결 중...</span>
59
70
  <span id="lastUpdate" class="sub"></span>
71
+ <div class="actions">
72
+ <button class="btn" id="guideBtn" title="도움말">?</button>
73
+ <button class="btn" id="reloadBtn" title="계정 브로커 리로드">Reload</button>
74
+ <a href="/broker/dashboard" target="_blank" class="btn" style="text-decoration:none">Broker</a>
75
+ </div>
60
76
  </div>
61
77
  </div>
62
78
 
79
+ <div class="guide" id="guidePanel">
80
+ <h3>AIMD 동시 워커</h3>
81
+ <p>AIMD(Additive Increase / Multiplicative Decrease) 알고리즘으로 최적 동시 워커 수를 자동 조절합니다. 게이지가 <code>10/10</code>에 가까우면 시스템이 포화 상태입니다.</p>
82
+ <h3>CLI 쿼터 사용률</h3>
83
+ <ul>
84
+ <li><strong>Claude</strong> — 5시간/주간 사용량. 80% 이상이면 빨간색 경고.</li>
85
+ <li><strong>Codex</strong> — Primary/Secondary 버킷별 사용률. 리셋 시간이 표시됩니다.</li>
86
+ <li><strong>Gemini</strong> — 남은 비율 기반 사용률. RPM/RPD 제한 포함.</li>
87
+ </ul>
88
+ <h3>호출 이력 타임라인</h3>
89
+ <p>최근 CLI 호출의 성공/실패/타임아웃을 시간순으로 표시합니다. <span style="color:#3fb950">녹색</span>=성공, <span style="color:#f85149">빨강</span>=실패, <span style="color:#d29922">노랑</span>=타임아웃.</p>
90
+ <h3>토큰 누적 현황</h3>
91
+ <p>CLI별 누적 토큰 사용량과 호출 횟수입니다. 세션 시작 이후의 합계입니다.</p>
92
+ <h3>조작</h3>
93
+ <ul>
94
+ <li><strong>Reload</strong> — <code>POST /broker/reload</code> 호출. accounts.json을 핫리로드합니다.</li>
95
+ <li><strong>Broker</strong> — 계정 브로커 대시보드(별도 페이지)를 엽니다.</li>
96
+ <li>데이터는 <strong>5초</strong>마다 자동 갱신됩니다.</li>
97
+ </ul>
98
+ </div>
99
+
63
100
  <div class="grid">
64
101
  <!-- AIMD 게이지 -->
65
102
  <div class="card">
@@ -347,6 +384,30 @@ body{background:#0d1117;color:#c9d1d9;font-family:system-ui,-apple-system,sans-s
347
384
  rTimer = setTimeout(function() { drawEvents(cachedEvents); }, 150);
348
385
  });
349
386
 
387
+ /* ── 가이드 토글 ── */
388
+ document.getElementById('guideBtn').onclick = function() {
389
+ var p = document.getElementById('guidePanel');
390
+ p.classList.toggle('open');
391
+ this.classList.toggle('ok');
392
+ };
393
+
394
+ /* ── 브로커 리로드 ── */
395
+ document.getElementById('reloadBtn').onclick = function() {
396
+ var btn = this;
397
+ btn.textContent = '...';
398
+ fetch('/broker/reload', { method: 'POST' })
399
+ .then(function(r) { return r.json(); })
400
+ .then(function(d) {
401
+ btn.textContent = d.ok ? 'OK (' + (d.accounts || 0) + ')' : 'Fail';
402
+ btn.classList.toggle('ok', d.ok);
403
+ setTimeout(function() { btn.textContent = 'Reload'; btn.classList.remove('ok'); }, 3000);
404
+ })
405
+ .catch(function() {
406
+ btn.textContent = 'Error';
407
+ setTimeout(function() { btn.textContent = 'Reload'; }, 3000);
408
+ });
409
+ };
410
+
350
411
  poll();
351
412
  setInterval(poll, POLL);
352
413
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "triflux",
3
- "version": "10.9.8",
3
+ "version": "10.9.10",
4
4
  "description": "CLI-first multi-model orchestrator for Claude Code — route tasks to Codex, Gemini, and Claude",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,26 +13,69 @@
13
13
  "tfx-doctor-tui": "bin/tfx-doctor-tui.mjs",
14
14
  "tfx-setup-tui": "bin/tfx-setup-tui.mjs"
15
15
  },
16
- "engines": {
17
- "node": ">=18.0.0"
18
- },
19
- "dependencies": {
20
- "@triflux/core": "10.0.1",
21
- "@triflux/remote": "^10.0.0-alpha.1"
22
- },
23
16
  "files": [
24
17
  "bin",
18
+ "tui",
19
+ "hub",
20
+ "config",
25
21
  "skills",
22
+ "!skills/tfx-workspace",
23
+ "!**/failure-reports",
24
+ "scripts",
26
25
  "hooks",
27
26
  "hud",
28
- "scripts",
29
- "hub",
30
27
  "mesh",
31
- "references",
32
- "CLAUDE.md",
28
+ ".claude-plugin",
33
29
  "README.md",
30
+ "README.ko.md",
34
31
  "LICENSE"
35
32
  ],
33
+ "workspaces": [
34
+ "packages/core",
35
+ "packages/remote",
36
+ "packages/triflux"
37
+ ],
38
+ "scripts": {
39
+ "pack": "node scripts/pack.mjs all",
40
+ "pack:core": "node scripts/pack.mjs core",
41
+ "pack:remote": "node scripts/pack.mjs remote",
42
+ "setup": "node scripts/setup.mjs",
43
+ "preinstall": "node scripts/preinstall.mjs",
44
+ "postinstall": "node scripts/setup.mjs",
45
+ "lint": "biome check .",
46
+ "lint:fix": "biome check --fix .",
47
+ "health": "npm test && npm run lint",
48
+ "test": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 \"tests/**/*.test.mjs\" \"scripts/__tests__/**/*.test.mjs\"",
49
+ "test:unit": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/unit/**/*.test.mjs",
50
+ "test:integration": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/integration/**/*.test.mjs",
51
+ "test:route-smoke": "node scripts/test-lock.mjs --test scripts/test-tfx-route-no-claude-native.mjs",
52
+ "test:contract": "node scripts/test-lock.mjs --test --test-force-exit --test-concurrency=8 tests/contract/**/*.test.mjs",
53
+ "test:coverage": "node --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=60 --test --test-force-exit --test-concurrency=8 \"tests/**/*.test.mjs\"",
54
+ "gen:skill-docs": "node scripts/gen-skill-docs.mjs",
55
+ "gen:skill-manifest": "node scripts/gen-skill-manifest.mjs"
56
+ },
57
+ "engines": {
58
+ "node": ">=18.0.0"
59
+ },
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+https://github.com/tellang/triflux.git"
63
+ },
64
+ "homepage": "https://github.com/tellang/triflux#readme",
65
+ "author": "tellang",
66
+ "license": "MIT",
67
+ "dependencies": {
68
+ "@modelcontextprotocol/sdk": "^1.27.1",
69
+ "better-sqlite3": "^12.6.2",
70
+ "pino": "^10.3.1",
71
+ "pino-pretty": "^13.1.3",
72
+ "systray2": "^2.1.4",
73
+ "zod": "^4.0.0"
74
+ },
75
+ "devDependencies": {
76
+ "@biomejs/biome": "^2.0.0",
77
+ "knip": "^6.3.0"
78
+ },
36
79
  "keywords": [
37
80
  "claude-code",
38
81
  "plugin",
@@ -43,13 +86,5 @@
43
86
  "multi-model",
44
87
  "triflux",
45
88
  "tfx"
46
- ],
47
- "author": "tellang",
48
- "license": "MIT",
49
- "homepage": "https://github.com/tellang/triflux#readme",
50
- "repository": {
51
- "type": "git",
52
- "url": "git+https://github.com/tellang/triflux.git",
53
- "directory": "packages/triflux"
54
- }
89
+ ]
55
90
  }
@@ -51,6 +51,7 @@ if (!createWorker) {
51
51
  function parseArgs(argv) {
52
52
  const args = {
53
53
  allowedMcpServerNames: [],
54
+ extraArgs: [],
54
55
  mcpConfig: [],
55
56
  };
56
57
 
@@ -94,6 +95,10 @@ function parseArgs(argv) {
94
95
  args.allowedMcpServerNames.push(next);
95
96
  index += 1;
96
97
  break;
98
+ case "--extra-arg":
99
+ args.extraArgs.push(next);
100
+ index += 1;
101
+ break;
97
102
  case "--mcp-config":
98
103
  args.mcpConfig.push(next);
99
104
  index += 1;
@@ -202,6 +207,7 @@ const worker = createWorker(args.type, {
202
207
  permissionMode: args.permissionMode,
203
208
  allowDangerouslySkipPermissions: args.allowDangerouslySkipPermissions,
204
209
  allowedMcpServerNames: args.allowedMcpServerNames,
210
+ extraArgs: args.extraArgs,
205
211
  mcpConfig:
206
212
  args.type === "claude" && args.mcpConfig.length === 0
207
213
  ? resolveDefaultMcpConfig(args.cwd || process.cwd())