triflux 10.4.0 → 10.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/.claude-plugin/marketplace.json +34 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/bin/tfx-doctor-tui.mjs +1 -1
  4. package/bin/tfx-doctor.mjs +6 -1
  5. package/bin/tfx-profile.mjs +1 -1
  6. package/bin/tfx-setup-tui.mjs +1 -1
  7. package/bin/tfx-setup.mjs +6 -1
  8. package/bin/triflux.mjs +2396 -1140
  9. package/config/mcp-registry.json +29 -0
  10. package/hooks/agent-route-guard.mjs +12 -8
  11. package/hooks/cross-review-tracker.mjs +21 -8
  12. package/hooks/error-context.mjs +19 -7
  13. package/hooks/hook-adaptive-collector.mjs +18 -16
  14. package/hooks/hook-manager.mjs +93 -32
  15. package/hooks/hook-orchestrator.mjs +108 -24
  16. package/hooks/hook-registry.json +267 -256
  17. package/hooks/keyword-rules.json +6 -10
  18. package/hooks/lib/resolve-root.mjs +1 -1
  19. package/hooks/mcp-config-watcher.mjs +6 -2
  20. package/hooks/pipeline-stop.mjs +3 -6
  21. package/hooks/safety-guard.mjs +99 -28
  22. package/hooks/session-start-fast.mjs +143 -0
  23. package/hooks/subagent-verifier.mjs +5 -4
  24. package/hub/account-broker.mjs +256 -60
  25. package/hub/adaptive-diagnostic.mjs +75 -48
  26. package/hub/adaptive-inject.mjs +96 -58
  27. package/hub/adaptive-memory.mjs +156 -42
  28. package/hub/adaptive.mjs +60 -31
  29. package/hub/assign-callbacks.mjs +163 -126
  30. package/hub/bridge.mjs +0 -1
  31. package/hub/cli-adapter-base.mjs +200 -48
  32. package/hub/codex-adapter.mjs +76 -96
  33. package/hub/codex-compat.mjs +3 -3
  34. package/hub/codex-preflight.mjs +63 -37
  35. package/hub/delegator/contracts.mjs +19 -23
  36. package/hub/delegator/index.mjs +14 -14
  37. package/hub/delegator/service.mjs +88 -64
  38. package/hub/delegator/tool-definitions.mjs +35 -35
  39. package/hub/fullcycle.mjs +33 -17
  40. package/hub/gemini-adapter.mjs +69 -94
  41. package/hub/hitl.mjs +202 -143
  42. package/hub/intent.mjs +161 -38
  43. package/hub/lib/cache-guard.mjs +43 -17
  44. package/hub/lib/mcp-response-cache.mjs +66 -32
  45. package/hub/lib/memory-store.mjs +285 -111
  46. package/hub/lib/path-utils.mjs +35 -37
  47. package/hub/lib/process-utils.mjs +106 -37
  48. package/hub/lib/spawn-trace.mjs +527 -0
  49. package/hub/lib/ssh-command.mjs +34 -4
  50. package/hub/lib/ssh-retry.mjs +5 -1
  51. package/hub/lib/uuidv7.mjs +4 -3
  52. package/hub/memory-doctor.mjs +266 -106
  53. package/hub/middleware/request-logger.mjs +61 -34
  54. package/hub/paths.mjs +9 -9
  55. package/hub/pipeline/gates/confidence.mjs +34 -15
  56. package/hub/pipeline/gates/consensus.mjs +27 -15
  57. package/hub/pipeline/gates/index.mjs +7 -3
  58. package/hub/pipeline/gates/selfcheck.mjs +57 -19
  59. package/hub/pipeline/index.mjs +77 -42
  60. package/hub/pipeline/state.mjs +10 -10
  61. package/hub/pipeline/transitions.mjs +40 -23
  62. package/hub/platform.mjs +57 -48
  63. package/hub/promote-penalties.mjs +25 -7
  64. package/hub/quality/deslop.mjs +70 -49
  65. package/hub/research.mjs +32 -25
  66. package/hub/router.mjs +924 -791
  67. package/hub/routing/complexity.mjs +132 -29
  68. package/hub/routing/index.mjs +17 -12
  69. package/hub/routing/q-learning.mjs +76 -28
  70. package/hub/server.mjs +4 -4
  71. package/hub/session-fingerprint.mjs +127 -61
  72. package/hub/state.mjs +84 -43
  73. package/hub/store-adapter.mjs +59 -26
  74. package/hub/store.mjs +356 -153
  75. package/hub/team/agent-map.json +22 -7
  76. package/hub/team/ansi.mjs +186 -122
  77. package/hub/team/backend.mjs +28 -10
  78. package/hub/team/cli/commands/attach.mjs +57 -37
  79. package/hub/team/cli/commands/control.mjs +29 -8
  80. package/hub/team/cli/commands/debug.mjs +95 -74
  81. package/hub/team/cli/commands/focus.mjs +80 -53
  82. package/hub/team/cli/commands/interrupt.mjs +18 -6
  83. package/hub/team/cli/commands/kill.mjs +16 -5
  84. package/hub/team/cli/commands/list.mjs +31 -24
  85. package/hub/team/cli/commands/send.mjs +19 -6
  86. package/hub/team/cli/commands/start/index.mjs +154 -31
  87. package/hub/team/cli/commands/start/parse-args.mjs +38 -11
  88. package/hub/team/cli/commands/start/start-headless.mjs +112 -36
  89. package/hub/team/cli/commands/start/start-in-process.mjs +50 -40
  90. package/hub/team/cli/commands/start/start-mux.mjs +122 -73
  91. package/hub/team/cli/commands/start/start-wt.mjs +86 -69
  92. package/hub/team/cli/commands/status.mjs +43 -14
  93. package/hub/team/cli/commands/stop.mjs +11 -4
  94. package/hub/team/cli/commands/task.mjs +8 -3
  95. package/hub/team/cli/commands/tasks.mjs +13 -13
  96. package/hub/team/cli/index.mjs +2 -2
  97. package/hub/team/cli/manifest.mjs +38 -8
  98. package/hub/team/cli/render.mjs +52 -30
  99. package/hub/team/cli/services/attach-fallback.mjs +74 -54
  100. package/hub/team/cli/services/hub-client.mjs +42 -14
  101. package/hub/team/cli/services/member-selector.mjs +37 -30
  102. package/hub/team/cli/services/native-control.mjs +143 -116
  103. package/hub/team/cli/services/runtime-mode.mjs +2 -1
  104. package/hub/team/cli/services/state-store.mjs +25 -8
  105. package/hub/team/cli/services/task-model.mjs +40 -30
  106. package/hub/team/conductor-mesh-bridge.mjs +24 -23
  107. package/hub/team/conductor.mjs +8 -4
  108. package/hub/team/dashboard-anchor.mjs +4 -5
  109. package/hub/team/dashboard-layout.mjs +3 -1
  110. package/hub/team/dashboard-open.mjs +41 -21
  111. package/hub/team/dashboard.mjs +76 -28
  112. package/hub/team/event-log.mjs +18 -10
  113. package/hub/team/handoff.mjs +31 -15
  114. package/hub/team/headless.mjs +2 -1
  115. package/hub/team/health-probe.mjs +69 -54
  116. package/hub/team/launcher-template.mjs +16 -13
  117. package/hub/team/native-supervisor.mjs +65 -21
  118. package/hub/team/native.mjs +74 -35
  119. package/hub/team/nativeProxy.mjs +184 -113
  120. package/hub/team/notify.mjs +120 -77
  121. package/hub/team/orchestrator.mjs +166 -161
  122. package/hub/team/pane.mjs +12 -7
  123. package/hub/team/process-cleanup.mjs +25 -16
  124. package/hub/team/psmux.mjs +491 -201
  125. package/hub/team/remote-probe.mjs +68 -52
  126. package/hub/team/remote-session.mjs +117 -59
  127. package/hub/team/remote-watcher.mjs +61 -33
  128. package/hub/team/routing.mjs +51 -25
  129. package/hub/team/runtime-strategy.mjs +3 -1
  130. package/hub/team/session.mjs +675 -611
  131. package/hub/team/shared.mjs +13 -13
  132. package/hub/team/staleState.mjs +72 -30
  133. package/hub/team/swarm-locks.mjs +15 -13
  134. package/hub/team/swarm-planner.mjs +32 -21
  135. package/hub/team/swarm-reconciler.mjs +48 -23
  136. package/hub/team/tui-lite.mjs +266 -68
  137. package/hub/team/tui-remote-adapter.mjs +14 -10
  138. package/hub/team/tui-viewer.mjs +99 -43
  139. package/hub/team/tui.mjs +708 -271
  140. package/hub/team/worktree-lifecycle.mjs +152 -58
  141. package/hub/team/wt-manager.mjs +24 -14
  142. package/hub/token-mode.mjs +71 -71
  143. package/hub/tray.mjs +411 -368
  144. package/hub/workers/claude-worker.mjs +162 -118
  145. package/hub/workers/codex-mcp.mjs +558 -507
  146. package/hub/workers/delegator-mcp.mjs +507 -333
  147. package/hub/workers/factory.mjs +21 -21
  148. package/hub/workers/gemini-worker.mjs +115 -84
  149. package/hub/workers/interface.mjs +6 -1
  150. package/hub/workers/worker-utils.mjs +21 -14
  151. package/hud/colors.mjs +27 -9
  152. package/hud/constants.mjs +162 -26
  153. package/hud/context-monitor.mjs +82 -41
  154. package/hud/hud-qos-status.mjs +129 -49
  155. package/hud/mission-board.mjs +6 -3
  156. package/hud/providers/claude.mjs +226 -115
  157. package/hud/providers/codex.mjs +62 -22
  158. package/hud/providers/gemini.mjs +168 -56
  159. package/hud/renderers.mjs +384 -119
  160. package/hud/terminal.mjs +101 -31
  161. package/hud/utils.mjs +78 -38
  162. package/mesh/index.mjs +11 -5
  163. package/mesh/mesh-budget.mjs +18 -9
  164. package/mesh/mesh-heartbeat.mjs +1 -1
  165. package/mesh/mesh-queue.mjs +3 -5
  166. package/mesh/mesh-router.mjs +5 -4
  167. package/package.json +56 -21
  168. package/scripts/__tests__/gen-skill-docs.test.mjs +36 -7
  169. package/scripts/__tests__/keyword-detector.test.mjs +77 -28
  170. package/scripts/__tests__/mcp-guard-engine.test.mjs +58 -20
  171. package/scripts/__tests__/remote-spawn-transfer.test.mjs +30 -19
  172. package/scripts/__tests__/remote-spawn.test.mjs +10 -4
  173. package/scripts/__tests__/session-start-fast.test.mjs +36 -0
  174. package/scripts/__tests__/skill-template.test.mjs +98 -50
  175. package/scripts/__tests__/smoke.test.mjs +1 -1
  176. package/scripts/__tests__/spawn-trace.test.mjs +102 -0
  177. package/scripts/__tests__/tfx-doctor-diagnose.test.mjs +48 -0
  178. package/scripts/cache-doctor.mjs +11 -4
  179. package/scripts/cache-warmup.mjs +96 -37
  180. package/scripts/claudemd-sync.mjs +27 -17
  181. package/scripts/codex-gateway-preflight.mjs +52 -37
  182. package/scripts/codex-mcp-gateway-sync.mjs +59 -39
  183. package/scripts/config-audit.mjs +232 -0
  184. package/scripts/convert-to-tmpl.mjs +54 -0
  185. package/scripts/cross-review-gate.mjs +35 -12
  186. package/scripts/cross-review-tracker.mjs +21 -8
  187. package/scripts/demo.mjs +35 -17
  188. package/scripts/doctor-diagnose.mjs +284 -0
  189. package/scripts/gen-skill-docs.mjs +7 -2
  190. package/scripts/gen-skill-manifest.mjs +2 -1
  191. package/scripts/headless-guard.mjs +86 -48
  192. package/scripts/hub-ensure.mjs +139 -120
  193. package/scripts/keyword-detector.mjs +293 -272
  194. package/scripts/keyword-rules-expander.mjs +538 -521
  195. package/scripts/lib/claudemd-scanner.mjs +6 -1
  196. package/scripts/lib/context.mjs +3 -3
  197. package/scripts/lib/cross-review-utils.mjs +6 -3
  198. package/scripts/lib/env-probe.mjs +47 -28
  199. package/scripts/lib/gemini-profiles.mjs +44 -10
  200. package/scripts/lib/handoff.mjs +33 -17
  201. package/scripts/lib/hook-utils.mjs +8 -6
  202. package/scripts/lib/keyword-rules.mjs +43 -19
  203. package/scripts/lib/logger.mjs +24 -24
  204. package/scripts/lib/mcp-filter.mjs +377 -239
  205. package/scripts/lib/mcp-guard-engine.mjs +194 -79
  206. package/scripts/lib/mcp-manifest.mjs +23 -13
  207. package/scripts/lib/mcp-server-catalog.mjs +355 -118
  208. package/scripts/lib/psmux-info.mjs +11 -6
  209. package/scripts/lib/remote-spawn-transfer.mjs +44 -14
  210. package/scripts/lib/skill-template.mjs +30 -7
  211. package/scripts/mcp-check.mjs +58 -39
  212. package/scripts/mcp-gateway-config.mjs +83 -39
  213. package/scripts/mcp-gateway-ensure.mjs +43 -35
  214. package/scripts/mcp-gateway-integration-test.mjs +70 -58
  215. package/scripts/mcp-gateway-start.mjs +126 -60
  216. package/scripts/mcp-gateway-verify.mjs +24 -22
  217. package/scripts/mcp-safety-guard.mjs +44 -11
  218. package/scripts/notion-read.mjs +669 -554
  219. package/scripts/pack.mjs +94 -89
  220. package/scripts/preflight-cache.mjs +27 -10
  221. package/scripts/preinstall.mjs +42 -13
  222. package/scripts/remote-spawn.mjs +309 -94
  223. package/scripts/run.cjs +8 -5
  224. package/scripts/session-spawn-helper.mjs +130 -39
  225. package/scripts/session-stale-cleanup.mjs +123 -0
  226. package/scripts/setup.mjs +941 -492
  227. package/scripts/test-lock.mjs +20 -7
  228. package/scripts/test-tfx-route-no-claude-native.mjs +61 -57
  229. package/scripts/tfx-batch-stats.mjs +117 -96
  230. package/scripts/tfx-gate-activate.mjs +11 -4
  231. package/scripts/tfx-route-post.mjs +87 -20
  232. package/scripts/tfx-route-worker.mjs +57 -51
  233. package/scripts/tfx-route.sh +41 -124
  234. package/scripts/tmp-cleanup.mjs +21 -7
  235. package/scripts/token-snapshot.mjs +204 -85
  236. package/skills/.omc/state/idle-notif-cooldown.json +1 -1
  237. package/skills/.omc/state/last-tool-error.json +1 -1
  238. package/skills/.omc/state/subagent-tracking.json +1 -1
  239. package/skills/_templates/base.md +1 -6
  240. package/skills/merge-worktree/SKILL.md.tmpl +144 -0
  241. package/skills/shared/telemetry-segment.md +6 -0
  242. package/skills/star-prompt/SKILL.md.tmpl +222 -0
  243. package/skills/tfx-analysis/SKILL.md.tmpl +107 -0
  244. package/skills/tfx-analysis/skill.json +1 -6
  245. package/skills/tfx-auto/SKILL.md +1 -0
  246. package/skills/{tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md → tfx-auto-codex/SKILL.md.tmpl} +33 -4
  247. package/skills/tfx-auto-codex/skill.json +1 -3
  248. package/skills/tfx-autopilot/SKILL.md.tmpl +116 -0
  249. package/skills/tfx-autopilot/skill.json +1 -5
  250. package/skills/tfx-autoresearch/SKILL.md.tmpl +136 -0
  251. package/skills/tfx-autoroute/SKILL.md.tmpl +189 -0
  252. package/skills/tfx-autoroute/skill.json +1 -7
  253. package/skills/tfx-codex/SKILL.md +1 -0
  254. package/skills/tfx-codex/skill.json +1 -3
  255. package/skills/tfx-codex-swarm/SKILL.md.tmpl +16 -0
  256. package/skills/tfx-codex-swarm/evals/evals.json +1 -1
  257. package/skills/tfx-codex-swarm/skill.json +1 -4
  258. package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +54 -12
  259. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +35 -7
  260. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +35 -7
  261. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +25 -5
  262. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +25 -5
  263. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +20 -4
  264. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +16 -4
  265. package/skills/tfx-consensus/SKILL.md.tmpl +146 -0
  266. package/skills/tfx-debate/SKILL.md.tmpl +192 -0
  267. package/skills/tfx-debate/skill.json +1 -7
  268. package/skills/tfx-deep-analysis/SKILL.md.tmpl +228 -0
  269. package/skills/tfx-deep-analysis/skill.json +1 -5
  270. package/skills/tfx-deep-interview/SKILL.md.tmpl +203 -0
  271. package/skills/tfx-deep-plan/SKILL.md.tmpl +282 -0
  272. package/skills/tfx-deep-qa/SKILL.md.tmpl +165 -0
  273. package/skills/tfx-deep-qa/skill.json +1 -6
  274. package/skills/tfx-deep-research/SKILL.md.tmpl +217 -0
  275. package/skills/tfx-deep-review/SKILL.md.tmpl +179 -0
  276. package/skills/tfx-doctor/SKILL.md +21 -0
  277. package/skills/tfx-doctor/SKILL.md.tmpl +172 -0
  278. package/skills/tfx-doctor/skill.json +1 -3
  279. package/skills/tfx-find/SKILL.md +1 -0
  280. package/skills/tfx-forge/SKILL.md.tmpl +187 -0
  281. package/skills/tfx-fullcycle/SKILL.md.tmpl +286 -0
  282. package/skills/tfx-fullcycle/skill.json +1 -6
  283. package/skills/{tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md → tfx-gemini/SKILL.md.tmpl} +16 -7
  284. package/skills/tfx-gemini/skill.json +1 -3
  285. package/skills/tfx-hooks/SKILL.md.tmpl +216 -0
  286. package/skills/tfx-hooks/skill.json +1 -3
  287. package/skills/tfx-hub/SKILL.md.tmpl +212 -0
  288. package/skills/tfx-hub/skill.json +1 -3
  289. package/skills/tfx-index/SKILL.md +1 -0
  290. package/skills/tfx-index/skill.json +1 -6
  291. package/skills/tfx-interview/SKILL.md.tmpl +285 -0
  292. package/skills/tfx-multi/SKILL.md.tmpl +183 -0
  293. package/skills/tfx-multi/skill.json +1 -3
  294. package/skills/tfx-panel/SKILL.md.tmpl +189 -0
  295. package/skills/tfx-panel/skill.json +1 -7
  296. package/skills/tfx-persist/SKILL.md.tmpl +270 -0
  297. package/skills/tfx-persist/skill.json +1 -7
  298. package/skills/tfx-plan/SKILL.md +1 -0
  299. package/skills/tfx-plan/skill.json +1 -6
  300. package/skills/tfx-profile/SKILL.md.tmpl +239 -0
  301. package/skills/tfx-profile/skill.json +1 -3
  302. package/skills/tfx-prune/SKILL.md.tmpl +200 -0
  303. package/skills/tfx-prune/skill.json +1 -7
  304. package/skills/tfx-psmux-rules/SKILL.md.tmpl +326 -0
  305. package/skills/tfx-psmux-rules/skill.json +1 -4
  306. package/skills/tfx-qa/SKILL.md +1 -0
  307. package/skills/tfx-qa/skill.json +1 -6
  308. package/skills/tfx-ralph/SKILL.md.tmpl +28 -0
  309. package/skills/tfx-ralph/skill.json +1 -4
  310. package/skills/tfx-remote-setup/SKILL.md.tmpl +576 -0
  311. package/skills/tfx-remote-setup/skill.json +1 -3
  312. package/skills/tfx-remote-spawn/SKILL.md.tmpl +263 -0
  313. package/skills/tfx-remote-spawn/references/hosts.json +16 -16
  314. package/skills/tfx-remote-spawn/skill.json +1 -4
  315. package/skills/tfx-research/SKILL.md +1 -0
  316. package/skills/tfx-review/SKILL.md +1 -0
  317. package/skills/tfx-review/skill.json +1 -6
  318. package/skills/tfx-setup/SKILL.md.tmpl +504 -0
  319. package/skills/tfx-setup/skill.json +1 -3
  320. package/skills/tfx-swarm/SKILL.md +22 -0
  321. package/skills/tfx-swarm/SKILL.md.tmpl +218 -0
  322. package/tui/codex-profile.mjs +457 -0
  323. package/tui/core.mjs +266 -0
  324. package/tui/doctor.mjs +375 -0
  325. package/tui/gemini-profile.mjs +299 -0
  326. package/tui/monitor-data.mjs +152 -0
  327. package/tui/monitor.mjs +339 -0
  328. package/tui/setup.mjs +533 -0
  329. package/CLAUDE.md +0 -193
  330. package/references/hosts.json +0 -33
  331. package/skills/tfx-workspace/async-tests/run-tests.sh +0 -203
  332. package/skills/tfx-workspace/evals/evals.json +0 -79
  333. package/skills/tfx-workspace/iteration-1/benchmark.json +0 -162
  334. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +0 -11
  335. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +0 -9
  336. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +0 -154
  337. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +0 -5
  338. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +0 -9
  339. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +0 -126
  340. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +0 -5
  341. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +0 -11
  342. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +0 -9
  343. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +0 -119
  344. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +0 -5
  345. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +0 -9
  346. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +0 -115
  347. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +0 -5
  348. package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +0 -10
  349. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +0 -8
  350. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +0 -86
  351. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +0 -5
  352. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +0 -8
  353. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +0 -81
  354. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +0 -5
  355. package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +0 -12
  356. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +0 -10
  357. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +0 -316
  358. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +0 -5
  359. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +0 -10
  360. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +0 -352
  361. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +0 -5
  362. package/skills/tfx-workspace/iteration-1/review.html +0 -1325
  363. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +0 -12
  364. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +0 -10
  365. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +0 -97
  366. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +0 -5
  367. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +0 -10
  368. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +0 -94
  369. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +0 -5
  370. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +0 -12
  371. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +0 -10
  372. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +0 -209
  373. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +0 -5
  374. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +0 -10
  375. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +0 -193
  376. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +0 -5
  377. package/skills/tfx-workspace/iteration-2/benchmark.json +0 -62
  378. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +0 -13
  379. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +0 -11
  380. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +0 -382
  381. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +0 -5
  382. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +0 -11
  383. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +0 -333
  384. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +0 -5
  385. package/skills/tfx-workspace/iteration-2/review.html +0 -1325
  386. package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +0 -217
  387. package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +0 -65
  388. package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +0 -94
  389. package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +0 -133
  390. package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +0 -426
  391. package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +0 -101
