@jsonstudio/rcc 0.90.252 → 0.90.352

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 (335) hide show
  1. package/README.md +16 -16
  2. package/config/providers/ali-coding-plan.json +73 -0
  3. package/dist/build-info.js +2 -2
  4. package/dist/cli/commands/camoufox.js +2 -2
  5. package/dist/cli/commands/camoufox.js.map +1 -1
  6. package/dist/cli/commands/clean.js +4 -3
  7. package/dist/cli/commands/clean.js.map +1 -1
  8. package/dist/cli/commands/config.js +2 -1
  9. package/dist/cli/commands/config.js.map +1 -1
  10. package/dist/cli/commands/env.js +2 -1
  11. package/dist/cli/commands/env.js.map +1 -1
  12. package/dist/cli/commands/init/basic.js +2 -1
  13. package/dist/cli/commands/init/basic.js.map +1 -1
  14. package/dist/cli/commands/init.js +4 -3
  15. package/dist/cli/commands/init.js.map +1 -1
  16. package/dist/cli/commands/launcher-kernel.js +34 -8
  17. package/dist/cli/commands/launcher-kernel.js.map +1 -1
  18. package/dist/cli/commands/port.js +1 -1
  19. package/dist/cli/commands/port.js.map +1 -1
  20. package/dist/cli/commands/restart.js +3 -2
  21. package/dist/cli/commands/restart.js.map +1 -1
  22. package/dist/cli/commands/session-admin.js +46 -8
  23. package/dist/cli/commands/session-admin.js.map +1 -1
  24. package/dist/cli/commands/session-inject.js +43 -4
  25. package/dist/cli/commands/session-inject.js.map +1 -1
  26. package/dist/cli/commands/start.js +4 -3
  27. package/dist/cli/commands/start.js.map +1 -1
  28. package/dist/cli/commands/stop.js +3 -2
  29. package/dist/cli/commands/stop.js.map +1 -1
  30. package/dist/cli/config/bundled-docs.js +2 -6
  31. package/dist/cli/config/bundled-docs.js.map +1 -1
  32. package/dist/cli/config/init-config.d.ts +1 -0
  33. package/dist/cli/config/init-config.js +6 -3
  34. package/dist/cli/config/init-config.js.map +1 -1
  35. package/dist/cli/config/init-provider-catalog.js +4 -4
  36. package/dist/cli/config/init-provider-catalog.js.map +1 -1
  37. package/dist/cli/config/precommand-default-script.js +3 -9
  38. package/dist/cli/config/precommand-default-script.js.map +1 -1
  39. package/dist/cli/guardian/paths.js +2 -3
  40. package/dist/cli/guardian/paths.js.map +1 -1
  41. package/dist/cli.js +10 -2
  42. package/dist/cli.js.map +1 -1
  43. package/dist/commands/camoufox-fp.js +2 -3
  44. package/dist/commands/camoufox-fp.js.map +1 -1
  45. package/dist/commands/migrate-user-config.d.ts +6 -0
  46. package/dist/commands/migrate-user-config.js +53 -0
  47. package/dist/commands/migrate-user-config.js.map +1 -0
  48. package/dist/commands/provider-update.js +9 -9
  49. package/dist/commands/provider-update.js.map +1 -1
  50. package/dist/commands/quota-daemon.js +3 -3
  51. package/dist/commands/quota-daemon.js.map +1 -1
  52. package/dist/commands/quota-status.js +2 -2
  53. package/dist/commands/quota-status.js.map +1 -1
  54. package/dist/commands/token-daemon.js +2 -2
  55. package/dist/commands/token-daemon.js.map +1 -1
  56. package/dist/commands/validate.js +2 -3
  57. package/dist/commands/validate.js.map +1 -1
  58. package/dist/config/auth-file-resolver.js +2 -2
  59. package/dist/config/auth-file-resolver.js.map +1 -1
  60. package/dist/config/provider-v2-loader.js +9 -6
  61. package/dist/config/provider-v2-loader.js.map +1 -1
  62. package/dist/config/routecodex-config-loader.js +2 -2
  63. package/dist/config/routecodex-config-loader.js.map +1 -1
  64. package/dist/config/unified-config-paths.js +33 -11
  65. package/dist/config/unified-config-paths.js.map +1 -1
  66. package/dist/config/user-config-migration.d.ts +42 -0
  67. package/dist/config/user-config-migration.js +188 -0
  68. package/dist/config/user-config-migration.js.map +1 -0
  69. package/dist/config/user-data-paths.d.ts +59 -0
  70. package/dist/config/user-data-paths.js +174 -0
  71. package/dist/config/user-data-paths.js.map +1 -0
  72. package/dist/config/virtual-router-builder.d.ts +1 -1
  73. package/dist/config/virtual-router-builder.js +1 -1
  74. package/dist/daemon-admin-ui/assets/index-Bnx13Byl.js +15 -0
  75. package/dist/daemon-admin-ui/index.html +1 -1
  76. package/dist/docs/daemon-admin-ui.html +9 -9
  77. package/dist/index.js +66 -13
  78. package/dist/index.js.map +1 -1
  79. package/dist/manager/modules/health/index.js +2 -2
  80. package/dist/manager/modules/health/index.js.map +1 -1
  81. package/dist/manager/modules/quota/antigravity-quota-persistence.d.ts +2 -1
  82. package/dist/manager/modules/quota/antigravity-quota-persistence.js +11 -22
  83. package/dist/manager/modules/quota/antigravity-quota-persistence.js.map +1 -1
  84. package/dist/manager/quota/provider-quota-center.js +33 -25
  85. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  86. package/dist/manager/quota/provider-quota-store.js +11 -4
  87. package/dist/manager/quota/provider-quota-store.js.map +1 -1
  88. package/dist/modules/config/pipeline-config-path.js +3 -3
  89. package/dist/modules/config/pipeline-config-path.js.map +1 -1
  90. package/dist/modules/llmswitch/bridge/index.d.ts +1 -1
  91. package/dist/modules/llmswitch/bridge/index.js +1 -1
  92. package/dist/modules/llmswitch/bridge/index.js.map +1 -1
  93. package/dist/modules/llmswitch/bridge/native-exports.d.ts +1 -0
  94. package/dist/modules/llmswitch/bridge/native-exports.js +27 -0
  95. package/dist/modules/llmswitch/bridge/native-exports.js.map +1 -1
  96. package/dist/modules/llmswitch/bridge/snapshot-recorder.js +95 -24
  97. package/dist/modules/llmswitch/bridge/snapshot-recorder.js.map +1 -1
  98. package/dist/modules/llmswitch/bridge/state-integrations.d.ts +18 -0
  99. package/dist/modules/llmswitch/bridge/state-integrations.js +28 -0
  100. package/dist/modules/llmswitch/bridge/state-integrations.js.map +1 -1
  101. package/dist/modules/llmswitch/bridge.d.ts +2 -2
  102. package/dist/modules/llmswitch/bridge.js +2 -2
  103. package/dist/modules/llmswitch/bridge.js.map +1 -1
  104. package/dist/modules/pipeline/utils/colored-logger.d.ts +1 -0
  105. package/dist/modules/pipeline/utils/colored-logger.js +13 -9
  106. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  107. package/dist/providers/auth/antigravity-fingerprint.js +2 -3
  108. package/dist/providers/auth/antigravity-fingerprint.js.map +1 -1
  109. package/dist/providers/auth/antigravity-reauth-state.js +2 -3
  110. package/dist/providers/auth/antigravity-reauth-state.js.map +1 -1
  111. package/dist/providers/auth/antigravity-user-agent.js +2 -2
  112. package/dist/providers/auth/antigravity-user-agent.js.map +1 -1
  113. package/dist/providers/auth/antigravity-warmup.js +2 -3
  114. package/dist/providers/auth/antigravity-warmup.js.map +1 -1
  115. package/dist/providers/auth/deepseek-account-auth.js +4 -3
  116. package/dist/providers/auth/deepseek-account-auth.js.map +1 -1
  117. package/dist/providers/auth/deepseek-account-token-acquirer.js +3 -2
  118. package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -1
  119. package/dist/providers/auth/oauth-auth.js +2 -3
  120. package/dist/providers/auth/oauth-auth.js.map +1 -1
  121. package/dist/providers/auth/oauth-lifecycle/path-resolver.js +6 -7
  122. package/dist/providers/auth/oauth-lifecycle/path-resolver.js.map +1 -1
  123. package/dist/providers/auth/oauth-lifecycle.js +4 -4
  124. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  125. package/dist/providers/auth/oauth-repair-cooldown.js +2 -3
  126. package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
  127. package/dist/providers/auth/token-scanner/index.js +2 -3
  128. package/dist/providers/auth/token-scanner/index.js.map +1 -1
  129. package/dist/providers/auth/token-storage/token-file-resolver.js +8 -7
  130. package/dist/providers/auth/token-storage/token-file-resolver.js.map +1 -1
  131. package/dist/providers/auth/tokenfile-auth.js +5 -6
  132. package/dist/providers/auth/tokenfile-auth.js.map +1 -1
  133. package/dist/providers/core/config/camoufox-launcher.js +3 -4
  134. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  135. package/dist/providers/core/config/provider-oauth-configs.js +2 -2
  136. package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
  137. package/dist/providers/core/hooks/hooks-integration.js +1 -1
  138. package/dist/providers/core/hooks/hooks-integration.js.map +1 -1
  139. package/dist/providers/core/runtime/deepseek-http-provider.js +2 -1
  140. package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -1
  141. package/dist/providers/core/utils/snapshot-writer.js +2 -1
  142. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  143. package/dist/providers/profile/families/anthropic-profile.js +32 -0
  144. package/dist/providers/profile/families/anthropic-profile.js.map +1 -1
  145. package/dist/server/handlers/config-admin-handler.d.ts +1 -1
  146. package/dist/server/handlers/config-admin-handler.js +6 -6
  147. package/dist/server/handlers/config-admin-handler.js.map +1 -1
  148. package/dist/server/handlers/handler-response-utils.js +9 -4
  149. package/dist/server/handlers/handler-response-utils.js.map +1 -1
  150. package/dist/server/runtime/http-server/clock-runtime-hooks.d.ts +2 -0
  151. package/dist/server/runtime/http-server/clock-runtime-hooks.js +91 -0
  152. package/dist/server/runtime/http-server/clock-runtime-hooks.js.map +1 -0
  153. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +51 -13
  154. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
  155. package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +1 -9
  156. package/dist/server/runtime/http-server/daemon-admin/auth-store.js +2 -18
  157. package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -1
  158. package/dist/server/runtime/http-server/daemon-admin/control-handler.js +3 -3
  159. package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
  160. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +2 -2
  161. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  162. package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js +5 -4
  163. package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js.map +1 -1
  164. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +3 -3
  165. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  166. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +2 -0
  167. package/dist/server/runtime/http-server/daemon-admin-routes.js +11 -8
  168. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  169. package/dist/server/runtime/http-server/executor/client-injection-flow.js +9 -1
  170. package/dist/server/runtime/http-server/executor/client-injection-flow.js.map +1 -1
  171. package/dist/server/runtime/http-server/executor/provider-response-converter.js +119 -26
  172. package/dist/server/runtime/http-server/executor/provider-response-converter.js.map +1 -1
  173. package/dist/server/runtime/http-server/executor/request-retry-helpers.d.ts +1 -0
  174. package/dist/server/runtime/http-server/executor/request-retry-helpers.js +26 -0
  175. package/dist/server/runtime/http-server/executor/request-retry-helpers.js.map +1 -1
  176. package/dist/server/runtime/http-server/http-server-bootstrap.js +2 -3
  177. package/dist/server/runtime/http-server/http-server-bootstrap.js.map +1 -1
  178. package/dist/server/runtime/http-server/http-server-lifecycle.js +2 -0
  179. package/dist/server/runtime/http-server/http-server-lifecycle.js.map +1 -1
  180. package/dist/server/runtime/http-server/http-server-runtime-setup.js +2 -0
  181. package/dist/server/runtime/http-server/http-server-runtime-setup.js.map +1 -1
  182. package/dist/server/runtime/http-server/http-server-session-daemon.js +9 -299
  183. package/dist/server/runtime/http-server/http-server-session-daemon.js.map +1 -1
  184. package/dist/server/runtime/http-server/middleware.d.ts +7 -0
  185. package/dist/server/runtime/http-server/middleware.js +1 -1
  186. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  187. package/dist/server/runtime/http-server/request-executor.js +36 -51
  188. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  189. package/dist/server/runtime/http-server/routes.js +10 -3
  190. package/dist/server/runtime/http-server/routes.js.map +1 -1
  191. package/dist/server/runtime/http-server/servertool-admin-state.d.ts +1 -0
  192. package/dist/server/runtime/http-server/servertool-admin-state.js +7 -2
  193. package/dist/server/runtime/http-server/servertool-admin-state.js.map +1 -1
  194. package/dist/server/runtime/http-server/session-client-route-utils.d.ts +1 -0
  195. package/dist/server/runtime/http-server/session-client-route-utils.js +49 -4
  196. package/dist/server/runtime/http-server/session-client-route-utils.js.map +1 -1
  197. package/dist/server/runtime/http-server/session-client-routes.d.ts +5 -1
  198. package/dist/server/runtime/http-server/session-client-routes.js +60 -30
  199. package/dist/server/runtime/http-server/session-client-routes.js.map +1 -1
  200. package/dist/server/runtime/http-server/session-dir.js +6 -12
  201. package/dist/server/runtime/http-server/session-dir.js.map +1 -1
  202. package/dist/server/runtime/http-server/stats-manager.js +4 -3
  203. package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
  204. package/dist/server/utils/non-blocking-error-logger.js +2 -1
  205. package/dist/server/utils/non-blocking-error-logger.js.map +1 -1
  206. package/dist/server/utils/request-log-color.js +10 -3
  207. package/dist/server/utils/request-log-color.js.map +1 -1
  208. package/dist/server/utils/stage-logger.js +71 -9
  209. package/dist/server/utils/stage-logger.js.map +1 -1
  210. package/dist/token-daemon/history-store.js +2 -1
  211. package/dist/token-daemon/history-store.js.map +1 -1
  212. package/dist/token-daemon/leader-lock.js +2 -2
  213. package/dist/token-daemon/leader-lock.js.map +1 -1
  214. package/dist/token-daemon/quota-auth-issue.js +2 -4
  215. package/dist/token-daemon/quota-auth-issue.js.map +1 -1
  216. package/dist/token-daemon/server-utils.js +3 -4
  217. package/dist/token-daemon/server-utils.js.map +1 -1
  218. package/dist/token-daemon/token-daemon.js +6 -6
  219. package/dist/token-daemon/token-daemon.js.map +1 -1
  220. package/dist/token-daemon/token-utils.js +2 -1
  221. package/dist/token-daemon/token-utils.js.map +1 -1
  222. package/dist/token-portal/fingerprint-summary.js +2 -3
  223. package/dist/token-portal/fingerprint-summary.js.map +1 -1
  224. package/dist/token-portal/local-token-portal.js +1 -1
  225. package/dist/token-portal/local-token-portal.js.map +1 -1
  226. package/dist/utils/daemon-stop-intent.js +2 -2
  227. package/dist/utils/daemon-stop-intent.js.map +1 -1
  228. package/dist/utils/errorsamples.js +3 -1
  229. package/dist/utils/errorsamples.js.map +1 -1
  230. package/dist/utils/llms-engine-shadow.js +2 -2
  231. package/dist/utils/llms-engine-shadow.js.map +1 -1
  232. package/dist/utils/managed-server-pids.js +2 -2
  233. package/dist/utils/managed-server-pids.js.map +1 -1
  234. package/dist/utils/process-lifecycle-logger.js +2 -1
  235. package/dist/utils/process-lifecycle-logger.js.map +1 -1
  236. package/dist/utils/runtime-exit-forensics.js +2 -2
  237. package/dist/utils/runtime-exit-forensics.js.map +1 -1
  238. package/dist/utils/session-log-color.js +31 -5
  239. package/dist/utils/session-log-color.js.map +1 -1
  240. package/dist/utils/snapshot-writer.js +2 -1
  241. package/dist/utils/snapshot-writer.js.map +1 -1
  242. package/docs/CODEX_AND_CLAUDE_CODE.md +1 -1
  243. package/docs/CONFIG_ARCHITECTURE.md +7 -7
  244. package/docs/DAEMON_CONTROL_PLANE.md +2 -2
  245. package/docs/INSTALLATION_AND_QUICKSTART.md +2 -2
  246. package/docs/INSTRUCTION_MARKUP.md +2 -2
  247. package/docs/OAUTH.md +6 -6
  248. package/docs/PORTS.md +1 -1
  249. package/docs/PROVIDERS_BUILTIN.md +2 -2
  250. package/docs/QUOTA_MANAGER_V3.md +2 -2
  251. package/docs/ROUTING_POLICY_SCHEMA.md +1 -1
  252. package/docs/SERVERTOOL_CLOCK_DESIGN.md +1 -1
  253. package/docs/SERVERTOOL_PRE_COMMAND_HOOKS.md +4 -4
  254. package/docs/anthropic-request-golden-samples.md +4 -4
  255. package/docs/chat-glm-500-analysis.md +2 -2
  256. package/docs/chat-request-golden-samples.md +4 -4
  257. package/docs/codex-samples-replay.md +3 -3
  258. package/docs/daemon-admin-api-design.md +2 -2
  259. package/docs/daemon-admin-ui.html +9 -9
  260. package/docs/design/servertool-stopmessage-lifecycle.md +5 -0
  261. package/docs/golden-ci-library.md +8 -8
  262. package/docs/monitoring/Design.md +2 -2
  263. package/docs/multi-token-auth-guide.md +6 -6
  264. package/docs/oauth-authentication-guide.md +1 -1
  265. package/docs/oauth-iflow-implementation.md +2 -2
  266. package/docs/pipeline-routing-report.md +1 -1
  267. package/docs/plans/manager-daemon/PLAN.md +1 -1
  268. package/docs/plans/provider-config-v2-plan.md +8 -8
  269. package/docs/plans/provider-runtime-manager-plan.md +4 -4
  270. package/docs/provider-analysis.md +5 -5
  271. package/docs/provider-quota-design.md +2 -2
  272. package/docs/providers/antigravity-fingerprint-ua-warmup.md +5 -5
  273. package/docs/providers/antigravity-gemini-provider-compat.md +3 -3
  274. package/docs/providers/deepseek-web-provider-design.md +1 -1
  275. package/docs/providers/gemini-provider.md +1 -1
  276. package/docs/providers/provider-composite-testing.md +2 -2
  277. package/docs/providers/tabglm-claude-code-compat.md +1 -1
  278. package/docs/replay-evidence-iflow-400.txt +3 -3
  279. package/docs/reports/routing-classification-report.json +6 -6
  280. package/docs/reports/routing-classification-report.md +6 -6
  281. package/docs/reports/thinking-keywords-report.json +6 -6
  282. package/docs/responses/README.md +5 -5
  283. package/docs/responses-generic-provider.md +1 -1
  284. package/docs/responses-passthrough-provider-design.md +7 -7
  285. package/docs/routing-instructions.md +1 -1
  286. package/docs/token-daemon-preview.html +3 -3
  287. package/docs/token-refresh-daemon-plan.md +7 -7
  288. package/docs/verification/modelscope-verify.md +2 -2
  289. package/docs/verified-configs/README.md +2 -2
  290. package/docs/verified-configs/v0.45.0/README.md +5 -5
  291. package/docs/verified-configs/v0.45.0/merged-config.5521.json +3 -3
  292. package/docs/verified-configs/v0.45.0/merged-config.qwen-5522.json +3 -3
  293. package/package.json +3 -2
  294. package/scripts/anthropic-four-config-e2e.mjs +5 -5
  295. package/scripts/anthropic-toolcall.mjs +1 -1
  296. package/scripts/batch-toolcall-report.mjs +1 -1
  297. package/scripts/build-core.mjs +2 -7
  298. package/scripts/claude-e2e-listdir-all.sh +1 -1
  299. package/scripts/claude-e2e-listdir-per-config.sh +4 -4
  300. package/scripts/clean-safe.mjs +1 -1
  301. package/scripts/cleanup-beads-oversized-notes.mjs +182 -0
  302. package/scripts/config-core-compare.ts +1 -1
  303. package/scripts/ensure-llmswitch-mode.mjs +7 -1
  304. package/scripts/glm1210-curl-test.sh +1 -1
  305. package/scripts/install-release.sh +1 -1
  306. package/scripts/mock-provider/capture-from-configs.mjs +1 -1
  307. package/scripts/outbound-network-toolcall.mjs +2 -2
  308. package/scripts/outbound-regression-codex-samples.mjs +1 -1
  309. package/scripts/pack-mode.mjs +14 -1
  310. package/scripts/pack-rcc.mjs +9 -4
  311. package/scripts/provider-v2-smoke.mjs +3 -3
  312. package/scripts/publish-rcc.mjs +8 -3
  313. package/scripts/replay-recorded-toolcall.mjs +1 -2
  314. package/scripts/responses-fai-capture.mjs +1 -1
  315. package/scripts/responses-sse-capture.mjs +1 -1
  316. package/scripts/responses-sse-proxy.mjs +1 -1
  317. package/scripts/responses-sse-replay-golden.mjs +252 -111
  318. package/scripts/run-bg.sh +1 -1
  319. package/scripts/run-fg-gtimeout.sh +1 -1
  320. package/scripts/tests/antigravity-codex-sample-pipeline-compare.mjs +1 -1
  321. package/scripts/tests/antigravity-gemini-dryrun-compare.mjs +1 -1
  322. package/scripts/tests/responses-provider-dry-run.mjs +1 -1
  323. package/scripts/tests/virtual-router-health.mjs +1 -1
  324. package/scripts/update-models.mjs +2 -2
  325. package/scripts/v2-simple-monitor.mjs +1 -1
  326. package/scripts/vendor-core.mjs +12 -7
  327. package/scripts/verify-e2e-gemini-followup-sample.mjs +1 -1
  328. package/scripts/verify-e2e-toolcall.mjs +2 -2
  329. package/scripts/verify-health.mjs +2 -2
  330. package/scripts/verify-sse-loop.mjs +1 -1
  331. package/scripts/virtual-router-dryrun.mjs +2 -2
  332. package/scripts/virtual-router-shadow-v2-real.mjs +3 -3
  333. package/dist/daemon-admin-ui/assets/index-C8vP_c5E.js +0 -15
  334. package/docs/rccx-wasm-migration.md +0 -74
  335. package/scripts/compare-codex-rccx.mjs +0 -326
