@kaitranntt/ccs 8.8.1 → 8.9.0-dev.10

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 (429) hide show
  1. package/README.md +9 -7
  2. package/dist/api/services/profile-lifecycle-validation.d.ts.map +1 -1
  3. package/dist/api/services/profile-lifecycle-validation.js +3 -8
  4. package/dist/api/services/profile-lifecycle-validation.js.map +1 -1
  5. package/dist/auth/auth-commands.js +3 -3
  6. package/dist/auth/auth-commands.js.map +1 -1
  7. package/dist/auth/resume-lane-diagnostics.d.ts +9 -0
  8. package/dist/auth/resume-lane-diagnostics.d.ts.map +1 -1
  9. package/dist/auth/resume-lane-diagnostics.js +105 -1
  10. package/dist/auth/resume-lane-diagnostics.js.map +1 -1
  11. package/dist/auth/resume-lane-warning.d.ts +9 -1
  12. package/dist/auth/resume-lane-warning.d.ts.map +1 -1
  13. package/dist/auth/resume-lane-warning.js +72 -5
  14. package/dist/auth/resume-lane-warning.js.map +1 -1
  15. package/dist/ccs.d.ts +1 -1
  16. package/dist/ccs.d.ts.map +1 -1
  17. package/dist/ccs.js +5 -1
  18. package/dist/ccs.js.map +1 -1
  19. package/dist/cliproxy/accounts/registry.d.ts.map +1 -1
  20. package/dist/cliproxy/accounts/registry.js +14 -16
  21. package/dist/cliproxy/accounts/registry.js.map +1 -1
  22. package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts +1 -1
  23. package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts.map +1 -1
  24. package/dist/cliproxy/auth/oauth-cli-args.d.ts +11 -0
  25. package/dist/cliproxy/auth/oauth-cli-args.d.ts.map +1 -0
  26. package/dist/cliproxy/auth/oauth-cli-args.js +53 -0
  27. package/dist/cliproxy/auth/oauth-cli-args.js.map +1 -0
  28. package/dist/cliproxy/auth/oauth-cli-capabilities.d.ts +11 -0
  29. package/dist/cliproxy/auth/oauth-cli-capabilities.d.ts.map +1 -0
  30. package/dist/cliproxy/auth/oauth-cli-capabilities.js +101 -0
  31. package/dist/cliproxy/auth/oauth-cli-capabilities.js.map +1 -0
  32. package/dist/cliproxy/auth/oauth-handler.d.ts +0 -6
  33. package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
  34. package/dist/cliproxy/auth/oauth-handler.js +70 -43
  35. package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
  36. package/dist/cliproxy/auth/test-fixtures/gemini-backend-guidance-child.scenario.d.ts +2 -0
  37. package/dist/cliproxy/auth/test-fixtures/gemini-backend-guidance-child.scenario.d.ts.map +1 -0
  38. package/dist/cliproxy/auth/test-fixtures/gemini-backend-guidance-child.scenario.js +207 -0
  39. package/dist/cliproxy/auth/test-fixtures/gemini-backend-guidance-child.scenario.js.map +1 -0
  40. package/dist/cliproxy/binary/install-lifecycle-lock.d.ts +2 -0
  41. package/dist/cliproxy/binary/install-lifecycle-lock.d.ts.map +1 -0
  42. package/dist/cliproxy/binary/install-lifecycle-lock.js +63 -0
  43. package/dist/cliproxy/binary/install-lifecycle-lock.js.map +1 -0
  44. package/dist/cliproxy/binary/installer.d.ts +13 -1
  45. package/dist/cliproxy/binary/installer.d.ts.map +1 -1
  46. package/dist/cliproxy/binary/installer.js +81 -42
  47. package/dist/cliproxy/binary/installer.js.map +1 -1
  48. package/dist/cliproxy/binary/lifecycle.d.ts +6 -1
  49. package/dist/cliproxy/binary/lifecycle.d.ts.map +1 -1
  50. package/dist/cliproxy/binary/lifecycle.js +13 -10
  51. package/dist/cliproxy/binary/lifecycle.js.map +1 -1
  52. package/dist/cliproxy/binary-manager.d.ts +3 -0
  53. package/dist/cliproxy/binary-manager.d.ts.map +1 -1
  54. package/dist/cliproxy/binary-manager.js +32 -30
  55. package/dist/cliproxy/binary-manager.js.map +1 -1
  56. package/dist/cliproxy/config/env-builder.d.ts +5 -0
  57. package/dist/cliproxy/config/env-builder.d.ts.map +1 -1
  58. package/dist/cliproxy/config/env-builder.js +24 -1
  59. package/dist/cliproxy/config/env-builder.js.map +1 -1
  60. package/dist/cliproxy/config/extended-context-config.d.ts.map +1 -1
  61. package/dist/cliproxy/config/extended-context-config.js +38 -1
  62. package/dist/cliproxy/config/extended-context-config.js.map +1 -1
  63. package/dist/cliproxy/config/generator.d.ts +2 -1
  64. package/dist/cliproxy/config/generator.d.ts.map +1 -1
  65. package/dist/cliproxy/config/generator.js +81 -11
  66. package/dist/cliproxy/config/generator.js.map +1 -1
  67. package/dist/cliproxy/config/oauth-model-alias-config.d.ts +6 -0
  68. package/dist/cliproxy/config/oauth-model-alias-config.d.ts.map +1 -0
  69. package/dist/cliproxy/config/oauth-model-alias-config.js +136 -0
  70. package/dist/cliproxy/config/oauth-model-alias-config.js.map +1 -0
  71. package/dist/cliproxy/config/payload-rule-config.d.ts +6 -0
  72. package/dist/cliproxy/config/payload-rule-config.d.ts.map +1 -0
  73. package/dist/cliproxy/config/payload-rule-config.js +137 -0
  74. package/dist/cliproxy/config/payload-rule-config.js.map +1 -0
  75. package/dist/cliproxy/executor/claude-launcher.d.ts +3 -0
  76. package/dist/cliproxy/executor/claude-launcher.d.ts.map +1 -1
  77. package/dist/cliproxy/executor/claude-launcher.js +7 -3
  78. package/dist/cliproxy/executor/claude-launcher.js.map +1 -1
  79. package/dist/cliproxy/executor/env-resolver.d.ts +2 -0
  80. package/dist/cliproxy/executor/env-resolver.d.ts.map +1 -1
  81. package/dist/cliproxy/executor/env-resolver.js +6 -4
  82. package/dist/cliproxy/executor/env-resolver.js.map +1 -1
  83. package/dist/cliproxy/executor/index.d.ts.map +1 -1
  84. package/dist/cliproxy/executor/index.js +7 -5
  85. package/dist/cliproxy/executor/index.js.map +1 -1
  86. package/dist/cliproxy/executor/launch-settings.d.ts.map +1 -1
  87. package/dist/cliproxy/executor/launch-settings.js +9 -2
  88. package/dist/cliproxy/executor/launch-settings.js.map +1 -1
  89. package/dist/cliproxy/model-catalog.d.ts +8 -0
  90. package/dist/cliproxy/model-catalog.d.ts.map +1 -1
  91. package/dist/cliproxy/model-catalog.js +109 -2
  92. package/dist/cliproxy/model-catalog.js.map +1 -1
  93. package/dist/cliproxy/quota/quota-fetcher-claude.d.ts.map +1 -1
  94. package/dist/cliproxy/quota/quota-fetcher-claude.js +11 -1
  95. package/dist/cliproxy/quota/quota-fetcher-claude.js.map +1 -1
  96. package/dist/cliproxy/routing/retry-settings.d.ts +18 -0
  97. package/dist/cliproxy/routing/retry-settings.d.ts.map +1 -0
  98. package/dist/cliproxy/routing/retry-settings.js +185 -0
  99. package/dist/cliproxy/routing/retry-settings.js.map +1 -0
  100. package/dist/cliproxy/routing/routing-strategy-http.d.ts +3 -0
  101. package/dist/cliproxy/routing/routing-strategy-http.d.ts.map +1 -1
  102. package/dist/cliproxy/routing/routing-strategy-http.js +13 -3
  103. package/dist/cliproxy/routing/routing-strategy-http.js.map +1 -1
  104. package/dist/cliproxy/services/binary-service.d.ts.map +1 -1
  105. package/dist/cliproxy/services/binary-service.js +24 -20
  106. package/dist/cliproxy/services/binary-service.js.map +1 -1
  107. package/dist/cliproxy/services/catalog-cache.d.ts.map +1 -1
  108. package/dist/cliproxy/services/catalog-cache.js +8 -0
  109. package/dist/cliproxy/services/catalog-cache.js.map +1 -1
  110. package/dist/cliproxy/session-tracker.d.ts.map +1 -1
  111. package/dist/cliproxy/session-tracker.js +4 -18
  112. package/dist/cliproxy/session-tracker.js.map +1 -1
  113. package/dist/cliproxy/types/binary-types.d.ts +1 -0
  114. package/dist/cliproxy/types/binary-types.d.ts.map +1 -1
  115. package/dist/cliproxy/types/config-types.d.ts +3 -0
  116. package/dist/cliproxy/types/config-types.d.ts.map +1 -1
  117. package/dist/codex-auth/shell-detect.d.ts +2 -0
  118. package/dist/codex-auth/shell-detect.d.ts.map +1 -1
  119. package/dist/codex-auth/shell-detect.js +15 -1
  120. package/dist/codex-auth/shell-detect.js.map +1 -1
  121. package/dist/commands/bar/bar-process-control.d.ts +43 -0
  122. package/dist/commands/bar/bar-process-control.d.ts.map +1 -0
  123. package/dist/commands/bar/bar-process-control.js +255 -0
  124. package/dist/commands/bar/bar-process-control.js.map +1 -0
  125. package/dist/commands/bar/bar-server-probe.d.ts +5 -2
  126. package/dist/commands/bar/bar-server-probe.d.ts.map +1 -1
  127. package/dist/commands/bar/bar-server-probe.js +38 -12
  128. package/dist/commands/bar/bar-server-probe.js.map +1 -1
  129. package/dist/commands/bar/help-subcommand.d.ts.map +1 -1
  130. package/dist/commands/bar/help-subcommand.js +2 -0
  131. package/dist/commands/bar/help-subcommand.js.map +1 -1
  132. package/dist/commands/bar/index.d.ts.map +1 -1
  133. package/dist/commands/bar/index.js +13 -3
  134. package/dist/commands/bar/index.js.map +1 -1
  135. package/dist/commands/bar/launch-descriptor.d.ts +2 -0
  136. package/dist/commands/bar/launch-descriptor.d.ts.map +1 -1
  137. package/dist/commands/bar/launch-descriptor.js +6 -1
  138. package/dist/commands/bar/launch-descriptor.js.map +1 -1
  139. package/dist/commands/bar/launch-subcommand.d.ts +18 -1
  140. package/dist/commands/bar/launch-subcommand.d.ts.map +1 -1
  141. package/dist/commands/bar/launch-subcommand.js +149 -45
  142. package/dist/commands/bar/launch-subcommand.js.map +1 -1
  143. package/dist/commands/bar/port-arg.d.ts +16 -0
  144. package/dist/commands/bar/port-arg.d.ts.map +1 -0
  145. package/dist/commands/bar/port-arg.js +41 -0
  146. package/dist/commands/bar/port-arg.js.map +1 -0
  147. package/dist/commands/bar/serve-subcommand.d.ts +5 -0
  148. package/dist/commands/bar/serve-subcommand.d.ts.map +1 -1
  149. package/dist/commands/bar/serve-subcommand.js +47 -29
  150. package/dist/commands/bar/serve-subcommand.js.map +1 -1
  151. package/dist/commands/bar/status-subcommand.d.ts.map +1 -1
  152. package/dist/commands/bar/status-subcommand.js +11 -2
  153. package/dist/commands/bar/status-subcommand.js.map +1 -1
  154. package/dist/commands/bar/stop-subcommand.d.ts +5 -0
  155. package/dist/commands/bar/stop-subcommand.d.ts.map +1 -1
  156. package/dist/commands/bar/stop-subcommand.js +71 -27
  157. package/dist/commands/bar/stop-subcommand.js.map +1 -1
  158. package/dist/commands/cliproxy/catalog-subcommand.d.ts.map +1 -1
  159. package/dist/commands/cliproxy/catalog-subcommand.js +2 -0
  160. package/dist/commands/cliproxy/catalog-subcommand.js.map +1 -1
  161. package/dist/commands/cliproxy/quota-subcommand/format-helpers.js +1 -1
  162. package/dist/commands/cliproxy/quota-subcommand/handlers.js +1 -1
  163. package/dist/commands/cliproxy/quota-subcommand/handlers.js.map +1 -1
  164. package/dist/commands/cliproxy/quota-subcommand/sections/claude.d.ts.map +1 -1
  165. package/dist/commands/cliproxy/quota-subcommand/sections/claude.js +3 -2
  166. package/dist/commands/cliproxy/quota-subcommand/sections/claude.js.map +1 -1
  167. package/dist/commands/cliproxy/quota-subcommand/sections/codex.js +1 -1
  168. package/dist/commands/cliproxy/quota-subcommand/sections/codex.js.map +1 -1
  169. package/dist/commands/cliproxy/quota-subcommand/sections/gemini-cli.js +1 -1
  170. package/dist/commands/cliproxy/quota-subcommand/sections/gemini-cli.js.map +1 -1
  171. package/dist/commands/setup-command.js +1 -1
  172. package/dist/commands/setup-command.js.map +1 -1
  173. package/dist/commands/version-command.js +1 -1
  174. package/dist/commands/version-command.js.map +1 -1
  175. package/dist/config/schemas/auth.d.ts +2 -2
  176. package/dist/config/schemas/auth.d.ts.map +1 -1
  177. package/dist/config/schemas/cliproxy.d.ts +66 -0
  178. package/dist/config/schemas/cliproxy.d.ts.map +1 -1
  179. package/dist/config/schemas/cliproxy.js +13 -1
  180. package/dist/config/schemas/cliproxy.js.map +1 -1
  181. package/dist/config/schemas/index.d.ts +1 -1
  182. package/dist/config/schemas/index.d.ts.map +1 -1
  183. package/dist/config/schemas/index.js.map +1 -1
  184. package/dist/config/schemas/version.d.ts +2 -1
  185. package/dist/config/schemas/version.d.ts.map +1 -1
  186. package/dist/config/schemas/version.js +2 -1
  187. package/dist/config/schemas/version.js.map +1 -1
  188. package/dist/copilot/copilot-executor.d.ts +3 -1
  189. package/dist/copilot/copilot-executor.d.ts.map +1 -1
  190. package/dist/copilot/copilot-executor.js +11 -7
  191. package/dist/copilot/copilot-executor.js.map +1 -1
  192. package/dist/cursor/cursor-profile-executor.d.ts +3 -1
  193. package/dist/cursor/cursor-profile-executor.d.ts.map +1 -1
  194. package/dist/cursor/cursor-profile-executor.js +8 -4
  195. package/dist/cursor/cursor-profile-executor.js.map +1 -1
  196. package/dist/delegation/delegation-handler.d.ts.map +1 -1
  197. package/dist/delegation/delegation-handler.js +12 -2
  198. package/dist/delegation/delegation-handler.js.map +1 -1
  199. package/dist/delegation/headless-executor.d.ts.map +1 -1
  200. package/dist/delegation/headless-executor.js +4 -3
  201. package/dist/delegation/headless-executor.js.map +1 -1
  202. package/dist/dispatcher/flows/copilot-flow.d.ts.map +1 -1
  203. package/dist/dispatcher/flows/copilot-flow.js +3 -2
  204. package/dist/dispatcher/flows/copilot-flow.js.map +1 -1
  205. package/dist/dispatcher/flows/cursor-flow.d.ts.map +1 -1
  206. package/dist/dispatcher/flows/cursor-flow.js +3 -2
  207. package/dist/dispatcher/flows/cursor-flow.js.map +1 -1
  208. package/dist/dispatcher/flows/settings-flow.d.ts.map +1 -1
  209. package/dist/dispatcher/flows/settings-flow.js +12 -10
  210. package/dist/dispatcher/flows/settings-flow.js.map +1 -1
  211. package/dist/management/instance-directory.d.ts +19 -0
  212. package/dist/management/instance-directory.d.ts.map +1 -1
  213. package/dist/management/instance-directory.js +130 -7
  214. package/dist/management/instance-directory.js.map +1 -1
  215. package/dist/management/instance-manager.d.ts +2 -5
  216. package/dist/management/instance-manager.d.ts.map +1 -1
  217. package/dist/management/instance-manager.js +26 -27
  218. package/dist/management/instance-manager.js.map +1 -1
  219. package/dist/management/shared-manager/canonical-first-file-claims.d.ts +6 -0
  220. package/dist/management/shared-manager/canonical-first-file-claims.d.ts.map +1 -0
  221. package/dist/management/shared-manager/canonical-first-file-claims.js +143 -0
  222. package/dist/management/shared-manager/canonical-first-file-claims.js.map +1 -0
  223. package/dist/management/shared-manager/canonical-first-file-reconciler.d.ts +15 -0
  224. package/dist/management/shared-manager/canonical-first-file-reconciler.d.ts.map +1 -0
  225. package/dist/management/shared-manager/canonical-first-file-reconciler.js +131 -0
  226. package/dist/management/shared-manager/canonical-first-file-reconciler.js.map +1 -0
  227. package/dist/management/shared-manager/diverged-file-adopter.d.ts +5 -0
  228. package/dist/management/shared-manager/diverged-file-adopter.d.ts.map +1 -0
  229. package/dist/management/shared-manager/diverged-file-adopter.js +391 -0
  230. package/dist/management/shared-manager/diverged-file-adopter.js.map +1 -0
  231. package/dist/management/shared-manager/fs-helpers.d.ts +9 -0
  232. package/dist/management/shared-manager/fs-helpers.d.ts.map +1 -1
  233. package/dist/management/shared-manager/fs-helpers.js +9 -0
  234. package/dist/management/shared-manager/fs-helpers.js.map +1 -1
  235. package/dist/management/shared-manager/plugin-layout-internals.d.ts +1 -1
  236. package/dist/management/shared-manager/plugin-layout-internals.d.ts.map +1 -1
  237. package/dist/management/shared-manager/plugin-layout-internals.js +54 -8
  238. package/dist/management/shared-manager/plugin-layout-internals.js.map +1 -1
  239. package/dist/management/shared-manager/shared-dir-linker.d.ts +1 -1
  240. package/dist/management/shared-manager/shared-dir-linker.d.ts.map +1 -1
  241. package/dist/management/shared-manager/shared-dir-linker.js +147 -75
  242. package/dist/management/shared-manager/shared-dir-linker.js.map +1 -1
  243. package/dist/management/shared-manager/types.d.ts +12 -1
  244. package/dist/management/shared-manager/types.d.ts.map +1 -1
  245. package/dist/management/shared-manager/types.js +12 -1
  246. package/dist/management/shared-manager/types.js.map +1 -1
  247. package/dist/proxy/proxy-daemon-entry.js +10 -2
  248. package/dist/proxy/proxy-daemon-entry.js.map +1 -1
  249. package/dist/proxy/server/messages-route.d.ts +2 -2
  250. package/dist/proxy/server/messages-route.d.ts.map +1 -1
  251. package/dist/proxy/server/messages-route.js +33 -24
  252. package/dist/proxy/server/messages-route.js.map +1 -1
  253. package/dist/proxy/server/proxy-server.d.ts +1 -0
  254. package/dist/proxy/server/proxy-server.d.ts.map +1 -1
  255. package/dist/proxy/server/proxy-server.js +57 -5
  256. package/dist/proxy/server/proxy-server.js.map +1 -1
  257. package/dist/proxy/server/upstream-transport.d.ts +14 -0
  258. package/dist/proxy/server/upstream-transport.d.ts.map +1 -0
  259. package/dist/proxy/server/upstream-transport.js +72 -0
  260. package/dist/proxy/server/upstream-transport.js.map +1 -0
  261. package/dist/proxy/transformers/request-transformer.d.ts.map +1 -1
  262. package/dist/proxy/transformers/request-transformer.js +43 -1
  263. package/dist/proxy/transformers/request-transformer.js.map +1 -1
  264. package/dist/services/logging/log-redaction.d.ts.map +1 -1
  265. package/dist/services/logging/log-redaction.js +4 -1
  266. package/dist/services/logging/log-redaction.js.map +1 -1
  267. package/dist/services/logging/log-types.d.ts +1 -0
  268. package/dist/services/logging/log-types.d.ts.map +1 -1
  269. package/dist/services/logging/log-types.js.map +1 -1
  270. package/dist/shared/extended-context-utils.d.ts +18 -2
  271. package/dist/shared/extended-context-utils.d.ts.map +1 -1
  272. package/dist/shared/extended-context-utils.js +38 -3
  273. package/dist/shared/extended-context-utils.js.map +1 -1
  274. package/dist/shared/provider-preset-catalog.d.ts +2 -1
  275. package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
  276. package/dist/shared/provider-preset-catalog.js +18 -1
  277. package/dist/shared/provider-preset-catalog.js.map +1 -1
  278. package/dist/types/config.d.ts +2 -2
  279. package/dist/types/config.d.ts.map +1 -1
  280. package/dist/ui/assets/{Trans-DTklOPAl.js → Trans-Dv0FgbfN.js} +1 -1
  281. package/dist/ui/assets/{accounts-Cvmw1zaL.js → accounts-DD4gJm5G.js} +1 -1
  282. package/dist/ui/assets/{alert-dialog-xN1Vxm4Q.js → alert-dialog-CfsyUL5i.js} +1 -1
  283. package/dist/ui/assets/{api-UjGDV1dn.js → api-Rml_6r1f.js} +1 -1
  284. package/dist/ui/assets/{auth-section-exE9zovq.js → auth-section-ud23YOqo.js} +1 -1
  285. package/dist/ui/assets/{backups-section-CANdqpNT.js → backups-section-BvojIR_s.js} +1 -1
  286. package/dist/ui/assets/{channels-C8d6AgLN.js → channels-C6JAnQ-P.js} +1 -1
  287. package/dist/ui/assets/{checkbox-B71vxZdD.js → checkbox-e4TE1vtU.js} +1 -1
  288. package/dist/ui/assets/{claude-extension-COD7m8Iq.js → claude-extension-Crqbbisi.js} +1 -1
  289. package/dist/ui/assets/cliproxy-CTzg_fbJ.js +4 -0
  290. package/dist/ui/assets/{cliproxy-ai-providers-C79GuQ92.js → cliproxy-ai-providers-DRfGjeni.js} +5 -5
  291. package/dist/ui/assets/{cliproxy-control-panel-B6_hOtz6.js → cliproxy-control-panel-C0TgmqD6.js} +1 -1
  292. package/dist/ui/assets/{codex-3mlgCMGk.js → codex-CGFN2_Yz.js} +1 -1
  293. package/dist/ui/assets/{confirm-dialog-CHnCNFFP.js → confirm-dialog-CWYwcPu7.js} +1 -1
  294. package/dist/ui/assets/{copilot-CfmS6yON.js → copilot-CDo33AQ9.js} +2 -2
  295. package/dist/ui/assets/{cursor-tzPHgV8J.js → cursor-nVJdycFe.js} +1 -1
  296. package/dist/ui/assets/{droid-Bc8LlbJa.js → droid-C1mg2O8N.js} +1 -1
  297. package/dist/ui/assets/{globalenv-section-DTYeLBoB.js → globalenv-section-D0iUrk5Z.js} +1 -1
  298. package/dist/ui/assets/{health-9Xyzeiyx.js → health-CIcj1Jxy.js} +1 -1
  299. package/dist/ui/assets/{index-B0M7QB1o.js → index-AosRBwPp.js} +1 -1
  300. package/dist/ui/assets/{index-DoHAX6LH.js → index-BCqgbLRB.js} +1 -1
  301. package/dist/ui/assets/{index-CEx6YJb5.js → index-BxcCMHzL.js} +1 -1
  302. package/dist/ui/assets/{index-Bz1gMXk1.js → index-DZbSKKhp.js} +1 -1
  303. package/dist/ui/assets/{index-DuD3QaMG.js → index-DvvpgsgL.js} +1 -1
  304. package/dist/ui/assets/index-DwlqXVPF.js +56 -0
  305. package/dist/ui/assets/{index-Bjg11-rW.js → index-W-L7VU-4.js} +1 -1
  306. package/dist/ui/assets/{logs-CrjUtfDp.js → logs-CLIARnH2.js} +1 -1
  307. package/dist/ui/assets/{masked-input-BAtRbixr.js → masked-input-BRcjJtU3.js} +1 -1
  308. package/dist/ui/assets/proxy-status-widget-CBBs3HmJ.js +1 -0
  309. package/dist/ui/assets/{raw-json-settings-editor-panel-CvJCywnk.js → raw-json-settings-editor-panel-DhDm8jkK.js} +1 -1
  310. package/dist/ui/assets/{searchable-select-Bn50_-2s.js → searchable-select-DW5e6ct1.js} +1 -1
  311. package/dist/ui/assets/{separator-DY36bzud.js → separator-D-2blr1t.js} +1 -1
  312. package/dist/ui/assets/{shared-BynjOvKs.js → shared-BIRVeSaP.js} +1 -1
  313. package/dist/ui/assets/{table-DdcK8yYq.js → table-CEyFyU_X.js} +1 -1
  314. package/dist/ui/assets/{updates-D27A1hQG.js → updates-Dcpm3clh.js} +1 -1
  315. package/dist/ui/assets/{use-accounts-CRxt0j07.js → use-accounts-Cjb9-mnK.js} +1 -1
  316. package/dist/ui/icons/orcarouter.svg +1 -0
  317. package/dist/ui/index.html +2 -2
  318. package/dist/utils/fetch-proxy-setup.d.ts.map +1 -1
  319. package/dist/utils/fetch-proxy-setup.js +10 -6
  320. package/dist/utils/fetch-proxy-setup.js.map +1 -1
  321. package/dist/utils/hooks/image-analysis-backend-resolver.d.ts.map +1 -1
  322. package/dist/utils/hooks/image-analysis-backend-resolver.js +6 -0
  323. package/dist/utils/hooks/image-analysis-backend-resolver.js.map +1 -1
  324. package/dist/utils/hooks/image-analysis-runtime-status.d.ts.map +1 -1
  325. package/dist/utils/hooks/image-analysis-runtime-status.js +8 -3
  326. package/dist/utils/hooks/image-analysis-runtime-status.js.map +1 -1
  327. package/dist/utils/package-manager-detector.d.ts.map +1 -1
  328. package/dist/utils/package-manager-detector.js +6 -2
  329. package/dist/utils/package-manager-detector.js.map +1 -1
  330. package/dist/utils/shell-executor.d.ts +1 -1
  331. package/dist/utils/shell-executor.d.ts.map +1 -1
  332. package/dist/utils/shell-executor.js +5 -8
  333. package/dist/utils/shell-executor.js.map +1 -1
  334. package/dist/utils/sync-lock-retry.d.ts +9 -0
  335. package/dist/utils/sync-lock-retry.d.ts.map +1 -0
  336. package/dist/utils/sync-lock-retry.js +107 -0
  337. package/dist/utils/sync-lock-retry.js.map +1 -0
  338. package/dist/utils/websearch/agy.d.ts +3 -1
  339. package/dist/utils/websearch/agy.d.ts.map +1 -1
  340. package/dist/utils/websearch/agy.js +33 -23
  341. package/dist/utils/websearch/agy.js.map +1 -1
  342. package/dist/utils/websearch/claude-tool-args.d.ts +1 -1
  343. package/dist/utils/websearch/claude-tool-args.d.ts.map +1 -1
  344. package/dist/utils/websearch/claude-tool-args.js +3 -2
  345. package/dist/utils/websearch/claude-tool-args.js.map +1 -1
  346. package/dist/utils/websearch/gemini-cli.d.ts +3 -1
  347. package/dist/utils/websearch/gemini-cli.d.ts.map +1 -1
  348. package/dist/utils/websearch/gemini-cli.js +33 -23
  349. package/dist/utils/websearch/gemini-cli.js.map +1 -1
  350. package/dist/utils/websearch/grok-cli.d.ts +3 -1
  351. package/dist/utils/websearch/grok-cli.d.ts.map +1 -1
  352. package/dist/utils/websearch/grok-cli.js +33 -23
  353. package/dist/utils/websearch/grok-cli.js.map +1 -1
  354. package/dist/utils/websearch/hook-config.d.ts +2 -1
  355. package/dist/utils/websearch/hook-config.d.ts.map +1 -1
  356. package/dist/utils/websearch/hook-config.js +1 -2
  357. package/dist/utils/websearch/hook-config.js.map +1 -1
  358. package/dist/utils/websearch/hook-env.d.ts +2 -1
  359. package/dist/utils/websearch/hook-env.d.ts.map +1 -1
  360. package/dist/utils/websearch/hook-env.js +1 -2
  361. package/dist/utils/websearch/hook-env.js.map +1 -1
  362. package/dist/utils/websearch/hook-installer.d.ts +2 -1
  363. package/dist/utils/websearch/hook-installer.d.ts.map +1 -1
  364. package/dist/utils/websearch/hook-installer.js +1 -2
  365. package/dist/utils/websearch/hook-installer.js.map +1 -1
  366. package/dist/utils/websearch/index.d.ts +2 -0
  367. package/dist/utils/websearch/index.d.ts.map +1 -1
  368. package/dist/utils/websearch/index.js +3 -1
  369. package/dist/utils/websearch/index.js.map +1 -1
  370. package/dist/utils/websearch/launch-state.d.ts +9 -0
  371. package/dist/utils/websearch/launch-state.d.ts.map +1 -0
  372. package/dist/utils/websearch/launch-state.js +15 -0
  373. package/dist/utils/websearch/launch-state.js.map +1 -0
  374. package/dist/utils/websearch/mcp-installer.d.ts +6 -5
  375. package/dist/utils/websearch/mcp-installer.d.ts.map +1 -1
  376. package/dist/utils/websearch/mcp-installer.js +10 -15
  377. package/dist/utils/websearch/mcp-installer.js.map +1 -1
  378. package/dist/utils/websearch/opencode-cli.d.ts +3 -1
  379. package/dist/utils/websearch/opencode-cli.d.ts.map +1 -1
  380. package/dist/utils/websearch/opencode-cli.js +33 -23
  381. package/dist/utils/websearch/opencode-cli.js.map +1 -1
  382. package/dist/utils/websearch/status.d.ts +7 -3
  383. package/dist/utils/websearch/status.d.ts.map +1 -1
  384. package/dist/utils/websearch/status.js +50 -31
  385. package/dist/utils/websearch/status.js.map +1 -1
  386. package/dist/utils/websearch-manager.d.ts +2 -0
  387. package/dist/utils/websearch-manager.d.ts.map +1 -1
  388. package/dist/utils/websearch-manager.js +3 -1
  389. package/dist/utils/websearch-manager.js.map +1 -1
  390. package/dist/web-server/model-pricing.d.ts.map +1 -1
  391. package/dist/web-server/model-pricing.js +43 -10
  392. package/dist/web-server/model-pricing.js.map +1 -1
  393. package/dist/web-server/routes/bar-routes.d.ts.map +1 -1
  394. package/dist/web-server/routes/bar-routes.js +15 -10
  395. package/dist/web-server/routes/bar-routes.js.map +1 -1
  396. package/dist/web-server/routes/cliproxy-routing-routes.d.ts.map +1 -1
  397. package/dist/web-server/routes/cliproxy-routing-routes.js +28 -0
  398. package/dist/web-server/routes/cliproxy-routing-routes.js.map +1 -1
  399. package/dist/web-server/routes/settings-routes.d.ts.map +1 -1
  400. package/dist/web-server/routes/settings-routes.js +1 -0
  401. package/dist/web-server/routes/settings-routes.js.map +1 -1
  402. package/dist/web-server/services/cliproxy-dashboard-install-service.d.ts +5 -0
  403. package/dist/web-server/services/cliproxy-dashboard-install-service.d.ts.map +1 -1
  404. package/dist/web-server/services/cliproxy-dashboard-install-service.js +53 -36
  405. package/dist/web-server/services/cliproxy-dashboard-install-service.js.map +1 -1
  406. package/dist/web-server/usage/claude-native-credentials.d.ts +23 -2
  407. package/dist/web-server/usage/claude-native-credentials.d.ts.map +1 -1
  408. package/dist/web-server/usage/claude-native-credentials.js +78 -14
  409. package/dist/web-server/usage/claude-native-credentials.js.map +1 -1
  410. package/dist/web-server/usage/native-quota-collector.d.ts +10 -9
  411. package/dist/web-server/usage/native-quota-collector.d.ts.map +1 -1
  412. package/dist/web-server/usage/native-quota-collector.js +113 -42
  413. package/dist/web-server/usage/native-quota-collector.js.map +1 -1
  414. package/lib/ccs +1 -1
  415. package/lib/ccs.ps1 +1 -1
  416. package/package.json +6 -2
  417. package/scripts/ci-parity-gate.sh +4 -30
  418. package/scripts/completion/ccs.bash +1 -1
  419. package/scripts/completion/ccs.fish +1 -1
  420. package/scripts/completion/ccs.ps1 +1 -1
  421. package/scripts/completion/ccs.zsh +1 -1
  422. package/scripts/dev-release.sh +1 -1
  423. package/scripts/hardening-inventory.js +37 -4
  424. package/scripts/maintainability-metrics.js +2 -8
  425. package/scripts/run-test-bucket.js +1 -0
  426. package/scripts/runtime-source-classifier.js +12 -0
  427. package/dist/ui/assets/cliproxy-CXDOPGj3.js +0 -4
  428. package/dist/ui/assets/index-EnTQAKOi.js +0 -56
  429. package/dist/ui/assets/proxy-status-widget-D87qCiqo.js +0 -1