@@ -23,7 +23,12 @@ const DEFAULT_TFX_TEMPLATE = [
23
23
  ].join("\n");
24
24
 
25
25
  const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
26
- const DEFAULT_TEMPLATE_PATH = join(SCRIPT_DIR, "..", "templates", "claudemd-tfx-section.md");
26
+ const DEFAULT_TEMPLATE_PATH = join(
27
+ SCRIPT_DIR,
28
+ "..",
29
+ "templates",
30
+ "claudemd-tfx-section.md",
31
+ );
27
32
 
28
33
  function resolveVersion(version) {
29
34
  if (version) return version;
@@ -19,10 +19,10 @@
19
19
  * log.info('result.processed'); // correlationId 자동 포함
20
20
  * }
21
21
  */
22
- import { AsyncLocalStorage } from 'node:async_hooks';
23
- import { randomUUID } from 'node:crypto';
22
+ import { AsyncLocalStorage } from "node:async_hooks";
23
+ import { randomUUID } from "node:crypto";
24
24
 
25
- import { logger } from './logger.mjs';
25
+ import { logger } from "./logger.mjs";
26
26
 
27
27
  /** @type {AsyncLocalStorage<{logger: import('pino').Logger, correlationId: string}>} */
28
28
  export const asyncLocalStorage = new AsyncLocalStorage();