@@ -7,7 +7,7 @@ import path from 'path';
7
7
  import { pathToFileURL } from 'url';
8
8
 
9
9
  const PROVIDER_ID = process.env.RCC_RESP_PROV || 'fai';
10
- const PROVIDER_DIR = path.join(os.homedir(), '.routecodex', 'provider');
10
+ const PROVIDER_DIR = path.join(os.homedir(), '.rcc', 'provider');
11
11
  const OUT_DIR = path.join(os.homedir(), '.routecodex', 'golden_samples', 'provider_golden_samples', 'responses', PROVIDER_ID);
12
12
 
13
13
  function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
@@ -10,7 +10,7 @@ import OpenAI from 'openai';
10
10
  const BASEDIR = process.cwd();
11
11
  const CODEx_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-chat');
12
12
  const RESP_SAMPLE_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
13
- const PROVIDER_DIR = path.join(os.homedir(), '.routecodex', 'provider');
13
+ const PROVIDER_DIR = path.join(os.homedir(), '.rcc', 'provider');
14
14
  const OUT_DIR = path.join(os.homedir(), '.routecodex', 'logs', 'responses-sse');
15
15
 
16
16
  function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
@@ -17,7 +17,7 @@ const replayLog = process.env.RCC_RESP_REPLAY_LOG || getArg('--replay');
17
17
  const port = Number(getArg('--port') || DEFAULT_PORT);
