@triflux/core 10.49.0 → 10.50.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 (46) hide show
  1. package/hooks/agy-session-hook.mjs +1 -1
  2. package/hooks/claude-cwd-projection-refresh.mjs +7 -79
  3. package/hooks/codex-session-hook.mjs +3 -8
  4. package/hooks/hook-orchestrator.mjs +8 -648
  5. package/hooks/lib/resolve-root.mjs +1 -1
  6. package/hub/bridge.mjs +290 -51
  7. package/hub/team/claude-daemon-control.mjs +54 -6
  8. package/hub/team/claude-transcript.mjs +240 -0
  9. package/hub/team/session-context.mjs +203 -0
  10. package/hud/constants.mjs +10 -0
  11. package/hud/hud-qos-status.mjs +23 -4
  12. package/hud/providers/gemini.mjs +4 -1
  13. package/hud/renderers.mjs +10 -6
  14. package/package.json +1 -1
  15. package/scripts/lib/doctor-env-checks.mjs +0 -85
  16. package/scripts/lib/legacy-hook-cleanup.mjs +230 -0
  17. package/scripts/lib/legacy-mcp-cleanup.mjs +772 -0
  18. package/scripts/lib/mcp-guard-engine.mjs +44 -271
  19. package/scripts/lib/mcp-manifest.mjs +2 -2
  20. package/scripts/lib/session-presence.mjs +249 -0
  21. package/hooks/agent-route-guard.mjs +0 -113
  22. package/hooks/cross-review-tracker.mjs +0 -135
  23. package/hooks/cto-north-star-brief.mjs +0 -133
  24. package/hooks/error-context.mjs +0 -185
  25. package/hooks/hook-adaptive-collector.mjs +0 -88
  26. package/hooks/hook-manager.mjs +0 -426
  27. package/hooks/hook-registry.json +0 -367
  28. package/hooks/hooks.json +0 -149
  29. package/hooks/keyword-rules.json +0 -676
  30. package/hooks/mcp-config-watcher.mjs +0 -84
  31. package/hooks/permission-safe-allow.mjs +0 -267
  32. package/hooks/pipeline-stop.mjs +0 -435
  33. package/hooks/post-tool-tips.mjs +0 -306
  34. package/hooks/pre-compact-snapshot.mjs +0 -181
  35. package/hooks/safety-guard.mjs +0 -466
  36. package/hooks/session-end-cleanup.mjs +0 -360
  37. package/hooks/session-start-fast.mjs +0 -579
  38. package/hooks/session-start-lake.mjs +0 -81
  39. package/hooks/subagent-tracker.mjs +0 -281
  40. package/hooks/subagent-verifier.mjs +0 -85
  41. package/scripts/lib/cross-review-utils.mjs +0 -59
  42. package/scripts/lib/hook-utils.mjs +0 -16
  43. package/scripts/lib/keyword-rules.mjs +0 -296
  44. package/scripts/lib/mcp-gateway-health-check.mjs +0 -224
  45. package/scripts/lib/mcp-gateway-servers.mjs +0 -70
  46. package/scripts/lib/mcp-gateway-wrapper-check.mjs +0 -35