@@ -32,8 +32,13 @@ export interface CredentialReaderDeps {
32
32
  homedir?: string;
33
33
  existsSyncImpl?: (p: string) => boolean;
34
34
  readFileSyncImpl?: (p: string) => string;
35
- execSyncImpl?: (cmd: string, opts: Record<string, unknown>) => string | Buffer;
35
+ execFileImpl?: ExecFileImpl;
36
+ keychainTimeoutMs?: number;
36
37
  }
38
+ type ExecFileCallback = (error: Error | null, stdout: string | Buffer) => void;
39
+ type ExecFileImpl = (file: string, args: readonly string[], options: Record<string, unknown>, callback: ExecFileCallback) => {
40
+ kill?: () => void;
41
+ } | void;
37
42
  /**
38
43
  * Read the native Claude Code credentials.
39
44
  *
@@ -41,7 +46,22 @@ export interface CredentialReaderDeps {
41
46
  * Keychain as a fallback. Returns null when neither source yields a parseable
42
47
  * object.
43
48
  */
44
- export declare function readClaudeCredentials(deps?: CredentialReaderDeps): ClaudeNativeCredentials | null;
49
+ export declare function readClaudeCredentials(deps?: CredentialReaderDeps): Promise<ClaudeNativeCredentials | null>;
50
+ /**
51
+ * Keychain service name Claude Code uses for a non-default CLAUDE_CONFIG_DIR:
52
+ * "Claude Code-credentials-<first 8 hex chars of sha256(configDir)>".
53
+ */
54
+ export declare function claudeKeychainServiceForConfigDir(configDir: string): string;
55
+ /**
56
+ * Read the Claude Code credentials for a specific CLAUDE_CONFIG_DIR (e.g. an
57
+ * isolated `ccs auth` instance directory).
58
+ *
59
+ * File-first (<configDir>/.credentials.json, no prompt), then the macOS
60
+ * Keychain item derived from the config dir path. On macOS Claude Code stores
61
+ * OAuth tokens in the Keychain by default, so without the Keychain fallback
62
+ * every isolated profile looks permanently logged-out to the bar.
63
+ */
64
+ export declare function readClaudeCredentialsForConfigDir(configDir: string, deps?: CredentialReaderDeps): Promise<ClaudeNativeCredentials | null>;
45
65
  /** Pull the OAuth access token, or null when absent. */