@@ -28,8 +28,10 @@ export function nowSec() {
28
28
  }
29
29
 
30
30
  export function resolveBaseDir(payload) {
31
- if (typeof payload?.cwd === "string" && payload.cwd.trim()) return payload.cwd;
32
- if (typeof payload?.directory === "string" && payload.directory.trim()) return payload.directory;
31
+ if (typeof payload?.cwd === "string" && payload.cwd.trim())
32
+ return payload.cwd;
33
+ if (typeof payload?.directory === "string" && payload.directory.trim())
34
+ return payload.directory;
33
35
  return process.cwd();
34
36
  }
35
37
 
@@ -38,7 +40,8 @@ export function shouldTrackPath(filePath) {
38
40
 
39
41
  const lower = filePath.toLowerCase();
40
42
  if (lower.startsWith(".omc/") || lower.startsWith(".claude/")) return false;
41
- if (lower === "package-lock.json" || lower.endsWith("/package-lock.json")) return false;
43
+ if (lower === "package-lock.json" || lower.endsWith("/package-lock.json"))
44
+ return false;
42
45
  if (/\.(md|lock|yml|yaml)$/i.test(lower)) return false;
43
46
  return true;
44
47
  }
@@ -1,9 +1,9 @@
1
+ import { execSync, spawn } from "node:child_process";
2
+ import { createHash } from "node:crypto";
1
3
  import { existsSync, readFileSync } from "node:fs";
