triflux 3.2.0-dev.3 → 3.2.0-dev.6

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.
@@ -0,0 +1,338 @@
1
+ {
2
+ "rules": [
3
+ {
4
+ "id": "tfx-cancel",
5
+ "patterns": [
6
+ {
7
+ "source": "\\b(canceltfx|stoptfx)\\b",
8
+ "flags": "i"
9
+ }
10
+ ],
11
+ "skill": "tfx-cancel",
12
+ "priority": 0,
13
+ "supersedes": [
14
+ "tfx-team",
15
+ "tfx-auto",
16
+ "tfx-auto-codex",
17
+ "tfx-codex",
18
+ "tfx-gemini"
19
+ ],
20
+ "exclusive": true,
21
+ "state": null,
22
+ "mcp_route": null
23
+ },
24
+ {
25
+ "id": "tfx-team",
26
+ "patterns": [
27
+ {
28
+ "source": "(?<!\\b(?:my|the|our|omc|oh-my-claudecode)\\s)\\btfx[\\s-]?team\\b",
29
+ "flags": "i"
30
+ }
31
+ ],
32
+ "skill": "tfx-team",
33
+ "priority": 1,
34
+ "supersedes": [],
35
+ "exclusive": false,
36
+ "state": null,
37
+ "mcp_route": null
38
+ },
39
+ {
40
+ "id": "tfx-auto-codex",
41
+ "patterns": [
42
+ {
43
+ "source": "\\btfx[\\s-]?auto[\\s-]?codex\\b",
44
+ "flags": "i"
45
+ }
46
+ ],
47
+ "skill": "tfx-auto-codex",
48
+ "priority": 1,
49
+ "supersedes": [
50
+ "tfx-auto",
51
+ "tfx-codex"
52
+ ],
53
+ "exclusive": false,
54
+ "state": null,
55
+ "mcp_route": null
56
+ },
57
+ {
58
+ "id": "tfx-auto",
59
+ "patterns": [
60
+ {
61
+ "source": "\\btfx[\\s-]?auto\\b",
62
+ "flags": "i"
63
+ }
64
+ ],
65
+ "skill": "tfx-auto",
66
+ "priority": 2,
67
+ "supersedes": [],
68
+ "exclusive": false,
69
+ "state": null,
70
+ "mcp_route": null
71
+ },
72
+ {
73
+ "id": "tfx-codex",
74
+ "patterns": [
75
+ {
76
+ "source": "\\btfx[\\s-]?codex\\b",
77
+ "flags": "i"
78
+ }
79
+ ],
80
+ "skill": "tfx-codex",
81
+ "priority": 3,
82
+ "supersedes": [],
83
+ "exclusive": false,
84
+ "state": null,
85
+ "mcp_route": null
86
+ },
87
+ {
88
+ "id": "tfx-gemini",
89
+ "patterns": [
90
+ {
91
+ "source": "\\btfx[\\s-]?gemini\\b",
92
+ "flags": "i"
93
+ }
94
+ ],
95
+ "skill": "tfx-gemini",
96
+ "priority": 3,
97
+ "supersedes": [],
98
+ "exclusive": false,
99
+ "state": null,
100
+ "mcp_route": null
101
+ },
102
+ {
103
+ "id": "notion-route",
104
+ "patterns": [
105
+ {
106
+ "source": "\\b(노션|notion)[\\s-]?(페이지|글|조회|생성|수정|검색)\\b",
107
+ "flags": "i"
108
+ },
109
+ {
110
+ "source": "(노션|notion)[\\s-]?(페이지|글|조회|생성|수정|검색)",
111
+ "flags": "i"
112
+ }
113
+ ],
114
+ "skill": null,
115
+ "priority": 10,
116
+ "supersedes": [],
117
+ "exclusive": false,
118
+ "state": null,
119
+ "mcp_route": "gemini"
120
+ },
121
+ {
122
+ "id": "chrome-route",
123
+ "patterns": [
124
+ {
125
+ "source": "\\b(크롬|chrome|브라우저)[\\s-]?(열|접속|로그인|navigate|click)\\b",
126
+ "flags": "i"
127
+ },
128
+ {
129
+ "source": "(크롬|chrome|브라우저)[\\s-]?(열|접속|로그인|navigate|click)",
130
+ "flags": "i"
131
+ }
132
+ ],
133
+ "skill": null,
134
+ "priority": 10,
135
+ "supersedes": [],
136
+ "exclusive": false,
137
+ "state": null,
138
+ "mcp_route": "gemini"
139
+ },
140
+ {
141
+ "id": "jira-route",
142
+ "patterns": [
143
+ {
144
+ "source": "\\b(jira|지라)[\\s-]?(이슈|티켓|생성|조회|스프린트)\\b",
145
+ "flags": "i"
146
+ },
147
+ {
148
+ "source": "(jira|지라)[\\s-]?(이슈|티켓|생성|조회|스프린트)",
149
+ "flags": "i"
150
+ }
151
+ ],
152
+ "skill": null,
153
+ "priority": 10,
154
+ "supersedes": [],
155
+ "exclusive": false,
156
+ "state": null,
157
+ "mcp_route": "codex"
158
+ },
159
+ {
160
+ "id": "mail-route",
161
+ "patterns": [
162
+ {
163
+ "source": "\\b(메일|gmail|이메일)[\\s-]?(보내|읽|검색|draft)\\b",
164
+ "flags": "i"
165
+ },
166
+ {
167
+ "source": "(메일|gmail|이메일)[\\s-]?(보내|읽|검색|draft)",
168
+ "flags": "i"
169
+ }
170
+ ],
171
+ "skill": null,
172
+ "priority": 10,
173
+ "supersedes": [],
174
+ "exclusive": false,
175
+ "state": null,
176
+ "mcp_route": "gemini"
177
+ },
178
+ {
179
+ "id": "calendar-route",
180
+ "patterns": [
181
+ {
182
+ "source": "\\b(일정|캘린더|calendar)[\\s-]?(생성|조회|추가)\\b",
183
+ "flags": "i"
184
+ },
185
+ {
186
+ "source": "(일정|캘린더|calendar)[\\s-]?(생성|조회|추가)",
187
+ "flags": "i"
188
+ }
189
+ ],
190
+ "skill": null,
191
+ "priority": 10,
192
+ "supersedes": [],
193
+ "exclusive": false,
194
+ "state": null,
195
+ "mcp_route": "gemini"
196
+ },
197
+ {
198
+ "id": "playwright-route",
199
+ "patterns": [
200
+ {
201
+ "source": "\\b(playwright|브라우저\\s*테스트)\\b",
202
+ "flags": "i"
203
+ },
204
+ {
205
+ "source": "(playwright|브라우저\\s*테스트)",
206
+ "flags": "i"
207
+ }
208
+ ],
209
+ "skill": null,
210
+ "priority": 10,
211
+ "supersedes": [],
212
+ "exclusive": false,
213
+ "state": null,
214
+ "mcp_route": "gemini"
215
+ },
216
+ {
217
+ "id": "canva-route",
218
+ "patterns": [
219
+ {
220
+ "source": "\\b(canva|캔바|디자인\\s*생성)\\b",
221
+ "flags": "i"
222
+ },
223
+ {
224
+ "source": "(canva|캔바|디자인\\s*생성)",
225
+ "flags": "i"
226
+ }
227
+ ],
228
+ "skill": null,
229
+ "priority": 10,
230
+ "supersedes": [],
231
+ "exclusive": false,
232
+ "state": null,
233
+ "mcp_route": "gemini"
234
+ },
235
+ {
236
+ "id": "tfx-hub",
237
+ "patterns": [
238
+ {
239
+ "source": "\\btfx[\\s-]?hub\\b",
240
+ "flags": "i"
241
+ }
242
+ ],
243
+ "skill": "tfx-hub",
244
+ "priority": 2,
245
+ "supersedes": [],
246
+ "exclusive": false,
247
+ "state": null,
248
+ "mcp_route": null
249
+ },
250
+ {
251
+ "id": "tfx-doctor",
252
+ "patterns": [
253
+ {
254
+ "source": "\\btfx[\\s-]?doctor\\b",
255
+ "flags": "i"
256
+ }
257
+ ],
258
+ "skill": "tfx-doctor",
259
+ "priority": 2,
260
+ "supersedes": [],
261
+ "exclusive": false,
262
+ "state": null,
263
+ "mcp_route": null
264
+ },
265
+ {
266
+ "id": "tfx-setup",
267
+ "patterns": [
268
+ {
269
+ "source": "\\btfx[\\s-]?setup\\b",
270
+ "flags": "i"
271
+ }
272
+ ],
273
+ "skill": "tfx-setup",
274
+ "priority": 2,
275
+ "supersedes": [],
276
+ "exclusive": false,
277
+ "state": null,
278
+ "mcp_route": null
279
+ },
280
+ {
281
+ "id": "confluence-route",
282
+ "patterns": [
283
+ {
284
+ "source": "\\b(confluence|위키|wiki)[\\s-]?(페이지|문서|조회|생성|수정|검색)\\b",
285
+ "flags": "i"
286
+ },
287
+ {
288
+ "source": "(confluence|위키|wiki)[\\s-]?(페이지|문서|조회|생성|수정|검색)",
289
+ "flags": "i"
290
+ }
291
+ ],
292
+ "skill": null,
293
+ "priority": 10,
294
+ "supersedes": [],
295
+ "exclusive": false,
296
+ "state": null,
297
+ "mcp_route": "gemini"
298
+ },
299
+ {
300
+ "id": "slack-route",
301
+ "patterns": [
302
+ {
303
+ "source": "\\b(slack|슬랙)[\\s-]?(메시지|채널|보내|읽|검색|알림)\\b",
304
+ "flags": "i"
305
+ },
306
+ {
307
+ "source": "(slack|슬랙)[\\s-]?(메시지|채널|보내|읽|검색|알림)",
308
+ "flags": "i"
309
+ }
310
+ ],
311
+ "skill": null,
312
+ "priority": 10,
313
+ "supersedes": [],
314
+ "exclusive": false,
315
+ "state": null,
316
+ "mcp_route": "gemini"
317
+ },
318
+ {
319
+ "id": "github-route",
320
+ "patterns": [
321
+ {
322
+ "source": "\\b(github|깃허브)[\\s-]?(이슈|issue|PR|pull|커밋|commit|리포|repo)\\b",
323
+ "flags": "i"
324
+ },
325
+ {
326
+ "source": "(github|깃허브)[\\s-]?(이슈|issue|PR|pull|커밋|commit|리포|repo)",
327
+ "flags": "i"
328
+ }
329
+ ],
330
+ "skill": null,
331
+ "priority": 10,
332
+ "supersedes": [],
333
+ "exclusive": false,
334
+ "state": null,
335
+ "mcp_route": "codex"
336
+ }
337
+ ]
338
+ }
package/hub/server.mjs CHANGED
@@ -116,16 +116,25 @@ export async function startHub({ port = 27888, dbPath, host = '127.0.0.1' } = {}
116
116
  return res.end();
117
117
  }