46
66
  export declare function getAccessToken(creds: ClaudeNativeCredentials | null): string | null;
47
67
  /** Pull the subscription tier (e.g. "max" / "pro"), or null. */
@@ -53,4 +73,5 @@ export declare function getSubscriptionTier(creds: ClaudeNativeCredentials | nul
53
73
  * token call against the hostile usage endpoint and never gets a phantom row.
54
74
  */
55
75
  export declare function hasSupportedSubscription(creds: ClaudeNativeCredentials | null): boolean;
76
+ export {};
56
77
  //# sourceMappingURL=claude-native-credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-native-credentials.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/claude-native-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;AAOH,iEAAiE;AACjE,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC;CAChF;AAuBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,GAAE,oBAAyB,GAC9B,uBAAuB,GAAG,IAAI,CAmChC;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGnF;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGxF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,OAAO,CAYvF"}
1
+ {"version":3,"file":"claude-native-credentials.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/claude-native-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;AAQH,iEAAiE;AACjE,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,KAAK,gBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;AAC/E,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,gBAAgB,KACvB;IAAE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC;AAwBlC;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAsBzC;AAgDD;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED;;;;;;;;GAQG;AACH,wBAAsB,iCAAiC,CACrD,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAoBzC;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGnF;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGxF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,GAAG,OAAO,CAYvF"}
@@ -38,12 +38,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
38
38
  return result;
39
39
  };
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.hasSupportedSubscription = exports.getSubscriptionTier = exports.getAccessToken = exports.readClaudeCredentials = void 0;
41
+ exports.hasSupportedSubscription = exports.getSubscriptionTier = exports.getAccessToken = exports.readClaudeCredentialsForConfigDir = exports.claudeKeychainServiceForConfigDir = exports.readClaudeCredentials = void 0;
42
42
  const node_fs_1 = require("node:fs");
