triflux 10.0.0 → 10.0.2

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 (426) hide show
  1. package/CLAUDE.md +171 -0
  2. package/README.md +32 -15
  3. package/bin/triflux.mjs +62 -5
  4. package/hooks/agent-route-guard.mjs +109 -0
  5. package/hooks/cross-review-tracker.mjs +122 -0
  6. package/hooks/error-context.mjs +148 -0
  7. package/hooks/hook-adaptive-collector.mjs +86 -0
  8. package/hooks/hook-manager.mjs +365 -0
  9. package/hooks/hook-orchestrator.mjs +312 -0
  10. package/hooks/hook-registry.json +246 -0
  11. package/hooks/hooks.json +89 -0
  12. package/hooks/keyword-rules.json +574 -0
  13. package/hooks/lib/resolve-root.mjs +59 -0
  14. package/hooks/mcp-config-watcher.mjs +80 -0
  15. package/hooks/pipeline-stop.mjs +76 -0
  16. package/hooks/safety-guard.mjs +169 -0
  17. package/hooks/subagent-verifier.mjs +80 -0
  18. package/hub/account-broker.mjs +251 -0
  19. package/hub/adaptive-diagnostic.mjs +323 -0
  20. package/hub/adaptive-inject.mjs +186 -0
  21. package/hub/adaptive-memory.mjs +163 -0
  22. package/hub/adaptive.mjs +143 -0
  23. package/hub/assign-callbacks.mjs +133 -0
  24. package/hub/bridge.mjs +799 -0
  25. package/hub/cli-adapter-base.mjs +280 -0
  26. package/hub/codex-adapter.mjs +199 -0
  27. package/hub/codex-compat.mjs +11 -0
  28. package/hub/codex-preflight.mjs +166 -0
  29. package/hub/delegator/contracts.mjs +37 -0
  30. package/hub/delegator/index.mjs +14 -0
  31. package/hub/delegator/schema/delegator-tools.schema.json +250 -0
  32. package/hub/delegator/service.mjs +307 -0
  33. package/hub/delegator/tool-definitions.mjs +35 -0
  34. package/hub/fullcycle.mjs +96 -0
  35. package/hub/gemini-adapter.mjs +180 -0
  36. package/hub/hitl.mjs +143 -0
  37. package/hub/intent.mjs +193 -0
  38. package/hub/lib/cache-guard.mjs +114 -0
  39. package/hub/lib/known-errors.json +72 -0
  40. package/hub/lib/memory-store.mjs +748 -0
  41. package/hub/lib/process-utils.mjs +361 -0
  42. package/hub/lib/ssh-command.mjs +211 -0
  43. package/hub/lib/ssh-retry.mjs +59 -0
  44. package/hub/lib/uuidv7.mjs +44 -0
  45. package/hub/memory-doctor.mjs +480 -0
  46. package/hub/middleware/request-logger.mjs +161 -0
  47. package/hub/paths.mjs +30 -0
  48. package/hub/pipe.mjs +664 -0
  49. package/hub/pipeline/gates/confidence.mjs +56 -0
  50. package/hub/pipeline/gates/consensus.mjs +94 -0
  51. package/hub/pipeline/gates/index.mjs +5 -0
  52. package/hub/pipeline/gates/selfcheck.mjs +82 -0
  53. package/hub/pipeline/index.mjs +318 -0
  54. package/hub/pipeline/state.mjs +191 -0
  55. package/hub/pipeline/transitions.mjs +124 -0
  56. package/hub/platform.mjs +225 -0
  57. package/hub/public/dashboard.html +355 -0
  58. package/hub/public/tray-icon.ico +0 -0
  59. package/hub/public/tray-icon.png +0 -0
  60. package/hub/quality/deslop.mjs +253 -0
  61. package/hub/reflexion.mjs +372 -0
  62. package/hub/research.mjs +146 -0
  63. package/hub/router.mjs +791 -0
  64. package/hub/routing/complexity.mjs +166 -0
  65. package/hub/routing/index.mjs +117 -0
  66. package/hub/routing/q-learning.mjs +336 -0
  67. package/hub/schema.sql +148 -0
  68. package/hub/server.mjs +1264 -0
  69. package/hub/session-fingerprint.mjs +352 -0
  70. package/hub/state.mjs +258 -0
  71. package/hub/store-adapter.mjs +118 -0
  72. package/hub/store.mjs +857 -0
  73. package/hub/team/agent-map.json +11 -0
  74. package/hub/team/ansi.mjs +379 -0
  75. package/hub/team/backend.mjs +90 -0
  76. package/hub/team/cli/commands/attach.mjs +37 -0
  77. package/hub/team/cli/commands/control.mjs +43 -0
  78. package/hub/team/cli/commands/debug.mjs +74 -0
  79. package/hub/team/cli/commands/focus.mjs +53 -0
  80. package/hub/team/cli/commands/interrupt.mjs +36 -0
  81. package/hub/team/cli/commands/kill.mjs +37 -0
  82. package/hub/team/cli/commands/list.mjs +24 -0
  83. package/hub/team/cli/commands/send.mjs +37 -0
  84. package/hub/team/cli/commands/start/index.mjs +106 -0
  85. package/hub/team/cli/commands/start/parse-args.mjs +130 -0
  86. package/hub/team/cli/commands/start/start-headless.mjs +109 -0
  87. package/hub/team/cli/commands/start/start-in-process.mjs +40 -0
  88. package/hub/team/cli/commands/start/start-mux.mjs +73 -0
  89. package/hub/team/cli/commands/start/start-wt.mjs +69 -0
  90. package/hub/team/cli/commands/status.mjs +87 -0
  91. package/hub/team/cli/commands/stop.mjs +31 -0
  92. package/hub/team/cli/commands/task.mjs +30 -0
  93. package/hub/team/cli/commands/tasks.mjs +13 -0
  94. package/hub/team/cli/help.mjs +42 -0
  95. package/hub/team/cli/index.mjs +41 -0
  96. package/hub/team/cli/manifest.mjs +29 -0
  97. package/hub/team/cli/render.mjs +30 -0
  98. package/hub/team/cli/services/attach-fallback.mjs +54 -0
  99. package/hub/team/cli/services/hub-client.mjs +227 -0
  100. package/hub/team/cli/services/member-selector.mjs +30 -0
  101. package/hub/team/cli/services/native-control.mjs +117 -0
  102. package/hub/team/cli/services/runtime-mode.mjs +62 -0
  103. package/hub/team/cli/services/state-store.mjs +48 -0
  104. package/hub/team/cli/services/task-model.mjs +30 -0
  105. package/hub/team/conductor-mesh-bridge.mjs +121 -0
  106. package/hub/team/conductor.mjs +671 -0
  107. package/hub/team/dashboard-anchor.mjs +14 -0
  108. package/hub/team/dashboard-layout.mjs +33 -0
  109. package/hub/team/dashboard-open.mjs +153 -0
  110. package/hub/team/dashboard.mjs +274 -0
  111. package/hub/team/event-log.mjs +76 -0
  112. package/hub/team/handoff.mjs +303 -0
  113. package/hub/team/headless.mjs +1156 -0
  114. package/hub/team/health-probe.mjs +272 -0
  115. package/hub/team/launcher-template.mjs +95 -0
  116. package/hub/team/lead-control.mjs +104 -0
  117. package/hub/team/native-supervisor.mjs +392 -0
  118. package/hub/team/native.mjs +649 -0
  119. package/hub/team/nativeProxy.mjs +688 -0
  120. package/hub/team/notify.mjs +293 -0
  121. package/hub/team/orchestrator.mjs +161 -0
  122. package/hub/team/pane.mjs +153 -0
  123. package/hub/team/process-cleanup.mjs +342 -0
  124. package/hub/team/psmux.mjs +1354 -0
  125. package/hub/team/remote-probe.mjs +276 -0
  126. package/hub/team/remote-session.mjs +299 -0
  127. package/hub/team/remote-watcher.mjs +478 -0
  128. package/hub/team/routing.mjs +223 -0
  129. package/hub/team/session-sync.mjs +169 -0
  130. package/hub/team/session.mjs +611 -0
  131. package/hub/team/shared.mjs +13 -0
  132. package/hub/team/staleState.mjs +361 -0
  133. package/hub/team/swarm-hypervisor.mjs +589 -0
  134. package/hub/team/swarm-locks.mjs +204 -0
  135. package/hub/team/swarm-planner.mjs +260 -0
  136. package/hub/team/swarm-reconciler.mjs +137 -0
  137. package/hub/team/tui-lite.mjs +380 -0
  138. package/hub/team/tui-remote-adapter.mjs +393 -0
  139. package/hub/team/tui-viewer.mjs +463 -0
  140. package/hub/team/tui.mjs +1449 -0
  141. package/hub/team/worktree-lifecycle.mjs +193 -0
  142. package/hub/team/wt-manager.mjs +407 -0
  143. package/hub/team/wt-templates.json +43 -0
  144. package/hub/team-bridge.mjs +27 -0
  145. package/hub/token-mode.mjs +224 -0
  146. package/hub/tools.mjs +636 -0
  147. package/hub/tray.mjs +376 -0
  148. package/hub/workers/claude-worker.mjs +475 -0
  149. package/hub/workers/codex-mcp.mjs +507 -0
  150. package/hub/workers/delegator-mcp.mjs +1076 -0
  151. package/hub/workers/factory.mjs +21 -0
  152. package/hub/workers/gemini-worker.mjs +374 -0
  153. package/hub/workers/interface.mjs +52 -0
  154. package/hub/workers/worker-utils.mjs +104 -0
  155. package/hud/colors.mjs +88 -0
  156. package/hud/constants.mjs +88 -0
  157. package/hud/context-monitor.mjs +403 -0
  158. package/hud/hud-qos-status.mjs +210 -0
  159. package/hud/providers/claude.mjs +314 -0
  160. package/hud/providers/codex.mjs +151 -0
  161. package/hud/providers/gemini.mjs +320 -0
  162. package/hud/renderers.mjs +442 -0
  163. package/hud/terminal.mjs +140 -0
  164. package/hud/utils.mjs +313 -0
  165. package/mesh/index.mjs +63 -0
  166. package/mesh/mesh-budget.mjs +128 -0
  167. package/mesh/mesh-heartbeat.mjs +100 -0
  168. package/mesh/mesh-protocol.mjs +96 -0
  169. package/mesh/mesh-queue.mjs +165 -0
  170. package/mesh/mesh-registry.mjs +78 -0
  171. package/mesh/mesh-router.mjs +76 -0
  172. package/package.json +8 -1
  173. package/references/hosts.json +33 -0
  174. package/scripts/__tests__/gen-skill-docs.test.mjs +87 -0
  175. package/scripts/__tests__/keyword-detector.test.mjs +234 -0
  176. package/scripts/__tests__/mcp-guard-engine.test.mjs +118 -0
  177. package/scripts/__tests__/remote-spawn-transfer.test.mjs +117 -0
  178. package/scripts/__tests__/remote-spawn.test.mjs +92 -0
  179. package/scripts/__tests__/skill-template.test.mjs +193 -0
  180. package/scripts/__tests__/smoke.test.mjs +34 -0
  181. package/scripts/cache-buildup.mjs +30 -0
  182. package/scripts/cache-doctor.mjs +149 -0
  183. package/scripts/cache-warmup.mjs +557 -0
  184. package/scripts/claudemd-sync.mjs +148 -0
  185. package/scripts/cli-route.sh +3 -0
  186. package/scripts/completions/tfx.bash +47 -0
  187. package/scripts/completions/tfx.fish +44 -0
  188. package/scripts/completions/tfx.zsh +83 -0
  189. package/scripts/cross-review-gate.mjs +126 -0
  190. package/scripts/cross-review-tracker.mjs +238 -0
  191. package/scripts/gen-skill-docs.mjs +111 -0
  192. package/scripts/headless-guard-fast.sh +21 -0
  193. package/scripts/headless-guard.mjs +360 -0
  194. package/scripts/hub-ensure.mjs +120 -0
  195. package/scripts/keyword-detector.mjs +272 -0
  196. package/scripts/keyword-rules-expander.mjs +521 -0
  197. package/scripts/lib/claudemd-scanner.mjs +218 -0
  198. package/scripts/lib/context.mjs +67 -0
  199. package/scripts/lib/cross-review-utils.mjs +51 -0
  200. package/scripts/lib/env-probe.mjs +241 -0
  201. package/scripts/lib/gemini-profiles.mjs +85 -0
  202. package/scripts/lib/handoff.mjs +171 -0
  203. package/scripts/lib/hook-utils.mjs +14 -0
  204. package/scripts/lib/keyword-rules.mjs +166 -0
  205. package/scripts/lib/logger.mjs +105 -0
  206. package/scripts/lib/mcp-filter.mjs +739 -0
  207. package/scripts/lib/mcp-guard-engine.mjs +954 -0
  208. package/scripts/lib/mcp-manifest.mjs +79 -0
  209. package/scripts/lib/mcp-server-catalog.mjs +118 -0
  210. package/scripts/lib/psmux-info.mjs +119 -0
  211. package/scripts/lib/remote-spawn-transfer.mjs +196 -0
  212. package/scripts/lib/skill-template.mjs +326 -0
  213. package/scripts/mcp-check.mjs +237 -0
  214. package/scripts/mcp-cleanup.ps1 +17 -0
  215. package/scripts/mcp-gateway-config.mjs +207 -0
  216. package/scripts/mcp-gateway-ensure.mjs +85 -0
  217. package/scripts/mcp-gateway-integration-test.mjs +228 -0
  218. package/scripts/mcp-gateway-start.mjs +226 -0
  219. package/scripts/mcp-gateway-start.ps1 +141 -0
  220. package/scripts/mcp-gateway-verify.mjs +77 -0
  221. package/scripts/mcp-safety-guard.mjs +44 -0
  222. package/scripts/notion-read.mjs +556 -0
  223. package/scripts/pack.mjs +295 -0
  224. package/scripts/preflight-cache.mjs +69 -0
  225. package/scripts/preinstall.mjs +96 -0
  226. package/scripts/remote-spawn.mjs +1376 -0
  227. package/scripts/run.cjs +79 -0
  228. package/scripts/session-spawn-helper.mjs +185 -0
  229. package/scripts/setup.mjs +1178 -0
  230. package/scripts/test-lock.mjs +71 -0
  231. package/scripts/test-tfx-route-no-claude-native.mjs +57 -0
  232. package/scripts/tfx-batch-stats.mjs +96 -0
  233. package/scripts/tfx-gate-activate.mjs +89 -0
  234. package/scripts/tfx-route-post.mjs +505 -0
  235. package/scripts/tfx-route-worker.mjs +223 -0
  236. package/scripts/tfx-route.sh +2014 -0
  237. package/scripts/tmp-cleanup.mjs +103 -0
  238. package/scripts/token-snapshot.mjs +575 -0
  239. package/skills/tfx-auto/SKILL.md.tmpl +2 -3
  240. package/skills/tfx-autoresearch/SKILL.md +6 -5
  241. package/skills/tfx-codex/SKILL.md.tmpl +2 -3
  242. package/skills/tfx-codex-swarm-workspace/iteration-1/benchmark.json +33 -0
  243. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/eval_metadata.json +42 -0
  244. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/grading.json +11 -0
  245. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/outputs/analysis.md +87 -0
  246. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/outputs/classification.md +35 -0
  247. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/outputs/commands.sh +275 -0
  248. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/outputs/routing.md +56 -0
  249. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/with_skill/timing.json +5 -0
  250. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/grading.json +11 -0
  251. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/outputs/analysis.md +92 -0
  252. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/outputs/classification.md +71 -0
  253. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/outputs/commands.sh +264 -0
  254. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/outputs/routing.md +113 -0
  255. package/skills/tfx-codex-swarm-workspace/iteration-1/full-swarm-all-prds/without_skill/timing.json +5 -0
  256. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/eval_metadata.json +32 -0
  257. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/grading.json +9 -0
  258. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/outputs/analysis.md +96 -0
  259. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/outputs/classification.md +38 -0
  260. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/outputs/commands.sh +151 -0
  261. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/outputs/routing.md +51 -0
  262. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/with_skill/timing.json +5 -0
  263. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/grading.json +9 -0
  264. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/outputs/analysis.md +127 -0
  265. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/outputs/classification.md +57 -0
  266. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/outputs/commands.sh +129 -0
  267. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/outputs/routing.md +84 -0
  268. package/skills/tfx-codex-swarm-workspace/iteration-1/implicit-swarm-no-keywords/without_skill/timing.json +5 -0
  269. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/eval_metadata.json +27 -0
  270. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/grading.json +8 -0
  271. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/outputs/analysis.md +98 -0
  272. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/outputs/classification.md +65 -0
  273. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/outputs/commands.sh +123 -0
  274. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/outputs/routing.md +66 -0
  275. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/with_skill/timing.json +5 -0
  276. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/grading.json +8 -0
  277. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/outputs/analysis.md +88 -0
  278. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/outputs/classification.md +40 -0
  279. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/outputs/commands.sh +130 -0
  280. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/outputs/routing.md +61 -0
  281. package/skills/tfx-codex-swarm-workspace/iteration-1/selective-spawn-with-override/without_skill/timing.json +5 -0
  282. package/skills/tfx-deep-interview/SKILL.md +1 -2
  283. package/skills/tfx-plan/SKILL.md.tmpl +2 -3
  284. package/skills/tfx-psmux-rules/SKILL.md +11 -2
  285. package/skills/tfx-qa/SKILL.md.tmpl +2 -3
  286. package/skills/tfx-remote-spawn/SKILL.md +8 -11
  287. package/skills/tfx-research/SKILL.md.tmpl +2 -3
  288. package/skills/tfx-review/SKILL.md.tmpl +2 -3
  289. package/skills/tfx-workspace/async-tests/run-tests.sh +203 -0
  290. package/skills/tfx-workspace/evals/evals.json +79 -0
  291. package/skills/tfx-workspace/iteration-1/benchmark.json +162 -0
  292. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/eval_metadata.json +11 -0
  293. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/grading.json +9 -0
  294. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/outputs/analysis.md +154 -0
  295. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/old_skill/timing.json +5 -0
  296. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/grading.json +9 -0
  297. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/outputs/analysis.md +126 -0
  298. package/skills/tfx-workspace/iteration-1/codex-gemini-remap/with_skill/timing.json +5 -0
  299. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/eval_metadata.json +11 -0
  300. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/grading.json +9 -0
  301. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/outputs/analysis.md +119 -0
  302. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/old_skill/timing.json +5 -0
  303. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/grading.json +9 -0
  304. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/outputs/analysis.md +115 -0
  305. package/skills/tfx-workspace/iteration-1/doctor-diagnosis/with_skill/timing.json +5 -0
  306. package/skills/tfx-workspace/iteration-1/hub-start-sequence/eval_metadata.json +10 -0
  307. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/grading.json +8 -0
  308. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/outputs/analysis.md +86 -0
  309. package/skills/tfx-workspace/iteration-1/hub-start-sequence/old_skill/timing.json +5 -0
  310. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/grading.json +8 -0
  311. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/outputs/analysis.md +81 -0
  312. package/skills/tfx-workspace/iteration-1/hub-start-sequence/with_skill/timing.json +5 -0
  313. package/skills/tfx-workspace/iteration-1/multi-team-creation/eval_metadata.json +12 -0
  314. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/grading.json +10 -0
  315. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/outputs/analysis.md +316 -0
  316. package/skills/tfx-workspace/iteration-1/multi-team-creation/old_skill/timing.json +5 -0
  317. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/grading.json +10 -0
  318. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/outputs/analysis.md +352 -0
  319. package/skills/tfx-workspace/iteration-1/multi-team-creation/with_skill/timing.json +5 -0
  320. package/skills/tfx-workspace/iteration-1/review.html +1325 -0
  321. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/eval_metadata.json +12 -0
  322. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/grading.json +10 -0
  323. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/outputs/analysis.md +97 -0
  324. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/old_skill/timing.json +5 -0
  325. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/grading.json +10 -0
  326. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/outputs/analysis.md +94 -0
  327. package/skills/tfx-workspace/iteration-1/routing-implement-shortcut/with_skill/timing.json +5 -0
  328. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/eval_metadata.json +12 -0
  329. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/grading.json +10 -0
  330. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/outputs/analysis.md +209 -0
  331. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/old_skill/timing.json +5 -0
  332. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/grading.json +10 -0
  333. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/outputs/analysis.md +193 -0
  334. package/skills/tfx-workspace/iteration-1/routing-multi-task-triage/with_skill/timing.json +5 -0
  335. package/skills/tfx-workspace/iteration-2/benchmark.json +62 -0
  336. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/eval_metadata.json +13 -0
  337. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/grading.json +11 -0
  338. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/outputs/analysis.md +382 -0
  339. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/old_skill/timing.json +5 -0
  340. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/grading.json +11 -0
  341. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/outputs/analysis.md +333 -0
  342. package/skills/tfx-workspace/iteration-2/multi-team-creation-refactored/with_skill/timing.json +5 -0
  343. package/skills/tfx-workspace/iteration-2/review.html +1325 -0
  344. package/skills/tfx-workspace/skill-snapshot/tfx-auto/SKILL.md +217 -0
  345. package/skills/{tfx-auto-codex/SKILL.md.tmpl → tfx-workspace/skill-snapshot/tfx-auto-codex/SKILL.md} +3 -31
  346. package/skills/tfx-workspace/skill-snapshot/tfx-codex/SKILL.md +65 -0
  347. package/skills/tfx-workspace/skill-snapshot/tfx-doctor/SKILL.md +94 -0
  348. package/skills/{tfx-gemini/SKILL.md.tmpl → tfx-workspace/skill-snapshot/tfx-gemini/SKILL.md} +6 -14
  349. package/skills/tfx-workspace/skill-snapshot/tfx-hub/SKILL.md +133 -0
  350. package/skills/tfx-workspace/skill-snapshot/tfx-multi/SKILL.md +426 -0
  351. package/skills/tfx-workspace/skill-snapshot/tfx-setup/SKILL.md +101 -0
  352. package/skills/merge-worktree/SKILL.md.tmpl +0 -144
  353. package/skills/shared/arguments-processing.md +0 -2
  354. package/skills/shared/mandatory-rules.md +0 -6
  355. package/skills/shared/telemetry-segment.md +0 -6
  356. package/skills/star-prompt/SKILL.md.tmpl +0 -122
  357. package/skills/tfx-analysis/SKILL.md.tmpl +0 -106
  358. package/skills/tfx-analysis/skill.json +0 -11
  359. package/skills/tfx-auto/skill.json +0 -26
  360. package/skills/tfx-auto-codex/skill.json +0 -8
  361. package/skills/tfx-autopilot/SKILL.md.tmpl +0 -115
  362. package/skills/tfx-autopilot/skill.json +0 -10
  363. package/skills/tfx-autoresearch/SKILL.md.tmpl +0 -135
  364. package/skills/tfx-autoresearch/skill.json +0 -14
  365. package/skills/tfx-autoroute/SKILL.md.tmpl +0 -188
  366. package/skills/tfx-autoroute/skill.json +0 -12
  367. package/skills/tfx-codex/skill.json +0 -8
  368. package/skills/tfx-codex-swarm/SKILL.md.tmpl +0 -16
  369. package/skills/tfx-codex-swarm/skill.json +0 -5
  370. package/skills/tfx-consensus/SKILL.md.tmpl +0 -145
  371. package/skills/tfx-consensus/skill.json +0 -8
  372. package/skills/tfx-debate/SKILL.md.tmpl +0 -191
  373. package/skills/tfx-debate/skill.json +0 -12
  374. package/skills/tfx-deep-analysis/SKILL.md.tmpl +0 -227
  375. package/skills/tfx-deep-analysis/skill.json +0 -10
  376. package/skills/tfx-deep-interview/SKILL.md.tmpl +0 -203
  377. package/skills/tfx-deep-interview/skill.json +0 -12
  378. package/skills/tfx-deep-plan/SKILL.md.tmpl +0 -281
  379. package/skills/tfx-deep-plan/skill.json +0 -13
  380. package/skills/tfx-deep-qa/SKILL.md.tmpl +0 -164
  381. package/skills/tfx-deep-qa/skill.json +0 -11
  382. package/skills/tfx-deep-research/SKILL.md.tmpl +0 -216
  383. package/skills/tfx-deep-research/skill.json +0 -14
  384. package/skills/tfx-deep-review/SKILL.md.tmpl +0 -178
  385. package/skills/tfx-deep-review/skill.json +0 -12
  386. package/skills/tfx-doctor/SKILL.md.tmpl +0 -172
  387. package/skills/tfx-doctor/skill.json +0 -8
  388. package/skills/tfx-find/skill.json +0 -12
  389. package/skills/tfx-forge/SKILL.md.tmpl +0 -187
  390. package/skills/tfx-forge/skill.json +0 -12
  391. package/skills/tfx-fullcycle/SKILL.md.tmpl +0 -285
  392. package/skills/tfx-fullcycle/skill.json +0 -11
  393. package/skills/tfx-gemini/skill.json +0 -8
  394. package/skills/tfx-hooks/SKILL.md.tmpl +0 -216
  395. package/skills/tfx-hooks/skill.json +0 -8
  396. package/skills/tfx-hub/SKILL.md.tmpl +0 -212
  397. package/skills/tfx-hub/skill.json +0 -8
  398. package/skills/tfx-index/skill.json +0 -11
  399. package/skills/tfx-interview/SKILL.md.tmpl +0 -284
  400. package/skills/tfx-interview/skill.json +0 -12
  401. package/skills/tfx-multi/SKILL.md.tmpl +0 -183
  402. package/skills/tfx-multi/skill.json +0 -8
  403. package/skills/tfx-panel/SKILL.md.tmpl +0 -188
  404. package/skills/tfx-panel/skill.json +0 -12
  405. package/skills/tfx-persist/SKILL.md.tmpl +0 -269
  406. package/skills/tfx-persist/skill.json +0 -12
  407. package/skills/tfx-plan/skill.json +0 -11
  408. package/skills/tfx-profile/SKILL.md.tmpl +0 -239
  409. package/skills/tfx-profile/skill.json +0 -8
  410. package/skills/tfx-prune/SKILL.md.tmpl +0 -199
  411. package/skills/tfx-prune/skill.json +0 -12
  412. package/skills/tfx-psmux-rules/SKILL.md.tmpl +0 -317
  413. package/skills/tfx-psmux-rules/skill.json +0 -8
  414. package/skills/tfx-qa/skill.json +0 -11
  415. package/skills/tfx-ralph/SKILL.md.tmpl +0 -27
  416. package/skills/tfx-ralph/skill.json +0 -8
  417. package/skills/tfx-remote-setup/SKILL.md.tmpl +0 -576
  418. package/skills/tfx-remote-setup/skill.json +0 -8
  419. package/skills/tfx-remote-spawn/SKILL.md.tmpl +0 -263
  420. package/skills/tfx-remote-spawn/skill.json +0 -9
  421. package/skills/tfx-research/skill.json +0 -13
  422. package/skills/tfx-review/skill.json +0 -11
  423. package/skills/tfx-setup/SKILL.md.tmpl +0 -380
  424. package/skills/tfx-setup/skill.json +0 -8
  425. package/skills/tfx-swarm/SKILL.md.tmpl +0 -154
  426. package/skills/tfx-swarm/skill.json +0 -5
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ // mcp-gateway-config.mjs — Claude Code MCP stdio↔SSE 전환
3
+ // Usage: node mcp-gateway-config.mjs --enable # stdio → SSE
4
+ // node mcp-gateway-config.mjs --disable # SSE → stdio (복원)
5
+
6
+ import { execSync } from 'node:child_process';
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
9
+ import { join, dirname } from 'node:path';
10
+ import { isServerEnabled } from './lib/mcp-manifest.mjs';
11
+
12
+ const BACKUP_FILE = join(homedir(), '.claude', 'cache', 'mcp-pre-gateway.json');
13
+
14
+ export const GATEWAY_SERVERS = [
15
+ { name: 'context7', port: 8100, stdioCmd: 'cmd /c npx -y @upstash/context7-mcp@latest' },
16
+ { name: 'brave-search', port: 8101, stdioCmd: 'cmd /c npx -y @brave/brave-search-mcp-server' },
17
+ { name: 'exa', port: 8102, stdioCmd: 'cmd /c npx -y exa-mcp-server' },
18
+ { name: 'tavily', port: 8103, stdioCmd: 'cmd /c npx -y tavily-mcp@latest' },
19
+ { name: 'jira', port: 8104, stdioCmd: 'cmd /c npx -y mcp-jira-cloud@latest' },
20
+ { name: 'serena', port: 8105, stdioCmd: 'uvx --from git+https://github.com/oraios/serena serena start-mcp-server' },
21
+ { name: 'notion', port: 8106, stdioCmd: 'cmd /c npx -y @notionhq/notion-mcp-server' },
22
+ { name: 'notion-guest', port: 8107, stdioCmd: 'cmd /c npx -y @notionhq/notion-mcp-server' },
23
+ ];
24
+
25
+ const SKIP_SERVERS = new Set([
26
+ 'playwright',
27
+ 'claude.ai Notion',
28
+ 'plugin:oh-my-claudecode:t',
29
+ ]);
30
+
31
+ // Git Bash에서 /c → C:/ 경로 변환 방지
32
+ const EXEC_ENV = { ...process.env, MSYS_NO_PATHCONV: '1' };
33
+
34
+ function run(cmd) {
35
+ try {
36
+ execSync(cmd, { stdio: 'pipe', encoding: 'utf8', timeout: 15000, env: EXEC_ENV });
37
+ return true;
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ function removeMcp(name) {
44
+ run(`claude mcp remove "${name}" -s user`);
45
+ run(`claude mcp remove "${name}" -s local`);
46
+ }
47
+
48
+ // ── 스냅샷: enable 전 기존 MCP 설정 백업 ──
49
+
50
+ function captureCurrentMcpState() {
51
+ const servers = {};
52
+ for (const { name } of GATEWAY_SERVERS) {
53
+ if (SKIP_SERVERS.has(name)) continue;
54
+ // claude mcp get으로 현재 등록 상태 확인
55
+ try {
56
+ const out = execSync(`claude mcp get "${name}" -s user`, {
57
+ stdio: 'pipe', encoding: 'utf8', timeout: 5000, env: EXEC_ENV,
58
+ }).trim();
59
+ servers[name] = { scope: 'user', raw: out };
60
+ } catch {
61
+ // user에 없으면 local 확인
62
+ try {
63
+ const out = execSync(`claude mcp get "${name}" -s local`, {
64
+ stdio: 'pipe', encoding: 'utf8', timeout: 5000, env: EXEC_ENV,
65
+ }).trim();
66
+ servers[name] = { scope: 'local', raw: out };
67
+ } catch {
68
+ servers[name] = null; // 기존에 없었음
69
+ }
70
+ }
71
+ }
72
+ return servers;
73
+ }
74
+
75
+ function saveBackup(servers) {
76
+ const dir = dirname(BACKUP_FILE);
77
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
78
+ const backup = { captured_at: new Date().toISOString(), servers };
79
+ writeFileSync(BACKUP_FILE, JSON.stringify(backup, null, 2));
80
+ console.log(` [BACKUP] ${BACKUP_FILE}`);
81
+ }
82
+
83
+ function loadBackup() {
84
+ if (!existsSync(BACKUP_FILE)) return null;
85
+ try {
86
+ return JSON.parse(readFileSync(BACKUP_FILE, 'utf8'));
87
+ } catch { return null; }
88
+ }
89
+
90
+ // ── enable: 스냅샷 → remove → SSE add (실패 시 rollback) ──
91
+
92
+ function enableSse() {
93
+ console.log('Switching MCP servers to SSE mode...\n');
94
+
95
+ // 1) 현재 상태 스냅샷
96
+ const snapshot = captureCurrentMcpState();
97
+ saveBackup(snapshot);
98
+
99
+ let ok = 0;
100
+ let fail = 0;
101
+
102
+ for (const { name, port } of GATEWAY_SERVERS) {
103
+ if (SKIP_SERVERS.has(name)) continue;
104
+ if (!isServerEnabled(name)) {
105
+ console.log(` [SKIP] ${name} — manifest에서 비활성`);
106
+ continue;
107
+ }
108
+
109
+ removeMcp(name);
110
+ const url = `http://localhost:${port}/sse`;
111
+ const success = run(`claude mcp add --transport sse -s user "${name}" ${url}`);
112
+
113
+ if (success) {
114
+ console.log(` [SSE] ${name} → ${url}`);
115
+ ok++;
116
+ } else {
117
+ // add 실패 → 원본 복원 시도
118
+ console.error(` [FAIL] ${name} — rollback 시도`);
119
+ const orig = snapshot[name];
120
+ if (orig) {
121
+ // H1 fix: orig.raw를 shell-escape하여 injection 방지
122
+ const safeRaw = (orig.raw || '').replace(/[;`$(){}|&<>]/g, '');
123
+ const restored = safeRaw ? run(`claude mcp add "${name}" -s ${orig.scope} -- ${safeRaw}`) : false;
124
+ console.error(` [ROLLBACK] ${name}: ${restored ? 'ok' : 'FAIL'}`);
125
+ }
126
+ fail++;
127
+ }
128
+ }
129
+
130
+ console.log(`\nDone: ${ok} switched, ${fail} failed`);
131
+ }
132
+
133
+ // ── disable: 백업에서 서버별 원복 ──
134
+
135
+ function disableSse() {
136
+ console.log('Restoring MCP servers from backup...\n');
137
+ const backup = loadBackup();
138
+
139
+ // C1 fix: 백업 없으면 전체 삭제 방지
140
+ if (!backup) {
141
+ console.error('No backup found — cannot restore. Run --enable first to create a backup.');
142
+ process.exit(1);
143
+ }
144
+
145
+ let ok = 0;
146
+ let fail = 0;
147
+
148
+ for (const { name, stdioCmd } of GATEWAY_SERVERS) {
149
+ if (SKIP_SERVERS.has(name)) continue;
150
+
151
+ const orig = backup.servers?.[name];
152
+
153
+ if (orig === null || orig === undefined) {
154
+ // 기존에 없었던 서버 → triflux가 추가한 것 → remove만
155
+ removeMcp(name);
156
+ console.log(` [REMOVE] ${name} — triflux가 추가한 서버, 원본 없음`);
157
+ ok++;
158
+ continue;
159
+ }
160
+
161
+ // H2 fix: 백업의 scope/raw를 사용하여 원본 복원, fallback으로 stdioCmd
162
+ removeMcp(name);
163
+ const restoreScope = orig.scope || 'user';
164
+ const restoreCmd = orig.raw && orig.raw.trim() ? orig.raw.trim() : stdioCmd;
165
+ const success = run(`claude mcp add "${name}" -s ${restoreScope} -- ${restoreCmd}`);
166
+
167
+ if (success) {
168
+ console.log(` [RESTORE] ${name} → scope=${restoreScope}`);
169
+ ok++;
170
+ } else {
171
+ // fallback: stdioCmd로 재시도
172
+ const fallback = run(`claude mcp add "${name}" -s user -- ${stdioCmd}`);
173
+ if (fallback) {
174
+ console.log(` [FALLBACK] ${name} → stdio (원본 복원 실패, 기본값 사용)`);
175
+ ok++;
176
+ } else {
177
+ console.error(` [FAIL] ${name}`);
178
+ fail++;
179
+ }
180
+ }
181
+ }
182
+
183
+ console.log(`\nDone: ${ok} restored, ${fail} failed`);
184
+ console.log(`Backup preserved at: ${BACKUP_FILE}`);
185
+ }
186
+
187
+ function printUsage() {
188
+ console.log(`Usage: node mcp-gateway-config.mjs [--enable|--disable]
189
+
190
+ --enable Switch Claude Code MCP servers from stdio to SSE (supergateway)
191
+ --disable Restore Claude Code MCP servers to original stdio mode
192
+
193
+ Servers managed: ${GATEWAY_SERVERS.map((s) => s.name).join(', ')}
194
+ Servers skipped: ${[...SKIP_SERVERS].join(', ')}`);
195
+ }
196
+
197
+ // ── main ──
198
+ const flag = process.argv[2];
199
+
200
+ if (flag === '--enable') {
201
+ enableSse();
202
+ } else if (flag === '--disable') {
203
+ disableSse();
204
+ } else {
205
+ printUsage();
206
+ process.exit(flag ? 1 : 0);
207
+ }
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ // mcp-gateway-ensure.mjs — SessionStart 훅에서 supergateway MCP 서비스 보장
3
+ // hub-ensure.mjs 패턴을 따름. 가볍게 헬스체크만 수행하고 필요시 기동.
4
+
5
+ import { existsSync, readFileSync } from 'node:fs';
6
+ import { join, dirname } from 'node:path';
7
+ import { execSync } from 'node:child_process';
8
+ import { tmpdir } from 'node:os';
9
+ import { fileURLToPath } from 'node:url';
10
+
11
+ const PLUGIN_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
12
+ const PID_FILE = join(tmpdir(), 'tfx-gateway-pids.json');
13
+ const PROBE_PORT = 8100; // context7 — 첫 번째 게이트웨이 포트로 alive 프로브
14
+ const PROBE_TIMEOUT_MS = 1500;
15
+ const STARTUP_WAIT_MS = 4000;
16
+ const POLL_INTERVAL_MS = 500;
17
+
18
+ /**
19
+ * 단일 포트 /healthz 프로브로 게이트웨이 클러스터 alive 판정.
20
+ * 모든 포트를 체크하면 hook timeout(8s)에 걸리므로 대표 포트 1개만 확인.
21
+ */
22
+ async function isGatewayAlive() {
23
+ try {
24
+ const res = await fetch(`http://127.0.0.1:${PROBE_PORT}/healthz`, {
25
+ signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
26
+ });
27
+ return res.ok;
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ /** 매니페스트 파일 존재 여부로 gateway 설치 판정 (빠른 경로) */
34
+ function hasManifest() {
35
+ return existsSync(PID_FILE);
36
+ }
37
+
38
+ /** mcp-gateway-start.mjs를 독립 프로세스로 기동 */
39
+ function startGateway() {
40
+ const scriptPath = join(PLUGIN_ROOT, 'scripts', 'mcp-gateway-start.mjs');
41
+ if (!existsSync(scriptPath)) return false;
42
+
43
+ try {
44
+ // PowerShell Start-Process: Windows Job Object에서 벗어나 부모 종료 후 생존
45
+ execSync(
46
+ `powershell -NoProfile -Command "Start-Process -WindowStyle Hidden -FilePath '${process.execPath}' -ArgumentList '${scriptPath.replaceAll("'", "''")}'"`
47
+ , { stdio: 'ignore', timeout: 10000 });
48
+ return true;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /** 게이트웨이 기동 후 프로브 포트 ready 대기 */
55
+ async function waitForGatewayReady(maxWaitMs = STARTUP_WAIT_MS) {
56
+ const deadline = Date.now() + maxWaitMs;
57
+ while (Date.now() < deadline) {
58
+ if (await isGatewayAlive()) return true;
59
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
60
+ }
61
+ return false;
62
+ }
63
+
64
+ // ── main ──
65
+
66
+ // 빠른 경로: 매니페스트 존재 + 프로브 포트 살아있으면 즉시 OK
67
+ if (hasManifest() && await isGatewayAlive()) {
68
+ process.stdout.write('gateway: ok');
69
+ process.exit(0);
70
+ }
71
+
72
+ // 매니페스트 없으면 gateway가 설정되지 않은 상태 — 조용히 스킵
73
+ if (!hasManifest()) {
74
+ process.stdout.write('gateway: not configured');
75
+ process.exit(0);
76
+ }
77
+
78
+ // 느린 경로: 게이트웨이 기동 시도
79
+ const started = startGateway();
80
+ if (started) {
81
+ const ready = await waitForGatewayReady();
82
+ process.stdout.write(ready ? 'gateway: ok' : 'gateway: starting');
83
+ } else {
84
+ process.stderr.write('[gateway-ensure] start failed');
85
+ }
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env node
2
+ // mcp-gateway-integration-test.mjs — P0 integration test for MCP Gateway
3
+ // Usage: node scripts/mcp-gateway-integration-test.mjs
4
+
5
+ import { execSync } from 'node:child_process';
6
+ import { join, dirname } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const SCRIPTS_DIR = dirname(fileURLToPath(import.meta.url));
10
+ const START_SCRIPT = join(SCRIPTS_DIR, 'mcp-gateway-start.mjs');
11
+ const CONFIG_SCRIPT = join(SCRIPTS_DIR, 'mcp-gateway-config.mjs');
12
+
13
+ const HEALTH_TIMEOUT_MS = 3000;
14
+ const STARTUP_WAIT_MS = 12000;
15
+ const POLL_INTERVAL_MS = 500;
16
+
17
+ const SERVERS = [
18
+ { name: 'context7', port: 8100 },
19
+ { name: 'brave-search', port: 8101 },
20
+ { name: 'exa', port: 8102 },
21
+ { name: 'tavily', port: 8103 },
22
+ { name: 'jira', port: 8104 },
23
+ { name: 'serena', port: 8105 },
24
+ { name: 'notion', port: 8106 },
25
+ { name: 'notion-guest', port: 8107 },
26
+ ];
27
+
28
+ // ── utilities ──
29
+
30
+ function sleep(ms) {
31
+ return new Promise((r) => setTimeout(r, ms));
32
+ }
33
+
34
+ async function checkHealth(port) {
35
+ try {
36
+ const res = await fetch(`http://127.0.0.1:${port}/healthz`, {
37
+ signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),
38
+ });
39
+ return res.ok;
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
44
+
45
+ function runScript(scriptPath, ...args) {
46
+ execSync(`node "${scriptPath}" ${args.join(' ')}`, {
47
+ stdio: 'inherit',
48
+ timeout: 30000,
49
+ env: { ...process.env, MSYS_NO_PATHCONV: '1' },
50
+ });
51
+ }
52
+
53
+ function countSupergateways() {
54
+ try {
55
+ // Write the query as a PS1 file to avoid shell quoting issues
56
+ const ps1 = [
57
+ `$procs = Get-CimInstance Win32_Process -Filter "Name='node.exe' OR Name='cmd.exe'"`,
58
+ `$hits = $procs | Where-Object { $_.CommandLine -match 'supergateway' }`,
59
+ `Write-Output $hits.Count`,
60
+ ].join('\n');
61
+ const out = execSync(
62
+ `powershell -NoProfile -Command "${ps1.replace(/\n/g, '; ')}"`,
63
+ { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'ignore'] },
64
+ );
65
+ return parseInt(out.trim(), 10) || 0;
66
+ } catch {
67
+ return 0;
68
+ }
69
+ }
70
+
71
+ // ── result tracking ──
72
+
73
+ const results = [];
74
+ let passed = 0;
75
+ let failed = 0;
76
+
77
+ function pass(label) {
78
+ console.log(` [PASS] ${label}`);
79
+ results.push({ label, ok: true });
80
+ passed++;
81
+ }
82
+
83
+ function fail(label, detail = '') {
84
+ const msg = detail ? `${label} — ${detail}` : label;
85
+ console.log(` [FAIL] ${msg}`);
86
+ results.push({ label, ok: false, detail });
87
+ failed++;
88
+ }
89
+
90
+ function printSummary() {
91
+ console.log('\n' + '='.repeat(56));
92
+ console.log('Integration Test Summary');
93
+ console.log('='.repeat(56));
94
+ for (const r of results) {
95
+ const mark = r.ok ? '\u2713' : '\u2717';
96
+ const detail = r.detail ? ` (${r.detail})` : '';
97
+ console.log(` ${mark} ${r.label}${detail}`);
98
+ }
99
+ console.log('='.repeat(56));
100
+ const total = passed + failed;
101
+ console.log(`Result: ${passed}/${total} passed, ${failed} failed`);
102
+ if (failed > 0) {
103
+ console.log('\n[FAIL] Integration test FAILED');
104
+ process.exitCode = 1;
105
+ } else {
106
+ console.log('\n[PASS] Integration test PASSED');
107
+ }
108
+ }
109
+
110
+ // ── main ──
111
+
112
+ async function main() {
113
+ console.log('\nMCP Gateway Integration Test');
114
+ console.log('='.repeat(56));
115
+
116
+ // STEP 1: Start gateways
117
+ console.log('\n[STEP 1] Starting gateways...');
118
+ try {
119
+ runScript(START_SCRIPT);
120
+ pass('Gateway start script ran without error');
121
+ } catch (err) {
122
+ fail('Gateway start script', err.message);
123
+ console.log('\n[ABORT] Cannot continue without gateways running');
124
+ printSummary();
125
+ return;
126
+ }
127
+
128
+ // STEP 2: Wait for health checks to pass (up to 12s)
129
+ console.log('\n[STEP 2] Waiting for health checks (up to 12s)...');
130
+ const deadline = Date.now() + STARTUP_WAIT_MS;
131
+ const pending = new Set(SERVERS.map((s) => s.port));
132
+
133
+ while (pending.size > 0 && Date.now() < deadline) {
134
+ await sleep(POLL_INTERVAL_MS);
135
+ for (const port of [...pending]) {
136
+ if (await checkHealth(port)) pending.delete(port);
137
+ }
138
+ }
139
+
140
+ let healthOk = 0;
141
+ let healthSkipped = 0;
142
+
143
+ for (const srv of SERVERS) {
144
+ const alive = !pending.has(srv.port);
145
+ if (alive) {
146
+ console.log(` [ok] ${srv.name.padEnd(16)} :${srv.port}`);
147
+ healthOk++;
148
+ } else {
149
+ // Servers that stay down are expected when env vars (API keys) are missing
150
+ console.log(` [skip] ${srv.name.padEnd(16)} :${srv.port} (not running — likely missing env)`);
151
+ healthSkipped++;
152
+ }
153
+ }
154
+
155
+ if (healthOk === 0) {
156
+ fail('Health check — no servers responded', `0/${SERVERS.length} up`);
157
+ } else {
158
+ pass(`Health check — ${healthOk} server(s) responding (${healthSkipped} skipped)`);
159
+ }
160
+
161
+ // STEP 3: Switch Claude Code config to SSE
162
+ console.log('\n[STEP 3] Switching Claude Code config to SSE mode...');
163
+ try {
164
+ runScript(CONFIG_SCRIPT, '--enable');
165
+ pass('Config switch to SSE (--enable)');
166
+ } catch (err) {
167
+ fail('Config switch to SSE', err.message);
168
+ }
169
+
170
+ // STEP 4: Verify SSE endpoints respond on each active port
171
+ console.log('\n[STEP 4] Verifying SSE endpoints (/healthz)...');
172
+ const sseResults = await Promise.allSettled(
173
+ SERVERS.map(async (srv) => ({ ...srv, alive: await checkHealth(srv.port) })),
174
+ );
175
+
176
+ let sseOk = 0;
177
+ for (const r of sseResults) {
178
+ if (r.status !== 'fulfilled') continue;
179
+ const { name, port, alive } = r.value;
180
+ if (alive) {
181
+ console.log(` [ok] ${name.padEnd(16)} :${port}`);
182
+ sseOk++;
183
+ } else {
184
+ console.log(` [skip] ${name.padEnd(16)} :${port} (not running)`);
185
+ }
186
+ }
187
+
188
+ if (sseOk === 0 && healthOk > 0) {
189
+ fail('SSE endpoint verification — servers went down after config switch');
190
+ } else if (sseOk > 0) {
191
+ pass(`SSE endpoint verification — ${sseOk} endpoint(s) healthy`);
192
+ } else {
193
+ pass('SSE endpoint verification — no servers running (all skipped due to missing env)');
194
+ }
195
+
196
+ // STEP 5: Restore stdio config
197
+ console.log('\n[STEP 5] Restoring stdio config...');
198
+ try {
199
+ runScript(CONFIG_SCRIPT, '--disable');
200
+ pass('Config restore to stdio (--disable)');
201
+ } catch (err) {
202
+ fail('Config restore to stdio', err.message);
203
+ }
204
+
205
+ // STEP 6: Stop gateways
206
+ console.log('\n[STEP 6] Stopping gateways...');
207
+ try {
208
+ runScript(START_SCRIPT, '--stop');
209
+ pass('Gateway stop script ran without error');
210
+ } catch (err) {
211
+ fail('Gateway stop script', err.message);
212
+ }
213
+
214
+ // STEP 7: Orphan check — brief settle, then verify no supergateway processes remain
215
+ console.log('\n[STEP 7] Checking for orphan supergateway processes...');
216
+ await sleep(2000);
217
+
218
+ const orphanCount = countSupergateways();
219
+ if (orphanCount === 0) {
220
+ pass('No orphan supergateway processes (WMI/tasklist clean)');
221
+ } else {
222
+ fail('Orphan processes found', `${orphanCount} supergateway process(es) still running`);
223
+ }
224
+
225
+ printSummary();
226
+ }
227
+
228
+ main();