118
118
 
119
- // /status — 허브 상태 (브라우저/curl 용)
120
- if (req.url === '/' || req.url === '/status') {
121
- res.writeHead(200, { 'Content-Type': 'application/json' });
122
- return res.end(JSON.stringify({
123
- ...router.getStatus('hub').data,
124
- sessions: transports.size,
125
- pid: process.pid,
126
- port,
127
- }));
128
- }
119
+ // /status — 상세 상태 (브라우저/curl 용)
120
+ if (req.url === '/' || req.url === '/status') {
121
+ const status = router.getStatus('hub').data;
122
+ res.writeHead(200, { 'Content-Type': 'application/json' });
123
+ return res.end(JSON.stringify({
124
+ ...status,
125
+ sessions: transports.size,
126
+ pid: process.pid,
127
+ port,
128
+ }));
129
+ }
130
+
131
+ // /health, /healthz — 최소 헬스 응답 (레거시 호환)
132
+ if (req.url === '/health' || req.url === '/healthz') {
133
+ const status = router.getStatus('hub').data;
134
+ const healthy = status?.hub?.state === 'healthy';
135
+ res.writeHead(healthy ? 200 : 503, { 'Content-Type': 'application/json' });
136
+ return res.end(JSON.stringify({ ok: healthy }));
137
+ }
129
138
 
130
139
  // /bridge/* — 경량 REST 엔드포인트 (tfx-route.sh 브릿지용)
131
140
  if (req.url.startsWith('/bridge')) {