43
43
  const node_child_process_1 = require("node:child_process");
44
+ const crypto = __importStar(require("node:crypto"));
44
45
  const os = __importStar(require("node:os"));
45
46
  const path = __importStar(require("node:path"));
46
47
  const KEYCHAIN_SERVICE = 'Claude Code-credentials';
48
+ const SECURITY_PATH = '/usr/bin/security';
47
49
  const KEYCHAIN_TIMEOUT_MS = 5000;
48
50
  /** Subscription types that mean "no real subscription" -> skip the fetch. */
49
51
  const UNSUPPORTED_SUBSCRIPTION_TYPES = new Set(['', 'free', 'none']);
@@ -68,12 +70,11 @@ function parseCredentials(raw) {
68
70
  * Keychain as a fallback. Returns null when neither source yields a parseable
69
71
  * object.
70
72
  */
71
- function readClaudeCredentials(deps = {}) {
73
+ async function readClaudeCredentials(deps = {}) {
72
74
  const platform = deps.platform ?? os.platform();
73
75
  const homedir = deps.homedir ?? os.homedir();
74
76
  const existsImpl = deps.existsSyncImpl ?? node_fs_1.existsSync;
75
77
  const readImpl = deps.readFileSyncImpl ?? ((p) => (0, node_fs_1.readFileSync)(p, 'utf8'));
76
- const execImpl = deps.execSyncImpl ?? node_child_process_1.execSync;
77
78
  const credentialsPath = path.join(homedir, '.claude', '.credentials.json');
78
79
  if (existsImpl(credentialsPath)) {
79
80
  try {
@@ -86,26 +87,89 @@ function readClaudeCredentials(deps = {}) {
86
87
  }
87
88
  }
88
89
  if (platform === 'darwin') {
90
+ const parsed = await readCredentialsFromKeychainService(KEYCHAIN_SERVICE, deps);
91
+ if (parsed)
92
+ return parsed;
93
+ }
94
+ return null;
95
+ }
96
+ exports.readClaudeCredentials = readClaudeCredentials;
97
+ /** Read + parse one Keychain generic-password item. Returns null on any failure. */
98
+ async function readCredentialsFromKeychainService(service, deps) {
99
+ const timeoutMs = deps.keychainTimeoutMs ?? KEYCHAIN_TIMEOUT_MS;
100
+ const execImpl = deps.execFileImpl ??
101
+ ((file, args, options, callback) => (0, node_child_process_1.execFile)(file, [...args], options, (error, stdout) => callback(error, stdout)));
102
+ return new Promise((resolve) => {
103
+ let settled = false;
104
+ let child;
105
+ const finish = (credentials) => {
106
+ if (settled)
107
+ return;
108
+ settled = true;
109
+ clearTimeout(timer);
110
+ resolve(credentials);
111
+ };
112
+ const timer = setTimeout(() => {
113
+ child?.kill?.();
114
+ finish(null);
115
+ }, timeoutMs);
89
116
  try {
90
- const out = execImpl(`security find-generic-password -s "${KEYCHAIN_SERVICE}" -w`, {
91
- timeout: KEYCHAIN_TIMEOUT_MS,
117
+ child = execImpl(SECURITY_PATH, ['find-generic-password', '-s', service, '-w'], {
118
+ timeout: timeoutMs,
92
119
  encoding: 'utf8',
93
- stdio: ['pipe', 'pipe', 'ignore'],
120
+ windowsHide: true,
121
+ maxBuffer: 1024 * 1024,
122
+ }, (error, stdout) => {
123
+ if (error)
124
+ return finish(null);
125
+ const raw = (typeof stdout === 'string' ? stdout : stdout.toString('utf8')).trim();
126
+ finish(raw ? parseCredentials(raw) : null);
94
127
  });
95
- const raw = (typeof out === 'string' ? out : out.toString('utf8')).trim();
96
- if (raw) {
97
- const parsed = parseCredentials(raw);
98
- if (parsed)
99
- return parsed;
100
- }
101
128
  }
102
129
  catch {
103
- // no Keychain entry / access denied -> null
130
+ finish(null);
131
+ }
132
+ });
133
+ }
134
+ /**
135
+ * Keychain service name Claude Code uses for a non-default CLAUDE_CONFIG_DIR:
136
+ * "Claude Code-credentials-<first 8 hex chars of sha256(configDir)>".
137
+ */
138
+ function claudeKeychainServiceForConfigDir(configDir) {
139
+ const hash = crypto.createHash('sha256').update(configDir).digest('hex').slice(0, 8);
140
+ return `${KEYCHAIN_SERVICE}-${hash}`;
141
+ }
142
+ exports.claudeKeychainServiceForConfigDir = claudeKeychainServiceForConfigDir;
143
+ /**
144
+ * Read the Claude Code credentials for a specific CLAUDE_CONFIG_DIR (e.g. an
145
+ * isolated `ccs auth` instance directory).
146
+ *
147
+ * File-first (<configDir>/.credentials.json, no prompt), then the macOS
148
+ * Keychain item derived from the config dir path. On macOS Claude Code stores
149
+ * OAuth tokens in the Keychain by default, so without the Keychain fallback
150
+ * every isolated profile looks permanently logged-out to the bar.
151
+ */
152
+ async function readClaudeCredentialsForConfigDir(configDir, deps = {}) {
153
+ const platform = deps.platform ?? os.platform();
154
+ const existsImpl = deps.existsSyncImpl ?? node_fs_1.existsSync;
155
+ const readImpl = deps.readFileSyncImpl ?? ((p) => (0, node_fs_1.readFileSync)(p, 'utf8'));
156
+ const credentialsPath = path.join(configDir, '.credentials.json');
157
+ if (existsImpl(credentialsPath)) {
158
+ try {
159
+ const parsed = parseCredentials(readImpl(credentialsPath));
160
+ if (parsed)
161
+ return parsed;
162
+ }
163
+ catch {
164
+ // fall through to Keychain
104
165
  }
105
166
  }
167
+ if (platform === 'darwin') {
168
+ return readCredentialsFromKeychainService(claudeKeychainServiceForConfigDir(configDir), deps);
169
+ }
106
170
  return null;
107
171
  }
108
- exports.readClaudeCredentials = readClaudeCredentials;
172
+ exports.readClaudeCredentialsForConfigDir = readClaudeCredentialsForConfigDir;
109
173
  /** Pull the OAuth access token, or null when absent. */
110
174
  function getAccessToken(creds) {
111
175
  const token = creds?.claudeAiOauth?.accessToken;
@@ -1 +1 @@
1
- {"version":3,"file":"claude-native-credentials.js","sourceRoot":"","sources":["../../../src/web-server/usage/claude-native-credentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-native-credentials.js","sourceRoot":"","sources":["../../../src/web-server/usage/claude-native-credentials.ts"],"names":[],"mappings":"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"}
@@ -14,9 +14,9 @@
14
14
  * - circuit breaker stops calling after repeated 429s for a cooldown
15
15
  * - serve-stale-on-failure; only omit a row when there is genuinely no data
16
16
  *
17
- * Claude path: reads per-profile .credentials.json (file-only, NO keychain)
18
- * and polls api.anthropic.com/api/oauth/usage. If the file is absent the
19
- * profile is emitted as a parked row (paused:true) — never a keychain call.
17
+ * Claude path: reads per-profile .credentials.json, then the per-config-dir
18
+ * Keychain item, and polls api.anthropic.com/api/oauth/usage. If neither source
19
+ * yields credentials the profile is emitted as a parked row (paused:true).
20
20
  *
21
21
  * Codex path: PRIMARY = live network (chatgpt.com/backend-api/wham/usage, via
22
22
  * fetchCodexQuota), FALLBACK = local session logs (getCodexLocalQuota), mirroring
@@ -29,9 +29,10 @@
29
29
  * is maintained — at most 2 live upstream calls per /summary regardless of
30
30
  * profile count.
31
31
  *
32
- * NO macOS Keychain access anywhere in this module. The old global-default
33
- * Claude reader (readClaudeCredentials) is kept for back-compat but is no longer
34
- * used by the multi-profile path.
32
+ * Claude per-profile reads are file-first with a per-config-dir macOS Keychain
33
+ * fallback (Claude Code stores OAuth tokens in the Keychain by default on
34
+ * macOS). The old global-default Claude reader (readClaudeCredentials) is kept
35
+ * for back-compat but is no longer used by the multi-profile path.
35
36
  */
36
37
  import { type ClaudeNativeCredentials } from './claude-native-credentials';
37
38
  import { type CodexLocalQuota } from './codex-local-quota-collector';
@@ -39,13 +40,13 @@ import type { ClaudeQuotaResult, CodexQuotaResult } from '../../cliproxy/quota/q
39
40
  import type { BarSummaryRow } from '../routes/bar-routes';
40
41
  export interface NativeQuotaDeps {
41
42
  /** Read the native Claude Code credentials (global default path). */
42
- readCredentials?: () => ClaudeNativeCredentials | null;
43
+ readCredentials?: () => ClaudeNativeCredentials | null | Promise<ClaudeNativeCredentials | null>;
43
44
  /**
44
- * Read credentials for a specific Claude profile (file-only, no keychain).
45
+ * Read credentials for a specific Claude profile (file-first, Keychain fallback).
45
46
  * Injected so tests never touch real fs or Keychain.
46
47
  * profile: the profile name (e.g. "work"); returns null when absent/unparseable.
47
48
  */
48
- readClaudeCredentialsForProfile?: (profile: string) => ClaudeNativeCredentials | null;
49
+ readClaudeCredentialsForProfile?: (profile: string) => ClaudeNativeCredentials | null | Promise<ClaudeNativeCredentials | null>;
49
50
  /** Fetch Claude quota with a directly-supplied native token. */
50
51
  fetchClaudeQuota?: (accessToken: string, accountId?: string) => Promise<ClaudeQuotaResult>;
51
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"native-quota-collector.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/native-quota-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAKL,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;AA4D7E,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,uBAAuB,GAAG,IAAI,CAAC;IACvD;;;;OAIG;IACH,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,uBAAuB,GAAG,IAAI,CAAC;IACtF,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC3F;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC/C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1E,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACtD;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACpC,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACnC,+CAA+C;IAC/C,oBAAoB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC3C,8CAA8C;IAC9C,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAgDD,6EAA6E;AAC7E,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAmwCD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,eAAoB,EAC1B,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzB,OAAO,CAAC,aAAa,EAAE,CAAC,CAmC1B;AA2GD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,IAAI,aAAa,EAAE,CAS5D"}
1
+ {"version":3,"file":"native-quota-collector.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/native-quota-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAML,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;AA4D7E,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,uBAAuB,GAAG,IAAI,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IACjG;;;;OAIG;IACH,+BAA+B,CAAC,EAAE,CAChC,OAAO,EAAE,MAAM,KACZ,uBAAuB,GAAG,IAAI,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IAC9E,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC3F;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC/C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1E,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACtD;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7F,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACpC,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACnC,+CAA+C;IAC/C,oBAAoB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC3C,8CAA8C;IAC9C,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAgDD,6EAA6E;AAC7E,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAw0CD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,eAAoB,EAC1B,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzB,OAAO,CAAC,aAAa,EAAE,CAAC,CAmC1B;AAkID;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,IAAI,aAAa,EAAE,CAS5D"}
@@ -15,9 +15,9 @@
15
15
  * - circuit breaker stops calling after repeated 429s for a cooldown
16
16
  * - serve-stale-on-failure; only omit a row when there is genuinely no data
17
17
  *
18
- * Claude path: reads per-profile .credentials.json (file-only, NO keychain)
19
- * and polls api.anthropic.com/api/oauth/usage. If the file is absent the
20
- * profile is emitted as a parked row (paused:true) — never a keychain call.
18
+ * Claude path: reads per-profile .credentials.json, then the per-config-dir
19
+ * Keychain item, and polls api.anthropic.com/api/oauth/usage. If neither source
20
+ * yields credentials the profile is emitted as a parked row (paused:true).
21
21
  *
22
22
  * Codex path: PRIMARY = live network (chatgpt.com/backend-api/wham/usage, via
23
23
  * fetchCodexQuota), FALLBACK = local session logs (getCodexLocalQuota), mirroring
@@ -30,9 +30,10 @@
30
30
  * is maintained — at most 2 live upstream calls per /summary regardless of
31
31
  * profile count.
32
32
  *
33
- * NO macOS Keychain access anywhere in this module. The old global-default
34
- * Claude reader (readClaudeCredentials) is kept for back-compat but is no longer
35
- * used by the multi-profile path.
33
+ * Claude per-profile reads are file-first with a per-config-dir macOS Keychain
34
+ * fallback (Claude Code stores OAuth tokens in the Keychain by default on
35
+ * macOS). The old global-default Claude reader (readClaudeCredentials) is kept
36
+ * for back-compat but is no longer used by the multi-profile path.
36
37
  */
37
38
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
38
39
  if (k2 === undefined) k2 = k;
@@ -381,38 +382,30 @@ function serveCached(state) {
381
382
  return { ...state.cachedRow, cached: true };
382
383
  }
383
384
  // ============================================================================
384
- // File-only Claude credentials reader for per-profile paths (NO keychain)
385
+ // Per-profile Claude credentials reader (file-first, Keychain fallback)
385
386
  // ============================================================================
386
387
  /**
387
- * Read credentials for a specific Claude Code profile (file-only, no keychain).
388
+ * Read credentials for a specific Claude Code profile (file-first, Keychain fallback).
388
389
  *
389
- * Looks for .credentials.json in the profile's instance directory. If the file
390
- * is absent or unparseable, returns null the caller emits a parked row.
391
- * Never calls security/Keychain zero new keychain access from this feature.
390
+ * Looks for .credentials.json in the profile's instance directory, then uses
391
+ * the bounded per-config-dir macOS Keychain fallback. If neither yields a
392
+ * parseable credential object, the caller emits a parked row.
392
393
  */
393
- function readClaudeCredentialsForProfileFromDisk(profile, readDefaultCredentials = claude_native_credentials_1.readClaudeCredentials) {
394
+ async function readClaudeCredentialsForProfileFromDisk(profile, readDefaultCredentials = claude_native_credentials_1.readClaudeCredentials) {
394
395
  try {
395
396
  const instanceDir = path.join((0, config_manager_1.getCcsDir)(), 'instances', profile);
396
- const credFile = path.join(instanceDir, '.credentials.json');
397
- if (fs.existsSync(credFile)) {
398
- const raw = fs.readFileSync(credFile, 'utf8');
399
- const parsed = JSON.parse(raw);
400
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
401
- return parsed;
402
- }
403
- return null;
404
- }
405
397
  // The bare `ccs` default login uses the standard global credential lookup:
406
398
  // ~/.claude/.credentials.json, falling back to the single global
407
399
  // "Claude Code-credentials" Keychain item that Claude Code itself maintains.
408
- // This is the ONE pre-existing global read the shipped Bar already performs --
409
- // NOT a per-profile Keychain scan. Isolated `ccs auth` profiles stay
410
- // file-only and never touch the Keychain; a real instance directory named
411
- // "default" is therefore parked when its file is absent.
412
400
  if (profile === DEFAULT_PROFILE && !fs.existsSync(instanceDir)) {
413
- return readDefaultCredentials();
401
+ return await readDefaultCredentials();
414
402
  }
415
- return null;
403
+ // Isolated `ccs auth` instance: <instanceDir>/.credentials.json first, then
404
+ // the per-config-dir Keychain item Claude Code maintains for this
405
+ // CLAUDE_CONFIG_DIR ("Claude Code-credentials-<sha256(dir)[0..8]>"). On
406
+ // macOS Claude Code stores tokens in the Keychain by default, so without
407
+ // the Keychain read every isolated profile is permanently parked.
408
+ return await (0, claude_native_credentials_1.readClaudeCredentialsForConfigDir)(instanceDir);
416
409
  }
417
410
  catch {
418
411
  return null;
@@ -643,6 +636,65 @@ function collectCachedOrParkedProfileRow(map, profile, now, buildParkedRow) {
643
636
  function markDefault(row, isDefault) {
644
637
  return { ...row, is_default: isDefault };
645
638
  }
639
+ /**
640
+ * Force paused:true on a non-default row AND its cached copy. Non-default rows
641
+ * always render dimmed (only the default profile is "active"), including the
642
+ * pass where the rotating live slot refreshed them — otherwise the row would
643
+ * flicker active for one poll and dim again on the next.
644
+ */
645
+ function markPausedAndSyncCache(map, profile, row) {
646
+ const state = map.get(profile);
647
+ if (state?.cachedRow) {
648
+ state.cachedRow = { ...state.cachedRow, paused: true };
649
+ }
650
+ return { ...row, paused: true };
651
+ }
652
+ /**
653
+ * True when the cached row was fetched BEFORE its own next_reset boundary and
654
+ * that boundary has now passed — the row describes the previous quota window,
655
+ * so its values (and the reset time itself) are visibly wrong in the bar.
656
+ * The cachedAt guard means a post-reset payload that still reports a past
657
+ * reset cannot cause a refetch loop: once re-fetched, normal TTL applies.
658
+ */
659
+ function isCachedRowStaleByReset(state, now) {
660
+ const nextReset = state.cachedRow?.next_reset;
661
+ if (!nextReset)
662
+ return false;
663
+ const resetMs = Date.parse(nextReset);
664
+ if (!Number.isFinite(resetMs))
665
+ return false;
666
+ return resetMs <= now && state.cachedAt < resetMs;
667
+ }
668
+ /**
669
+ * Pick the non-default profile the rotating live slot should refresh this pass:
670
+ * the stalest profile whose cached row is missing, past its TTL, or past its
671
+ * own quota reset, skipping profiles inside a breaker/cooldown window (their
672
+ * collector would refuse the fetch anyway, wasting the slot). Returns null
673
+ * when every profile is fresh.
674
+ */
675
+ function pickRotatingLiveProfile(map, profiles, defaultProfile, now) {
676
+ let picked = null;
677
+ let pickedAt = Number.POSITIVE_INFINITY;
678
+ for (const p of profiles) {
679
+ if (p === defaultProfile)
680
+ continue;
681
+ const state = map.get(p);
682
+ if (state && (now < state.breakerOpenUntil || now < state.cooldownUntil))
683
+ continue;
684
+ const cachedRow = state?.cachedRow ?? null;
685
+ const cachedAt = state?.cachedAt ?? 0;
686
+ if (cachedRow && state) {
687
+ const ttl = cachedRow.quotaStatus === 'unsupported' ? PARKED_TTL_MS : NATIVE_QUOTA_TTL_MS;
688
+ if (now - cachedAt < ttl && !isCachedRowStaleByReset(state, now))
689
+ continue;
690
+ }
691
+ if (cachedAt < pickedAt) {
692
+ pickedAt = cachedAt;
693
+ picked = p;
694
+ }
695
+ }
696
+ return picked;
697
+ }
646
698
  /**
647
699
  * Tag the row with is_default AND write the flag back onto the cached copy. The
648
700
  * collector caches a row before the default profile is known (the default is
@@ -664,10 +716,13 @@ async function collectClaudeRowForProfile(profile, deps, force = false) {
664
716
  // Serve from cache while within TTL — force bypasses the short-circuit. Parked
665
717
  // rows (no creds -> quotaStatus 'unsupported') use a short TTL so a fresh login
666
718
  // is picked up within seconds instead of staying dimmed for the full quota TTL.
719
+ // A row whose own next_reset has passed is stale regardless of TTL — the
720
+ // quota snapped back at the boundary and the cached values are visibly wrong.
667
721
  if (!force && state.cachedRow) {
668
722
  const ttl = state.cachedRow.quotaStatus === 'unsupported' ? PARKED_TTL_MS : NATIVE_QUOTA_TTL_MS;
669
- if (now - state.cachedAt < ttl)
723
+ if (now - state.cachedAt < ttl && !isCachedRowStaleByReset(state, now)) {
670
724
  return serveCached(state);
725
+ }
671
726
  }
672
727
  // Breaker open or cooldown active -> zero network, serve stale (may be null).
673
728
  // Force does NOT bypass the breaker — it protects the account.
@@ -678,7 +733,7 @@ async function collectClaudeRowForProfile(profile, deps, force = false) {
678
733
  if (state.pending) {
679
734
  return state.pending;
680
735
  }
681
- // For per-profile reads: use the injected seam (file-only, no keychain).
736
+ // For per-profile reads: use the injected seam (file-first, Keychain fallback).
682
737
  const readDefaultCredentials = deps.readCredentials ?? claude_native_credentials_1.readClaudeCredentials;
683
738
  const readCreds = deps.readClaudeCredentialsForProfile ??
684
739
  ((p) => readClaudeCredentialsForProfileFromDisk(p, readDefaultCredentials));
@@ -692,11 +747,11 @@ async function collectClaudeRowForProfile(profile, deps, force = false) {
692
747
  // pending DURING assignment, leaving a stale resolved promise that the
693
748
  // next call's coalescing check would return instead of re-evaluating.
694
749
  await Promise.resolve();
695
- const creds = readCreds(profile);
750
+ const creds = await readCreds(profile);
696
751
  // No credentials file found -> emit parked row (needs auth, file absent).
697
752
  // This is the expected case when the profile exists in the registry but the
698
- // user has not logged in via 'ccs auth' for this machine or the credentials
699
- // are stored only in keychain (which we deliberately do not access here).
753
+ // user has not logged in via 'ccs auth' for this machine or neither the
754
+ // profile file nor its bounded macOS Keychain fallback yielded credentials.
700
755
  if (!creds) {
701
756
  const parkedRow = buildParkedClaudeProfileRow(profile, now);
702
757
  // Cache the parked row so repeated calls don't re-stat the fs.
@@ -797,10 +852,12 @@ async function collectCodexRowForProfile(profile, deps, force = false) {
797
852
  // Serve from cache while within TTL — force bypasses the short-circuit. Parked
798
853
  // rows (no auth -> quotaStatus 'unsupported') use a short TTL so a fresh login
799
854
  // is picked up within seconds instead of staying dimmed for the full quota TTL.
855
+ // A row whose own next_reset has passed is stale regardless of TTL.
800
856
  if (!force && state.cachedRow) {
801
857
  const ttl = state.cachedRow.quotaStatus === 'unsupported' ? PARKED_TTL_MS : NATIVE_QUOTA_TTL_MS;
802
- if (now - state.cachedAt < ttl)
858
+ if (now - state.cachedAt < ttl && !isCachedRowStaleByReset(state, now)) {
803
859
  return serveCached(state);
860
+ }
804
861
  }
805
862
  // Breaker open or cooldown active -> skip network, go to LOCAL fallback.
806
863
  // Force does NOT bypass the breaker — it protects the account.
@@ -986,7 +1043,7 @@ async function collectClaudeRow(deps, force = false) {
986
1043
  const sleep = deps.sleep ?? defaultSleep;
987
1044
  state.pending = (async () => {
988
1045
  try {
989
- const creds = readCredentialsFn();
1046
+ const creds = await readCredentialsFn();
990
1047
  // No token / unsupported subscription -> never spend a call, omit the row.
991
1048
  if (!creds || !(0, claude_native_credentials_1.hasSupportedSubscription)(creds)) {
992
1049
  return serveCached(state);
@@ -1363,28 +1420,42 @@ async function getNativeAccountRowsMultiProfile(deps, force) {
1363
1420
  const tasks = [];
1364
1421
  const results = [];
1365
1422
  const now = (deps.now ?? Date.now)();
1366
- // Preserve the safety budget: only the active/default profile for each surface
1367
- // may perform a live refresh. Non-default profiles are cache-only (or parked)
1368
- // so one /summary request can trigger at most one Claude and one Codex live
1369
- // upstream call regardless of configured profile count.
1423
+ // Preserve the safety budget: the active/default profile for each surface is
1424
+ // live-polled every pass, plus ONE rotating live slot for the stalest
1425
+ // non-default profile. All other profiles are cache-only (or parked), so one
1426
+ // /summary request triggers at most two Claude and two Codex live upstream
1427
+ // calls regardless of configured profile count — every account converges to
1428
+ // real quota within a few polls without per-profile fan-out.
1429
+ const claudeRotating = pickRotatingLiveProfile(claudeProfileStates, claudeProfiles, claudeDefault, now);
1430
+ const codexRotating = pickRotatingLiveProfile(codexProfileStates, codexProfiles, codexDefault, now);
1370
1431
  for (const p of claudeProfiles) {
1371
1432
  const isDefault = p === claudeDefault;
1372
- if (!isDefault) {
1433
+ if (!isDefault && p !== claudeRotating) {
1373
1434
  results.push(markDefaultAndSyncCache(claudeProfileStates, p, collectCachedOrParkedProfileRow(claudeProfileStates, p, now, buildParkedClaudeProfileRow), false));
1374
1435
  continue;
1375
1436
  }
1376
1437
  tasks.push(collectClaudeRowForProfile(p, deps, force || claudeProfileStates.get(p)?.cachedRow?.quotaStatus === 'unsupported')
1377
- .then((r) => (r ? markDefaultAndSyncCache(claudeProfileStates, p, r, true) : null))
1438
+ .then((r) => {
1439
+ if (!r)
1440
+ return null;
1441
+ const marked = markDefaultAndSyncCache(claudeProfileStates, p, r, isDefault);
1442
+ return isDefault ? marked : markPausedAndSyncCache(claudeProfileStates, p, marked);
1443
+ })
1378
1444
  .catch(() => null));
1379
1445
  }
1380
1446
  for (const p of codexProfiles) {
1381
1447
  const isDefault = p === codexDefault;
1382
- if (!isDefault) {
1448
+ if (!isDefault && p !== codexRotating) {
1383
1449
  results.push(markDefaultAndSyncCache(codexProfileStates, p, collectCachedOrParkedProfileRow(codexProfileStates, p, now, buildParkedCodexProfileRow), false));
1384
1450
  continue;
1385
1451
  }
1386
1452
  tasks.push(collectCodexRowForProfile(p, deps, force || codexProfileStates.get(p)?.cachedRow?.quotaStatus === 'unsupported')
1387
- .then((r) => (r ? markDefaultAndSyncCache(codexProfileStates, p, r, true) : null))
1453
+ .then((r) => {
1454
+ if (!r)
1455
+ return null;
1456
+ const marked = markDefaultAndSyncCache(codexProfileStates, p, r, isDefault);
1457
+ return isDefault ? marked : markPausedAndSyncCache(codexProfileStates, p, marked);
1458
+ })
1388
1459
  .catch(() => null));
1389
1460
  }
1390
1461
  results.push(...(await Promise.all(tasks)));