18
18
  const host = getArg('--host') || DEFAULT_HOST;
19
19
 
20
- const PROVIDER_ROOT = path.join(os.homedir(), '.routecodex', 'provider');
20
+ const PROVIDER_ROOT = path.join(os.homedir(), '.rcc', 'provider');
21
21
  const CAPTURE_ROOT = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses', 'sse-proxy');
22
22
 
23
23
  function getArg(flag) {
@@ -1,138 +1,279 @@
1
1
  #!/usr/bin/env node
2
- // Replay a Responses golden provider-request sample to a live provider and aggregate SSE → JSON → Chat.
3
- // Usage:
4
- // RCC_RESP_PROV=<providerId> node scripts/responses-sse-replay-golden.mjs
2
+ // Server-side replay for codex-samples /v1/responses requests.
3
+ // This script intentionally replays through RouteCodex HTTP server instead of calling provider URLs directly.
4
+ //
5
5
  // Env:
6
- // RCC_RESP_PROV: fc|c4m|fai (default fc)
7
- // RCC_RESP_PICK: substring to pick a specific sample file
6
+ // RCC_REPLAY_BASE server base URL (default http://127.0.0.1:5555)
7
+ // RCC_REPLAY_KEY x-routecodex-api-key (default routecodex-test)
8
+ // RCC_RESP_PROVIDER provider directory filter (optional)
9
+ // RCC_RESP_PICK request-id/path substring filter (optional)
10
+ // RCC_RESP_REQ exact request directory name, e.g. req_1773310208018_9b3ec605 (optional)
11
+ //
12
+ // Output:
13
+ // ~/.routecodex/logs/responses-sse/server-replay_<timestamp>.{request,response,sse,json,chat}.*
8
14
 
9
- import fs from 'fs';
10
- import os from 'os';
11
- import path from 'path';
12
- import { pathToFileURL } from 'url';
15
+ import fs from 'node:fs';
16
+ import os from 'node:os';
17
+ import path from 'node:path';
18
+ import { pathToFileURL } from 'node:url';
13
19
 
14
- const PROVIDER_DIR = path.join(os.homedir(), '.routecodex', 'provider');
15
- const SAMPLES_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
20
+ const DEFAULT_BASE = process.env.RCC_REPLAY_BASE || 'http://127.0.0.1:5555';
21
+ const DEFAULT_KEY =
22
+ process.env.RCC_REPLAY_KEY ||
23
+ process.env.ROUTECODEX_HTTP_APIKEY ||
24
+ process.env.ROUTECODEX_API_KEY ||
25
+ 'routecodex-test';
26
+ const FILTER_PROVIDER = (process.env.RCC_RESP_PROVIDER || '').trim();
27
+ const FILTER_PICK = (process.env.RCC_RESP_PICK || '').trim();
28
+ const FILTER_REQ = (process.env.RCC_RESP_REQ || '').trim();
29
+ const SAMPLES_ROOT = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
16
30
  const OUT_DIR = path.join(os.homedir(), '.routecodex', 'logs', 'responses-sse');
17
31
 
18
- function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
19
- function nowStamp() { return new Date().toISOString().replace(/[:.]/g, '-'); }
32
+ function nowStamp() {
33
+ return new Date().toISOString().replace(/[:.]/g, '-');
34
+ }
35
+
36
+ function ensureDir(p) {
37
+ fs.mkdirSync(p, { recursive: true });
38
+ }
39
+
40
+ function readJson(p) {
41
+ return JSON.parse(fs.readFileSync(p, 'utf-8'));
42
+ }
43
+
44
+ async function healthCheck(baseUrl) {
45
+ try {
46
+ const res = await fetch(`${baseUrl.replace(/\/$/, '')}/health`, { method: 'GET' });
47
+ return res.ok;
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
20
52
 
21
- function findProviderConfig(providerId) {
22
- const dir = path.join(PROVIDER_DIR, providerId);
23
- const candidates = ['config.v1.json', 'config.json'];
24
- for (const name of candidates) {
25
- const p = path.join(dir, name);
26
- if (fs.existsSync(p)) {
27
- return JSON.parse(fs.readFileSync(p, 'utf-8'));
53
+ function findClientRequestFiles(root) {
54
+ const result = [];
55
+ if (!fs.existsSync(root)) {
56
+ return result;
57
+ }
58
+ const providerDirs = fs.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory());
59
+ for (const providerDir of providerDirs) {
60
+ if (FILTER_PROVIDER && !providerDir.name.includes(FILTER_PROVIDER)) {
61
+ continue;
62
+ }
63
+ const providerPath = path.join(root, providerDir.name);
64
+ const reqDirs = fs.readdirSync(providerPath, { withFileTypes: true }).filter((d) => d.isDirectory());
65
+ for (const reqDir of reqDirs) {
66
+ if (FILTER_REQ && reqDir.name !== FILTER_REQ) {
67
+ continue;
68
+ }
69
+ if (FILTER_PICK && !reqDir.name.includes(FILTER_PICK) && !providerDir.name.includes(FILTER_PICK)) {
70
+ continue;
71
+ }
72
+ const clientReq = path.join(providerPath, reqDir.name, 'client-request.json');
73
+ if (!fs.existsSync(clientReq)) {
74
+ continue;
75
+ }
76
+ const stat = fs.statSync(clientReq);
77
+ result.push({
78
+ provider: providerDir.name,
79
+ requestId: reqDir.name,
80
+ file: clientReq,
81
+ mtimeMs: stat.mtimeMs
82
+ });
28
83
  }
29
84
  }
30
- throw new Error(`No provider config for ${providerId}`);
85
+ result.sort((a, b) => b.mtimeMs - a.mtimeMs);
86
+ return result;
31
87
  }
32
88
 
33
- function extractProviderEntry(doc, providerId) {
34
- const pipelines = doc?.pipeline_assembler?.config?.pipelines || [];
35
- for (const p of pipelines) {
36
- const prov = p?.modules?.provider;
37
- if (!prov?.config) continue;
38
- const pid = prov.config.providerId || path.basename(path.dirname(p?.__file || ''));
39
- if (pid === providerId) return prov.config;
40
- }
41
- // fallback v1
42
- const providers = doc?.virtualrouter?.providers || {};
43
- return Object.values(providers)[0] || null;
89
+ function extractRequestBody(doc) {
90
+ if (doc && typeof doc === 'object') {
91
+ if (doc.body && typeof doc.body === 'object' && !Array.isArray(doc.body)) {
92
+ if (doc.body.body && typeof doc.body.body === 'object' && !Array.isArray(doc.body.body)) {
93
+ return doc.body.body;
94
+ }
95
+ return doc.body;
96
+ }
97
+ if (doc.data && typeof doc.data === 'object' && !Array.isArray(doc.data)) {
98
+ const data = doc.data;
99
+ if (data.body && typeof data.body === 'object' && !Array.isArray(data.body)) {
100
+ if (data.body.body && typeof data.body.body === 'object' && !Array.isArray(data.body.body)) {
101
+ return data.body.body;
102
+ }
103
+ return data.body;
104
+ }
105
+ }
106
+ }
107
+ return undefined;
44
108
  }
45
109
 
46
- function listGoldenRequests() {
47
- if (!fs.existsSync(SAMPLES_DIR)) return [];
48
- return fs.readdirSync(SAMPLES_DIR).filter(n => n.endsWith('_provider-request.json'));
110
+ function extractEntryEndpoint(doc) {
111
+ const endpoint = doc?.meta?.entryEndpoint;
112
+ if (typeof endpoint === 'string' && endpoint.trim().length) {
113
+ return endpoint.trim();
114
+ }
115
+ return '/v1/responses';
49
116
  }
50
117
 
51
- function pickGoldenForBaseUrl(files, baseUrl, pickHint) {
52
- const want = String(baseUrl || '').replace(/\/$/, '');
53
- const host = want.split('://')[1] || want; // naive
54
- let matches = files.filter(f => {
55
- try {
56
- const obj = JSON.parse(fs.readFileSync(path.join(SAMPLES_DIR, f), 'utf-8'));
57
- const url = obj?.data?.url || obj?.url || '';
58
- return typeof url === 'string' && url.includes(host);
59
- } catch { return false; }
60
- });
61
- if (pickHint) matches = matches.filter(f => f.includes(pickHint));
62
- if (!matches.length) matches = files; // fallback to any
63
- // prefer ones containing input[] and tools
64
- matches.sort((a, b) => {
65
- const aa = fs.readFileSync(path.join(SAMPLES_DIR, a), "utf-8");
66
- const bb = fs.readFileSync(path.join(SAMPLES_DIR, b), "utf-8");
67
- const sa = (aa.includes("\"input\"") ? 10 : 0) + (aa.includes("\"tools\"") ? 2 : 0) + (aa.includes("function_call_arguments") ? 1 : 0);
68
- const sb = (bb.includes("\"input\"") ? 10 : 0) + (bb.includes("\"tools\"") ? 2 : 0) + (bb.includes("function_call_arguments") ? 1 : 0);
69
- return sb - sa;
70
- });
71
- return matches[0] || null;
118
+ function extractStreamFlag(doc, body) {
119
+ if (typeof body?.stream === 'boolean') {
120
+ return body.stream;
121
+ }
122
+ if (typeof doc?.meta?.stream === 'boolean') {
123
+ return doc.meta.stream;
124
+ }
125
+ return true;
126
+ }
127
+
128
+ async function readSseFrames(stream) {
129
+ const reader = stream?.getReader?.();
130
+ if (!reader) {
131
+ return [];
132
+ }
133
+ const decoder = new TextDecoder();
134
+ let buffer = '';
135
+ const frames = [];
136
+ while (true) {
137
+ const { value, done } = await reader.read();
138
+ if (done) {
139
+ break;
140
+ }
141
+ buffer += decoder.decode(value, { stream: true });
142
+ let idx = buffer.indexOf('\n\n');
143
+ while (idx >= 0) {
144
+ const frame = buffer.slice(0, idx).trim();
145
+ buffer = buffer.slice(idx + 2);
146
+ if (frame.length) {
147
+ frames.push(frame);
148
+ }
149
+ idx = buffer.indexOf('\n\n');
150
+ }
151
+ }
152
+ buffer += decoder.decode(new Uint8Array(), { stream: false });
153
+ if (buffer.trim().length) {
154
+ frames.push(buffer.trim());
155
+ }
156
+ return frames;
157
+ }
158
+
159
+ async function convertSseFramesToJson(frames, requestId, model) {
160
+ try {
161
+ const convPath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/sse/sse-to-json/index.js')).href;
162
+ const bridgePath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/conversion/responses/responses-openai-bridge.js')).href;
163
+ const { ResponsesSseToJsonConverter } = await import(convPath);
164
+ const { buildChatResponseFromResponses } = await import(bridgePath);
165
+ const converter = new ResponsesSseToJsonConverter();
166
+ async function* toChunks() {
167
+ for (const frame of frames) {
168
+ yield `${frame}\n\n`;
169
+ }
170
+ }
171
+ const json = await converter.convertSseToJson(toChunks(), {
172
+ requestId,
173
+ model: typeof model === 'string' && model.length ? model : 'unknown'
174
+ });
175
+ const chat = buildChatResponseFromResponses(json);
176
+ return { json, chat };
177
+ } catch {
178
+ return { json: null, chat: null };
179
+ }
72
180
  }
73
181
 
74
182
  async function main() {
75
- const providerId = process.env.RCC_RESP_PROV || 'fc';
76
- const pickHint = process.env.RCC_RESP_PICK || '';
77
- const cfgDoc = findProviderConfig(providerId);
78
- const prov = extractProviderEntry(cfgDoc, providerId);
79
- if (!prov) throw new Error('provider entry missing');
80
- const baseUrl = String(prov.baseUrl || prov.baseURL || '').replace(/\/$/, '');
81
- const endpoint = String(prov.endpoint || '/responses');
82
- const apiKey = prov.auth?.apiKey || cfgDoc?.keyVault?.[providerId]?.key1?.value;
83
- if (!apiKey) throw new Error('no apikey');
84
-
85
- const files = listGoldenRequests();
86
- if (!files.length) throw new Error('no responses golden requests');
87
- const chosen = pickGoldenForBaseUrl(files, baseUrl, pickHint);
88
- if (!chosen) throw new Error('no suitable golden request');
89
- const sample = JSON.parse(fs.readFileSync(path.join(SAMPLES_DIR, chosen), 'utf-8'));
90
- const body = sample?.data?.body || sample?.body || sample?.data || sample;
91
- if (!body || typeof body !== 'object') throw new Error('invalid golden body');
92
- // Override model if provider specifies one
93
- const model = prov.model || prov.modelId || prov.defaultModel || body.model;
94
- body.model = model;
95
- body.stream = true;
96
-
97
- const httpPath = pathToFileURL(path.join(process.cwd(), 'dist/providers/core/utils/http-client.js')).href;
98
- const { HttpClient } = await import(httpPath);
99
- const convPath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/sse/sse-to-json/index.js')).href;
100
- const bridgePath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/conversion/responses/responses-openai-bridge.js')).href;
101
- const { ResponsesSseToJsonConverter } = await import(convPath);
102
- const { buildChatResponseFromResponses } = await import(bridgePath);
183
+ const baseUrl = DEFAULT_BASE.replace(/\/$/, '');
184
+ const healthy = await healthCheck(baseUrl);
185
+ if (!healthy) {
186
+ throw new Error(`routecodex server not healthy: ${baseUrl}/health`);
187
+ }
188
+
189
+ const candidates = findClientRequestFiles(SAMPLES_ROOT);
190
+ if (!candidates.length) {
191
+ throw new Error(`no client-request samples found under ${SAMPLES_ROOT}`);
192
+ }
193
+ const picked = candidates[0];
194
+ const sample = readJson(picked.file);
195
+ const body = extractRequestBody(sample);
196
+ if (!body || typeof body !== 'object' || Array.isArray(body)) {
197
+ throw new Error(`invalid sample request body: ${picked.file}`);
198
+ }
199
+
200
+ const endpoint = extractEntryEndpoint(sample);
201
+ const wantsStream = extractStreamFlag(sample, body);
202
+ const requestBody = { ...body, stream: wantsStream };
203
+ const targetUrl = `${baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;
204
+
205
+ ensureDir(OUT_DIR);
206
+ const runBase = path.join(OUT_DIR, `server-replay_${nowStamp()}`);
207
+ const requestOut = `${runBase}.request.json`;
208
+ const metaOut = `${runBase}.response.meta.json`;
209
+ const sseOut = `${runBase}.response.sse.log`;
210
+ const sseNdjsonOut = `${runBase}.response.sse.ndjson`;
211
+ const jsonOut = `${runBase}.response.json`;
212
+ const chatOut = `${runBase}.chat.json`;
103
213
 
104
214
  const headers = {
105
215
  'Content-Type': 'application/json',
216
+ 'Accept': wantsStream ? 'text/event-stream' : 'application/json',
106
217
  'OpenAI-Beta': 'responses-2024-12-17',
107
- 'Authorization': `Bearer ${apiKey}`
218
+ 'x-routecodex-api-key': DEFAULT_KEY
108
219
  };
109
220
 
110
- ensureDir(OUT_DIR);
111
- const base = path.join(OUT_DIR, `${providerId}_replay_${nowStamp()}`);
112
- const sseLog = `${base}.sse.log`;
113
- const jsonOut = `${base}.json`;
114
- const chatOut = `${base}.chat.json`;
115
- fs.writeFileSync(`${base}.request.json`, JSON.stringify({ url: baseUrl+endpoint, headers, body }, null, 2));
116
-
117
- const client = new HttpClient({ baseUrl, timeout: 300000 });
118
- const stream = await client.postStream(endpoint, body, { ...headers, Accept: 'text/event-stream' });
119
- const conv = new ResponsesSseToJsonConverter();
120
- const json = await conv.convertSseToJson(stream, {
121
- requestId: path.basename(base),
122
- model: String(body.model||'unknown'),
123
- onEvent: (evt) => {
124
- try {
125
- fs.appendFileSync(sseLog, `event: ${evt.type}\n`);
126
- fs.appendFileSync(sseLog, `data: ${JSON.stringify(evt.data)}\n\n`);
127
- } catch {}
128
- }
221
+ fs.writeFileSync(requestOut, JSON.stringify({
222
+ targetUrl,
223
+ endpoint,
224
+ sample: picked,
225
+ headers: { ...headers, 'x-routecodex-api-key': '***' },
226
+ body: requestBody
227
+ }, null, 2));
228
+
229
+ const res = await fetch(targetUrl, {
230
+ method: 'POST',
231
+ headers,
232
+ body: JSON.stringify(requestBody)
129
233
  });
130
- fs.writeFileSync(jsonOut, JSON.stringify(json, null, 2));
131
- const chat = buildChatResponseFromResponses(json);
132
- fs.writeFileSync(chatOut, JSON.stringify(chat, null, 2));
133
- const tc = chat?.choices?.[0]?.message?.tool_calls || [];
134
- const ok = Array.isArray(tc) && tc.length > 0;
135
- console.log('[responses-sse-replay-golden] provider=%s sample=%s tool_calls=%s out=%s', providerId, chosen, ok ? tc.length : 0, chatOut);
234
+ fs.writeFileSync(metaOut, JSON.stringify({
235
+ status: res.status,
236
+ statusText: res.statusText,
237
+ headers: Object.fromEntries(res.headers.entries())
238
+ }, null, 2));
239
+ if (!res.ok) {
240
+ const text = await res.text();
241
+ fs.writeFileSync(`${runBase}.response.error.txt`, text, 'utf-8');
242
+ throw new Error(`HTTP ${res.status}: ${text.slice(0, 500)}`);
243
+ }
244
+
245
+ if (!wantsStream) {
246
+ const json = await res.json();
247
+ fs.writeFileSync(jsonOut, JSON.stringify(json, null, 2));
248
+ console.log('[responses-sse-replay-golden] mode=json sample=%s out=%s', picked.file, jsonOut);
249
+ return;
250
+ }
251
+
252
+ const frames = await readSseFrames(res.body);
253
+ fs.writeFileSync(sseOut, frames.map((frame) => `${frame}\n\n`).join(''), 'utf-8');
254
+ fs.writeFileSync(sseNdjsonOut, frames.join('\n'), 'utf-8');
255
+ const converted = await convertSseFramesToJson(
256
+ frames,
257
+ picked.requestId,
258
+ typeof (requestBody).model === 'string' ? (requestBody).model : undefined
259
+ );
260
+ if (converted.json) {
261
+ fs.writeFileSync(jsonOut, JSON.stringify(converted.json, null, 2));
262
+ }
263
+ if (converted.chat) {
264
+ fs.writeFileSync(chatOut, JSON.stringify(converted.chat, null, 2));
265
+ }
266
+ console.log(
267
+ '[responses-sse-replay-golden] mode=sse sample=%s frames=%d sse=%s json=%s chat=%s',
268
+ picked.file,
269
+ frames.length,
270
+ sseOut,
271
+ converted.json ? jsonOut : '(skip)',
272
+ converted.chat ? chatOut : '(skip)'
273
+ );
136
274
  }
137
275
 
138
- main().catch(e => { console.error(e); process.exit(1); });
276
+ main().catch((err) => {
277
+ console.error('[responses-sse-replay-golden] failed:', err?.message || String(err));
278
+ process.exit(1);
279
+ });
package/scripts/run-bg.sh CHANGED
@@ -44,7 +44,7 @@ detect_port() {
44
44
  local p="${TARGET_PORT:-}"
45
45
  if [[ -n "$p" ]]; then echo "$p"; return; fi
46
46
  if [[ -n "${ROUTECODEX_PORT:-}" ]]; then echo "${ROUTECODEX_PORT}"; return; fi
47
- local cfg="$HOME/.routecodex/config.json"
47
+ local cfg="$HOME/.rcc/config.json"
48
48
  if command -v jq >/dev/null 2>&1 && [[ -f "$cfg" ]]; then
49
49
  p=$(jq -r '.port // empty' "$cfg" 2>/dev/null || true)
50
50
  if [[ -n "$p" && "$p" =~ ^[0-9]+$ ]]; then echo "$p"; return; fi
@@ -38,7 +38,7 @@ detect_port() {
38
38
  local p="${TARGET_PORT:-}"
39
39
  if [[ -n "$p" ]]; then echo "$p"; return; fi
40
40
  if [[ -n "${ROUTECODEX_PORT:-}" ]]; then echo "${ROUTECODEX_PORT}"; return; fi
41
- local cfg="$HOME/.routecodex/config.json"
41
+ local cfg="$HOME/.rcc/config.json"
42
42
  if command -v jq >/dev/null 2>&1 && [[ -f "$cfg" ]]; then
43
43
  p=$(jq -r '.port // empty' "$cfg" 2>/dev/null || true)
44
44
  if [[ -n "$p" && "$p" =~ ^[0-9]+$ ]]; then echo "$p"; return; fi
@@ -180,7 +180,7 @@ async function main() {
180
180
  const samplePath = args.sample || args._[0];
181
181
  if (!samplePath) throw new Error('Missing --sample <file.json>');
182
182
 
183
- const configPath = args.config || path.join(os.homedir(), '.routecodex', 'config.json');
183
+ const configPath = args.config || path.join(os.homedir(), '.rcc', 'config.json');
184
184
  const outDir = args.out || path.join(process.cwd(), 'test-results', 'antigravity-pipeline-compare');
185
185
  fs.mkdirSync(outDir, { recursive: true });
186
186
 
@@ -85,7 +85,7 @@ async function main() {
85
85
  const baselinePath = args.baseline || args._[1];
86
86
  if (!baselinePath) throw new Error('Missing --baseline <provider-request.json>');
87
87
 
88
- const configPath = args.config || path.join(os.homedir(), '.routecodex', 'config.json');
88
+ const configPath = args.config || path.join(os.homedir(), '.rcc', 'config.json');
89
89
  const outDir = args.out || path.join(process.cwd(), 'test-results', 'antigravity-gemini-dryrun');
90
90
  fs.mkdirSync(outDir, { recursive: true });
91
91
 
@@ -21,7 +21,7 @@ function usage(err) {
21
21
  }
22
22
 
23
23
  const args = process.argv.slice(2);
24
- const configPath = args[0] || path.join(process.env.HOME || '~', '.routecodex', 'provider', 'c4m', 'config.v1.json');
24
+ const configPath = args[0] || path.join(process.env.HOME || '~', '.rcc', 'provider', 'c4m', 'config.v1.json');
25
25
  if (!fs.existsSync(configPath)) usage(`Config file not found: ${configPath}`);
26
26
  const providerTarget = args[1] || 'c4m.gpt-5.1';
27
27
  const [providerId, modelId = 'gpt-5.1'] = providerTarget.split('.');
@@ -360,7 +360,7 @@ async function scenarioRealConfig(configPath) {
360
360
  async function main() {
361
361
  const args = parseArgs(process.argv.slice(2));
362
362
  if (args.help) {
363
- console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.routecodex/config.json]');
363
+ console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.rcc/config.json]');
364
364
  return;
365
365
  }
366
366
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Update provider models from /v1/models endpoint and write into the user's
4
- * RouteCodex config (defaults to ~/.routecodex/config.json).
4
+ * RouteCodex config (defaults to ~/.rcc/config.json).
5
5
  *
6
6
  * Usage:
7
7
  * node scripts/update-models.mjs --provider qwen-provider [--write] [--config path]
@@ -27,7 +27,7 @@ function expandHome(p){ return p && p.startsWith('~/')? p.replace(/^~\//, `${pro
27
27
 
28
28
  function resolveConfigPath(explicit){
29
29
  const envPath = process.env.ROUTECODEX_CONFIG_PATH || process.env.ROUTECODEX_CONFIG;
30
- const fallback = path.join(process.env.HOME || '', '.routecodex', 'config.json');
30
+ const fallback = path.join(process.env.HOME || '', '.rcc', 'config.json');
31
31
  const candidate = expandHome(explicit || envPath || fallback);
32
32
  if (!candidate) {
33
33
  throw new Error('Unable to resolve configuration path');
@@ -149,7 +149,7 @@ const debugLogsCount = fs.existsSync(debugLogsDir)
149
149
 
150
150
  if (debugLogsCount > 0) {
151
151
  console.log('✅ 流水线系统活跃');
152
- console.log('💡 建议使用: routecodex start --config ~/.routecodex/config.json (默认监听 5555 端口)');
152
+ console.log('💡 建议使用: routecodex start --config ~/.rcc/config.json (默认监听 5555 端口)');
153
153
  } else {
154
154
  console.log('⚠️ 流水线系统可能未启动');
155
155
  console.log('💡 建议检查 5555 端口上的 RouteCodex 服务是否已启动(routecodex start)');
@@ -18,11 +18,11 @@ async function main() {
18
18
  const legacyVendorDir = path.join(root, 'vendor', 'rcc-llmswitch-core');
19
19
  const scopedVendorDir = path.join(root, 'vendor', '@jsonstudio', 'llms');
20
20
 
21
- // In release mode we rely on npm-installed `@jsonstudio/llms`, so the local sharedmodule dist
22
- // is optional and must not block CI (where sharedmodule often doesn't exist).
23
- // In dev mode, `node_modules/@jsonstudio/llms` is typically symlinked to sharedmodule/llmswitch-core,
24
- // so we keep a hard requirement for the dist output.
25
- if (mode === 'dev' && !await exists(sharedDist)) {
21
+ const hasLocalSharedDist = await exists(sharedDist);
22
+
23
+ // 当本地 sharedmodule/llmswitch-core 存在时,dev/release 都以它为唯一真源。
24
+ // 仅在 release 且本地 sharedmodule 缺失时,才允许退回 npm-installed @jsonstudio/llms。
25
+ if (!hasLocalSharedDist && mode === 'dev') {
26
26
  console.error('[vendor-core] ERROR: 未找到 sharedmodule/llmswitch-core/dist (BUILD_MODE=dev)');
27
27
  console.error('[vendor-core] 请先进入 sharedmodule/llmswitch-core 并运行 `npm run build`。');
28
28
  process.exit(2);
@@ -37,10 +37,15 @@ async function main() {
37
37
  console.log('[vendor-core] removed legacy vendor/@jsonstudio/llms directory');
38
38
  }
39
39
 
40
- if (mode === 'dev') {
40
+ if (hasLocalSharedDist) {
41
+ const banner = mode === 'dev'
42
+ ? '[vendor-core] BUILD_MODE=dev: direct-use local sharedmodule/llmswitch-core/dist (no vendor copy).'
43
+ : '[vendor-core] BUILD_MODE=release with local sharedmodule/llmswitch-core/dist: direct-use local core (no vendor copy).';
44
+ console.log(banner);
45
+ } else if (mode === 'dev') {
41
46
  console.log('[vendor-core] sharedmodule/llmswitch-core/dist 将被直接引用,已停止生成 vendor 副本。');
42
47
  } else {
43
- console.log('[vendor-core] BUILD_MODE=release: using npm-installed @jsonstudio/llms (no vendor copy).');
48
+ console.log('[vendor-core] BUILD_MODE=release without local sharedmodule: using npm-installed @jsonstudio/llms (no vendor copy).');
44
49
  }
45
50
  }
46
51
 
@@ -24,7 +24,7 @@ const VERIFY_BASE = process.env.ROUTECODEX_VERIFY_BASE_URL || `http://127.0.0.1:
24
24
  const VERIFY_CONFIG =
25
25
  process.env.ROUTECODEX_VERIFY_CONFIG ||
26
26
  process.env.ROUTECODEX_CONFIG_PATH ||
27
- `${process.env.HOME || ''}/.routecodex/config.json`;
27
+ `${process.env.HOME || ''}/.rcc/config.json`;
28
28
 
29
29
  const DEFAULT_SAMPLE = path.join(
30
30
  os.homedir(),
@@ -16,11 +16,11 @@ const VERIFY_BASE = process.env.ROUTECODEX_VERIFY_BASE_URL || `http://127.0.0.1:
16
16
  const EXPLICIT_VERIFY_CONFIG = String(
17
17
  process.env.ROUTECODEX_VERIFY_CONFIG || process.env.ROUTECODEX_CONFIG_PATH || ''
18
18
  ).trim();
19
- const DEFAULT_USER_CONFIG = `${process.env.HOME || ''}/.routecodex/config.json`;
19
+ const DEFAULT_USER_CONFIG = `${process.env.HOME || ''}/.rcc/config.json`;
20
20
  const USE_USER_CONFIG = String(process.env.ROUTECODEX_VERIFY_USE_USER_CONFIG || '').trim() === '1';
21
21
  const GEMINI_CLI_CONFIG =
22
22
  process.env.ROUTECODEX_VERIFY_GEMINI_CLI_CONFIG ||
23
- `${process.env.HOME || ''}/.routecodex/provider/gemini-cli/config.v1.json`;
23
+ `${process.env.HOME || ''}/.rcc/provider/gemini-cli/config.v1.json`;
24
24
 
25
25
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
26
26
  const DEFAULT_AGENTS_PATH = path.resolve(__dirname, '..', 'AGENTS.md');
@@ -55,8 +55,8 @@ async function waitForHealth() {
55
55
  async function resolveTestModel() {
56
56
  const home = os.homedir();
57
57
  const candidates = [
58
- path.join(home, '.routecodex', 'config', 'generated', `virtual-router-config.${port}.generated.json`),
59
- path.join(home, '.routecodex', 'config', 'generated', 'virtual-router-config.generated.json'),
58
+ path.join(home, '.rcc', 'config', 'generated', `virtual-router-config.${port}.generated.json`),
59
+ path.join(home, '.rcc', 'config', 'generated', 'virtual-router-config.generated.json'),
60
60
  ];
61
61
  for (const file of candidates) {
62
62
  try {
@@ -42,7 +42,7 @@ function resolveSecretValue(value) {
42
42
  }
43
43
 
44
44
  function loadProviderEntry(providerId) {
45
- const providerRoot = path.join(os.homedir(), '.routecodex', 'provider', providerId);
45
+ const providerRoot = path.join(os.homedir(), '.rcc', 'provider', providerId);
46
46
  for (const name of PROVIDER_CONFIG_FILES) {
47
47
  const full = path.join(providerRoot, name);
48
48
  if (!fs.existsSync(full)) continue;
@@ -6,7 +6,7 @@
6
6
  * node scripts/virtual-router-dryrun.mjs --sampleDir <~/.routecodex/codex-samples/.../req_...> [options]
7
7
  *
8
8
  * Options:
9
- * --config <path> RouteCodex user config (default: ~/.routecodex/config.json)
9
+ * --config <path> RouteCodex user config (default: ~/.rcc/config.json)
10
10
  * --serverId <host:port> Router state serverId (default: 0.0.0.0:5520)
11
11
  * --repeat <n> Repeat route() N times (default: 8)
12
12
  * --mode <base|actual|both> Run modes (default: both)
@@ -154,7 +154,7 @@ async function main() {
154
154
  process.exit(1);
155
155
  }
156
156
 
157
- const configPath = args.config || path.join(os.homedir(), '.routecodex', 'config.json');
157
+ const configPath = args.config || path.join(os.homedir(), '.rcc', 'config.json');
158
158
  const serverId = args.serverId || '0.0.0.0:5520';
159
159
  const repeat = Math.max(1, Number.parseInt(String(args.repeat || '8'), 10) || 8);
160
160
  const mode = String(args.mode || 'both').trim().toLowerCase();