2
- import { join, dirname } from "node:path";
3
4
  import { homedir } from "node:os";
4
- import { execSync, spawn } from "node:child_process";
5
+ import { dirname, join } from "node:path";
5
6
  import { fileURLToPath } from "node:url";
6
- import { createHash } from "node:crypto";
7
7
  import { whichCommand, whichCommandAsync } from "../../hub/platform.mjs";
8
8
 
9
9
  const DEFAULT_STATUS_URL = "http://127.0.0.1:27888/status";
@@ -73,10 +73,13 @@ function normalizeCliNames(names) {
73
73
  }
74
74
 
75
75
  function mapCliResults(names, results) {
76
- return names.reduce((acc, name, index) => ({
77
- ...acc,
78
- [name]: results[index],
79
- }), {});
76
+ return names.reduce(
77
+ (acc, name, index) => ({
78
+ ...acc,
79
+ [name]: results[index],
80
+ }),
81
+ {},
82
+ );
80
83
  }
81
84
 
82
85
  async function resolveCliProbe(name, options = {}) {
@@ -115,13 +118,18 @@ export function checkCliSync(name, options = {}) {
115
118
  const cached = readCachedCliResult(cliName);
116
119
  if (cached) return cached;
117
120
 
118
- const path = (options.whichCommandFn || whichCommand)(cliName, buildCliProbeOptions(options));
121
+ const path = (options.whichCommandFn || whichCommand)(
122
+ cliName,
123
+ buildCliProbeOptions(options),
124
+ );
119
125
  return storeCliResult(cliName, toCliResult(path));
120
126
  }
121
127
 
122
128
  export async function probeClis(names, options = {}) {
123
129
  const cliNames = normalizeCliNames(names);
124
- const results = await Promise.all(cliNames.map((name) => checkCli(name, options)));
130
+ const results = await Promise.all(
131
+ cliNames.map((name) => checkCli(name, options)),
132
+ );
125
133
  return mapCliResults(cliNames, results);
126
134
  }
127
135
 
@@ -137,15 +145,18 @@ export function detectCodexAuthState({
137
145
  } = {}) {
138
146
  try {
139
147
  const authPath = join(homeDir, ".codex", "auth.json");
140
- if (!existsSyncFn(authPath)) return { plan: "unknown", source: "no_auth", fingerprint: "no_auth" };
148
+ if (!existsSyncFn(authPath))
149
+ return { plan: "unknown", source: "no_auth", fingerprint: "no_auth" };
141
150
 
142
151
  const auth = JSON.parse(readFileSyncFn(authPath, "utf8"));
143
152
  if (auth.auth_mode !== "chatgpt") {
144
153
  const fingerprint = createHash("sha256")
145
- .update(JSON.stringify({
146
- auth_mode: auth.auth_mode || "api_key",
147
- has_api_key: Boolean(auth.api_key || auth.apiKey),
148
- }))
154
+ .update(
155
+ JSON.stringify({
156
+ auth_mode: auth.auth_mode || "api_key",
157
+ has_api_key: Boolean(auth.api_key || auth.apiKey),
158
+ }),
159
+ )
149
160
  .digest("hex");
150
161
  return { plan: "api", source: "api_key", fingerprint };
151
162
  }
@@ -156,20 +167,30 @@ export function detectCodexAuthState({
156
167
  plan: "unknown",
157
168
  source: "no_token",
158
169
  fingerprint: createHash("sha256")
159
- .update(JSON.stringify({ auth_mode: auth.auth_mode || "chatgpt", token: null }))
170
+ .update(
171
+ JSON.stringify({
172
+ auth_mode: auth.auth_mode || "chatgpt",
173
+ token: null,
174
+ }),
175
+ )
160
176
  .digest("hex"),
161
177
  };
162
178
  }
163
179
 
164
- const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString());
165
- const plan = payload?.["https://api.openai.com/auth"]?.chatgpt_plan_type || "unknown";
180
+ const payload = JSON.parse(
181
+ Buffer.from(token.split(".")[1], "base64url").toString(),
182
+ );
183
+ const plan =
184
+ payload?.["https://api.openai.com/auth"]?.chatgpt_plan_type || "unknown";
166
185
  const fingerprint = createHash("sha256")
167
- .update(JSON.stringify({
168
- auth_mode: auth.auth_mode || "chatgpt",
169
- plan,
170
- sub: payload?.sub || null,
171
- exp: payload?.exp || null,
172
- }))
186
+ .update(
187
+ JSON.stringify({
188
+ auth_mode: auth.auth_mode || "chatgpt",
189
+ plan,
190
+ sub: payload?.sub || null,
191
+ exp: payload?.exp || null,
192
+ }),
193
+ )
173
194
  .digest("hex");
174
195
  return { plan, source: "jwt", fingerprint };
175
196
  } catch {
@@ -205,7 +226,8 @@ export function checkHub({
205
226
  if (!restart) return { ok: false, state: "unreachable", restart: "disabled" };
206
227
 
207
228
  const serverPath = join(pkgRoot, "hub", "server.mjs");
208
- if (!existsSyncFn(serverPath)) return { ok: false, state: "unreachable", restart: "no_server" };
229
+ if (!existsSyncFn(serverPath))
230
+ return { ok: false, state: "unreachable", restart: "no_server" };
209
231
 
210
232
  try {
211
233
  const child = spawnFn(process.execPath, [serverPath], {
@@ -235,7 +257,4 @@ export function checkHub({
235
257
  return { ok: false, state: "unreachable", restart: "timeout" };
236
258
  }
237
259
 
238
- export {
239
- DEFAULT_PKG_ROOT,
240
- DEFAULT_STATUS_URL,
241
- };
260
+ export { DEFAULT_PKG_ROOT, DEFAULT_STATUS_URL };
@@ -1,19 +1,33 @@
1
- import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
1
+ import {
2
+ copyFileSync,
3
+ existsSync,
4
+ mkdirSync,
5
+ readFileSync,
6
+ writeFileSync,
7
+ } from "node:fs";
2
8
  import { homedir } from "node:os";
3
9
  import { join } from "node:path";
4
10
 
5
11
  const DEFAULT_GEMINI_PROFILES = {
6
12
  model: "gemini-3.1-pro-preview",
7
13
  profiles: {
8
- pro31: { model: "gemini-3.1-pro-preview", hint: "3.1 Pro — 플래그십 (1M ctx, 멀티모달)" },
9
- flash3: { model: "gemini-3-flash-preview", hint: "3.0 Flash — 빠른 응답, 비용 효율" },
14
+ pro31: {
15
+ model: "gemini-3.1-pro-preview",
16
+ hint: "3.1 Pro — 플래그십 (1M ctx, 멀티모달)",
17
+ },
18
+ flash3: {
19
+ model: "gemini-3-flash-preview",
20
+ hint: "3.0 Flash — 빠른 응답, 비용 효율",
21
+ },
10
22
  pro25: { model: "gemini-2.5-pro", hint: "2.5 Pro — 안정 (추론 강화)" },
11
23
  flash25: { model: "gemini-2.5-flash", hint: "2.5 Flash — 경량 범용" },
12
24
  lite25: { model: "gemini-2.5-flash-lite", hint: "2.5 Flash Lite — 최경량" },
13
25
  },
14
26
  };
15
27
 
16
- const DEFAULT_PROFILE_COUNT = Object.keys(DEFAULT_GEMINI_PROFILES.profiles).length;
28
+ const DEFAULT_PROFILE_COUNT = Object.keys(
29
+ DEFAULT_GEMINI_PROFILES.profiles,
30
+ ).length;
17
31
 
18
32
  function ensureGeminiProfiles({
19
33
  geminiDir = join(homedir(), ".gemini"),
@@ -23,7 +37,11 @@ function ensureGeminiProfiles({
23
37
  if (!existsSync(geminiDir)) mkdirSync(geminiDir, { recursive: true });
24
38
 
25
39
  if (!existsSync(profilesPath)) {
26
- writeFileSync(profilesPath, JSON.stringify(DEFAULT_GEMINI_PROFILES, null, 2) + "\n", { encoding: "utf8", mode: 0o600 });
40
+ writeFileSync(
41
+ profilesPath,
42
+ JSON.stringify(DEFAULT_GEMINI_PROFILES, null, 2) + "\n",
43
+ { encoding: "utf8", mode: 0o600 },
44
+ );
27
45
  return {
28
46
  ok: true,
29
47
  created: true,
@@ -37,8 +55,14 @@ function ensureGeminiProfiles({
37
55
  try {
38
56
  cfg = JSON.parse(readFileSync(profilesPath, "utf8"));
39
57
  } catch {
40
- try { copyFileSync(profilesPath, profilesPath + `.bak.${Date.now()}`); } catch {}
41
- writeFileSync(profilesPath, JSON.stringify(DEFAULT_GEMINI_PROFILES, null, 2) + "\n", { encoding: "utf8", mode: 0o600 });
58
+ try {
59
+ copyFileSync(profilesPath, profilesPath + `.bak.${Date.now()}`);
60
+ } catch {}
61
+ writeFileSync(
62
+ profilesPath,
63
+ JSON.stringify(DEFAULT_GEMINI_PROFILES, null, 2) + "\n",
64
+ { encoding: "utf8", mode: 0o600 },
65
+ );
42
66
  return {
43
67
  ok: true,
44
68
  created: true,
@@ -49,10 +73,17 @@ function ensureGeminiProfiles({
49
73
  }
50
74
 
51
75
  if (!cfg || typeof cfg !== "object" || Array.isArray(cfg)) cfg = {};
52
- if (!cfg.profiles || typeof cfg.profiles !== "object" || Array.isArray(cfg.profiles)) cfg.profiles = {};
76
+ if (
77
+ !cfg.profiles ||
78
+ typeof cfg.profiles !== "object" ||
79
+ Array.isArray(cfg.profiles)
80
+ )
81
+ cfg.profiles = {};
53
82
 
54
83
  let added = 0;
55
- for (const [name, value] of Object.entries(DEFAULT_GEMINI_PROFILES.profiles)) {
84
+ for (const [name, value] of Object.entries(
85
+ DEFAULT_GEMINI_PROFILES.profiles,
86
+ )) {
56
87
  if (!cfg.profiles[name]) {
57
88
  cfg.profiles[name] = value;
58
89
  added++;
@@ -61,7 +92,10 @@ function ensureGeminiProfiles({
61
92
  if (!cfg.model) cfg.model = DEFAULT_GEMINI_PROFILES.model;
62
93
 
63
94
  if (added > 0) {
64
- writeFileSync(profilesPath, JSON.stringify(cfg, null, 2) + "\n", { encoding: "utf8", mode: 0o600 });
95
+ writeFileSync(profilesPath, JSON.stringify(cfg, null, 2) + "\n", {
96
+ encoding: "utf8",
97
+ mode: 0o600,
98
+ });
65
99
  }
66
100
 
67
101
  return {
@@ -18,7 +18,9 @@ function runCommand(command, cwd, executor = execSync) {
18
18
  }
19
19
 
20
20
  function parseStatusLines(statusText) {
21
- const lines = String(statusText || "").split(/\r?\n/u).filter(Boolean);
21
+ const lines = String(statusText || "")
22
+ .split(/\r?\n/u)
23
+ .filter(Boolean);
22
24
  const changedFiles = [];
23
25
  const status = [];
24
26
 
@@ -28,7 +30,9 @@ function parseStatusLines(statusText) {
28
30
 
29
31
  const rawStatus = normalized.slice(0, 2).trim() || "??";
30
32
  const rawPath = normalized.slice(3).trim();
31
- const filePath = rawPath.includes(" -> ") ? rawPath.split(" -> ").at(-1)?.trim() : rawPath;
33
+ const filePath = rawPath.includes(" -> ")
34
+ ? rawPath.split(" -> ").at(-1)?.trim()
35
+ : rawPath;
32
36
  if (!filePath) continue;
33
37
 
34
38
  changedFiles.push(filePath);
@@ -82,22 +86,30 @@ function formatAheadBehind(value) {
82
86
 
83
87
  export function collectHandoffContext(options = {}) {
84
88
  const cwd = resolve(options.cwd || process.cwd());
85
- const executor = typeof options.commandRunner === "function" ? options.commandRunner : execSync;
89
+ const executor =
90
+ typeof options.commandRunner === "function"
91
+ ? options.commandRunner
92
+ : execSync;
86
93
  const target = options.target === "local" ? "local" : "remote";
87
94
  const decisions = normalizeDecisions(options.decisions, options.decisionFile);
88
95
  const generatedAt = options.generatedAt || new Date().toISOString();
89
96
  const claudeMdPaths = Array.isArray(options.claudeMdPaths)
90
97
  ? options.claudeMdPaths
91
98
  : findAllClaudeMdPaths({
92
- cwd,
93
- homeDir: options.homeDir,
94
- });
99
+ cwd,
100
+ homeDir: options.homeDir,
101
+ });
95
102
 
96
103
  const gitRoot = runCommand("git rev-parse --show-toplevel", cwd, executor);
97
- const branch = runCommand("git rev-parse --abbrev-ref HEAD", cwd, executor) || null;
104
+ const branch =
105
+ runCommand("git rev-parse --abbrev-ref HEAD", cwd, executor) || null;
98
106
  const shortStatus = runCommand("git status --short", cwd, executor);
99
107
  const diffStat = runCommand("git diff --stat --no-color", cwd, executor);
100
- const upstreamRaw = runCommand("git rev-list --left-right --count @{upstream}...HEAD", cwd, executor);
108
+ const upstreamRaw = runCommand(
109
+ "git rev-list --left-right --count @{upstream}...HEAD",
110
+ cwd,
111
+ executor,
112
+ );
101
113
  const parsedStatus = parseStatusLines(shortStatus);
102
114
 
103
115
  return {
@@ -122,15 +134,19 @@ export function buildHandoffPrompt(context) {
122
134
  const upstream = safeContext.upstream
123
135
  ? `ahead ${safeContext.upstream.ahead}, behind ${safeContext.upstream.behind}`
124
136
  : "unknown";
125
- const changedFiles = safeContext.changedFiles.length > 0
126
- ? safeContext.changedFiles.map((file) => `- ${file}`).join("\n")
127
- : "- 변경 파일 없음";
128
- const decisions = safeContext.decisions.length > 0
129
- ? safeContext.decisions.map((decision) => `- ${decision}`).join("\n")
130
- : "- 명시된 결정사항 없음";
131
- const claudeMdList = Array.isArray(safeContext.claudeMdPaths) && safeContext.claudeMdPaths.length > 0
132
- ? safeContext.claudeMdPaths.map((path) => `- ${path}`).join("\n")
133
- : "- 자동 탐지된 CLAUDE.md 없음";
137
+ const changedFiles =
138
+ safeContext.changedFiles.length > 0
139
+ ? safeContext.changedFiles.map((file) => `- ${file}`).join("\n")
140
+ : "- 변경 파일 없음";
141
+ const decisions =
142
+ safeContext.decisions.length > 0
143
+ ? safeContext.decisions.map((decision) => `- ${decision}`).join("\n")
144
+ : "- 명시된 결정사항 없음";
145
+ const claudeMdList =
146
+ Array.isArray(safeContext.claudeMdPaths) &&
147
+ safeContext.claudeMdPaths.length > 0
148
+ ? safeContext.claudeMdPaths.map((path) => `- ${path}`).join("\n")
149
+ : "- 자동 탐지된 CLAUDE.md 없음";
134
150
  const diffStat = safeContext.diffStat || "(diff stat 없음)";
135
151
 
136
152
  return [
@@ -1,10 +1,12 @@
1
1
  export function nudge(message) {
2
- process.stdout.write(JSON.stringify({
3
- hookSpecificOutput: {
4
- hookEventName: "PreToolUse",
5
- additionalContext: message,
6
- },
7
- }));
2
+ process.stdout.write(
3
+ JSON.stringify({
4
+ hookSpecificOutput: {
5
+ hookEventName: "PreToolUse",
6
+ additionalContext: message,
7
+ },
8
+ }),
9
+ );
8
10
  process.exit(0);
9
11
  }
10
12
 
@@ -28,21 +28,31 @@ function normalizeRule(rule) {
28
28
  if (!rule || typeof rule !== "object") return null;
29
29
  if (typeof rule.id !== "string" || !rule.id.trim()) return null;
30
30
  if (!Array.isArray(rule.patterns) || rule.patterns.length === 0) return null;
31
- if (typeof rule.priority !== "number" || !Number.isFinite(rule.priority)) return null;
31
+ if (typeof rule.priority !== "number" || !Number.isFinite(rule.priority))
32
+ return null;
32
33
 
33
34
  const patterns = rule.patterns.map(normalizePattern).filter(Boolean);
34
35
  if (patterns.length === 0) return null;
35
36
 
36
- const skill = typeof rule.skill === "string" && rule.skill.trim() ? rule.skill.trim() : null;
37
- const action = typeof rule.action === "string" && rule.action.trim() ? rule.action.trim() : null;
38
- const mcpRoute = typeof rule.mcp_route === "string" && VALID_MCP_ROUTES.has(rule.mcp_route)
39
- ? rule.mcp_route
40
- : null;
37
+ const skill =
38
+ typeof rule.skill === "string" && rule.skill.trim()
39
+ ? rule.skill.trim()
40
+ : null;
41
+ const action =
42
+ typeof rule.action === "string" && rule.action.trim()
43
+ ? rule.action.trim()
44
+ : null;
45
+ const mcpRoute =
46
+ typeof rule.mcp_route === "string" && VALID_MCP_ROUTES.has(rule.mcp_route)
47
+ ? rule.mcp_route
48
+ : null;
41
49
 
42
50
  if (!skill && !mcpRoute && !action) return null;
43
51
 
44
52
  const supersedes = Array.isArray(rule.supersedes)
45
- ? rule.supersedes.filter((id) => typeof id === "string" && id.trim()).map((id) => id.trim())
53
+ ? rule.supersedes
54
+ .filter((id) => typeof id === "string" && id.trim())
55
+ .map((id) => id.trim())
46
56
  : [];
47
57
 
48
58
  const state = normalizeState(rule.state);
@@ -57,7 +67,7 @@ function normalizeRule(rule) {
57
67
  supersedes,
58
68
  exclusive: rule.exclusive === true,
59
69
  state,
60
- mcp_route: mcpRoute
70
+ mcp_route: mcpRoute,
61
71
  };
62
72
  }
63
73
 
@@ -81,26 +91,40 @@ export function loadRules(rulesPath) {
81
91
 
82
92
  // pattern.source / flags를 RegExp로 컴파일
83
93
  export function compileRules(rules) {
84
- return rules.map((rule) => {
85
- try {
86
- return { ...rule, compiledPatterns: rule.patterns.map((p) => new RegExp(p.source, p.flags)) };
87
- } catch (error) {
88
- logRuleError(`정규식 컴파일 실패: ${rule.id}`, error);
89
- return null;
90
- }
91
- }).filter(Boolean);
94
+ return rules
95
+ .map((rule) => {
96
+ try {
97
+ return {
98
+ ...rule,
99
+ compiledPatterns: rule.patterns.map(
100
+ (p) => new RegExp(p.source, p.flags),
101
+ ),
102
+ };
103
+ } catch (error) {
104
+ logRuleError(`정규식 컴파일 실패: ${rule.id}`, error);
105
+ return null;
106
+ }
107
+ })
108
+ .filter(Boolean);
92
109
  }
93
110
 
94
111
  // 입력 텍스트에서 매칭된 규칙 목록 반환
95
112
  export function matchRules(compiledRules, cleanText) {
96
- if (!Array.isArray(compiledRules) || typeof cleanText !== "string" || !cleanText) {
113
+ if (
114
+ !Array.isArray(compiledRules) ||
115
+ typeof cleanText !== "string" ||
116
+ !cleanText
117
+ ) {
97
118
  return [];
98
119
  }
99
120
 
100
121
  const matches = [];
101
122
 
102
123
  for (const rule of compiledRules) {
103
- if (!Array.isArray(rule.compiledPatterns) || rule.compiledPatterns.length === 0) {
124
+ if (
125
+ !Array.isArray(rule.compiledPatterns) ||
126
+ rule.compiledPatterns.length === 0
127
+ ) {
104
128
  continue;
105
129
  }
106
130
 
@@ -119,7 +143,7 @@ export function matchRules(compiledRules, cleanText) {
119
143
  supersedes: rule.supersedes || [],
120
144
  exclusive: rule.exclusive === true,
121
145
  state: rule.state || null,
122
- mcp_route: rule.mcp_route || null
146
+ mcp_route: rule.mcp_route || null,
123
147
  });
124
148
  }
125
149
 
@@ -27,17 +27,17 @@
27
27
  * error — 작업 실패 (CLI 실행 실패, MCP 연결 끊김)
28
28
  * fatal — 프로세스 위협 (DB 연결 불가, 포트 충돌)
29
29
  */
30
- import pino from 'pino';
30
+ import pino from "pino";
31
31
 
32
- const isDev = process.env.NODE_ENV !== 'production';
32
+ const isDev = process.env.NODE_ENV !== "production";
33
33
 
34
34
  export const logger = pino({
35
- level: process.env.LOG_LEVEL || (isDev ? 'debug' : 'info'),
35
+ level: process.env.LOG_LEVEL || (isDev ? "debug" : "info"),
36
36
 
37
37
  // 모든 로그에 포함되는 기본 필드
38
38
  base: {
39
- service: process.env.SERVICE_NAME || 'triflux',
40
- env: process.env.NODE_ENV || 'development',
39
+ service: process.env.SERVICE_NAME || "triflux",
40
+ env: process.env.NODE_ENV || "development",
41
41
  },
42
42
 
43
43
  // 레벨을 대문자로 출력 (AI 파싱 용이)
@@ -51,18 +51,18 @@ export const logger = pino({
51
51
  // 민감정보 자동 필터링
52
52
  redact: {
53
53
  paths: [
54
- 'password',
55
- 'token',
56
- 'apiKey',
57
- 'secret',
58
- 'authorization',
59
- '*.password',
60
- '*.token',
61
- '*.apiKey',
62
- '*.secret',
63
- 'req.headers.authorization',
64
- 'req.headers.cookie',
65
- 'hubToken',
54
+ "password",
55
+ "token",
56
+ "apiKey",
57
+ "secret",
58
+ "authorization",
59
+ "*.password",
60
+ "*.token",
61
+ "*.apiKey",
62
+ "*.secret",
63
+ "req.headers.authorization",
64
+ "req.headers.cookie",
65
+ "hubToken",
66
66
  ],
67
67
  remove: true,
68
68
  },
@@ -70,11 +70,11 @@ export const logger = pino({
70
70
  // 개발 환경: 컬러 콘솔 출력
71
71
  transport: isDev
72
72
  ? {
73
- target: 'pino-pretty',
73
+ target: "pino-pretty",
74
74
  options: {
75
75
  colorize: true,
76
- translateTime: 'yyyy-mm-dd HH:MM:ss',
77
- ignore: 'pid,hostname',
76
+ translateTime: "yyyy-mm-dd HH:MM:ss",
77
+ ignore: "pid,hostname",
78
78
  },
79
79
  }
80
80
  : undefined,
@@ -92,14 +92,14 @@ export function createModuleLogger(module) {
92
92
  }
93
93
 
94
94
  // 정상 종료 시 버퍼 flush 보장
95
- process.on('uncaughtException', (err) => {
96
- logger.fatal({ err }, 'process.uncaught_exception');
95
+ process.on("uncaughtException", (err) => {
96
+ logger.fatal({ err }, "process.uncaught_exception");
97
97
  logger.flush();
98
98
  process.exit(1);
99
99
  });
100
100
 
101
- process.on('unhandledRejection', (reason) => {
102
- logger.fatal({ reason: String(reason) }, 'process.unhandled_rejection');
101
+ process.on("unhandledRejection", (reason) => {
102
+ logger.fatal({ reason: String(reason) }, "process.unhandled_rejection");
103
103
  logger.flush();
104
104
  process.exit(1);
105
105
  });