@kaitranntt/ccs 8.1.4 → 8.2.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/base-kiro.settings.json +4 -4
- package/config/base-qoder.settings.json +10 -0
- package/dist/channels/official-channels-runtime.js +1 -1
- package/dist/channels/official-channels-runtime.js.map +1 -1
- package/dist/cliproxy/accounts/registry.d.ts.map +1 -1
- package/dist/cliproxy/accounts/registry.js +11 -4
- package/dist/cliproxy/accounts/registry.js.map +1 -1
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js +1 -1
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js +88 -11
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js.map +1 -1
- package/dist/cliproxy/auth/auth-types.d.ts +2 -0
- package/dist/cliproxy/auth/auth-types.d.ts.map +1 -1
- package/dist/cliproxy/auth/auth-types.js +7 -0
- package/dist/cliproxy/auth/auth-types.js.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.js +19 -10
- package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
- package/dist/cliproxy/auth/oauth-trace/redactor.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-trace/redactor.js +1 -0
- package/dist/cliproxy/auth/oauth-trace/redactor.js.map +1 -1
- package/dist/cliproxy/auth/oauth-trace/trace-recorder.js +2 -2
- package/dist/cliproxy/auth/oauth-trace/trace-recorder.js.map +1 -1
- package/dist/cliproxy/binary/version-checker.d.ts +4 -2
- package/dist/cliproxy/binary/version-checker.d.ts.map +1 -1
- package/dist/cliproxy/binary/version-checker.js +30 -20
- package/dist/cliproxy/binary/version-checker.js.map +1 -1
- package/dist/cliproxy/executor/arg-parser.d.ts +8 -5
- package/dist/cliproxy/executor/arg-parser.d.ts.map +1 -1
- package/dist/cliproxy/executor/arg-parser.js +21 -10
- package/dist/cliproxy/executor/arg-parser.js.map +1 -1
- package/dist/cliproxy/executor/browser-launch-setup.d.ts +1 -0
- package/dist/cliproxy/executor/browser-launch-setup.d.ts.map +1 -1
- package/dist/cliproxy/executor/browser-launch-setup.js +4 -3
- package/dist/cliproxy/executor/browser-launch-setup.js.map +1 -1
- package/dist/cliproxy/executor/index.d.ts.map +1 -1
- package/dist/cliproxy/executor/index.js +15 -6
- package/dist/cliproxy/executor/index.js.map +1 -1
- package/dist/cliproxy/executor/proxy-resolver.d.ts +15 -9
- package/dist/cliproxy/executor/proxy-resolver.d.ts.map +1 -1
- package/dist/cliproxy/executor/proxy-resolver.js +14 -5
- package/dist/cliproxy/executor/proxy-resolver.js.map +1 -1
- package/dist/cliproxy/model-catalog.d.ts.map +1 -1
- package/dist/cliproxy/model-catalog.js +79 -2
- package/dist/cliproxy/model-catalog.js.map +1 -1
- package/dist/cliproxy/provider-capabilities.d.ts.map +1 -1
- package/dist/cliproxy/provider-capabilities.js +12 -0
- package/dist/cliproxy/provider-capabilities.js.map +1 -1
- package/dist/cliproxy/proxy/proxy-config-resolver.d.ts.map +1 -1
- package/dist/cliproxy/proxy/proxy-config-resolver.js +11 -1
- package/dist/cliproxy/proxy/proxy-config-resolver.js.map +1 -1
- package/dist/cliproxy/proxy/tool-sanitization-proxy.d.ts.map +1 -1
- package/dist/cliproxy/proxy/tool-sanitization-proxy.js +160 -8
- package/dist/cliproxy/proxy/tool-sanitization-proxy.js.map +1 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.d.ts +14 -0
- package/dist/cliproxy/proxy/upstream-response-timeout.d.ts.map +1 -0
- package/dist/cliproxy/proxy/upstream-response-timeout.js +72 -0
- package/dist/cliproxy/proxy/upstream-response-timeout.js.map +1 -0
- package/dist/cliproxy/quota/quota-fetcher-claude.d.ts +9 -0
- package/dist/cliproxy/quota/quota-fetcher-claude.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude.js +53 -16
- package/dist/cliproxy/quota/quota-fetcher-claude.js.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-codex.d.ts +2 -2
- package/dist/cliproxy/quota/quota-fetcher-codex.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-codex.js +2 -4
- package/dist/cliproxy/quota/quota-fetcher-codex.js.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher.js +4 -0
- package/dist/cliproxy/quota/quota-fetcher.js.map +1 -1
- package/dist/cliproxy/quota/quota-label-sanitizer.d.ts +10 -0
- package/dist/cliproxy/quota/quota-label-sanitizer.d.ts.map +1 -0
- package/dist/cliproxy/quota/quota-label-sanitizer.js +31 -0
- package/dist/cliproxy/quota/quota-label-sanitizer.js.map +1 -0
- package/dist/cliproxy/quota/quota-manager.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-manager.js +32 -1
- package/dist/cliproxy/quota/quota-manager.js.map +1 -1
- package/dist/cliproxy/routing/routing-strategy-http.d.ts.map +1 -1
- package/dist/cliproxy/routing/routing-strategy-http.js +35 -26
- package/dist/cliproxy/routing/routing-strategy-http.js.map +1 -1
- package/dist/cliproxy/services/catalog-cache.d.ts.map +1 -1
- package/dist/cliproxy/services/catalog-cache.js +5 -3
- package/dist/cliproxy/services/catalog-cache.js.map +1 -1
- package/dist/cliproxy/services/stats-fetcher.d.ts +13 -0
- package/dist/cliproxy/services/stats-fetcher.d.ts.map +1 -1
- package/dist/cliproxy/services/stats-fetcher.js +25 -1
- package/dist/cliproxy/services/stats-fetcher.js.map +1 -1
- package/dist/cliproxy/types/provider-types.d.ts +1 -1
- package/dist/cliproxy/types/provider-types.d.ts.map +1 -1
- package/dist/cliproxy/types/provider-types.js +1 -0
- package/dist/cliproxy/types/provider-types.js.map +1 -1
- package/dist/codex-auth/codex-config-symlink.js +21 -4
- package/dist/codex-auth/codex-config-symlink.js.map +1 -1
- package/dist/codex-auth/commands/import-default-command.d.ts +1 -1
- package/dist/codex-auth/commands/import-default-command.d.ts.map +1 -1
- package/dist/codex-auth/commands/import-default-command.js +12 -25
- package/dist/codex-auth/commands/import-default-command.js.map +1 -1
- package/dist/commands/api-command/help.js +1 -1
- package/dist/commands/api-command/help.js.map +1 -1
- package/dist/commands/bar/index.d.ts +8 -0
- package/dist/commands/bar/index.d.ts.map +1 -0
- package/dist/commands/bar/index.js +69 -0
- package/dist/commands/bar/index.js.map +1 -0
- package/dist/commands/bar/install-subcommand.d.ts +50 -0
- package/dist/commands/bar/install-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/install-subcommand.js +383 -0
- package/dist/commands/bar/install-subcommand.js.map +1 -0
- package/dist/commands/bar/launch-subcommand.d.ts +38 -0
- package/dist/commands/bar/launch-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/launch-subcommand.js +144 -0
- package/dist/commands/bar/launch-subcommand.js.map +1 -0
- package/dist/commands/bar/uninstall-subcommand.d.ts +13 -0
- package/dist/commands/bar/uninstall-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/uninstall-subcommand.js +78 -0
- package/dist/commands/bar/uninstall-subcommand.js.map +1 -0
- package/dist/commands/bar/version-subcommand.d.ts +8 -0
- package/dist/commands/bar/version-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/version-subcommand.js +62 -0
- package/dist/commands/bar/version-subcommand.js.map +1 -0
- package/dist/commands/cleanup-command.d.ts.map +1 -1
- package/dist/commands/cleanup-command.js +99 -51
- package/dist/commands/cleanup-command.js.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand.d.ts +10 -1
- package/dist/commands/cliproxy/quota-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand.js +15 -6
- package/dist/commands/cliproxy/quota-subcommand.js.map +1 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +7 -0
- package/dist/commands/command-catalog.js.map +1 -1
- package/dist/commands/config-channels-command.d.ts +1 -4
- package/dist/commands/config-channels-command.d.ts.map +1 -1
- package/dist/commands/config-channels-command.js +20 -24
- package/dist/commands/config-channels-command.js.map +1 -1
- package/dist/commands/root-command-router.d.ts.map +1 -1
- package/dist/commands/root-command-router.js +7 -0
- package/dist/commands/root-command-router.js.map +1 -1
- package/dist/config/loader/yaml-serializer.d.ts.map +1 -1
- package/dist/config/loader/yaml-serializer.js +13 -0
- package/dist/config/loader/yaml-serializer.js.map +1 -1
- package/dist/config/reserved-names.d.ts +1 -1
- package/dist/config/reserved-names.d.ts.map +1 -1
- package/dist/config/reserved-names.js +1 -0
- package/dist/config/reserved-names.js.map +1 -1
- package/dist/config/schemas/proxy-server.js +1 -1
- package/dist/config/schemas/quota.d.ts +26 -2
- package/dist/config/schemas/quota.d.ts.map +1 -1
- package/dist/config/schemas/quota.js +20 -1
- package/dist/config/schemas/quota.js.map +1 -1
- package/dist/cursor/cursor-daemon-auth.d.ts +2 -0
- package/dist/cursor/cursor-daemon-auth.d.ts.map +1 -0
- package/dist/cursor/cursor-daemon-auth.js +49 -0
- package/dist/cursor/cursor-daemon-auth.js.map +1 -0
- package/dist/cursor/cursor-daemon-entry.d.ts.map +1 -1
- package/dist/cursor/cursor-daemon-entry.js +44 -0
- package/dist/cursor/cursor-daemon-entry.js.map +1 -1
- package/dist/cursor/cursor-daemon.d.ts +2 -1
- package/dist/cursor/cursor-daemon.d.ts.map +1 -1
- package/dist/cursor/cursor-daemon.js +21 -5
- package/dist/cursor/cursor-daemon.js.map +1 -1
- package/dist/cursor/cursor-models.d.ts.map +1 -1
- package/dist/cursor/cursor-models.js +2 -1
- package/dist/cursor/cursor-models.js.map +1 -1
- package/dist/cursor/cursor-profile-executor.d.ts +1 -1
- package/dist/cursor/cursor-profile-executor.d.ts.map +1 -1
- package/dist/cursor/cursor-profile-executor.js +7 -4
- package/dist/cursor/cursor-profile-executor.js.map +1 -1
- package/dist/cursor/cursor-runtime-probe.d.ts.map +1 -1
- package/dist/cursor/cursor-runtime-probe.js +4 -2
- package/dist/cursor/cursor-runtime-probe.js.map +1 -1
- package/dist/cursor/types.d.ts +1 -0
- package/dist/cursor/types.d.ts.map +1 -1
- package/dist/dispatcher/profile-resolver.d.ts +16 -0
- package/dist/dispatcher/profile-resolver.d.ts.map +1 -1
- package/dist/dispatcher/profile-resolver.js +49 -3
- package/dist/dispatcher/profile-resolver.js.map +1 -1
- package/dist/docker/docker-key-rotation.d.ts +2 -0
- package/dist/docker/docker-key-rotation.d.ts.map +1 -1
- package/dist/docker/docker-key-rotation.js +9 -1
- package/dist/docker/docker-key-rotation.js.map +1 -1
- package/dist/glmt/sse-parser.d.ts +1 -0
- package/dist/glmt/sse-parser.d.ts.map +1 -1
- package/dist/glmt/sse-parser.js +13 -1
- package/dist/glmt/sse-parser.js.map +1 -1
- package/dist/management/shared-manager.d.ts.map +1 -1
- package/dist/management/shared-manager.js +9 -1
- package/dist/management/shared-manager.js.map +1 -1
- package/dist/proxy/profile-router.d.ts +2 -0
- package/dist/proxy/profile-router.d.ts.map +1 -1
- package/dist/proxy/profile-router.js +6 -2
- package/dist/proxy/profile-router.js.map +1 -1
- package/dist/proxy/proxy-daemon.js +1 -1
- package/dist/proxy/proxy-daemon.js.map +1 -1
- package/dist/proxy/server/messages-route.d.ts.map +1 -1
- package/dist/proxy/server/messages-route.js +79 -7
- package/dist/proxy/server/messages-route.js.map +1 -1
- package/dist/proxy/transformers/request-transformer.d.ts.map +1 -1
- package/dist/proxy/transformers/request-transformer.js +9 -2
- package/dist/proxy/transformers/request-transformer.js.map +1 -1
- package/dist/shared/claude-extension-setup.d.ts.map +1 -1
- package/dist/shared/claude-extension-setup.js +2 -1
- package/dist/shared/claude-extension-setup.js.map +1 -1
- package/dist/shared/cliproxy-model-routing.d.ts.map +1 -1
- package/dist/shared/cliproxy-model-routing.js +1 -0
- package/dist/shared/cliproxy-model-routing.js.map +1 -1
- package/dist/shared/stale-codex-translator-settings.d.ts.map +1 -1
- package/dist/shared/stale-codex-translator-settings.js +48 -9
- package/dist/shared/stale-codex-translator-settings.js.map +1 -1
- package/dist/targets/codex-adapter.d.ts.map +1 -1
- package/dist/targets/codex-adapter.js +10 -8
- package/dist/targets/codex-adapter.js.map +1 -1
- package/dist/targets/target-metadata.js +1 -1
- package/dist/targets/target-metadata.js.map +1 -1
- package/dist/ui/assets/{Trans-DyZQZ3e2.js → Trans-BkttMZOY.js} +1 -1
- package/dist/ui/assets/accounts-CMnafyvZ.js +1 -0
- package/dist/ui/assets/{alert-dialog-DWHL-dqd.js → alert-dialog-Dgbg5gJ1.js} +1 -1
- package/dist/ui/assets/api-VhuWZte1.js +4 -0
- package/dist/ui/assets/{auth-section-B4o90dwz.js → auth-section-DV1ImDLn.js} +1 -1
- package/dist/ui/assets/{backups-section-1AsdSIJO.js → backups-section-D7r-Huo_.js} +1 -1
- package/dist/ui/assets/{channels-CU4Zdsc_.js → channels-CKUk3W1L.js} +1 -1
- package/dist/ui/assets/{checkbox-CbCKGH8I.js → checkbox-B6j6PA4N.js} +1 -1
- package/dist/ui/assets/claude-extension-B9phgEGW.js +1 -0
- package/dist/ui/assets/cliproxy-CjZiufaQ.js +4 -0
- package/dist/ui/assets/{cliproxy-ai-providers-Dr4L5NRY.js → cliproxy-ai-providers-J_8Tg44E.js} +6 -6
- package/dist/ui/assets/cliproxy-control-panel-DOxGnabX.js +1 -0
- package/dist/ui/assets/codex-BJuDLXfe.js +30 -0
- package/dist/ui/assets/{confirm-dialog-b5Dahgnk.js → confirm-dialog-CjwyQ3AU.js} +1 -1
- package/dist/ui/assets/{copilot-B1Ojakbt.js → copilot-Nhs4PdOq.js} +2 -2
- package/dist/ui/assets/{cursor-PUtNVPx1.js → cursor-DqFROSqy.js} +1 -1
- package/dist/ui/assets/{droid-S2gclncb.js → droid-CBwAiZcv.js} +1 -1
- package/dist/ui/assets/{globalenv-section-7wKSmNSG.js → globalenv-section-D9WhcK3S.js} +1 -1
- package/dist/ui/assets/{health-hMLN_gyw.js → health-CE3lFqFV.js} +1 -1
- package/dist/ui/assets/icons-gI6odJjU.js +1 -0
- package/dist/ui/assets/{index-Cx0dmbiQ.js → index-Bssd99Pa.js} +1 -1
- package/dist/ui/assets/index-C6D81JHk.js +1 -0
- package/dist/ui/assets/{index-BWboJia4.js → index-D--xE6Kq.js} +1 -1
- package/dist/ui/assets/index-DFYK4jw3.js +56 -0
- package/dist/ui/assets/{index-DkR2KVhF.js → index-DGsfFqiO.js} +1 -1
- package/dist/ui/assets/index-UEdhhar4.css +1 -0
- package/dist/ui/assets/{index-Coc3_ABK.js → index-bJvDY0e2.js} +1 -1
- package/dist/ui/assets/{index-CxvNNHgE.js → index-vK0cF4_0.js} +1 -1
- package/dist/ui/assets/logs-BUA9GCN2.js +1 -0
- package/dist/ui/assets/{masked-input-4L9CIZGb.js → masked-input-BZdCgWmH.js} +1 -1
- package/dist/ui/assets/providers/qoder.svg +1 -0
- package/dist/ui/assets/proxy-status-widget-I35xB9u9.js +1 -0
- package/dist/ui/assets/{raw-json-settings-editor-panel-DXh8c8rA.js → raw-json-settings-editor-panel-DuL_4ncA.js} +1 -1
- package/dist/ui/assets/{searchable-select-CtvEQrMo.js → searchable-select-BleLprBy.js} +1 -1
- package/dist/ui/assets/{separator-E0ISp1SN.js → separator-De5-VTtx.js} +1 -1
- package/dist/ui/assets/{shared-BeYwHeNS.js → shared-Bu81YVUK.js} +2 -2
- package/dist/ui/assets/{table-BBslZvNP.js → table-DsXaM2jg.js} +1 -1
- package/dist/ui/assets/updates-C2bOO3Fo.js +1 -0
- package/dist/ui/assets/{use-accounts-BdalFsdY.js → use-accounts-C2OmaTJU.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/browser/browser-settings.d.ts.map +1 -1
- package/dist/utils/browser/browser-settings.js +13 -3
- package/dist/utils/browser/browser-settings.js.map +1 -1
- package/dist/utils/glmt-deprecation.d.ts.map +1 -1
- package/dist/utils/glmt-deprecation.js +1 -3
- package/dist/utils/glmt-deprecation.js.map +1 -1
- package/dist/utils/retry-strategy.js +1 -1
- package/dist/utils/retry-strategy.js.map +1 -1
- package/dist/web-server/index.d.ts.map +1 -1
- package/dist/web-server/index.js +0 -9
- package/dist/web-server/index.js.map +1 -1
- package/dist/web-server/middleware/auth-middleware.d.ts.map +1 -1
- package/dist/web-server/middleware/auth-middleware.js +26 -4
- package/dist/web-server/middleware/auth-middleware.js.map +1 -1
- package/dist/web-server/model-pricing.d.ts +18 -2
- package/dist/web-server/model-pricing.d.ts.map +1 -1
- package/dist/web-server/model-pricing.js +79 -3
- package/dist/web-server/model-pricing.js.map +1 -1
- package/dist/web-server/models-dev/pricing-resolver.js +14 -14
- package/dist/web-server/models-dev/pricing-resolver.js.map +1 -1
- package/dist/web-server/routes/account-routes.d.ts.map +1 -1
- package/dist/web-server/routes/account-routes.js +116 -0
- package/dist/web-server/routes/account-routes.js.map +1 -1
- package/dist/web-server/routes/bar-routes.d.ts +149 -0
- package/dist/web-server/routes/bar-routes.d.ts.map +1 -0
- package/dist/web-server/routes/bar-routes.js +415 -0
- package/dist/web-server/routes/bar-routes.js.map +1 -0
- package/dist/web-server/routes/cliproxy-auth-routes.d.ts +10 -0
- package/dist/web-server/routes/cliproxy-auth-routes.d.ts.map +1 -1
- package/dist/web-server/routes/cliproxy-auth-routes.js +45 -13
- package/dist/web-server/routes/cliproxy-auth-routes.js.map +1 -1
- package/dist/web-server/routes/cliproxy-local-proxy.d.ts.map +1 -1
- package/dist/web-server/routes/cliproxy-local-proxy.js +25 -8
- package/dist/web-server/routes/cliproxy-local-proxy.js.map +1 -1
- package/dist/web-server/routes/cursor-routes.d.ts.map +1 -1
- package/dist/web-server/routes/cursor-routes.js +6 -1
- package/dist/web-server/routes/cursor-routes.js.map +1 -1
- package/dist/web-server/routes/image-analysis-routes.d.ts.map +1 -1
- package/dist/web-server/routes/image-analysis-routes.js +7 -0
- package/dist/web-server/routes/image-analysis-routes.js.map +1 -1
- package/dist/web-server/routes/index.d.ts.map +1 -1
- package/dist/web-server/routes/index.js +18 -0
- package/dist/web-server/routes/index.js.map +1 -1
- package/dist/web-server/routes/profile-routes.d.ts.map +1 -1
- package/dist/web-server/routes/profile-routes.js +6 -1
- package/dist/web-server/routes/profile-routes.js.map +1 -1
- package/dist/web-server/routes/settings-routes.d.ts.map +1 -1
- package/dist/web-server/routes/settings-routes.js +10 -1
- package/dist/web-server/routes/settings-routes.js.map +1 -1
- package/dist/web-server/services/claude-extension-settings-service.d.ts.map +1 -1
- package/dist/web-server/services/claude-extension-settings-service.js +5 -1
- package/dist/web-server/services/claude-extension-settings-service.js.map +1 -1
- package/dist/web-server/usage/bar-analytics.d.ts +101 -0
- package/dist/web-server/usage/bar-analytics.d.ts.map +1 -0
- package/dist/web-server/usage/bar-analytics.js +315 -0
- package/dist/web-server/usage/bar-analytics.js.map +1 -0
- package/dist/web-server/usage/claude-native-credentials.d.ts +56 -0
- package/dist/web-server/usage/claude-native-credentials.d.ts.map +1 -0
- package/dist/web-server/usage/claude-native-credentials.js +140 -0
- package/dist/web-server/usage/claude-native-credentials.js.map +1 -0
- package/dist/web-server/usage/cliproxy-snapshot-reader.d.ts +24 -0
- package/dist/web-server/usage/cliproxy-snapshot-reader.d.ts.map +1 -0
- package/dist/web-server/usage/cliproxy-snapshot-reader.js +82 -0
- package/dist/web-server/usage/cliproxy-snapshot-reader.js.map +1 -0
- package/dist/web-server/usage/cliproxy-usage-syncer.d.ts +3 -2
- package/dist/web-server/usage/cliproxy-usage-syncer.d.ts.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-syncer.js +46 -13
- package/dist/web-server/usage/cliproxy-usage-syncer.js.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts +9 -3
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.js +133 -19
- package/dist/web-server/usage/cliproxy-usage-transformer.js.map +1 -1
- package/dist/web-server/usage/codex-local-quota-collector.d.ts +74 -0
- package/dist/web-server/usage/codex-local-quota-collector.d.ts.map +1 -0
- package/dist/web-server/usage/codex-local-quota-collector.js +250 -0
- package/dist/web-server/usage/codex-local-quota-collector.js.map +1 -0
- package/dist/web-server/usage/codex-native-usage-collector.d.ts.map +1 -1
- package/dist/web-server/usage/codex-native-usage-collector.js +18 -2
- package/dist/web-server/usage/codex-native-usage-collector.js.map +1 -1
- package/dist/web-server/usage/data-aggregator.d.ts +11 -0
- package/dist/web-server/usage/data-aggregator.d.ts.map +1 -1
- package/dist/web-server/usage/data-aggregator.js +29 -1
- package/dist/web-server/usage/data-aggregator.js.map +1 -1
- package/dist/web-server/usage/native-quota-collector.d.ts +44 -0
- package/dist/web-server/usage/native-quota-collector.d.ts.map +1 -0
- package/dist/web-server/usage/native-quota-collector.js +378 -0
- package/dist/web-server/usage/native-quota-collector.js.map +1 -0
- package/dist/web-server/usage/profile-filter.d.ts +1 -1
- package/dist/web-server/usage/profile-filter.d.ts.map +1 -1
- package/dist/web-server/usage/profile-filter.js +6 -1
- package/dist/web-server/usage/profile-filter.js.map +1 -1
- package/dist/web-server/usage/types.d.ts +2 -0
- package/dist/web-server/usage/types.d.ts.map +1 -1
- package/lib/mcp/ccs-browser-server.cjs +31 -15
- package/package.json +1 -1
- package/scripts/completion/ccs.bash +0 -12
- package/scripts/completion/ccs.fish +0 -11
- package/scripts/completion/ccs.ps1 +0 -10
- package/scripts/completion/ccs.zsh +0 -13
- package/scripts/github/stable-release-issue-cleanup-lib.mjs +115 -0
- package/scripts/github/stable-release-issue-cleanup.mjs +134 -0
- package/dist/ui/assets/accounts-BPJltru3.js +0 -1
- package/dist/ui/assets/api-BxPN-zy4.js +0 -4
- package/dist/ui/assets/claude-extension-CWpjmIGt.js +0 -1
- package/dist/ui/assets/cliproxy-K6eBb5VO.js +0 -4
- package/dist/ui/assets/cliproxy-control-panel-Cz5r7kHP.js +0 -1
- package/dist/ui/assets/codex-0HdbW8NR.js +0 -30
- package/dist/ui/assets/icons-DzKUh8vG.js +0 -1
- package/dist/ui/assets/index-BMoGhs28.css +0 -1
- package/dist/ui/assets/index-COt1pbk-.js +0 -1
- package/dist/ui/assets/index-CcGVqYOy.js +0 -56
- package/dist/ui/assets/logs-BRFVfyLc.js +0 -1
- package/dist/ui/assets/proxy-status-widget-s1UWOE23.js +0 -1
- package/dist/ui/assets/updates-CDrm903n.js +0 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bar Routes — /api/bar/summary aggregator
|
|
4
|
+
*
|
|
5
|
+
* One GET returns the full glance array for CCS Bar (macOS MenuBarExtra).
|
|
6
|
+
* Supports cached (instant) and ?refresh=true (live provider pull) modes.
|
|
7
|
+
*
|
|
8
|
+
* Design:
|
|
9
|
+
* - Calls data sources DIRECTLY (not via HTTP routes) so rate-limiters are irrelevant.
|
|
10
|
+
* - Force-fresh = invalidate quota-response-cache then call the fetcher server-side.
|
|
11
|
+
* - Debounce: if a fresh pull happened < 15s ago, serve cache even when refresh=true.
|
|
12
|
+
* - Per-account failure degrades THAT row (null fields + needsReauth/health:error);
|
|
13
|
+
* other rows are unaffected — the payload always returns HTTP 200.
|
|
14
|
+
* - today_cost sourced from getTodayCostByAccount() (Phase 1A output).
|
|
15
|
+
* - health derived from runHealthChecks() summary (overall, not per-account for v1).
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.createBarRouter = exports.resetForceFreshDebounce = void 0;
|
|
19
|
+
const express_1 = require("express");
|
|
20
|
+
const bar_analytics_1 = require("../usage/bar-analytics");
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Timing budgets (module-level; the bar must NEVER block on a slow provider)
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/** Debounce window: skip force-fresh if last fresh pull was < 15s ago */
|
|
25
|
+
const FORCE_FRESH_DEBOUNCE_MS = 15000;
|
|
26
|
+
/** Hard ceiling for the whole /summary response. Past this we paint from cache. */
|
|
27
|
+
const REQUEST_DEADLINE_MS = 2500;
|
|
28
|
+
/** Per-account synchronous wait before falling back to stale cache (bg fetch continues). */
|
|
29
|
+
const PER_ACCOUNT_TIMEOUT_MS = 5000;
|
|
30
|
+
/** Bound for the cost side-load so a slow snapshot read can't dominate the response. */
|
|
31
|
+
const SIDELOAD_TIMEOUT_MS = 1500;
|
|
32
|
+
/**
|
|
33
|
+
* Bound for the native-subscription side-load. A slow or failed native fetch
|
|
34
|
+
* resolves to [] so the response paints CLIProxy rows only — never errors, never
|
|
35
|
+
* blocks. Native rows have their own 10-min cache, so the common path is instant.
|
|
36
|
+
*/
|
|
37
|
+
const NATIVE_SIDELOAD_TIMEOUT_MS = 1500;
|
|
38
|
+
/** Timestamp of the last successful force-fresh pull (epoch ms, 0 = never) */
|
|
39
|
+
let lastForceFreshAt = 0;
|
|
40
|
+
/** Reset module state — called in tests to prevent cross-test pollution */
|
|
41
|
+
function resetForceFreshDebounce() {
|
|
42
|
+
lastForceFreshAt = 0;
|
|
43
|
+
}
|
|
44
|
+
exports.resetForceFreshDebounce = resetForceFreshDebounce;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a promise to its value, or to null if it doesn't settle within `ms`.
|
|
47
|
+
* The underlying promise keeps running (used to let a slow fetch warm the cache
|
|
48
|
+
* for the next open while the current response degrades gracefully).
|
|
49
|
+
*/
|
|
50
|
+
function withTimeout(p, ms) {
|
|
51
|
+
return new Promise((resolve) => {
|
|
52
|
+
let settled = false;
|
|
53
|
+
const timer = setTimeout(() => {
|
|
54
|
+
if (!settled) {
|
|
55
|
+
settled = true;
|
|
56
|
+
resolve(null);
|
|
57
|
+
}
|
|
58
|
+
}, ms);
|
|
59
|
+
p.then((v) => {
|
|
60
|
+
if (!settled) {
|
|
61
|
+
settled = true;
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
resolve(v);
|
|
64
|
+
}
|
|
65
|
+
}, () => {
|
|
66
|
+
if (!settled) {
|
|
67
|
+
settled = true;
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
resolve(null);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map a row to its wire shape. The native-only additions use snake_case parent
|
|
76
|
+
* keys ("quota_windows" / "stale_as_of") to match the existing payload's mixed
|
|
77
|
+
* casing; inner QuotaWindowDetail keys stay camelCase and pass through as-is.
|
|
78
|
+
* Rows without the native fields serialize byte-identically to before, so
|
|
79
|
+
* CLIProxy decode/encode tests are unaffected.
|
|
80
|
+
*/
|
|
81
|
+
function serializeBarRow(row) {
|
|
82
|
+
const { quotaWindows, staleAsOf, ...rest } = row;
|
|
83
|
+
const wire = { ...rest };
|
|
84
|
+
if (quotaWindows !== undefined)
|
|
85
|
+
wire.quota_windows = quotaWindows;
|
|
86
|
+
if (staleAsOf !== undefined && staleAsOf !== null)
|
|
87
|
+
wire.stale_as_of = staleAsOf;
|
|
88
|
+
return wire;
|
|
89
|
+
}
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Per-account health derivation
|
|
92
|
+
// ============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Tri-state quota availability derived from the QuotaResult.
|
|
95
|
+
*
|
|
96
|
+
* We branch ONLY on the result's stable errorCode, never on a provider
|
|
97
|
+
* registry: ghcp is listed in MANAGED_QUOTA_PROVIDERS, yet fetchAccountQuota
|
|
98
|
+
* returns unsupported for every provider !== 'agy'. The result's
|
|
99
|
+
* 'quota_not_supported' code is the only honest signal that a provider has no
|
|
100
|
+
* quota API, so we use it here.
|
|
101
|
+
*
|
|
102
|
+
* success → 'ok'
|
|
103
|
+
* errorCode 'quota_not_supported' → 'unsupported' (no quota API; healthy)
|
|
104
|
+
* anything else (null/timeout/reauth/other failure) → 'error'
|
|
105
|
+
*/
|
|
106
|
+
function deriveQuotaStatus(quota) {
|
|
107
|
+
if (quota?.success === true)
|
|
108
|
+
return 'ok';
|
|
109
|
+
if (quota && quota.errorCode === 'quota_not_supported')
|
|
110
|
+
return 'unsupported';
|
|
111
|
+
return 'error';
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Health for a single account, derived from its own quota-fetch result.
|
|
115
|
+
*
|
|
116
|
+
* The menu bar is a per-account glance, so health is per-row — NOT the global
|
|
117
|
+
* system audit. (The system audit is also unsafe here: it shells out via a
|
|
118
|
+
* synchronous execSync that would block the event loop on the request path.)
|
|
119
|
+
*
|
|
120
|
+
* A provider with no quota API (quotaStatus 'unsupported', e.g. ghcp/kiro) is
|
|
121
|
+
* healthy — it must not show a permanent warning dot. 'warning' is reserved for
|
|
122
|
+
* genuine transient fetch failures, 'error' for accounts needing reauth.
|
|
123
|
+
*
|
|
124
|
+
* needsReauth → 'error' (token expired; user action required)
|
|
125
|
+
* quota unsupported → 'ok' (no quota API is not a fault)
|
|
126
|
+
* fetch failed → 'warning' (transient/unknown; row degrades but isn't fatal)
|
|
127
|
+
* success → 'ok'
|
|
128
|
+
*/
|
|
129
|
+
function deriveHealth(quota, quotaStatus) {
|
|
130
|
+
if (quota?.needsReauth)
|
|
131
|
+
return 'error';
|
|
132
|
+
if (quotaStatus === 'unsupported')
|
|
133
|
+
return 'ok';
|
|
134
|
+
if (!quota || !quota.success)
|
|
135
|
+
return 'warning';
|
|
136
|
+
return 'ok';
|
|
137
|
+
}
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Quota → bar row mapping
|
|
140
|
+
// ============================================================================
|
|
141
|
+
/**
|
|
142
|
+
* Extract the primary quota percentage from a QuotaResult.
|
|
143
|
+
* For Antigravity accounts: use the first model's percentage.
|
|
144
|
+
* Returns null on failure or missing data.
|
|
145
|
+
*/
|
|
146
|
+
function extractQuotaPercentage(quota) {
|
|
147
|
+
if (!quota.success || quota.models.length === 0)
|
|
148
|
+
return null;
|
|
149
|
+
// Use the first model (highest weight) as the representative percentage
|
|
150
|
+
return quota.models[0].percentage ?? null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Extract the next reset timestamp from a QuotaResult.
|
|
154
|
+
* Returns null if not available.
|
|
155
|
+
*/
|
|
156
|
+
function extractNextReset(quota) {
|
|
157
|
+
if (!quota.success || quota.models.length === 0)
|
|
158
|
+
return null;
|
|
159
|
+
return quota.models[0].resetTime ?? null;
|
|
160
|
+
}
|
|
161
|
+
async function fetchAccountData(account, forceRefresh, deps) {
|
|
162
|
+
const provider = account.provider;
|
|
163
|
+
const accountId = account.id;
|
|
164
|
+
const now = new Date().toISOString();
|
|
165
|
+
// Read any prior cache up front so it survives as a stale fallback even when a
|
|
166
|
+
// refresh fetch is slow or fails (stale-while-revalidate).
|
|
167
|
+
const cached = deps.getCachedQuota(provider, accountId);
|
|
168
|
+
// Paused accounts: serve cache if present, otherwise degrade.
|
|
169
|
+
// Never trigger a live fetch for a user-paused account.
|
|
170
|
+
if (account.paused === true) {
|
|
171
|
+
return { quota: cached ?? null, cached: cached !== null, fetchedAt: now };
|
|
172
|
+
}
|
|
173
|
+
// Default mode serves a present cache instantly (no provider call).
|
|
174
|
+
if (!forceRefresh && cached) {
|
|
175
|
+
return { quota: cached, cached: true, fetchedAt: now };
|
|
176
|
+
}
|
|
177
|
+
// Force-fresh busts the route cache first (the stale value captured above
|
|
178
|
+
// still backs the fallback below).
|
|
179
|
+
if (forceRefresh) {
|
|
180
|
+
deps.invalidateQuotaCache(provider, accountId);
|
|
181
|
+
}
|
|
182
|
+
// Live fetch (force-refresh, or default-mode cache miss). It overwrites the
|
|
183
|
+
// cache on success and is bounded by PER_ACCOUNT_TIMEOUT_MS; if it overruns,
|
|
184
|
+
// the fetch keeps running (warming the cache for the next open) while this row
|
|
185
|
+
// degrades to the stale value so the payload never blocks.
|
|
186
|
+
const live = deps.fetchAccountQuota(provider, accountId).then((quota) => {
|
|
187
|
+
deps.setCachedQuota(provider, accountId, quota);
|
|
188
|
+
return quota;
|
|
189
|
+
});
|
|
190
|
+
const fresh = await withTimeout(live, PER_ACCOUNT_TIMEOUT_MS);
|
|
191
|
+
if (fresh)
|
|
192
|
+
return { quota: fresh, cached: false, fetchedAt: now };
|
|
193
|
+
return { quota: cached ?? null, cached: cached !== null, fetchedAt: now };
|
|
194
|
+
}
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Row builder
|
|
197
|
+
// ============================================================================
|
|
198
|
+
/**
|
|
199
|
+
* Resolve the cost-lookup key for an account.
|
|
200
|
+
*
|
|
201
|
+
* The attribution pipeline (buildAuthIndexToAccountMap) stores email as the
|
|
202
|
+
* map value, so costByAccount keys are emails. For providers where
|
|
203
|
+
* account.id == email (agy, gemini, anthropic, etc.) this is a no-op.
|
|
204
|
+
* For duplicate-email providers like codex, account.id may be "email#variant",
|
|
205
|
+
* so we prefer account.email for the lookup to ensure the keys match.
|
|
206
|
+
* Falls back to account.id when email is absent (e.g. kiro/ghcp).
|
|
207
|
+
*/
|
|
208
|
+
function resolveCostKey(account) {
|
|
209
|
+
return account.email ?? account.id;
|
|
210
|
+
}
|
|
211
|
+
function buildRow(account, fetchResult, costByAccount,
|
|
212
|
+
/** Set of cost-keys that are shared by more than one account. Cost is unknowable for these. */
|
|
213
|
+
sharedCostKeys) {
|
|
214
|
+
const { quota, cached, fetchedAt } = fetchResult;
|
|
215
|
+
const costKey = resolveCostKey(account);
|
|
216
|
+
const quotaStatus = deriveQuotaStatus(quota);
|
|
217
|
+
const health = deriveHealth(quota, quotaStatus);
|
|
218
|
+
const isDefault = account.isDefault ?? false;
|
|
219
|
+
const lastActivityAt = account.lastUsedAt ?? null;
|
|
220
|
+
// When multiple accounts share the same cost-key (e.g. two codex accounts with
|
|
221
|
+
// the same email), we cannot attribute the combined cost to either individual
|
|
222
|
+
// account, so it is null=unknowable. A missing key on a single-owner account is
|
|
223
|
+
// ALSO null=unknown (no usage record on a possibly-stale snapshot), distinct from
|
|
224
|
+
// a genuine 0 spend — the UI renders "no data" vs "$0.00" honestly.
|
|
225
|
+
const todayCost = sharedCostKeys.has(costKey) ? null : (costByAccount[costKey] ?? null);
|
|
226
|
+
if (!quota || !quota.success) {
|
|
227
|
+
// Degraded row: preserve identity fields, null out quota data
|
|
228
|
+
return {
|
|
229
|
+
account_id: account.id,
|
|
230
|
+
provider: account.provider,
|
|
231
|
+
displayName: account.nickname ?? account.id,
|
|
232
|
+
tier: account.tier ?? null,
|
|
233
|
+
paused: account.paused ?? false,
|
|
234
|
+
quota_percentage: null,
|
|
235
|
+
quotaStatus,
|
|
236
|
+
next_reset: null,
|
|
237
|
+
is_default: isDefault,
|
|
238
|
+
last_activity_at: lastActivityAt,
|
|
239
|
+
today_cost: todayCost,
|
|
240
|
+
health,
|
|
241
|
+
cached,
|
|
242
|
+
fetchedAt,
|
|
243
|
+
needsReauth: quota?.needsReauth ?? false,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
account_id: account.id,
|
|
248
|
+
provider: account.provider,
|
|
249
|
+
displayName: account.nickname ?? account.id,
|
|
250
|
+
tier: quota.tier ?? account.tier ?? null,
|
|
251
|
+
paused: account.paused ?? false,
|
|
252
|
+
quota_percentage: extractQuotaPercentage(quota),
|
|
253
|
+
quotaStatus,
|
|
254
|
+
next_reset: extractNextReset(quota),
|
|
255
|
+
is_default: isDefault,
|
|
256
|
+
last_activity_at: lastActivityAt,
|
|
257
|
+
today_cost: todayCost,
|
|
258
|
+
health,
|
|
259
|
+
cached,
|
|
260
|
+
fetchedAt,
|
|
261
|
+
needsReauth: quota.needsReauth ?? false,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
// ============================================================================
|
|
265
|
+
// Router factory
|
|
266
|
+
// ============================================================================
|
|
267
|
+
/**
|
|
268
|
+
* Create the bar router with injected dependencies.
|
|
269
|
+
*
|
|
270
|
+
* Production usage: call without arguments (defaults resolve from real modules).
|
|
271
|
+
* Test usage: pass mock implementations for each dep.
|
|
272
|
+
*/
|
|
273
|
+
function createBarRouter(deps) {
|
|
274
|
+
const router = (0, express_1.Router)();
|
|
275
|
+
/**
|
|
276
|
+
* GET /summary[?refresh=true]
|
|
277
|
+
*
|
|
278
|
+
* Returns the menu-bar glance array for all CLIProxy accounts.
|
|
279
|
+
*
|
|
280
|
+
* Query params:
|
|
281
|
+
* refresh=true — force-fresh from provider (debounced to once per 15s)
|
|
282
|
+
*/
|
|
283
|
+
router.get('/summary', async (req, res) => {
|
|
284
|
+
try {
|
|
285
|
+
const wantsRefresh = req.query['refresh'] === 'true';
|
|
286
|
+
// Determine effective refresh mode after applying debounce.
|
|
287
|
+
// IMPORTANT: set lastForceFreshAt at decision time (before awaiting any
|
|
288
|
+
// fetches) to prevent a read-modify-write race where two concurrent
|
|
289
|
+
// refresh=true requests both pass the debounce check before either
|
|
290
|
+
// records the timestamp.
|
|
291
|
+
let doForceRefresh = false;
|
|
292
|
+
if (wantsRefresh) {
|
|
293
|
+
const sinceLastFresh = Date.now() - lastForceFreshAt;
|
|
294
|
+
if (sinceLastFresh >= FORCE_FRESH_DEBOUNCE_MS) {
|
|
295
|
+
doForceRefresh = true;
|
|
296
|
+
lastForceFreshAt = Date.now(); // claim the window before any async work
|
|
297
|
+
}
|
|
298
|
+
// else: debounce active — fall through to cache path
|
|
299
|
+
}
|
|
300
|
+
// Cost side-load is bounded so a slow usage-snapshot read can't stall the
|
|
301
|
+
// glance. (Health is per-account, derived from each quota result below —
|
|
302
|
+
// no blocking system audit on the request path.)
|
|
303
|
+
const details = await withTimeout(deps.loadCliproxyDetails(), SIDELOAD_TIMEOUT_MS);
|
|
304
|
+
const costByAccount = details
|
|
305
|
+
? deps.getTodayCostByAccount(details)
|
|
306
|
+
: {};
|
|
307
|
+
// Flatten all accounts across providers
|
|
308
|
+
const summary = deps.getAllAccountsSummary();
|
|
309
|
+
const allAccounts = Object.values(summary).flat();
|
|
310
|
+
// Fix #11: compute which cost-keys are shared by >1 account so buildRow can
|
|
311
|
+
// report null (unknowable) rather than the combined total for those rows.
|
|
312
|
+
const costKeyCount = new Map();
|
|
313
|
+
for (const account of allAccounts) {
|
|
314
|
+
const key = resolveCostKey(account);
|
|
315
|
+
costKeyCount.set(key, (costKeyCount.get(key) ?? 0) + 1);
|
|
316
|
+
}
|
|
317
|
+
const sharedCostKeys = new Set(Array.from(costKeyCount.entries())
|
|
318
|
+
.filter(([, count]) => count > 1)
|
|
319
|
+
.map(([key]) => key));
|
|
320
|
+
// Build every row synchronously from whatever is in cache right now. This
|
|
321
|
+
// is the instant-paint fallback and the source of truth when the deadline
|
|
322
|
+
// fires before live fetches finish.
|
|
323
|
+
const cacheRows = () => {
|
|
324
|
+
const at = new Date().toISOString();
|
|
325
|
+
return allAccounts.map((account) => {
|
|
326
|
+
const cached = deps.getCachedQuota(account.provider, account.id);
|
|
327
|
+
return buildRow(account, { quota: cached ?? null, cached: cached !== null, fetchedAt: at }, costByAccount, sharedCostKeys);
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
// Fetch quota in parallel with per-account error isolation. Each row is
|
|
331
|
+
// bounded inside fetchAccountData; the whole gather is additionally raced
|
|
332
|
+
// against REQUEST_DEADLINE_MS so the response NEVER hangs on a slow
|
|
333
|
+
// provider — past the deadline we paint from cache and let background
|
|
334
|
+
// fetches warm the next open.
|
|
335
|
+
const CONCURRENCY_CAP = 5;
|
|
336
|
+
const gather = (async () => {
|
|
337
|
+
const rows = [];
|
|
338
|
+
for (let i = 0; i < allAccounts.length; i += CONCURRENCY_CAP) {
|
|
339
|
+
const batch = allAccounts.slice(i, i + CONCURRENCY_CAP);
|
|
340
|
+
const batchRows = await Promise.all(batch.map(async (account) => {
|
|
341
|
+
const fetchResult = await fetchAccountData(account, doForceRefresh, deps);
|
|
342
|
+
return buildRow(account, fetchResult, costByAccount, sharedCostKeys);
|
|
343
|
+
}));
|
|
344
|
+
rows.push(...batchRows);
|
|
345
|
+
}
|
|
346
|
+
return rows;
|
|
347
|
+
})();
|
|
348
|
+
const deadline = new Promise((resolve) => {
|
|
349
|
+
setTimeout(() => resolve(cacheRows()), REQUEST_DEADLINE_MS);
|
|
350
|
+
});
|
|
351
|
+
const rows = await Promise.race([gather, deadline]);
|
|
352
|
+
// Native subscription rows (Claude Code + Codex) are side-loaded AFTER the
|
|
353
|
+
// CLIProxy rows resolve, bounded so a slow/failed native fetch degrades to
|
|
354
|
+
// [] rather than blocking or erroring the response.
|
|
355
|
+
const getNative = deps.getNativeAccountRows ?? (async () => []);
|
|
356
|
+
const nativeRows = (await withTimeout(getNative(), NATIVE_SIDELOAD_TIMEOUT_MS)) ?? [];
|
|
357
|
+
res.json([...rows, ...nativeRows].map(serializeBarRow));
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
console.error('[bar-routes] /summary error:', err.message);
|
|
361
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
/**
|
|
365
|
+
* GET /analytics
|
|
366
|
+
*
|
|
367
|
+
* Rolls up the merged, multi-source usage (Claude Code, Codex, Droid, CLIProxy)
|
|
368
|
+
* into today / 7-day / 30-day spend, a 30-day sparkline, top models, and a
|
|
369
|
+
* per-surface breakdown. Reads the dashboard's stale-while-revalidate caches so
|
|
370
|
+
* recent activity shows even when the CLIProxy snapshot is frozen by a restart.
|
|
371
|
+
* Both loads are bounded so a slow read can't stall the menu; on miss the
|
|
372
|
+
* windows degrade to empty rather than failing the payload.
|
|
373
|
+
*/
|
|
374
|
+
router.get('/analytics', async (_req, res) => {
|
|
375
|
+
try {
|
|
376
|
+
const [daily, hourly] = await Promise.all([
|
|
377
|
+
withTimeout(deps.loadDailyUsage(), SIDELOAD_TIMEOUT_MS).catch(() => []),
|
|
378
|
+
withTimeout(deps.loadHourlyUsage(), SIDELOAD_TIMEOUT_MS).catch(() => []),
|
|
379
|
+
]);
|
|
380
|
+
const analytics = (0, bar_analytics_1.computeBarAnalyticsFromDaily)(daily ?? [], hourly ?? [], new Date());
|
|
381
|
+
res.json(analytics);
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
console.error('[bar-routes] /analytics error:', err.message);
|
|
385
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
return router;
|
|
389
|
+
}
|
|
390
|
+
exports.createBarRouter = createBarRouter;
|
|
391
|
+
// ============================================================================
|
|
392
|
+
// Default production router (sync imports — matches all other route modules)
|
|
393
|
+
// ============================================================================
|
|
394
|
+
const query_1 = require("../../cliproxy/accounts/query");
|
|
395
|
+
const quota_response_cache_1 = require("../../cliproxy/quota/quota-response-cache");
|
|
396
|
+
const quota_fetcher_1 = require("../../cliproxy/quota/quota-fetcher");
|
|
397
|
+
const data_aggregator_1 = require("../usage/data-aggregator");
|
|
398
|
+
const cliproxy_snapshot_reader_1 = require("../usage/cliproxy-snapshot-reader");
|
|
399
|
+
const aggregator_1 = require("../usage/aggregator");
|
|
400
|
+
const native_quota_collector_1 = require("../usage/native-quota-collector");
|
|
401
|
+
/** Production bar router — wired to real dependencies */
|
|
402
|
+
const barRouter = createBarRouter({
|
|
403
|
+
getAllAccountsSummary: query_1.getAllAccountsSummary,
|
|
404
|
+
getCachedQuota: quota_response_cache_1.getCachedQuota,
|
|
405
|
+
setCachedQuota: quota_response_cache_1.setCachedQuota,
|
|
406
|
+
invalidateQuotaCache: quota_response_cache_1.invalidateQuotaCache,
|
|
407
|
+
fetchAccountQuota: quota_fetcher_1.fetchAccountQuota,
|
|
408
|
+
getTodayCostByAccount: data_aggregator_1.getTodayCostByAccount,
|
|
409
|
+
loadCliproxyDetails: cliproxy_snapshot_reader_1.loadCliproxySnapshotDetails,
|
|
410
|
+
loadDailyUsage: () => (0, aggregator_1.getCachedDailyData)(),
|
|
411
|
+
loadHourlyUsage: () => (0, aggregator_1.getCachedHourlyData)(),
|
|
412
|
+
getNativeAccountRows: () => (0, native_quota_collector_1.getNativeAccountRows)(),
|
|
413
|
+
});
|
|
414
|
+
exports.default = barRouter;
|
|
415
|
+
//# sourceMappingURL=bar-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-routes.js","sourceRoot":"","sources":["../../../src/web-server/routes/bar-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,5 +20,15 @@ export declare function getStartAuthNicknameError(provider: CLIProxyProvider, ni
|
|
|
20
20
|
error: string;
|
|
21
21
|
code: 'INVALID_NICKNAME' | 'NICKNAME_EXISTS';
|
|
22
22
|
} | null;
|
|
23
|
+
export declare function getReauthAccountTarget(accountId: string | undefined, existingAccounts: Array<{
|
|
24
|
+
id: string;
|
|
25
|
+
nickname?: string;
|
|
26
|
+
}>): {
|
|
27
|
+
account?: {
|
|
28
|
+
id: string;
|
|
29
|
+
nickname?: string;
|
|
30
|
+
};
|
|
31
|
+
error?: string;
|
|
32
|
+
};
|
|
23
33
|
export default router;
|
|
24
34
|
//# sourceMappingURL=cliproxy-auth-routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliproxy-auth-routes.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/cliproxy-auth-routes.ts"],"names":[],"mappings":"AA8CA,OAAO,EAOL,cAAc,EAIf,MAAM,gCAAgC,CAAC;AAMxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgB7D,QAAA,MAAM,MAAM,4CAAW,CAAC;AAkLxB,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,UAAU,EAAE,cAAc,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBzC;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,cAAc,CAAA;CAAE,GACxC,MAAM,GAAG,IAAI,CAuBf;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAK7E;AASD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,gBAAgB,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1D,sBAAsB,CAAC,EAAE,MAAM,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,GAAG,iBAAiB,CAAA;CAAE,GAAG,IAAI,CAqBxE;
|
|
1
|
+
{"version":3,"file":"cliproxy-auth-routes.d.ts","sourceRoot":"","sources":["../../../src/web-server/routes/cliproxy-auth-routes.ts"],"names":[],"mappings":"AA8CA,OAAO,EAOL,cAAc,EAIf,MAAM,gCAAgC,CAAC;AAMxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgB7D,QAAA,MAAM,MAAM,4CAAW,CAAC;AAkLxB,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,UAAU,EAAE,cAAc,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBzC;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,cAAc,CAAA;CAAE,GACxC,MAAM,GAAG,IAAI,CAuBf;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAK7E;AASD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,gBAAgB,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1D,sBAAsB,CAAC,EAAE,MAAM,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,GAAG,iBAAiB,CAAA;CAAE,GAAG,IAAI,CAqBxE;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,gBAAgB,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACzD;IAAE,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAajE;AA+mCD,eAAe,MAAM,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getStartAuthNicknameError = exports.getStartAuthFailureMessage = exports.getStartUrlUnsupportedReason = exports.getKiroStartIDCValidationError = void 0;
|
|
3
|
+
exports.getReauthAccountTarget = exports.getStartAuthNicknameError = exports.getStartAuthFailureMessage = exports.getStartUrlUnsupportedReason = exports.getKiroStartIDCValidationError = void 0;
|
|
4
4
|
const express_1 = require("express");
|
|
5
5
|
const auth_handler_1 = require("../../cliproxy/auth/auth-handler");
|
|
6
6
|
const project_selection_handler_1 = require("../../cliproxy/auth/project-selection-handler");
|
|
@@ -210,6 +210,19 @@ function getStartAuthNicknameError(provider, nickname, existingAccounts, allowEx
|
|
|
210
210
|
return null;
|
|
211
211
|
}
|
|
212
212
|
exports.getStartAuthNicknameError = getStartAuthNicknameError;
|
|
213
|
+
function getReauthAccountTarget(accountId, existingAccounts) {
|
|
214
|
+
if (!accountId) {
|
|
215
|
+
return {};
|
|
216
|
+
}
|
|
217
|
+
const account = existingAccounts.find((candidate) => candidate.id === accountId);
|
|
218
|
+
if (!account) {
|
|
219
|
+
return {
|
|
220
|
+
error: `Account '${accountId}' not found for this provider`,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return { account };
|
|
224
|
+
}
|
|
225
|
+
exports.getReauthAccountTarget = getReauthAccountTarget;
|
|
213
226
|
/**
|
|
214
227
|
* GET /api/cliproxy/auth - Get auth status for built-in CLIProxy profiles
|
|
215
228
|
* Also fetches CLIProxyAPI stats to update lastUsedAt for active providers
|
|
@@ -464,6 +477,7 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
464
477
|
const { provider } = req.params;
|
|
465
478
|
const requestBody = req.body && typeof req.body === 'object' ? req.body : {};
|
|
466
479
|
const nicknameRaw = typeof requestBody.nickname === 'string' ? requestBody.nickname : undefined;
|
|
480
|
+
const accountId = typeof requestBody.accountId === 'string' ? requestBody.accountId.trim() : undefined;
|
|
467
481
|
const noIncognitoBody = typeof requestBody.noIncognito === 'boolean' ? requestBody.noIncognito : undefined;
|
|
468
482
|
const kiroMethodRaw = requestBody.kiroMethod;
|
|
469
483
|
const kiroIDCStartUrl = typeof requestBody.kiroIDCStartUrl === 'string'
|
|
@@ -492,6 +506,15 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
492
506
|
res.status(400).json({ error: `Invalid provider: ${provider}` });
|
|
493
507
|
return;
|
|
494
508
|
}
|
|
509
|
+
const localProvider = provider;
|
|
510
|
+
const existingAccounts = (0, account_manager_1.getProviderAccounts)(localProvider);
|
|
511
|
+
const reauthTarget = getReauthAccountTarget(accountId, existingAccounts);
|
|
512
|
+
if (reauthTarget.error) {
|
|
513
|
+
res.status(404).json({ error: reauthTarget.error });
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const targetAccountId = reauthTarget.account?.id;
|
|
517
|
+
const effectiveNickname = nickname || reauthTarget.account?.nickname;
|
|
495
518
|
if (provider === 'kiro' && invalidKiroMethod) {
|
|
496
519
|
res.status(400).json({
|
|
497
520
|
error: 'Invalid kiroMethod. Supported: aws, aws-authcode, google, github, idc',
|
|
@@ -536,7 +559,6 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
536
559
|
return;
|
|
537
560
|
}
|
|
538
561
|
try {
|
|
539
|
-
const localProvider = provider;
|
|
540
562
|
const knownTokenFiles = (0, token_manager_1.listProviderTokenSnapshots)(localProvider);
|
|
541
563
|
const response = await fetch((0, proxy_target_resolver_1.buildProxyUrl)(target, '/v0/management/gitlab-auth-url'), {
|
|
542
564
|
method: 'POST',
|
|
@@ -557,14 +579,14 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
557
579
|
});
|
|
558
580
|
return;
|
|
559
581
|
}
|
|
560
|
-
const tokenSnapshot = (0, token_manager_1.findNewTokenSnapshot)((0, token_manager_1.listProviderTokenSnapshots)(localProvider), knownTokenFiles);
|
|
582
|
+
const tokenSnapshot = (0, token_manager_1.findNewTokenSnapshot)((0, token_manager_1.listProviderTokenSnapshots)(localProvider), knownTokenFiles, targetAccountId);
|
|
561
583
|
if (!tokenSnapshot) {
|
|
562
584
|
res.status(409).json({
|
|
563
585
|
error: 'GitLab PAT authentication completed, but CCS could not find the saved token.',
|
|
564
586
|
});
|
|
565
587
|
return;
|
|
566
588
|
}
|
|
567
|
-
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider),
|
|
589
|
+
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider), effectiveNickname, false, targetAccountId || tokenSnapshot.file);
|
|
568
590
|
if (!account) {
|
|
569
591
|
res.status(409).json({
|
|
570
592
|
error: 'GitLab PAT authentication succeeded, but account registration failed.',
|
|
@@ -594,8 +616,7 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
594
616
|
return;
|
|
595
617
|
}
|
|
596
618
|
}
|
|
597
|
-
const
|
|
598
|
-
const nicknameError = getStartAuthNicknameError(provider, nickname, existingAccounts);
|
|
619
|
+
const nicknameError = getStartAuthNicknameError(localProvider, effectiveNickname, existingAccounts, targetAccountId);
|
|
599
620
|
if (nicknameError) {
|
|
600
621
|
res.status(400).json(nicknameError);
|
|
601
622
|
return;
|
|
@@ -612,7 +633,8 @@ router.post('/:provider/start', async (req, res) => {
|
|
|
612
633
|
const account = await (0, auth_handler_1.triggerOAuth)(provider, {
|
|
613
634
|
add: true, // Always add mode from UI
|
|
614
635
|
headless: false, // Force interactive mode
|
|
615
|
-
nickname:
|
|
636
|
+
nickname: effectiveNickname || undefined,
|
|
637
|
+
expectedAccountId: targetAccountId,
|
|
616
638
|
acceptAgyRisk: provider === 'agy',
|
|
617
639
|
kiroMethod: provider === 'kiro' ? kiroMethod : undefined,
|
|
618
640
|
kiroIDCStartUrl: provider === 'kiro' ? kiroIDCStartUrl : undefined,
|
|
@@ -762,6 +784,7 @@ router.post('/:provider/start-url', async (req, res) => {
|
|
|
762
784
|
const { provider } = req.params;
|
|
763
785
|
const requestBody = req.body && typeof req.body === 'object' ? req.body : {};
|
|
764
786
|
const nicknameRaw = typeof requestBody.nickname === 'string' ? requestBody.nickname : undefined;
|
|
787
|
+
const accountId = typeof requestBody.accountId === 'string' ? requestBody.accountId.trim() : undefined;
|
|
765
788
|
const kiroMethodRaw = requestBody.kiroMethod;
|
|
766
789
|
const gitlabAuthModeRaw = requestBody.gitlabAuthMode;
|
|
767
790
|
const gitlabBaseUrl = typeof requestBody.gitlabBaseUrl === 'string' ? requestBody.gitlabBaseUrl.trim() : undefined;
|
|
@@ -818,8 +841,16 @@ router.post('/:provider/start-url', async (req, res) => {
|
|
|
818
841
|
res.status(400).json({ error: unsupportedReason });
|
|
819
842
|
return;
|
|
820
843
|
}
|
|
821
|
-
const
|
|
822
|
-
const
|
|
844
|
+
const localProvider = provider;
|
|
845
|
+
const existingAccounts = (0, account_manager_1.getProviderAccounts)(localProvider);
|
|
846
|
+
const reauthTarget = getReauthAccountTarget(accountId, existingAccounts);
|
|
847
|
+
if (reauthTarget.error) {
|
|
848
|
+
res.status(404).json({ error: reauthTarget.error });
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
const targetAccountId = reauthTarget.account?.id;
|
|
852
|
+
const effectiveNickname = nickname || reauthTarget.account?.nickname;
|
|
853
|
+
const nicknameError = getStartAuthNicknameError(localProvider, effectiveNickname, existingAccounts, targetAccountId);
|
|
823
854
|
if (nicknameError) {
|
|
824
855
|
res.status(400).json(nicknameError);
|
|
825
856
|
return;
|
|
@@ -889,8 +920,9 @@ router.post('/:provider/start-url', async (req, res) => {
|
|
|
889
920
|
}
|
|
890
921
|
if (oauthState) {
|
|
891
922
|
rememberManualAuthState(oauthState, {
|
|
892
|
-
nickname:
|
|
893
|
-
|
|
923
|
+
nickname: effectiveNickname || undefined,
|
|
924
|
+
expectedAccountId: targetAccountId,
|
|
925
|
+
knownTokenFiles: (0, token_manager_1.listProviderTokenSnapshots)(localProvider),
|
|
894
926
|
});
|
|
895
927
|
}
|
|
896
928
|
res.json({
|
|
@@ -966,7 +998,7 @@ router.get('/:provider/status', async (req, res) => {
|
|
|
966
998
|
});
|
|
967
999
|
return;
|
|
968
1000
|
}
|
|
969
|
-
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider), pendingAuth.nickname, false, tokenSnapshot.file);
|
|
1001
|
+
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider), pendingAuth.nickname, false, pendingAuth.expectedAccountId || tokenSnapshot.file);
|
|
970
1002
|
if (!account) {
|
|
971
1003
|
pendingManualAuthState.delete(state);
|
|
972
1004
|
res.status(409).json({
|
|
@@ -1093,7 +1125,7 @@ router.post('/:provider/submit-callback', async (req, res) => {
|
|
|
1093
1125
|
});
|
|
1094
1126
|
return;
|
|
1095
1127
|
}
|
|
1096
|
-
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider), pendingAuth.nickname, false, tokenSnapshot.file);
|
|
1128
|
+
const account = (0, token_manager_1.registerAccountFromToken)(localProvider, (0, token_manager_1.getProviderTokenDir)(localProvider), pendingAuth.nickname, false, pendingAuth.expectedAccountId || tokenSnapshot.file);
|
|
1097
1129
|
if (!account) {
|
|
1098
1130
|
if (parsed.state) {
|
|
1099
1131
|
pendingManualAuthState.delete(parsed.state);
|