@kaitranntt/ccs 8.2.0 → 8.3.0-dev.1
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/README.md +12 -0
- package/config/base-claude.settings.json +1 -5
- package/dist/api/services/cliproxy-profile-bridge.d.ts.map +1 -1
- package/dist/api/services/cliproxy-profile-bridge.js +6 -0
- package/dist/api/services/cliproxy-profile-bridge.js.map +1 -1
- package/dist/api/services/profile-writer.d.ts.map +1 -1
- package/dist/api/services/profile-writer.js +18 -8
- package/dist/api/services/profile-writer.js.map +1 -1
- package/dist/auth/commands/create-command.d.ts.map +1 -1
- package/dist/auth/commands/create-command.js +11 -0
- package/dist/auth/commands/create-command.js.map +1 -1
- package/dist/cliproxy/accounts/account-safety-cross-lane.d.ts +41 -0
- package/dist/cliproxy/accounts/account-safety-cross-lane.d.ts.map +1 -0
- package/dist/cliproxy/accounts/account-safety-cross-lane.js +177 -0
- package/dist/cliproxy/accounts/account-safety-cross-lane.js.map +1 -0
- package/dist/cliproxy/accounts/account-safety.d.ts +29 -1
- package/dist/cliproxy/accounts/account-safety.d.ts.map +1 -1
- package/dist/cliproxy/accounts/account-safety.js +41 -7
- package/dist/cliproxy/accounts/account-safety.js.map +1 -1
- package/dist/cliproxy/accounts/drain-order.d.ts +277 -0
- package/dist/cliproxy/accounts/drain-order.d.ts.map +1 -0
- package/dist/cliproxy/accounts/drain-order.js +575 -0
- package/dist/cliproxy/accounts/drain-order.js.map +1 -0
- package/dist/cliproxy/accounts/pool-state.d.ts +132 -0
- package/dist/cliproxy/accounts/pool-state.d.ts.map +1 -0
- package/dist/cliproxy/accounts/pool-state.js +201 -0
- package/dist/cliproxy/accounts/pool-state.js.map +1 -0
- package/dist/cliproxy/accounts/registry.d.ts +17 -1
- package/dist/cliproxy/accounts/registry.d.ts.map +1 -1
- package/dist/cliproxy/accounts/registry.js +47 -1
- package/dist/cliproxy/accounts/registry.js.map +1 -1
- package/dist/cliproxy/accounts/types.d.ts +20 -0
- package/dist/cliproxy/accounts/types.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.js +29 -0
- package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
- package/dist/cliproxy/binary/platform-detector.d.ts.map +1 -1
- package/dist/cliproxy/binary/platform-detector.js +34 -1
- package/dist/cliproxy/binary/platform-detector.js.map +1 -1
- package/dist/cliproxy/binary/types.d.ts +3 -0
- package/dist/cliproxy/binary/types.d.ts.map +1 -1
- package/dist/cliproxy/binary/types.js +7 -2
- package/dist/cliproxy/binary/types.js.map +1 -1
- package/dist/cliproxy/binary/version-cache.d.ts.map +1 -1
- package/dist/cliproxy/binary/version-cache.js +4 -0
- package/dist/cliproxy/binary/version-cache.js.map +1 -1
- package/dist/cliproxy/claude-shadow-warning.d.ts +39 -0
- package/dist/cliproxy/claude-shadow-warning.d.ts.map +1 -0
- package/dist/cliproxy/claude-shadow-warning.js +187 -0
- package/dist/cliproxy/claude-shadow-warning.js.map +1 -0
- package/dist/cliproxy/config/base-config-loader.d.ts +6 -5
- package/dist/cliproxy/config/base-config-loader.d.ts.map +1 -1
- package/dist/cliproxy/config/base-config-loader.js +19 -12
- package/dist/cliproxy/config/base-config-loader.js.map +1 -1
- package/dist/cliproxy/config/env-builder.d.ts +3 -0
- package/dist/cliproxy/config/env-builder.d.ts.map +1 -1
- package/dist/cliproxy/config/env-builder.js +158 -20
- package/dist/cliproxy/config/env-builder.js.map +1 -1
- package/dist/cliproxy/config/generator.d.ts +2 -1
- package/dist/cliproxy/config/generator.d.ts.map +1 -1
- package/dist/cliproxy/config/generator.js +66 -9
- package/dist/cliproxy/config/generator.js.map +1 -1
- package/dist/cliproxy/config/thinking-config.d.ts.map +1 -1
- package/dist/cliproxy/config/thinking-config.js +2 -0
- package/dist/cliproxy/config/thinking-config.js.map +1 -1
- package/dist/cliproxy/executor/account-resolution.d.ts.map +1 -1
- package/dist/cliproxy/executor/account-resolution.js +5 -0
- package/dist/cliproxy/executor/account-resolution.js.map +1 -1
- package/dist/cliproxy/executor/auth-coordinator.d.ts +4 -0
- package/dist/cliproxy/executor/auth-coordinator.d.ts.map +1 -1
- package/dist/cliproxy/executor/auth-coordinator.js +5 -1
- package/dist/cliproxy/executor/auth-coordinator.js.map +1 -1
- package/dist/cliproxy/executor/index.d.ts.map +1 -1
- package/dist/cliproxy/executor/index.js +20 -0
- package/dist/cliproxy/executor/index.js.map +1 -1
- package/dist/cliproxy/model-catalog.d.ts.map +1 -1
- package/dist/cliproxy/model-catalog.js +15 -0
- package/dist/cliproxy/model-catalog.js.map +1 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.d.ts.map +1 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.js +8 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.js.map +1 -1
- 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.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-manager.d.ts +7 -0
- package/dist/cliproxy/quota/quota-manager.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-manager.js +51 -2
- package/dist/cliproxy/quota/quota-manager.js.map +1 -1
- package/dist/cliproxy/routing/pool-onboarding-hint.d.ts +95 -0
- package/dist/cliproxy/routing/pool-onboarding-hint.d.ts.map +1 -0
- package/dist/cliproxy/routing/pool-onboarding-hint.js +172 -0
- package/dist/cliproxy/routing/pool-onboarding-hint.js.map +1 -0
- package/dist/cliproxy/routing/pool-opt-in-prompt.d.ts +50 -0
- package/dist/cliproxy/routing/pool-opt-in-prompt.d.ts.map +1 -0
- package/dist/cliproxy/routing/pool-opt-in-prompt.js +232 -0
- package/dist/cliproxy/routing/pool-opt-in-prompt.js.map +1 -0
- package/dist/cliproxy/routing/routing-strategy.d.ts +132 -0
- package/dist/cliproxy/routing/routing-strategy.d.ts.map +1 -1
- package/dist/cliproxy/routing/routing-strategy.js +342 -5
- package/dist/cliproxy/routing/routing-strategy.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/commands/bar/help-subcommand.d.ts +2 -0
- package/dist/commands/bar/help-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/help-subcommand.js +63 -0
- package/dist/commands/bar/help-subcommand.js.map +1 -0
- 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 +78 -0
- package/dist/commands/bar/index.js.map +1 -0
- package/dist/commands/bar/install-subcommand.d.ts +92 -0
- package/dist/commands/bar/install-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/install-subcommand.js +605 -0
- package/dist/commands/bar/install-subcommand.js.map +1 -0
- package/dist/commands/bar/launch-subcommand.d.ts +64 -0
- package/dist/commands/bar/launch-subcommand.d.ts.map +1 -0
- package/dist/commands/bar/launch-subcommand.js +236 -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/cliproxy/help-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/help-subcommand.js +20 -1
- package/dist/commands/cliproxy/help-subcommand.js.map +1 -1
- package/dist/commands/cliproxy/index.d.ts.map +1 -1
- package/dist/commands/cliproxy/index.js +20 -0
- package/dist/commands/cliproxy/index.js.map +1 -1
- package/dist/commands/cliproxy/order-subcommand.d.ts +16 -0
- package/dist/commands/cliproxy/order-subcommand.d.ts.map +1 -0
- package/dist/commands/cliproxy/order-subcommand.js +520 -0
- package/dist/commands/cliproxy/order-subcommand.js.map +1 -0
- package/dist/commands/cliproxy/pool-state-renderer.d.ts +40 -0
- package/dist/commands/cliproxy/pool-state-renderer.d.ts.map +1 -0
- package/dist/commands/cliproxy/pool-state-renderer.js +220 -0
- package/dist/commands/cliproxy/pool-state-renderer.js.map +1 -0
- package/dist/commands/cliproxy/pool-subcommand.d.ts +10 -0
- package/dist/commands/cliproxy/pool-subcommand.d.ts.map +1 -0
- package/dist/commands/cliproxy/pool-subcommand.js +112 -0
- package/dist/commands/cliproxy/pool-subcommand.js.map +1 -0
- package/dist/commands/cliproxy/quota-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand.js +7 -0
- package/dist/commands/cliproxy/quota-subcommand.js.map +1 -1
- package/dist/commands/cliproxy/routing-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/routing-subcommand.js +19 -0
- package/dist/commands/cliproxy/routing-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/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +6 -1
- package/dist/commands/help-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/schemas/cliproxy.d.ts +37 -0
- package/dist/config/schemas/cliproxy.d.ts.map +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/config/unified-config-loader.d.ts.map +1 -1
- package/dist/config/unified-config-loader.js +3 -0
- package/dist/config/unified-config-loader.js.map +1 -1
- package/dist/dispatcher/flows/account-flow.d.ts.map +1 -1
- package/dist/dispatcher/flows/account-flow.js +9 -0
- package/dist/dispatcher/flows/account-flow.js.map +1 -1
- package/dist/glmt/delta-accumulator.d.ts.map +1 -1
- package/dist/glmt/delta-accumulator.js +1 -0
- package/dist/glmt/delta-accumulator.js.map +1 -1
- package/dist/management/doctor.d.ts.map +1 -1
- package/dist/management/doctor.js +10 -0
- package/dist/management/doctor.js.map +1 -1
- package/dist/proxy/profile-router.d.ts +14 -0
- package/dist/proxy/profile-router.d.ts.map +1 -1
- package/dist/proxy/profile-router.js +1 -0
- package/dist/proxy/profile-router.js.map +1 -1
- package/dist/proxy/server/http-helpers.d.ts +5 -0
- package/dist/proxy/server/http-helpers.d.ts.map +1 -1
- package/dist/proxy/server/http-helpers.js +40 -1
- package/dist/proxy/server/http-helpers.js.map +1 -1
- package/dist/proxy/server/messages-route.d.ts.map +1 -1
- package/dist/proxy/server/messages-route.js +173 -10
- package/dist/proxy/server/messages-route.js.map +1 -1
- package/dist/proxy/upstream-url.d.ts +42 -2
- package/dist/proxy/upstream-url.d.ts.map +1 -1
- package/dist/proxy/upstream-url.js +83 -4
- package/dist/proxy/upstream-url.js.map +1 -1
- package/dist/ui/assets/{Trans-DsGR5Bhb.js → Trans-RG_sMDEu.js} +1 -1
- package/dist/ui/assets/accounts-yTXURc-q.js +1 -0
- package/dist/ui/assets/{alert-dialog-Do0XfN46.js → alert-dialog-DjvPgzFs.js} +1 -1
- package/dist/ui/assets/{api-B7OYas_V.js → api-Ck1dtNEM.js} +3 -3
- package/dist/ui/assets/{auth-section-BmTeNetL.js → auth-section-DBnY_LPz.js} +1 -1
- package/dist/ui/assets/{backups-section-COawLfTr.js → backups-section-Ci-uL4Of.js} +1 -1
- package/dist/ui/assets/{channels-C9LVYmNJ.js → channels-BeS9O5q0.js} +1 -1
- package/dist/ui/assets/{checkbox-BkFzg8C-.js → checkbox-DFeFDZBp.js} +1 -1
- package/dist/ui/assets/{claude-extension-Ch7L4lTF.js → claude-extension-DS5qN19Z.js} +1 -1
- package/dist/ui/assets/{cliproxy-B3uWt6gn.js → cliproxy-D7HJH4mZ.js} +1 -1
- package/dist/ui/assets/{cliproxy-ai-providers-Bn1_AdKD.js → cliproxy-ai-providers-oJQZXrtc.js} +1 -1
- package/dist/ui/assets/{cliproxy-control-panel-DC4pOOfY.js → cliproxy-control-panel-2mRPEcRj.js} +1 -1
- package/dist/ui/assets/codex-D0AUQ6jA.js +30 -0
- package/dist/ui/assets/{confirm-dialog-4rb-E8-R.js → confirm-dialog-B37-CVuq.js} +1 -1
- package/dist/ui/assets/{copilot-zgPXNkMw.js → copilot-KaaW-mko.js} +2 -2
- package/dist/ui/assets/{cursor-lRPpppk-.js → cursor-BKiTgYi5.js} +1 -1
- package/dist/ui/assets/{droid-koOj34SB.js → droid-DHdqGnFw.js} +2 -2
- package/dist/ui/assets/{globalenv-section-jOkPVwvN.js → globalenv-section-SfZO97nU.js} +1 -1
- package/dist/ui/assets/health-CSRS9O0D.js +1 -0
- package/dist/ui/assets/icons-DSLG1YsC.js +1 -0
- package/dist/ui/assets/{index-D7crOfea.js → index-CGgavq2X.js} +37 -37
- package/dist/ui/assets/{index-BLC5PyZn.js → index-ChTYEBCZ.js} +1 -1
- package/dist/ui/assets/index-Cu_F55_O.js +1 -0
- package/dist/ui/assets/{index-CRhKyfnS.js → index-DJ66NrBH.js} +1 -1
- package/dist/ui/assets/index-DWUuSBUe.js +1 -0
- package/dist/ui/assets/{index-BK-PSsqi.js → index-DycwEe96.js} +1 -1
- package/dist/ui/assets/index-DzFlVVV3.css +1 -0
- package/dist/ui/assets/{index-De3yNJ94.js → index-iQuEEGbH.js} +1 -1
- package/dist/ui/assets/{logs-BplpQHRb.js → logs-tiZ_51mo.js} +1 -1
- package/dist/ui/assets/{masked-input-DuLL3EwS.js → masked-input-D9FVoeMA.js} +1 -1
- package/dist/ui/assets/proxy-status-widget-2k26d8pS.js +1 -0
- package/dist/ui/assets/{raw-json-settings-editor-panel-ClPqZ6iZ.js → raw-json-settings-editor-panel-CguBh93H.js} +1 -1
- package/dist/ui/assets/{searchable-select-BH1b065u.js → searchable-select-C4wShshD.js} +1 -1
- package/dist/ui/assets/{separator-BOiJ0l4s.js → separator-mvGlDdEW.js} +1 -1
- package/dist/ui/assets/{shared-CunXigZu.js → shared-Ck0yAwbs.js} +1 -1
- package/dist/ui/assets/{table-C7ysR1Xz.js → table-DrUJOxKL.js} +1 -1
- package/dist/ui/assets/updates-BVHBFcq8.js +1 -0
- package/dist/ui/assets/{use-accounts-CwRU3ln9.js → use-accounts-DLtuaniS.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/browser/mcp-installer.d.ts.map +1 -1
- package/dist/utils/browser/mcp-installer.js +5 -34
- package/dist/utils/browser/mcp-installer.js.map +1 -1
- package/dist/utils/claude-user-config-lock.d.ts +9 -0
- package/dist/utils/claude-user-config-lock.d.ts.map +1 -0
- package/dist/utils/claude-user-config-lock.js +96 -0
- package/dist/utils/claude-user-config-lock.js.map +1 -0
- package/dist/utils/image-analysis/mcp-installer.d.ts.map +1 -1
- package/dist/utils/image-analysis/mcp-installer.js +5 -34
- package/dist/utils/image-analysis/mcp-installer.js.map +1 -1
- package/dist/utils/websearch/mcp-installer.d.ts.map +1 -1
- package/dist/utils/websearch/mcp-installer.js +112 -78
- package/dist/utils/websearch/mcp-installer.js.map +1 -1
- package/dist/web-server/model-pricing.d.ts.map +1 -1
- package/dist/web-server/model-pricing.js +7 -0
- package/dist/web-server/model-pricing.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/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/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 +14 -2
- package/dist/web-server/usage/cliproxy-usage-syncer.js.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts +8 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.js +31 -4
- 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/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/types.d.ts +2 -0
- package/dist/web-server/usage/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/run-test-bucket.js +183 -17
- package/dist/ui/assets/accounts-DHBmHeH-.js +0 -1
- package/dist/ui/assets/codex-CcODhykP.js +0 -30
- package/dist/ui/assets/health-CxHauE3Y.js +0 -1
- package/dist/ui/assets/icons-DzKUh8vG.js +0 -1
- package/dist/ui/assets/index-DOfPoKe_.css +0 -1
- package/dist/ui/assets/index-DUGnoURR.js +0 -1
- package/dist/ui/assets/index-I_ek1xyD.js +0 -1
- package/dist/ui/assets/proxy-status-widget-BruRPTSl.js +0 -1
- package/dist/ui/assets/updates-BtBCV2xk.js +0 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bar Analytics Aggregator
|
|
4
|
+
*
|
|
5
|
+
* Pure functions that roll up the flat CliproxyUsageHistoryDetail array (the
|
|
6
|
+
* same snapshot the bar already loads for per-account cost) into the small,
|
|
7
|
+
* glanceable analytics the menu bar surfaces: today / 7-day / 30-day spend,
|
|
8
|
+
* a 7-day cost sparkline, and the top models by spend.
|
|
9
|
+
*
|
|
10
|
+
* Kept dependency-free and deterministic (the reference "now" is injected) so
|
|
11
|
+
* it is trivially unit-testable and cheap enough to run on every bar open.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.computeBarAnalyticsFromDaily = exports.computeBarAnalytics = exports.localDayKey = void 0;
|
|
15
|
+
// 30-day trailing window: gives a non-empty sparkline shape even when the last
|
|
16
|
+
// 7 days are zero, so a stale-but-real history doesn't read as a broken chart.
|
|
17
|
+
const SPARKLINE_DAYS = 30;
|
|
18
|
+
const TOP_MODELS_LIMIT = 5;
|
|
19
|
+
/** Local-time YYYY-MM-DD key for a Date (matches the user's calendar day). */
|
|
20
|
+
function localDayKey(d) {
|
|
21
|
+
const y = d.getFullYear();
|
|
22
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
23
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
24
|
+
return `${y}-${m}-${day}`;
|
|
25
|
+
}
|
|
26
|
+
exports.localDayKey = localDayKey;
|
|
27
|
+
/**
|
|
28
|
+
* Local-time YYYY-MM key for a Date. Local (not a UTC ISO slice) so it matches
|
|
29
|
+
* the local-day semantics of `dayDelta`/`localDayKey` — a record near midnight
|
|
30
|
+
* lands in the same month the user sees on their calendar.
|
|
31
|
+
*/
|
|
32
|
+
function localMonthKey(d) {
|
|
33
|
+
const y = d.getFullYear();
|
|
34
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
35
|
+
return `${y}-${m}`;
|
|
36
|
+
}
|
|
37
|
+
/** Whole-day difference (a - b) in local days, via midnight-anchored dates. */
|
|
38
|
+
function dayDelta(a, b) {
|
|
39
|
+
const da = new Date(a.getFullYear(), a.getMonth(), a.getDate());
|
|
40
|
+
const db = new Date(b.getFullYear(), b.getMonth(), b.getDate());
|
|
41
|
+
return Math.round((da.getTime() - db.getTime()) / 86400000);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Roll the raw details into the bar analytics payload, relative to `now`.
|
|
45
|
+
* Failed requests are excluded from spend (they carry no real cost).
|
|
46
|
+
*/
|
|
47
|
+
function computeBarAnalytics(details, now) {
|
|
48
|
+
const today = { cost: 0, requests: 0 };
|
|
49
|
+
const last7d = { cost: 0, requests: 0 };
|
|
50
|
+
const last30d = { cost: 0, requests: 0 };
|
|
51
|
+
const monthToDate = { cost: 0, requests: 0 };
|
|
52
|
+
const allTime = { cost: 0, requests: 0 };
|
|
53
|
+
// Current local calendar month — records keyed to it feed month-to-date.
|
|
54
|
+
const currentMonth = localMonthKey(now);
|
|
55
|
+
// Seed the sparkline with the trailing 7 local days (zero-filled, ordered).
|
|
56
|
+
const dayBuckets = new Map();
|
|
57
|
+
for (let i = SPARKLINE_DAYS - 1; i >= 0; i--) {
|
|
58
|
+
const d = new Date(now.getFullYear(), now.getMonth(), now.getDate() - i);
|
|
59
|
+
dayBuckets.set(localDayKey(d), { date: localDayKey(d), cost: 0, requests: 0 });
|
|
60
|
+
}
|
|
61
|
+
// Track per-model spend over both the trailing 30 days and all-time so we can
|
|
62
|
+
// show recent leaders when fresh, and lifetime leaders when the proxy has
|
|
63
|
+
// simply been idle lately.
|
|
64
|
+
const model30d = new Map();
|
|
65
|
+
const modelAll = new Map();
|
|
66
|
+
const bump = (map, model, cost, requests) => {
|
|
67
|
+
const existing = map.get(model);
|
|
68
|
+
if (existing) {
|
|
69
|
+
existing.cost += cost;
|
|
70
|
+
existing.requests += requests;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
map.set(model, { model, cost, requests });
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
// Epoch ms of the most recent non-failed record, tracked inside the single
|
|
77
|
+
// loop the function already runs (O(1) extra per iteration, no new I/O).
|
|
78
|
+
let lastActivityMs = -Infinity;
|
|
79
|
+
for (const detail of details) {
|
|
80
|
+
if (detail.failed)
|
|
81
|
+
continue;
|
|
82
|
+
const ts = new Date(detail.timestamp);
|
|
83
|
+
if (Number.isNaN(ts.getTime()))
|
|
84
|
+
continue;
|
|
85
|
+
const delta = dayDelta(now, ts); // 0 = today, 1 = yesterday, …
|
|
86
|
+
if (delta < 0)
|
|
87
|
+
continue; // ignore future-dated noise
|
|
88
|
+
if (ts.getTime() > lastActivityMs)
|
|
89
|
+
lastActivityMs = ts.getTime();
|
|
90
|
+
const cost = Number.isFinite(detail.cost) ? detail.cost : 0;
|
|
91
|
+
const requests = Number.isFinite(detail.requestCount) ? detail.requestCount : 0;
|
|
92
|
+
allTime.cost += cost;
|
|
93
|
+
allTime.requests += requests;
|
|
94
|
+
bump(modelAll, detail.model, cost, requests);
|
|
95
|
+
if (localMonthKey(ts) === currentMonth) {
|
|
96
|
+
monthToDate.cost += cost;
|
|
97
|
+
monthToDate.requests += requests;
|
|
98
|
+
}
|
|
99
|
+
if (delta === 0) {
|
|
100
|
+
today.cost += cost;
|
|
101
|
+
today.requests += requests;
|
|
102
|
+
}
|
|
103
|
+
// Window math stays 7-day; only the sparkline bucket fill widens to 30.
|
|
104
|
+
if (delta < 7) {
|
|
105
|
+
last7d.cost += cost;
|
|
106
|
+
last7d.requests += requests;
|
|
107
|
+
}
|
|
108
|
+
if (delta < SPARKLINE_DAYS) {
|
|
109
|
+
const bucket = dayBuckets.get(localDayKey(ts));
|
|
110
|
+
if (bucket) {
|
|
111
|
+
bucket.cost += cost;
|
|
112
|
+
bucket.requests += requests;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (delta < 30) {
|
|
116
|
+
last30d.cost += cost;
|
|
117
|
+
last30d.requests += requests;
|
|
118
|
+
bump(model30d, detail.model, cost, requests);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const lastActivityAt = lastActivityMs === -Infinity ? null : new Date(lastActivityMs).toISOString();
|
|
122
|
+
const daysSinceLastActivity = lastActivityAt === null ? null : dayDelta(now, new Date(lastActivityAt));
|
|
123
|
+
// Prefer recent leaders; fall back to lifetime when the last 30 days are idle.
|
|
124
|
+
const recentHasData = last30d.cost > 0 || last30d.requests > 0;
|
|
125
|
+
const sourceMap = recentHasData ? model30d : modelAll;
|
|
126
|
+
const topModels = Array.from(sourceMap.values())
|
|
127
|
+
.filter((m) => m.cost > 0 || m.requests > 0)
|
|
128
|
+
.sort((a, b) => b.cost - a.cost)
|
|
129
|
+
.slice(0, TOP_MODELS_LIMIT);
|
|
130
|
+
return {
|
|
131
|
+
today,
|
|
132
|
+
last7d,
|
|
133
|
+
last30d,
|
|
134
|
+
monthToDate,
|
|
135
|
+
allTime,
|
|
136
|
+
byDay: Array.from(dayBuckets.values()),
|
|
137
|
+
topModels,
|
|
138
|
+
topModelsWindow: recentHasData ? '30d' : 'all',
|
|
139
|
+
// The snapshot-detail path has no surface attribution; the daily path does.
|
|
140
|
+
bySurface: [],
|
|
141
|
+
lastActivityAt,
|
|
142
|
+
daysSinceLastActivity,
|
|
143
|
+
hasRecentData: recentHasData,
|
|
144
|
+
generatedAt: now.toISOString(),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
exports.computeBarAnalytics = computeBarAnalytics;
|
|
148
|
+
// Maps a raw usage-pipeline `source` to the label shown in the bar. Unknown
|
|
149
|
+
// sources fall through to their raw key so a new collector is never silently
|
|
150
|
+
// dropped — it just shows un-prettified until added here.
|
|
151
|
+
const SURFACE_LABELS = {
|
|
152
|
+
'custom-parser': 'Claude Code',
|
|
153
|
+
'codex-native': 'Codex',
|
|
154
|
+
'droid-native': 'Droid',
|
|
155
|
+
cliproxy: 'CLIProxy',
|
|
156
|
+
};
|
|
157
|
+
/** Human-friendly surface name for a raw usage `source` key. */
|
|
158
|
+
function surfaceLabel(source) {
|
|
159
|
+
if (SURFACE_LABELS[source])
|
|
160
|
+
return SURFACE_LABELS[source];
|
|
161
|
+
return source || 'Other';
|
|
162
|
+
}
|
|
163
|
+
/** Local-midnight Date from a YYYY-MM-DD day key (calendar-day anchored). */
|
|
164
|
+
function dateFromDayKey(key) {
|
|
165
|
+
const [y, m, d] = key.split('-').map((n) => parseInt(n, 10));
|
|
166
|
+
return new Date(y, (m || 1) - 1, d || 1);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Roll the merged, multi-source usage aggregates into the bar analytics payload.
|
|
170
|
+
*
|
|
171
|
+
* Unlike `computeBarAnalytics` (which reads only the CLIProxy snapshot — frozen
|
|
172
|
+
* whenever the proxy restarts), this consumes the same merged daily/hourly data
|
|
173
|
+
* the dashboard uses, so recent activity from Claude Code, Codex, Droid, and the
|
|
174
|
+
* CLIProxy router all show up. `daily` carries cost+models+source; `hourly`
|
|
175
|
+
* carries the request counts (daily aggregates don't), so the two are combined:
|
|
176
|
+
* cost/models/surface-cost from daily, request counts from hourly.
|
|
177
|
+
*/
|
|
178
|
+
function computeBarAnalyticsFromDaily(daily, hourly, now) {
|
|
179
|
+
const today = { cost: 0, requests: 0 };
|
|
180
|
+
const last7d = { cost: 0, requests: 0 };
|
|
181
|
+
const last30d = { cost: 0, requests: 0 };
|
|
182
|
+
const monthToDate = { cost: 0, requests: 0 };
|
|
183
|
+
const allTime = { cost: 0, requests: 0 };
|
|
184
|
+
// Daily keys (YYYY-MM-DD) and hourly keys (YYYY-MM-DD HH:00) are already local,
|
|
185
|
+
// so slice(0,7) yields the local YYYY-MM to compare against the current month.
|
|
186
|
+
const currentMonth = localMonthKey(now);
|
|
187
|
+
const dayBuckets = new Map();
|
|
188
|
+
for (let i = SPARKLINE_DAYS - 1; i >= 0; i--) {
|
|
189
|
+
const d = new Date(now.getFullYear(), now.getMonth(), now.getDate() - i);
|
|
190
|
+
dayBuckets.set(localDayKey(d), { date: localDayKey(d), cost: 0, requests: 0 });
|
|
191
|
+
}
|
|
192
|
+
const model30d = new Map();
|
|
193
|
+
const modelAll = new Map();
|
|
194
|
+
const bumpModel = (map, model, cost) => {
|
|
195
|
+
const existing = map.get(model);
|
|
196
|
+
if (existing)
|
|
197
|
+
existing.cost += cost;
|
|
198
|
+
else
|
|
199
|
+
map.set(model, { model, cost, requests: 0 });
|
|
200
|
+
};
|
|
201
|
+
const surface30d = new Map();
|
|
202
|
+
const surfaceAll = new Map();
|
|
203
|
+
const bumpSurface = (map, source, cost, requests) => {
|
|
204
|
+
const existing = map.get(source);
|
|
205
|
+
if (existing) {
|
|
206
|
+
existing.cost += cost;
|
|
207
|
+
existing.requests += requests;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
map.set(source, { source, surface: surfaceLabel(source), cost, requests });
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
// Latest local-day with real activity (cost or requests), across both passes.
|
|
214
|
+
let lastActivityKey = null;
|
|
215
|
+
const touchActivity = (dayKey) => {
|
|
216
|
+
if (lastActivityKey === null || dayKey > lastActivityKey)
|
|
217
|
+
lastActivityKey = dayKey;
|
|
218
|
+
};
|
|
219
|
+
// Pass 1 — daily: cost, per-model spend, per-surface spend, sparkline cost.
|
|
220
|
+
for (const d of daily) {
|
|
221
|
+
if (!d || !d.date)
|
|
222
|
+
continue;
|
|
223
|
+
const delta = dayDelta(now, dateFromDayKey(d.date));
|
|
224
|
+
if (delta < 0)
|
|
225
|
+
continue; // ignore future-dated noise
|
|
226
|
+
const cost = Number.isFinite(d.totalCost) ? d.totalCost : Number.isFinite(d.cost) ? d.cost : 0;
|
|
227
|
+
const source = d.source || '';
|
|
228
|
+
allTime.cost += cost;
|
|
229
|
+
bumpSurface(surfaceAll, source, cost, 0);
|
|
230
|
+
for (const mb of d.modelBreakdowns || []) {
|
|
231
|
+
bumpModel(modelAll, mb.modelName, Number.isFinite(mb.cost) ? mb.cost : 0);
|
|
232
|
+
}
|
|
233
|
+
if (cost > 0)
|
|
234
|
+
touchActivity(d.date);
|
|
235
|
+
if (d.date.slice(0, 7) === currentMonth)
|
|
236
|
+
monthToDate.cost += cost;
|
|
237
|
+
if (delta === 0)
|
|
238
|
+
today.cost += cost;
|
|
239
|
+
if (delta < 7)
|
|
240
|
+
last7d.cost += cost;
|
|
241
|
+
if (delta < 30) {
|
|
242
|
+
last30d.cost += cost;
|
|
243
|
+
bumpSurface(surface30d, source, cost, 0);
|
|
244
|
+
for (const mb of d.modelBreakdowns || []) {
|
|
245
|
+
bumpModel(model30d, mb.modelName, Number.isFinite(mb.cost) ? mb.cost : 0);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (delta < SPARKLINE_DAYS) {
|
|
249
|
+
const bucket = dayBuckets.get(d.date);
|
|
250
|
+
if (bucket)
|
|
251
|
+
bucket.cost += cost;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Pass 2 — hourly: request counts (daily aggregates don't carry them).
|
|
255
|
+
for (const h of hourly) {
|
|
256
|
+
if (!h || !h.hour)
|
|
257
|
+
continue;
|
|
258
|
+
const dayKey = h.hour.slice(0, 10);
|
|
259
|
+
const delta = dayDelta(now, dateFromDayKey(dayKey));
|
|
260
|
+
if (delta < 0)
|
|
261
|
+
continue;
|
|
262
|
+
const requests = Number.isFinite(h.requestCount) ? h.requestCount : 0;
|
|
263
|
+
if (requests <= 0)
|
|
264
|
+
continue;
|
|
265
|
+
const source = h.source || '';
|
|
266
|
+
allTime.requests += requests;
|
|
267
|
+
bumpSurface(surfaceAll, source, 0, requests);
|
|
268
|
+
touchActivity(dayKey);
|
|
269
|
+
if (h.hour.slice(0, 7) === currentMonth)
|
|
270
|
+
monthToDate.requests += requests;
|
|
271
|
+
if (delta === 0)
|
|
272
|
+
today.requests += requests;
|
|
273
|
+
if (delta < 7)
|
|
274
|
+
last7d.requests += requests;
|
|
275
|
+
if (delta < 30) {
|
|
276
|
+
last30d.requests += requests;
|
|
277
|
+
bumpSurface(surface30d, source, 0, requests);
|
|
278
|
+
}
|
|
279
|
+
if (delta < SPARKLINE_DAYS) {
|
|
280
|
+
const bucket = dayBuckets.get(dayKey);
|
|
281
|
+
if (bucket)
|
|
282
|
+
bucket.requests += requests;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Prefer recent leaders; fall back to lifetime when the last 30 days are idle.
|
|
286
|
+
const recentHasData = last30d.cost > 0 || last30d.requests > 0;
|
|
287
|
+
const topModels = Array.from((recentHasData ? model30d : modelAll).values())
|
|
288
|
+
.filter((m) => m.cost > 0 || m.requests > 0)
|
|
289
|
+
.sort((a, b) => b.cost - a.cost)
|
|
290
|
+
.slice(0, TOP_MODELS_LIMIT);
|
|
291
|
+
const bySurface = Array.from((recentHasData ? surface30d : surfaceAll).values())
|
|
292
|
+
.filter((s) => s.cost > 0 || s.requests > 0)
|
|
293
|
+
.sort((a, b) => b.cost - a.cost);
|
|
294
|
+
const lastActivityAt = lastActivityKey ? dateFromDayKey(lastActivityKey).toISOString() : null;
|
|
295
|
+
const daysSinceLastActivity = lastActivityKey
|
|
296
|
+
? dayDelta(now, dateFromDayKey(lastActivityKey))
|
|
297
|
+
: null;
|
|
298
|
+
return {
|
|
299
|
+
today,
|
|
300
|
+
last7d,
|
|
301
|
+
last30d,
|
|
302
|
+
monthToDate,
|
|
303
|
+
allTime,
|
|
304
|
+
byDay: Array.from(dayBuckets.values()),
|
|
305
|
+
topModels,
|
|
306
|
+
topModelsWindow: recentHasData ? '30d' : 'all',
|
|
307
|
+
bySurface,
|
|
308
|
+
lastActivityAt,
|
|
309
|
+
daysSinceLastActivity,
|
|
310
|
+
hasRecentData: recentHasData,
|
|
311
|
+
generatedAt: now.toISOString(),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
exports.computeBarAnalyticsFromDaily = computeBarAnalyticsFromDaily;
|
|
315
|
+
//# sourceMappingURL=bar-analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-analytics.js","sourceRoot":"","sources":["../../../src/web-server/usage/bar-analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Claude Code credential reader.
|
|
3
|
+
*
|
|
4
|
+
* Reads the LOGGED-IN Claude Code OAuth token so the bar can show the user's
|
|
5
|
+
* own subscription quota (Max/Pro/Team) without going through CLIProxy-managed
|
|
6
|
+
* auth files.
|
|
7
|
+
*
|
|
8
|
+
* File-first, Keychain-fallback: we read ~/.claude/.credentials.json directly
|
|
9
|
+
* because hitting the macOS Keychain pops a permission dialog. The Keychain
|
|
10
|
+
* fallback is load-bearing on machines where Claude Code stores the token there
|
|
11
|
+
* instead of on disk, so it must be kept even though the file path is preferred.
|
|
12
|
+
*
|
|
13
|
+
* Only the user's own token is read here; the single read-only Anthropic usage
|
|
14
|
+
* endpoint is the only thing that ever sees it (see native-quota-collector).
|
|
15
|
+
*/
|
|
16
|
+
/// <reference types="node" />
|
|
17
|
+
/// <reference types="node" />
|
|
18
|
+
/// <reference types="node" />
|
|
19
|
+
/** Shape of the relevant slice of ~/.claude/.credentials.json */
|
|
20
|
+
export interface ClaudeNativeCredentials {
|
|
21
|
+
claudeAiOauth?: {
|
|
22
|
+
accessToken?: string;
|
|
23
|
+
subscriptionType?: string;
|
|
24
|
+
rateLimitTier?: string;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
};
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
/** Injectable seams so unit tests never touch the real fs/Keychain. */
|
|
30
|
+
export interface CredentialReaderDeps {
|
|
31
|
+
platform?: NodeJS.Platform;
|
|
32
|
+
homedir?: string;
|
|
33
|
+
existsSyncImpl?: (p: string) => boolean;
|
|
34
|
+
readFileSyncImpl?: (p: string) => string;
|
|
35
|
+
execSyncImpl?: (cmd: string, opts: Record<string, unknown>) => string | Buffer;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Read the native Claude Code credentials.
|
|
39
|
+
*
|
|
40
|
+
* Order: the on-disk credentials file first (no prompt), then the macOS
|
|
41
|
+
* Keychain as a fallback. Returns null when neither source yields a parseable
|
|
42
|
+
* object.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readClaudeCredentials(deps?: CredentialReaderDeps): ClaudeNativeCredentials | null;
|
|
45
|
+
/** Pull the OAuth access token, or null when absent. */
|
|
46
|
+
export declare function getAccessToken(creds: ClaudeNativeCredentials | null): string | null;
|
|
47
|
+
/** Pull the subscription tier (e.g. "max" / "pro"), or null. */
|
|
48
|
+
export declare function getSubscriptionTier(creds: ClaudeNativeCredentials | null): string | null;
|
|
49
|
+
/**
|
|
50
|
+
* True when the credentials describe a real, entitled subscription.
|
|
51
|
+
*
|
|
52
|
+
* Gating on this BEFORE fetching means a free/logged-out user never spends a
|
|
53
|
+
* token call against the hostile usage endpoint and never gets a phantom row.
|
|
54
|
+
*/
|
|
55
|
+
export declare function hasSupportedSubscription(creds: ClaudeNativeCredentials | null): boolean;
|
|
56
|
+
//# sourceMappingURL=claude-native-credentials.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native Claude Code credential reader.
|
|
4
|
+
*
|
|
5
|
+
* Reads the LOGGED-IN Claude Code OAuth token so the bar can show the user's
|
|
6
|
+
* own subscription quota (Max/Pro/Team) without going through CLIProxy-managed
|
|
7
|
+
* auth files.
|
|
8
|
+
*
|
|
9
|
+
* File-first, Keychain-fallback: we read ~/.claude/.credentials.json directly
|
|
10
|
+
* because hitting the macOS Keychain pops a permission dialog. The Keychain
|
|
11
|
+
* fallback is load-bearing on machines where Claude Code stores the token there
|
|
12
|
+
* instead of on disk, so it must be kept even though the file path is preferred.
|
|
13
|
+
*
|
|
14
|
+
* Only the user's own token is read here; the single read-only Anthropic usage
|
|
15
|
+
* endpoint is the only thing that ever sees it (see native-quota-collector).
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.hasSupportedSubscription = exports.getSubscriptionTier = exports.getAccessToken = exports.readClaudeCredentials = void 0;
|
|
42
|
+
const node_fs_1 = require("node:fs");
|
|
43
|
+
const node_child_process_1 = require("node:child_process");
|
|
44
|
+
const os = __importStar(require("node:os"));
|
|
45
|
+
const path = __importStar(require("node:path"));
|
|
46
|
+
const KEYCHAIN_SERVICE = 'Claude Code-credentials';
|
|
47
|
+
const KEYCHAIN_TIMEOUT_MS = 5000;
|
|
48
|
+
/** Subscription types that mean "no real subscription" -> skip the fetch. */
|
|
49
|
+
const UNSUPPORTED_SUBSCRIPTION_TYPES = new Set(['', 'free', 'none']);
|
|
50
|
+
/** rateLimitTier values that imply an entitled subscription. */
|
|
51
|
+
const SUPPORTED_RATE_LIMIT_TIER = /claude|max|pro|team|enterprise/;
|
|
52
|
+
function parseCredentials(raw) {
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(raw);
|
|
55
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// fall through
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Read the native Claude Code credentials.
|
|
66
|
+
*
|
|
67
|
+
* Order: the on-disk credentials file first (no prompt), then the macOS
|
|
68
|
+
* Keychain as a fallback. Returns null when neither source yields a parseable
|
|
69
|
+
* object.
|
|
70
|
+
*/
|
|
71
|
+
function readClaudeCredentials(deps = {}) {
|
|
72
|
+
const platform = deps.platform ?? os.platform();
|
|
73
|
+
const homedir = deps.homedir ?? os.homedir();
|
|
74
|
+
const existsImpl = deps.existsSyncImpl ?? node_fs_1.existsSync;
|
|
75
|
+
const readImpl = deps.readFileSyncImpl ?? ((p) => (0, node_fs_1.readFileSync)(p, 'utf8'));
|
|
76
|
+
const execImpl = deps.execSyncImpl ?? node_child_process_1.execSync;
|
|
77
|
+
const credentialsPath = path.join(homedir, '.claude', '.credentials.json');
|
|
78
|
+
if (existsImpl(credentialsPath)) {
|
|
79
|
+
try {
|
|
80
|
+
const parsed = parseCredentials(readImpl(credentialsPath));
|
|
81
|
+
if (parsed)
|
|
82
|
+
return parsed;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// fall through to Keychain
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (platform === 'darwin') {
|
|
89
|
+
try {
|
|
90
|
+
const out = execImpl(`security find-generic-password -s "${KEYCHAIN_SERVICE}" -w`, {
|
|
91
|
+
timeout: KEYCHAIN_TIMEOUT_MS,
|
|
92
|
+
encoding: 'utf8',
|
|
93
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
94
|
+
});
|
|
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
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// no Keychain entry / access denied -> null
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
exports.readClaudeCredentials = readClaudeCredentials;
|
|
109
|
+
/** Pull the OAuth access token, or null when absent. */
|
|
110
|
+
function getAccessToken(creds) {
|
|
111
|
+
const token = creds?.claudeAiOauth?.accessToken;
|
|
112
|
+
return typeof token === 'string' && token.trim().length > 0 ? token : null;
|
|
113
|
+
}
|
|
114
|
+
exports.getAccessToken = getAccessToken;
|
|
115
|
+
/** Pull the subscription tier (e.g. "max" / "pro"), or null. */
|
|
116
|
+
function getSubscriptionTier(creds) {
|
|
117
|
+
const tier = creds?.claudeAiOauth?.subscriptionType;
|
|
118
|
+
return typeof tier === 'string' && tier.trim().length > 0 ? tier.trim() : null;
|
|
119
|
+
}
|
|
120
|
+
exports.getSubscriptionTier = getSubscriptionTier;
|
|
121
|
+
/**
|
|
122
|
+
* True when the credentials describe a real, entitled subscription.
|
|
123
|
+
*
|
|
124
|
+
* Gating on this BEFORE fetching means a free/logged-out user never spends a
|
|
125
|
+
* token call against the hostile usage endpoint and never gets a phantom row.
|
|
126
|
+
*/
|
|
127
|
+
function hasSupportedSubscription(creds) {
|
|
128
|
+
const subscriptionType = String(creds?.claudeAiOauth?.subscriptionType ?? '')
|
|
129
|
+
.trim()
|
|
130
|
+
.toLowerCase();
|
|
131
|
+
if (subscriptionType && !UNSUPPORTED_SUBSCRIPTION_TYPES.has(subscriptionType)) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
const rateLimitTier = String(creds?.claudeAiOauth?.rateLimitTier ?? '')
|
|
135
|
+
.trim()
|
|
136
|
+
.toLowerCase();
|
|
137
|
+
return SUPPORTED_RATE_LIMIT_TIER.test(rateLimitTier);
|
|
138
|
+
}
|
|
139
|
+
exports.hasSupportedSubscription = hasSupportedSubscription;
|
|
140
|
+
//# sourceMappingURL=claude-native-credentials.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLIProxy Snapshot Reader
|
|
3
|
+
*
|
|
4
|
+
* Lightweight reader that extracts the flat CliproxyUsageHistoryDetail array
|
|
5
|
+
* from the persisted snapshot at ~/.ccs/cache/cliproxy-usage/latest.json.
|
|
6
|
+
*
|
|
7
|
+
* This is a read-only helper — it never writes or syncs. The syncer owns
|
|
8
|
+
* the write path; this module owns the "give me the raw details" path
|
|
9
|
+
* needed by the bar-routes aggregator for per-account cost mapping.
|
|
10
|
+
*/
|
|
11
|
+
import { type CliproxyUsageHistoryDetail } from './cliproxy-usage-transformer';
|
|
12
|
+
/**
|
|
13
|
+
* Read the persisted CLIProxy usage snapshot and return its raw detail records.
|
|
14
|
+
*
|
|
15
|
+
* Returns an empty array when:
|
|
16
|
+
* - The snapshot file does not exist
|
|
17
|
+
* - The file cannot be parsed as JSON
|
|
18
|
+
* - The snapshot version is unrecognised
|
|
19
|
+
* - The details array is absent or malformed
|
|
20
|
+
*
|
|
21
|
+
* Individual malformed detail records are silently dropped (normalizer returns null).
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadCliproxySnapshotDetails(): Promise<CliproxyUsageHistoryDetail[]>;
|
|
24
|
+
//# sourceMappingURL=cliproxy-snapshot-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliproxy-snapshot-reader.d.ts","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-snapshot-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAC;AAQtC;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC,CA4BzF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLIProxy Snapshot Reader
|
|
4
|
+
*
|
|
5
|
+
* Lightweight reader that extracts the flat CliproxyUsageHistoryDetail array
|
|
6
|
+
* from the persisted snapshot at ~/.ccs/cache/cliproxy-usage/latest.json.
|
|
7
|
+
*
|
|
8
|
+
* This is a read-only helper — it never writes or syncs. The syncer owns
|
|
9
|
+
* the write path; this module owns the "give me the raw details" path
|
|
10
|
+
* needed by the bar-routes aggregator for per-account cost mapping.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadCliproxySnapshotDetails = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const config_loader_facade_1 = require("../../config/config-loader-facade");
|
|
40
|
+
const cliproxy_usage_transformer_1 = require("./cliproxy-usage-transformer");
|
|
41
|
+
const SUPPORTED_SNAPSHOT_VERSION = 3;
|
|
42
|
+
function getLatestSnapshotPath() {
|
|
43
|
+
return path.join((0, config_loader_facade_1.getCcsDir)(), 'cache', 'cliproxy-usage', 'latest.json');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read the persisted CLIProxy usage snapshot and return its raw detail records.
|
|
47
|
+
*
|
|
48
|
+
* Returns an empty array when:
|
|
49
|
+
* - The snapshot file does not exist
|
|
50
|
+
* - The file cannot be parsed as JSON
|
|
51
|
+
* - The snapshot version is unrecognised
|
|
52
|
+
* - The details array is absent or malformed
|
|
53
|
+
*
|
|
54
|
+
* Individual malformed detail records are silently dropped (normalizer returns null).
|
|
55
|
+
*/
|
|
56
|
+
async function loadCliproxySnapshotDetails() {
|
|
57
|
+
const snapshotPath = getLatestSnapshotPath();
|
|
58
|
+
try {
|
|
59
|
+
if (!fs.existsSync(snapshotPath)) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
const raw = fs.readFileSync(snapshotPath, 'utf-8');
|
|
63
|
+
const snapshot = JSON.parse(raw);
|
|
64
|
+
if (snapshot.version !== SUPPORTED_SNAPSHOT_VERSION) {
|
|
65
|
+
// Legacy / future snapshot — skip rather than mis-interpret
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const details = snapshot.details;
|
|
69
|
+
if (!Array.isArray(details)) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
return details
|
|
73
|
+
.map((item) => (0, cliproxy_usage_transformer_1.normalizeCliproxyUsageHistoryDetail)(item))
|
|
74
|
+
.filter((item) => item !== null);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// IO / parse errors are non-fatal — bar glance degrades gracefully
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.loadCliproxySnapshotDetails = loadCliproxySnapshotDetails;
|
|
82
|
+
//# sourceMappingURL=cliproxy-snapshot-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliproxy-snapshot-reader.js","sourceRoot":"","sources":["../../../src/web-server/usage/cliproxy-snapshot-reader.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,4CAA8B;AAC9B,gDAAkC;AAClC,4EAA8D;AAC9D,6EAGsC;AAEtC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAErC,SAAS,qBAAqB;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAA,gCAAS,GAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,2BAA2B;IAC/C,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAE7C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAE5D,IAAI,QAAQ,CAAC,OAAO,KAAK,0BAA0B,EAAE,CAAC;YACpD,4DAA4D;YAC5D,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,OAAO;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,gEAAmC,EAAC,IAAI,CAAC,CAAC;aACxD,MAAM,CAAC,CAAC,IAAI,EAAsC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AA5BD,kEA4BC"}
|