@@ -1,367 +0,0 @@
1
- {
2
- "$schema": "hook-registry-schema",
3
- "version": 1,
4
- "description": "훅 우선순위 레지스트리 — 오케스트레이터가 이 파일을 읽어 순차 실행한다. priority 낮을수록 먼저 실행.",
5
- "defaults": {
6
- "triflux_priority": 0,
7
- "omc_priority": 50,
8
- "external_priority": 100
9
- },
10
- "events": {
11
- "CwdChanged": [
12
- {
13
- "id": "tfx-claude-cwd-projection-refresh",
14
- "source": "triflux",
15
- "matcher": "*",
16
- "command": "node \"${PLUGIN_ROOT}/hooks/claude-cwd-projection-refresh.mjs\"",
17
- "priority": 0,
18
- "enabled": true,
19
- "timeout": 2,
20
- "blocking": false,
21
- "description": "Claude /cd CwdChanged 이벤트를 Triflux native-bridge projection cwd에 반영"
22
- }
23
- ],
24
- "PermissionRequest": [
25
- {
26
- "id": "tfx-permission-safe-allow",
27
- "source": "triflux",
28
- "matcher": "Bash",
29
- "command": "node \"${PLUGIN_ROOT}/hooks/permission-safe-allow.mjs\"",
30
- "priority": 0,
31
- "enabled": true,
32
- "timeout": 2,
33
- "blocking": false,
34
- "description": "안전한 repo-local Bash PermissionRequest 자동 허용 (#245)"
35
- }
36
- ],
37
- "PreToolUse": [
38
- {
39
- "id": "tfx-safety-guard",
40
- "source": "triflux",
41
- "matcher": "Bash",
42
- "command": "node \"${PLUGIN_ROOT}/hooks/safety-guard.mjs\"",
43
- "priority": 0,
44
- "enabled": true,
45
- "timeout": 3,
46
- "blocking": true,
47
- "description": "위험 Bash 명령 사전 차단 (rm -rf, force push 등)"
48
- },
49
- {
50
- "id": "tfx-agent-route-guard",
51
- "source": "triflux",
52
- "matcher": "Agent",
53
- "command": "node \"${PLUGIN_ROOT}/hooks/agent-route-guard.mjs\"",
54
- "priority": 0,
55
- "enabled": true,
56
- "timeout": 3,
57
- "blocking": false,
58
- "description": "서브에이전트 스폰 시 triflux 컨텍스트 주입"
59
- },
60
- {
61
- "id": "tfx-cross-review-gate",
62
- "source": "triflux",
63
- "matcher": "Bash",
64
- "command": "node \"${PLUGIN_ROOT}/scripts/cross-review-gate.mjs\"",
65
- "priority": 1,
66
- "enabled": true,
67
- "timeout": 3,
68
- "blocking": true,
69
- "description": "git commit 전 교차 리뷰 미검증 파일 차단/경고"
70
- },
71
- {
72
- "id": "omc-tfx-gate-activate",
73
- "source": "omc",
74
- "matcher": "Skill",
75
- "command": "node \"${HOME}/.claude/scripts/tfx-gate-activate.mjs\"",
76
- "priority": 50,
77
- "enabled": true,
78
- "timeout": 2,
79
- "blocking": false,
80
- "description": "tfx-multi 상태 추적 게이트"
81
- },
82
- {
83
- "id": "tfx-write-edit-passthrough",
84
- "source": "triflux",
85
- "matcher": "Edit|Write",
86
- "command": "exit 0",
87
- "priority": 999,
88
- "enabled": true,
89
- "blocking": false,
90
- "description": "Edit/Write passthrough"
91
- }
92
- ],
93
- "PostToolUse": [
94
- {
95
- "id": "tfx-cross-review-tracker",
96
- "source": "triflux",
97
- "matcher": "Edit|Write",
98
- "command": "node \"${PLUGIN_ROOT}/hooks/cross-review-tracker.mjs\"",
99
- "priority": 0,
100
- "enabled": true,
101
- "timeout": 3,
102
- "blocking": false,
103
- "description": "파일 수정 추적 → 교차 리뷰 nudge"
104
- },
105
- {
106
- "id": "tfx-mcp-config-watcher",
107
- "source": "triflux",
108
- "matcher": "Edit|Write",
109
- "command": "node \"${PLUGIN_ROOT}/hooks/mcp-config-watcher.mjs\"",
110
- "priority": 1,
111
- "enabled": true,
112
- "timeout": 3,
113
- "blocking": false,
114
- "description": "감시 대상 MCP 설정 변경 감지 → stdio MCP 자동 치환"
115
- },
116
- {
117
- "id": "tfx-post-tool-tips",
118
- "source": "triflux",
119
- "matcher": "Bash|Edit|Write",
120
- "command": "node \"${PLUGIN_ROOT}/hooks/post-tool-tips.mjs\"",
121
- "priority": 2,
122
- "enabled": true,
123
- "timeout": 2,
124
- "blocking": false,
125
- "description": "중요 경로 변경 시 opt-in rules reminder 주입 (#245)"
126
- }
127
- ],
128
- "PostToolUseFailure": [
129
- {
130
- "id": "tfx-error-context",
131
- "source": "triflux",
132
- "matcher": "*",
133
- "command": "node \"${PLUGIN_ROOT}/hooks/error-context.mjs\"",
134
- "priority": 0,
135
- "enabled": true,
136
- "timeout": 3,
137
- "blocking": false,
138
- "description": "도구 실패 시 에러 힌트 자동 주입"
139
- },
140
- {
141
- "id": "tfx-adaptive-collector",
142
- "source": "triflux",
143
- "matcher": "*",
144
- "command": "node \"${PLUGIN_ROOT}/hooks/hook-adaptive-collector.mjs\"",
145
- "priority": 1,
146
- "enabled": true,
147
- "timeout": 3,
148
- "blocking": false,
149
- "description": "에러 패턴 수집 → Neural Memory adaptive engine 학습"
150
- }
151
- ],
152
- "UserPromptSubmit": [
153
- {
154
- "id": "tfx-keyword-detector",
155
- "source": "triflux",
156
- "matcher": "*",
157
- "command": "node \"${PLUGIN_ROOT}/scripts/run.cjs\" \"${PLUGIN_ROOT}/scripts/keyword-detector.mjs\"",
158
- "priority": 0,
159
- "enabled": true,
160
- "timeout": 5,
161
- "blocking": false,
162
- "description": "키워드 매칭 → 스킬 자동 라우팅"
163
- },
164
- {
165
- "id": "tfx-cto-north-star-brief",
166
- "source": "triflux",
167
- "matcher": "*",
168
- "command": "node \"${PLUGIN_ROOT}/hooks/cto-north-star-brief.mjs\"",
169
- "priority": 2,
170
- "enabled": true,
171
- "timeout": 2,
172
- "blocking": false,
173
- "description": "CTO north-star brief를 UserPromptSubmit additionalContext로 변경 시 주입"
174
- }
175
- ],
176
- "SessionStart": [
177
- {
178
- "id": "tfx-setup",
179
- "source": "triflux",
180
- "matcher": "*",
181
- "command": "node \"${PLUGIN_ROOT}/scripts/setup.mjs\"",
182
- "priority": 0,
183
- "enabled": true,
184
- "timeout": 10,
185
- "blocking": false,
186
- "description": "triflux 환경 초기화"
187
- },
188
- {
189
- "id": "tfx-mcp-safety-guard",
190
- "source": "triflux",
191
- "matcher": "*",
192
- "command": "node \"${PLUGIN_ROOT}/scripts/mcp-safety-guard.mjs\"",
193
- "priority": 1,
194
- "enabled": true,
195
- "timeout": 3,
196
- "blocking": false,
197
- "description": "Gemini stdio MCP 자동 감지 + 제거 (spawn EPERM 방지)"
198
- },
199
- {
200
- "id": "tfx-hub-ensure",
201
- "source": "triflux",
202
- "matcher": "*",
203
- "command": "node \"${PLUGIN_ROOT}/scripts/hub-ensure.mjs\"",
204
- "priority": 2,
205
- "enabled": true,
206
- "timeout": 8,
207
- "blocking": true,
208
- "description": "tfx-hub 서비스 헬스체크 및 시작 (BLOCKING — 세션 시작 전 Hub 준비 보장)"
209
- },
210
- {
211
- "id": "tfx-preflight-cache",
212
- "source": "triflux",
213
- "matcher": "*",
214
- "command": "node \"${PLUGIN_ROOT}/scripts/preflight-cache.mjs\"",
215
- "priority": 3,
216
- "enabled": true,
217
- "timeout": 5,
218
- "blocking": false,
219
- "description": "CLI/Hub 가용성 캐시 (hub-ensure 완료 후 실행)"
220
- },
221
- {
222
- "id": "tfx-mcp-gateway-ensure",
223
- "source": "triflux",
224
- "matcher": "*",
225
- "command": "node \"${PLUGIN_ROOT}/scripts/mcp-gateway-ensure.mjs\"",
226
- "priority": 4,
227
- "enabled": true,
228
- "timeout": 8,
229
- "blocking": false,
230
- "description": "supergateway MCP 서비스 헬스체크 및 자동 기동"
231
- },
232
- {
233
- "id": "tfx-session-stale-cleanup",
234
- "source": "triflux",
235
- "matcher": "*",
236
- "command": "node \"${PLUGIN_ROOT}/scripts/session-stale-cleanup.mjs\"",
237
- "priority": 5,
238
- "enabled": true,
239
- "timeout": 3,
240
- "blocking": false,
241
- "description": "이전 세션의 stale tfx-multi 상태 파일 정리 (#62)"
242
- },
243
- {
244
- "id": "tfx-session-lake",
245
- "source": "triflux",
246
- "matcher": "*",
247
- "command": "node \"${PLUGIN_ROOT}/hooks/session-start-lake.mjs\"",
248
- "priority": 6,
249
- "enabled": true,
250
- "timeout": 3,
251
- "blocking": false,
252
- "description": "CTO north-star brief를 SessionStart additionalContext로 주입"
253
- },
254
- {
255
- "id": "ext-session-vault-start",
256
- "source": "session-vault",
257
- "requires": "$HOME/Desktop/Projects/tools/session-vault",
258
- "matcher": "*",
259
- "command": "bash \"${HOME}/Desktop/Projects/tools/session-vault/scripts/start_hook.sh\"",
260
- "priority": 100,
261
- "enabled": false,
262
- "timeout": 10,
263
- "blocking": false,
264
- "description": "세션 볼트 로깅 시작"
265
- }
266
- ],
267
- "Stop": [
268
- {
269
- "id": "tfx-pipeline-stop",
270
- "source": "triflux",
271
- "matcher": "*",
272
- "command": "node \"${PLUGIN_ROOT}/hooks/pipeline-stop.mjs\"",
273
- "priority": 0,
274
- "enabled": true,
275
- "timeout": 5,
276
- "blocking": true,
277
- "description": "컨텍스트 guard/retry cap + 활성 파이프라인 감지 → Stop 차단"
278
- },
279
- {
280
- "id": "ext-session-vault-export",
281
- "source": "session-vault",
282
- "requires": "$HOME/Desktop/Projects/tools/session-vault",
283
- "matcher": "*",
284
- "command": "bash \"${HOME}/Desktop/Projects/tools/session-vault/scripts/export_hook.sh\"",
285
- "priority": 100,
286
- "enabled": false,
287
- "timeout": 30,
288
- "blocking": false,
289
- "description": "세션 트랜스크립트 내보내기"
290
- },
291
- {
292
- "id": "ext-mcp-cleanup",
293
- "source": "system",
294
- "matcher": "*",
295
- "command": "powershell -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File \"${HOME}/.claude/scripts/mcp-cleanup.ps1\"",
296
- "priority": 100,
297
- "enabled": false,
298
- "timeout": 8,
299
- "blocking": false,
300
- "description": "MCP 고아 프로세스 정리"
301
- }
302
- ],
303
- "SessionEnd": [
304
- {
305
- "id": "tfx-session-end-cleanup",
306
- "source": "triflux",
307
- "matcher": "*",
308
- "command": "node \"${PLUGIN_ROOT}/hooks/session-end-cleanup.mjs\"",
309
- "priority": 0,
310
- "enabled": true,
311
- "timeout": 3,
312
- "blocking": false,
313
- "description": "세션 종료 시 lifecycle 상태 보고 및 opt-in 정리 (#245)"
314
- }
315
- ],
316
- "SubagentStart": [
317
- {
318
- "id": "tfx-subagent-tracker",
319
- "source": "triflux",
320
- "matcher": "*",
321
- "command": "node \"${PLUGIN_ROOT}/hooks/subagent-tracker.mjs\"",
322
- "priority": 0,
323
- "enabled": true,
324
- "timeout": 2,
325
- "blocking": false,
326
- "description": "서브에이전트 lifecycle 시작/종료 상태 추적 (#245)"
327
- }
328
- ],
329
- "SubagentStop": [
330
- {
331
- "id": "tfx-subagent-tracker",
332
- "source": "triflux",
333
- "matcher": "*",
334
- "command": "node \"${PLUGIN_ROOT}/hooks/subagent-tracker.mjs\"",
335
- "priority": 0,
336
- "enabled": true,
337
- "timeout": 2,
338
- "blocking": false,
339
- "description": "서브에이전트 lifecycle 시작/종료 상태 추적 (#245)"
340
- },
341
- {
342
- "id": "tfx-subagent-verifier",
343
- "source": "triflux",
344
- "matcher": "*",
345
- "command": "node \"${PLUGIN_ROOT}/hooks/subagent-verifier.mjs\"",
346
- "priority": 1,
347
- "enabled": true,
348
- "timeout": 3,
349
- "blocking": false,
350
- "description": "서브에이전트 결과 품질 체크"
351
- }
352
- ],
353
- "PreCompact": [
354
- {
355
- "id": "tfx-pre-compact-snapshot",
356
- "source": "triflux",
357
- "matcher": "*",
358
- "command": "node \"${PLUGIN_ROOT}/hooks/pre-compact-snapshot.mjs\"",
359
- "priority": 0,
360
- "enabled": true,
361
- "timeout": 3,
362
- "blocking": false,
363
- "description": "compact 직전 repo-local 진행 상태 스냅샷 주입 (#245)"
364
- }
365
- ]
366
- }
367
- }
package/hooks/hooks.json DELETED
@@ -1,149 +0,0 @@
1
- {
2
- "description": "triflux lifecycle hooks v2 — hook-orchestrator 기반 순차 실행. 우선순위는 hook-registry.json에서 관리.",
3
- "hooks": {
4
- "SessionStart": [
5
- {
6
- "matcher": "*",
7
- "hooks": [
8
- {
9
- "type": "command",
10
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
11
- "timeout": 15
12
- }
13
- ]
14
- }
15
- ],
16
- "CwdChanged": [
17
- {
18
- "matcher": "*",
19
- "hooks": [
20
- {
21
- "type": "command",
22
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
23
- "timeout": 5
24
- }
25
- ]
26
- }
27
- ],
28
- "UserPromptSubmit": [
29
- {
30
- "matcher": "*",
31
- "hooks": [
32
- {
33
- "type": "command",
34
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
35
- "timeout": 10
36
- }
37
- ]
38
- }
39
- ],
40
- "PermissionRequest": [
41
- {
42
- "matcher": "Bash",
43
- "hooks": [
44
- {
45
- "type": "command",
46
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
47
- "timeout": 3
48
- }
49
- ]
50
- }
51
- ],
52
- "PreToolUse": [
53
- {
54
- "matcher": "Bash|Agent|Skill",
55
- "hooks": [
56
- {
57
- "type": "command",
58
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
59
- "timeout": 10
60
- }
61
- ]
62
- }
63
- ],
64
- "PostToolUse": [
65
- {
66
- "matcher": "Bash|Edit|Write",
67
- "hooks": [
68
- {
69
- "type": "command",
70
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
71
- "timeout": 5
72
- }
73
- ]
74
- }
75
- ],
76
- "PostToolUseFailure": [
77
- {
78
- "matcher": "*",
79
- "hooks": [
80
- {
81
- "type": "command",
82
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
83
- "timeout": 5
84
- }
85
- ]
86
- }
87
- ],
88
- "Stop": [
89
- {
90
- "matcher": "*",
91
- "hooks": [
92
- {
93
- "type": "command",
94
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
95
- "timeout": 35
96
- }
97
- ]
98
- }
99
- ],
100
- "SessionEnd": [
101
- {
102
- "matcher": "*",
103
- "hooks": [
104
- {
105
- "type": "command",
106
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
107
- "timeout": 5
108
- }
109
- ]
110
- }
111
- ],
112
- "SubagentStart": [
113
- {
114
- "matcher": "*",
115
- "hooks": [
116
- {
117
- "type": "command",
118
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
119
- "timeout": 5
120
- }
121
- ]
122
- }
123
- ],
124
- "SubagentStop": [
125
- {
126
- "matcher": "*",
127
- "hooks": [
128
- {
129
- "type": "command",
130
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
131
- "timeout": 5
132
- }
133
- ]
134
- }
135
- ],
136
- "PreCompact": [
137
- {
138
- "matcher": "*",
139
- "hooks": [
140
- {
141
- "type": "command",
142
- "command": "node -e \"const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),cp=require('node:child_process');const roots=[];try{roots.push(fs.readFileSync(path.join(os.homedir(),'.claude','scripts','.tfx-pkg-root'),'utf8').trim())}catch{}roots.push(process.env.PLUGIN_ROOT,process.env.CLAUDE_PLUGIN_ROOT);try{roots.push(cp.execFileSync('git',['rev-parse','--show-toplevel'],{encoding:'utf8',stdio:['ignore','pipe','ignore']}).trim())}catch{}roots.push(process.cwd());const root=roots.find(r=>r&&fs.existsSync(path.join(r,'hooks','hook-orchestrator.mjs')));if(!root){console.error('[triflux hook] cannot locate hooks/hook-orchestrator.mjs');process.exit(1)}const child=cp.spawnSync(process.execPath,[path.join(root,'hooks','hook-orchestrator.mjs')],{stdio:'inherit',env:process.env,windowsHide:true});process.exit(child.status??(child.signal?1:0));\"",
143
- "timeout": 5
144
- }
145
- ]
146
- }
147
- ]
148
- }
149
- }