@kaitranntt/ccs 8.2.0 → 8.3.0
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/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,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pool onboarding hint
|
|
4
|
+
*
|
|
5
|
+
* Fires once (per install, TTY only) when a user has >= 2 native Claude account
|
|
6
|
+
* profiles and has not yet enabled pool routing. Covers the #1464 use case:
|
|
7
|
+
* existing users with multiple native profiles who have never touched CLIProxy
|
|
8
|
+
* and would miss the 1->2 account-add opt-in prompt.
|
|
9
|
+
*
|
|
10
|
+
* Three hint sites call this module:
|
|
11
|
+
* 1. ccs doctor (post-checks summary, fires for ALL install types)
|
|
12
|
+
* 2. account-flow launch (print-only, pre-spawn) - unified config only
|
|
13
|
+
* 3. ccs auth create (before spawning Claude for a 2nd+ profile) - unified config only
|
|
14
|
+
*
|
|
15
|
+
* Sites 2 and 3 are gated on hasUnifiedConfig() so that legacy profiles.json-only
|
|
16
|
+
* installs receive the hint exclusively from ccs doctor (site 1). This ensures
|
|
17
|
+
* once-per-install dismissal semantics for every install type: unified installs
|
|
18
|
+
* dismiss via config.yaml on first show; legacy installs see the hint from
|
|
19
|
+
* doctor only (which is the natural discovery surface for that population).
|
|
20
|
+
*
|
|
21
|
+
* Dismissal: stored in pool_routing.onboarding_hint_dismissed in config.yaml.
|
|
22
|
+
* Reuses the Phase 3 pool_routing schema family - one schema home, no duplicate
|
|
23
|
+
* plumbing. Legacy installs cannot persist a dismissal without config.yaml;
|
|
24
|
+
* this is intentional - dismissal for legacy users happens via ccs migrate or
|
|
25
|
+
* pool enable (both create config.yaml).
|
|
26
|
+
*
|
|
27
|
+
* TTY contract: non-TTY sessions never print the hint (single line only).
|
|
28
|
+
* The hint is informational only - it never blocks the calling flow.
|
|
29
|
+
*
|
|
30
|
+
* History note: pooled sessions live in the CLIProxy lane, not the native
|
|
31
|
+
* profile's CLAUDE_CONFIG_DIR lane. Transcripts and --continue inventory do
|
|
32
|
+
* NOT follow. This is stated on the docs page linked in the hint copy.
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.maybeShowPoolOnboardingHint = exports.countNativeClaudeProfiles = exports.dismissOnboardingHint = exports.isOnboardingHintDismissed = exports.POOL_DOCS_LINK = void 0;
|
|
36
|
+
const ui_1 = require("../../utils/ui");
|
|
37
|
+
const config_loader_facade_1 = require("../../config/config-loader-facade");
|
|
38
|
+
const profile_registry_1 = require("../../auth/profile-registry");
|
|
39
|
+
// Docs anchor - Phase 7 acceptance item: verify curl returns HTTP 200 before release.
|
|
40
|
+
// Pattern matches canonical docs domain used in error-codes.ts and version-command.ts.
|
|
41
|
+
exports.POOL_DOCS_LINK = 'https://docs.ccs.kaitran.ca/features/pool';
|
|
42
|
+
/**
|
|
43
|
+
* Whether the one-time pool onboarding hint has already been dismissed.
|
|
44
|
+
*
|
|
45
|
+
* @param config - Optional pre-loaded config to avoid a redundant disk read +
|
|
46
|
+
* YAML parse. When omitted the config is loaded here.
|
|
47
|
+
*/
|
|
48
|
+
function isOnboardingHintDismissed(config) {
|
|
49
|
+
const cfg = config ?? (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
|
|
50
|
+
return cfg.cliproxy?.pool_routing?.onboarding_hint_dismissed === true;
|
|
51
|
+
}
|
|
52
|
+
exports.isOnboardingHintDismissed = isOnboardingHintDismissed;
|
|
53
|
+
/**
|
|
54
|
+
* Mark the pool onboarding hint as permanently dismissed.
|
|
55
|
+
* Written after first display so subsequent invocations are silent.
|
|
56
|
+
*
|
|
57
|
+
* Guard: skipped when config.yaml does not yet exist (legacy profiles.json-only
|
|
58
|
+
* installs). Writing here would create config.yaml, flipping isUnifiedMode()
|
|
59
|
+
* and silently mode-migrating the install outside the deliberate ccs migrate
|
|
60
|
+
* flow. For those users the hint may re-appear across process restarts; that
|
|
61
|
+
* is acceptable -- the hint is informational and non-blocking, and the user
|
|
62
|
+
* can silence it permanently via ccs migrate.
|
|
63
|
+
*/
|
|
64
|
+
function dismissOnboardingHint() {
|
|
65
|
+
if (!(0, config_loader_facade_1.hasUnifiedConfig)()) {
|
|
66
|
+
// Legacy-only install: skip persist to avoid implicit config.yaml creation.
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
(0, config_loader_facade_1.mutateConfig)((cfg) => {
|
|
70
|
+
if (!cfg.cliproxy)
|
|
71
|
+
return;
|
|
72
|
+
cfg.cliproxy.pool_routing = {
|
|
73
|
+
...cfg.cliproxy.pool_routing,
|
|
74
|
+
onboarding_hint_dismissed: true,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
exports.dismissOnboardingHint = dismissOnboardingHint;
|
|
79
|
+
/**
|
|
80
|
+
* Whether pool routing is currently enabled.
|
|
81
|
+
*
|
|
82
|
+
* @param config - Optional pre-loaded config to avoid a redundant disk read +
|
|
83
|
+
* YAML parse. When omitted the config is loaded here.
|
|
84
|
+
*/
|
|
85
|
+
function isPoolEnabled(config) {
|
|
86
|
+
const cfg = config ?? (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
|
|
87
|
+
return cfg.cliproxy?.pool_routing?.enabled === true;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Count native Claude account profiles (type === 'account').
|
|
91
|
+
*
|
|
92
|
+
* Uses ProfileRegistry so the count respects both legacy profiles.json and
|
|
93
|
+
* unified config accounts - same source of truth as the rest of the codebase.
|
|
94
|
+
*
|
|
95
|
+
* type === 'account' implies Claude: per the profile-registry schema, every
|
|
96
|
+
* account profile is an isolated Claude instance (CLAUDE_CONFIG_DIR lane) with
|
|
97
|
+
* no CLI discriminator. Gemini/Codex multi-account lives in CLIProxy auth
|
|
98
|
+
* files, never in profiles.json, so this filter cannot over-count.
|
|
99
|
+
*/
|
|
100
|
+
function countNativeClaudeProfiles() {
|
|
101
|
+
try {
|
|
102
|
+
const registry = new profile_registry_1.ProfileRegistry();
|
|
103
|
+
const profiles = registry.getAllProfilesMerged();
|
|
104
|
+
return Object.values(profiles).filter((p) => p.type === 'account').length;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.countNativeClaudeProfiles = countNativeClaudeProfiles;
|
|
111
|
+
/**
|
|
112
|
+
* Maybe print the one-time pool onboarding hint.
|
|
113
|
+
*
|
|
114
|
+
* Skips silently when any of the following are true:
|
|
115
|
+
* - Not a TTY (piped / CI / non-interactive)
|
|
116
|
+
* - Fewer than 2 native Claude account profiles exist
|
|
117
|
+
* - Pool routing is already enabled
|
|
118
|
+
* - The hint was already dismissed
|
|
119
|
+
* - Any error occurs while deciding (e.g. malformed config.yaml)
|
|
120
|
+
*
|
|
121
|
+
* Checks run cheapest-first: TTY and profile count are evaluated before any
|
|
122
|
+
* config read, and the config is loaded exactly once for the two
|
|
123
|
+
* config-derived checks. The entire decision is wrapped in try/catch so a
|
|
124
|
+
* hint failure can never break an account launch.
|
|
125
|
+
*
|
|
126
|
+
* When the hint is printed for the first time it is also dismissed so it
|
|
127
|
+
* never appears again (it is informational, not an interactive prompt).
|
|
128
|
+
*
|
|
129
|
+
* @param profileCount - Pre-computed profile count (pass undefined to compute
|
|
130
|
+
* it here). The caller may pass a count it already has to avoid a second
|
|
131
|
+
* registry read.
|
|
132
|
+
*/
|
|
133
|
+
function maybeShowPoolOnboardingHint(profileCount) {
|
|
134
|
+
// A hint must never break a launch. Any error in the decision path
|
|
135
|
+
// (malformed config.yaml, registry read failure, etc.) silently skips the
|
|
136
|
+
// hint rather than rethrowing into the caller's account-launch flow.
|
|
137
|
+
try {
|
|
138
|
+
// Cheapest checks first, no disk read required.
|
|
139
|
+
// Non-TTY: stay silent (piped / CI / non-interactive).
|
|
140
|
+
if (!process.stdout.isTTY) {
|
|
141
|
+
return { printed: false, skipReason: 'non-tty' };
|
|
142
|
+
}
|
|
143
|
+
const count = profileCount ?? countNativeClaudeProfiles();
|
|
144
|
+
if (count < 2) {
|
|
145
|
+
return { printed: false, skipReason: 'fewer-than-2-profiles' };
|
|
146
|
+
}
|
|
147
|
+
// Load config once and reuse it for both config-derived checks below,
|
|
148
|
+
// avoiding two disk reads + YAML parses per call.
|
|
149
|
+
const config = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
|
|
150
|
+
if (isPoolEnabled(config)) {
|
|
151
|
+
return { printed: false, skipReason: 'pool-already-enabled' };
|
|
152
|
+
}
|
|
153
|
+
if (isOnboardingHintDismissed(config)) {
|
|
154
|
+
return { printed: false, skipReason: 'dismissed' };
|
|
155
|
+
}
|
|
156
|
+
console.log((0, ui_1.info)(`You have ${count} Claude profiles. Pool routing can auto-continue 'ccs claude' when one account hits its limit. Enable: ccs cliproxy pool --enable Docs: ${exports.POOL_DOCS_LINK}`));
|
|
157
|
+
// Dismiss so subsequent invocations (other sites or next run) are silent.
|
|
158
|
+
try {
|
|
159
|
+
dismissOnboardingHint();
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Best-effort: a config write failure must not surface to the user here.
|
|
163
|
+
}
|
|
164
|
+
return { printed: true };
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Decision failed (e.g. malformed config) - skip the hint, never throw.
|
|
168
|
+
return { printed: false, skipReason: 'error' };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.maybeShowPoolOnboardingHint = maybeShowPoolOnboardingHint;
|
|
172
|
+
//# sourceMappingURL=pool-onboarding-hint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-onboarding-hint.js","sourceRoot":"","sources":["../../../src/cliproxy/routing/pool-onboarding-hint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool routing opt-in prompt
|
|
3
|
+
*
|
|
4
|
+
* Fires at the 1->2 account-add transition for verified providers (claude, agy).
|
|
5
|
+
* Informed-consent copy: discloses instance-global effect and lists ALL providers
|
|
6
|
+
* with >=2 accounts that will be affected.
|
|
7
|
+
*
|
|
8
|
+
* Codex/gemini get no prompt until failover behavior is verified for pool routing
|
|
9
|
+
* (spike Test D pending). They continue with implicit round-robin.
|
|
10
|
+
*
|
|
11
|
+
* Remote/Docker targets: prompt replaced by manual-config hint because session
|
|
12
|
+
* affinity is not remotely toggleable from CCS (PR #1117 precedent).
|
|
13
|
+
*/
|
|
14
|
+
import type { CLIProxyProvider } from '../types';
|
|
15
|
+
/**
|
|
16
|
+
* Whether the pool routing opt-in prompt has been permanently dismissed.
|
|
17
|
+
* Dismissal is recorded per-provider in pool_routing.prompt_dismissed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isPoolPromptDismissed(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Mark the pool routing prompt as permanently dismissed (user said no explicitly).
|
|
22
|
+
*/
|
|
23
|
+
export declare function dismissPoolPrompt(): void;
|
|
24
|
+
export interface PoolOptInResult {
|
|
25
|
+
/** Whether the prompt was shown */
|
|
26
|
+
prompted: boolean;
|
|
27
|
+
/** Whether pool routing was enabled */
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
/** Whether the prompt was skipped (remote, dismissed, not verified, already enabled) */
|
|
30
|
+
skipped: boolean;
|
|
31
|
+
skipReason?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Offer pool routing opt-in when the account count crosses 1->2 for a verified provider.
|
|
35
|
+
*
|
|
36
|
+
* Call this immediately after a successful account registration when the provider
|
|
37
|
+
* transitions from 1 to 2 accounts. The function is a no-op when:
|
|
38
|
+
* - Pool routing is already enabled
|
|
39
|
+
* - Provider is not in the verified pool list (codex, gemini, etc.)
|
|
40
|
+
* - The prompt was previously dismissed
|
|
41
|
+
* - Target is non-TTY (piped input / CI)
|
|
42
|
+
*
|
|
43
|
+
* Remote/Docker targets get a manual-config hint instead of an interactive prompt.
|
|
44
|
+
*
|
|
45
|
+
* @param provider - The provider that just reached 2 accounts
|
|
46
|
+
* @param accountCountBefore - Number of accounts before this add (should be 1 for transition)
|
|
47
|
+
* @param port - CLIProxy port (default: 8317)
|
|
48
|
+
*/
|
|
49
|
+
export declare function maybeOfferPoolRouting(provider: CLIProxyProvider, accountCountBefore: number, port?: number): Promise<PoolOptInResult>;
|
|
50
|
+
//# sourceMappingURL=pool-opt-in-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-opt-in-prompt.d.ts","sourceRoot":"","sources":["../../../src/cliproxy/routing/pool-opt-in-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AA2BjD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAYxC;AAyBD,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,gBAAgB,EAC1B,kBAAkB,EAAE,MAAM,EAC1B,IAAI,GAAE,MAA8B,GACnC,OAAO,CAAC,eAAe,CAAC,CAgJ1B"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pool routing opt-in prompt
|
|
4
|
+
*
|
|
5
|
+
* Fires at the 1->2 account-add transition for verified providers (claude, agy).
|
|
6
|
+
* Informed-consent copy: discloses instance-global effect and lists ALL providers
|
|
7
|
+
* with >=2 accounts that will be affected.
|
|
8
|
+
*
|
|
9
|
+
* Codex/gemini get no prompt until failover behavior is verified for pool routing
|
|
10
|
+
* (spike Test D pending). They continue with implicit round-robin.
|
|
11
|
+
*
|
|
12
|
+
* Remote/Docker targets: prompt replaced by manual-config hint because session
|
|
13
|
+
* affinity is not remotely toggleable from CCS (PR #1117 precedent).
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.maybeOfferPoolRouting = exports.dismissPoolPrompt = exports.isPoolPromptDismissed = void 0;
|
|
17
|
+
const ui_1 = require("../../utils/ui");
|
|
18
|
+
const prompt_1 = require("../../utils/prompt");
|
|
19
|
+
const proxy_target_resolver_1 = require("../proxy/proxy-target-resolver");
|
|
20
|
+
const routing_strategy_1 = require("./routing-strategy");
|
|
21
|
+
const config_loader_facade_1 = require("../../config/config-loader-facade");
|
|
22
|
+
const port_manager_1 = require("../config/port-manager");
|
|
23
|
+
const path_resolver_1 = require("../config/path-resolver");
|
|
24
|
+
const path_resolver_2 = require("../config/path-resolver");
|
|
25
|
+
const account_manager_1 = require("../accounts/account-manager");
|
|
26
|
+
const registry_1 = require("../accounts/registry");
|
|
27
|
+
/**
|
|
28
|
+
* Collect names of all providers that currently have >= 2 accounts registered.
|
|
29
|
+
* Derived from the registry's actual provider keys so this list can never drift
|
|
30
|
+
* from the CLIProxyProvider type union (spec requirement: disclose ALL affected
|
|
31
|
+
* providers, not just a hardcoded subset).
|
|
32
|
+
*/
|
|
33
|
+
function getMultiAccountProviders() {
|
|
34
|
+
const result = [];
|
|
35
|
+
try {
|
|
36
|
+
const registry = (0, registry_1.loadAccountsRegistry)();
|
|
37
|
+
for (const p of Object.keys(registry.providers)) {
|
|
38
|
+
try {
|
|
39
|
+
if ((0, account_manager_1.getProviderAccounts)(p).length >= 2)
|
|
40
|
+
result.push(p);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Provider registry entry present but accounts unreadable — skip
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Registry unreadable (first-run, corrupt) — return empty; caller falls back to provider param
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Whether the pool routing opt-in prompt has been permanently dismissed.
|
|
54
|
+
* Dismissal is recorded per-provider in pool_routing.prompt_dismissed.
|
|
55
|
+
*/
|
|
56
|
+
function isPoolPromptDismissed() {
|
|
57
|
+
return (0, config_loader_facade_1.loadOrCreateUnifiedConfig)().cliproxy?.pool_routing?.prompt_dismissed === true;
|
|
58
|
+
}
|
|
59
|
+
exports.isPoolPromptDismissed = isPoolPromptDismissed;
|
|
60
|
+
/**
|
|
61
|
+
* Mark the pool routing prompt as permanently dismissed (user said no explicitly).
|
|
62
|
+
*/
|
|
63
|
+
function dismissPoolPrompt() {
|
|
64
|
+
// Defense in depth: never write the unified config on a legacy install — that
|
|
65
|
+
// would create config.yaml and silently flip isUnifiedMode(). maybeOfferPoolRouting
|
|
66
|
+
// already gates the only caller, but this keeps the exported helper safe too.
|
|
67
|
+
if (!(0, config_loader_facade_1.hasUnifiedConfig)())
|
|
68
|
+
return;
|
|
69
|
+
(0, config_loader_facade_1.mutateConfig)((cfg) => {
|
|
70
|
+
if (!cfg.cliproxy)
|
|
71
|
+
return;
|
|
72
|
+
cfg.cliproxy.pool_routing = {
|
|
73
|
+
...cfg.cliproxy.pool_routing,
|
|
74
|
+
prompt_dismissed: true,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
exports.dismissPoolPrompt = dismissPoolPrompt;
|
|
79
|
+
/**
|
|
80
|
+
* Show the remote/Docker hint instead of an interactive prompt.
|
|
81
|
+
* Session affinity is not remotely toggleable from CCS (fail-closed
|
|
82
|
+
* per PR #1117 precedent) so we emit guidance only.
|
|
83
|
+
*/
|
|
84
|
+
function printRemoteHint(provider) {
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log((0, ui_1.info)(`[i] Pool routing hint: you now have 2+ ${provider} accounts on a remote/Docker CLIProxy.`));
|
|
87
|
+
console.log(' CCS cannot toggle session affinity on remote targets yet (management API limitation).');
|
|
88
|
+
console.log(' To enable pool routing manually, add to your CLIProxy config.yaml:');
|
|
89
|
+
console.log(' disable-cooling: false');
|
|
90
|
+
console.log(` max-retry-credentials: ${routing_strategy_1.POOL_MAX_RETRY_CREDENTIALS}`);
|
|
91
|
+
console.log(' routing:');
|
|
92
|
+
console.log(' strategy: fill-first');
|
|
93
|
+
console.log(' session-affinity: true');
|
|
94
|
+
console.log(' session-affinity-ttl: "1h"');
|
|
95
|
+
console.log('');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Offer pool routing opt-in when the account count crosses 1->2 for a verified provider.
|
|
99
|
+
*
|
|
100
|
+
* Call this immediately after a successful account registration when the provider
|
|
101
|
+
* transitions from 1 to 2 accounts. The function is a no-op when:
|
|
102
|
+
* - Pool routing is already enabled
|
|
103
|
+
* - Provider is not in the verified pool list (codex, gemini, etc.)
|
|
104
|
+
* - The prompt was previously dismissed
|
|
105
|
+
* - Target is non-TTY (piped input / CI)
|
|
106
|
+
*
|
|
107
|
+
* Remote/Docker targets get a manual-config hint instead of an interactive prompt.
|
|
108
|
+
*
|
|
109
|
+
* @param provider - The provider that just reached 2 accounts
|
|
110
|
+
* @param accountCountBefore - Number of accounts before this add (should be 1 for transition)
|
|
111
|
+
* @param port - CLIProxy port (default: 8317)
|
|
112
|
+
*/
|
|
113
|
+
async function maybeOfferPoolRouting(provider, accountCountBefore, port = port_manager_1.CLIPROXY_DEFAULT_PORT) {
|
|
114
|
+
// Fast path: only fire at the 1->2 transition (accountCountBefore check only).
|
|
115
|
+
// The actual post-add count is verified below, after cheap early-exit guards pass,
|
|
116
|
+
// so that provider/dismissed/remote guards still return their expected skipReason
|
|
117
|
+
// regardless of whether the registry has been populated in the test environment.
|
|
118
|
+
if (accountCountBefore !== 1) {
|
|
119
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'not-at-transition' };
|
|
120
|
+
}
|
|
121
|
+
// Legacy install guard: on a profiles.json/config.json-only install there is no
|
|
122
|
+
// unified config.yaml. Both accept (enablePoolRouting) and decline
|
|
123
|
+
// (dismissPoolPrompt) write the unified config, which would create config.yaml
|
|
124
|
+
// and silently flip isUnifiedMode() outside the deliberate `ccs migrate` flow,
|
|
125
|
+
// orphaning the user's config.json profiles. Skip entirely before any prompt
|
|
126
|
+
// or dismissal persistence. Mirrors the guards in create-command.ts and
|
|
127
|
+
// account-flow.ts and the hazard documented in pool-onboarding-hint.ts.
|
|
128
|
+
// Silent by design: legacy installs receive pool guidance exclusively from
|
|
129
|
+
// ccs doctor (pool-onboarding-hint site 1); printing here would nag on every
|
|
130
|
+
// account add with no dismissal available.
|
|
131
|
+
if (!(0, config_loader_facade_1.hasUnifiedConfig)()) {
|
|
132
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'legacy-config' };
|
|
133
|
+
}
|
|
134
|
+
// Only for providers where pool routing is verified
|
|
135
|
+
if (!routing_strategy_1.POOL_ROUTING_VERIFIED_PROVIDERS.has(provider)) {
|
|
136
|
+
return {
|
|
137
|
+
prompted: false,
|
|
138
|
+
enabled: false,
|
|
139
|
+
skipped: true,
|
|
140
|
+
skipReason: `provider-${provider}-unverified`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// No-op if already enabled
|
|
144
|
+
const config = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
|
|
145
|
+
if (config.cliproxy?.pool_routing?.enabled === true) {
|
|
146
|
+
return { prompted: false, enabled: true, skipped: true, skipReason: 'already-enabled' };
|
|
147
|
+
}
|
|
148
|
+
// No-op if user already dismissed
|
|
149
|
+
if (isPoolPromptDismissed()) {
|
|
150
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'dismissed' };
|
|
151
|
+
}
|
|
152
|
+
// Remote / Docker target: print hint, do not prompt.
|
|
153
|
+
// Check before account count so remote targets with locally-unknown registries
|
|
154
|
+
// still get the hint (the remote CLIProxy holds the authoritative account list).
|
|
155
|
+
const target = (0, proxy_target_resolver_1.getProxyTarget)();
|
|
156
|
+
if (target.isRemote) {
|
|
157
|
+
printRemoteHint(provider);
|
|
158
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'remote-target' };
|
|
159
|
+
}
|
|
160
|
+
// Verify the actual post-add count is >= 2. registerAccount deduplicates by
|
|
161
|
+
// email/token-file so re-authenticating the single existing account keeps the
|
|
162
|
+
// count at 1 — not a real 1->2 transition. Checking here (before TTY) ensures
|
|
163
|
+
// re-auth dedup always returns not-at-transition even in non-TTY/CI sessions.
|
|
164
|
+
const accountCountAfter = (0, account_manager_1.getProviderAccounts)(provider).length;
|
|
165
|
+
if (accountCountAfter < 2) {
|
|
166
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'not-at-transition' };
|
|
167
|
+
}
|
|
168
|
+
// Non-TTY (piped input / CI): skip silently
|
|
169
|
+
if (!process.stdin.isTTY || !process.stderr.isTTY) {
|
|
170
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'non-tty' };
|
|
171
|
+
}
|
|
172
|
+
// Automation bypass: InteractivePrompt.confirm auto-returns true when --yes/-y
|
|
173
|
+
// is in argv or CCS_YES=1 is set, regardless of the default:false. This is an
|
|
174
|
+
// INSTANCE-GLOBAL routing/cooling consent decision; a generic automation flag
|
|
175
|
+
// must never grant it. Skip WITHOUT printing the prompt and WITHOUT persisting
|
|
176
|
+
// dismissal, so a future interactive run still offers the opt-in.
|
|
177
|
+
if (process.env.CCS_YES === '1' ||
|
|
178
|
+
process.argv.includes('--yes') ||
|
|
179
|
+
process.argv.includes('-y')) {
|
|
180
|
+
return { prompted: false, enabled: false, skipped: true, skipReason: 'automation-bypass' };
|
|
181
|
+
}
|
|
182
|
+
// Gather all providers with 2+ accounts for disclosure
|
|
183
|
+
const multiAccountProviders = getMultiAccountProviders();
|
|
184
|
+
const providerList = multiAccountProviders.length > 0 ? multiAccountProviders.join(', ') : provider;
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log((0, ui_1.warn)('Pool routing: you now have 2+ accounts for ' + provider));
|
|
187
|
+
console.log('');
|
|
188
|
+
console.log(' CCS can enable pool routing (fill-first + session affinity + 429 cooldown).');
|
|
189
|
+
console.log(' This is an INSTANCE-GLOBAL change: it affects account selection for ALL');
|
|
190
|
+
console.log(` CLIProxy providers on this machine: ${providerList}`);
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log(' What changes:');
|
|
193
|
+
console.log(' - disable-cooling: false (cooldown is required for retry-cap to work)');
|
|
194
|
+
console.log(' A 429 suspends a credential briefly (1s -> 30m exp backoff).');
|
|
195
|
+
console.log(' A 401/403 suspends it for 30 minutes (correct: broken auth = no traffic).');
|
|
196
|
+
console.log(' - routing: fill-first (drain one account before switching)');
|
|
197
|
+
console.log(' - session-affinity: true (TTL 1h, pinned per conversation)');
|
|
198
|
+
console.log(` - max-retry-credentials: ${routing_strategy_1.POOL_MAX_RETRY_CREDENTIALS} (stop after ${routing_strategy_1.POOL_MAX_RETRY_CREDENTIALS} attempts per request)`);
|
|
199
|
+
console.log('');
|
|
200
|
+
console.log(' You can roll back at any time: ccs cliproxy pool --disable');
|
|
201
|
+
console.log(' (Or re-enable later: ccs cliproxy pool --enable)');
|
|
202
|
+
console.log('');
|
|
203
|
+
const yes = await prompt_1.InteractivePrompt.confirm(' Enable pool routing for all CLIProxy providers?', { default: false });
|
|
204
|
+
if (!yes) {
|
|
205
|
+
// Persist decline so we don't re-ask on every subsequent add
|
|
206
|
+
dismissPoolPrompt();
|
|
207
|
+
console.log((0, ui_1.info)(" Declined. Pool routing stays off. Run 'ccs cliproxy pool --enable' to opt in later."));
|
|
208
|
+
console.log('');
|
|
209
|
+
return { prompted: true, enabled: false, skipped: false };
|
|
210
|
+
}
|
|
211
|
+
const configPath = (0, path_resolver_1.getConfigPathForPort)(port);
|
|
212
|
+
const authDir = (0, path_resolver_2.getAuthDir)();
|
|
213
|
+
const result = (0, routing_strategy_1.enablePoolRouting)(port, { configPath, authDir });
|
|
214
|
+
console.log('');
|
|
215
|
+
if (result.failed) {
|
|
216
|
+
// Config regeneration failed and the flag was rolled back: pool routing is
|
|
217
|
+
// NOT active. Surface the recovery copy and report enabled:false so callers
|
|
218
|
+
// (and quota/dashboard) do not claim pool ON.
|
|
219
|
+
console.log((0, ui_1.warn)(result.message));
|
|
220
|
+
console.log('');
|
|
221
|
+
return { prompted: true, enabled: false, skipped: false };
|
|
222
|
+
}
|
|
223
|
+
if (result.changed) {
|
|
224
|
+
console.log((0, ui_1.info)(result.message));
|
|
225
|
+
}
|
|
226
|
+
console.log('');
|
|
227
|
+
// User accepted and enablePoolRouting completed: pool routing is enabled
|
|
228
|
+
// even when this call was an idempotent no-op (changed=false).
|
|
229
|
+
return { prompted: true, enabled: true, skipped: false };
|
|
230
|
+
}
|
|
231
|
+
exports.maybeOfferPoolRouting = maybeOfferPoolRouting;
|
|
232
|
+
//# sourceMappingURL=pool-opt-in-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-opt-in-prompt.js","sourceRoot":"","sources":["../../../src/cliproxy/routing/pool-opt-in-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,138 @@ import type { CliproxyRoutingStrategy } from '../types';
|
|
|
2
2
|
export declare const DEFAULT_CLIPROXY_ROUTING_STRATEGY: CliproxyRoutingStrategy;
|
|
3
3
|
export declare const DEFAULT_CLIPROXY_SESSION_AFFINITY_ENABLED = false;
|
|
4
4
|
export declare const DEFAULT_CLIPROXY_SESSION_AFFINITY_TTL = "1h";
|
|
5
|
+
/**
|
|
6
|
+
* Pool routing defaults written to config when pool routing is enabled.
|
|
7
|
+
* fill-first + session affinity drains one account before using another,
|
|
8
|
+
* maximising per-account context depth while honouring cooldown windows.
|
|
9
|
+
*/
|
|
10
|
+
export declare const POOL_ROUTING_STRATEGY: CliproxyRoutingStrategy;
|
|
11
|
+
export declare const POOL_SESSION_AFFINITY_ENABLED = true;
|
|
12
|
+
export declare const POOL_SESSION_AFFINITY_TTL = "1h";
|
|
13
|
+
export declare const POOL_MAX_RETRY_CREDENTIALS = 3;
|
|
14
|
+
/**
|
|
15
|
+
* Providers for which pool routing is available and the opt-in prompt
|
|
16
|
+
* shows the full cooling/routing disclosure. Others (codex, gemini)
|
|
17
|
+
* have failover behaviour that is unverified for pool routing; they get
|
|
18
|
+
* a softened prompt variant or no prompt until spike Test D confirms.
|
|
19
|
+
*/
|
|
20
|
+
export declare const POOL_ROUTING_VERIFIED_PROVIDERS: Set<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Minimum CLIProxy version that supports pool routing keys:
|
|
23
|
+
* max-retry-credentials and the cooling flip.
|
|
24
|
+
* Older binaries silently ignore unknown keys — pool rails would appear active
|
|
25
|
+
* but have no effect. Warn the user at enable time if below this version.
|
|
26
|
+
*
|
|
27
|
+
* NOTE: Update this constant when upstream first ships these keys.
|
|
28
|
+
* Current best estimate based on spec; adjust after spike Test D confirms.
|
|
29
|
+
*/
|
|
30
|
+
export declare const POOL_ROUTING_MIN_VERSION = "6.9.45";
|
|
31
|
+
export interface EnablePoolRoutingResult {
|
|
32
|
+
/** Whether the pool routing state actually changed */
|
|
33
|
+
changed: boolean;
|
|
34
|
+
/** Whether an existing explicit user routing setting was preserved */
|
|
35
|
+
preservedExplicitSetting: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* True when the config could not be regenerated and the pool flag was rolled
|
|
38
|
+
* back. Pool routing is NOT active; the message carries recovery guidance.
|
|
39
|
+
*/
|
|
40
|
+
failed?: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
export interface DisablePoolRoutingResult {
|
|
44
|
+
changed: boolean;
|
|
45
|
+
/** True when the config could not be regenerated and the flag was rolled back. */
|
|
46
|
+
failed?: boolean;
|
|
47
|
+
message: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Detect whether the user has set a routing strategy that differs from the
|
|
51
|
+
* injected default (round-robin).
|
|
52
|
+
*
|
|
53
|
+
* Background: loadOrCreateUnifiedConfig persists injected defaults to disk on
|
|
54
|
+
* first load, so `strategy: round-robin` may appear in the raw YAML even on a
|
|
55
|
+
* pristine config — it was injected by CCS, not written by the user. A stored
|
|
56
|
+
* value EQUAL to the default is therefore treated as NOT explicit so that
|
|
57
|
+
* enablePoolRouting does not falsely claim to be "preserving a custom strategy".
|
|
58
|
+
*
|
|
59
|
+
* A value that DIFFERS from the default (e.g. fill-first) is treated as
|
|
60
|
+
* user-managed: preserve it and warn.
|
|
61
|
+
*/
|
|
62
|
+
export declare function hasExplicitRoutingStrategy(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Detect whether the user has set session-affinity to a value that differs
|
|
65
|
+
* from the injected default (false).
|
|
66
|
+
*
|
|
67
|
+
* Same rationale as hasExplicitRoutingStrategy: loadOrCreateUnifiedConfig may
|
|
68
|
+
* persist `session_affinity: false` as a default, so presence alone is not
|
|
69
|
+
* sufficient — only a value that differs from the default counts as explicit.
|
|
70
|
+
*/
|
|
71
|
+
export declare function hasExplicitSessionAffinity(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Enable pool routing: write pool_routing.enabled = true and the canonical
|
|
74
|
+
* pool defaults (fill-first, session affinity 1h, max-retry-credentials: 3)
|
|
75
|
+
* to the CCS unified config. Regenerates the CLIProxy config.yaml so the
|
|
76
|
+
* cooling flip and routing block take effect immediately (CLIProxy hot-reloads).
|
|
77
|
+
*
|
|
78
|
+
* Explicit user routing settings are preserved and a warning is emitted.
|
|
79
|
+
* The pool flag is written regardless — the generator uses fill-first/affinity
|
|
80
|
+
* from the pool defaults when pool is enabled, bypassing any stored routing.
|
|
81
|
+
*
|
|
82
|
+
* Idempotent: calling when already enabled is a no-op.
|
|
83
|
+
*/
|
|
84
|
+
export declare function enablePoolRouting(port: number, options?: {
|
|
85
|
+
configPath?: string;
|
|
86
|
+
authDir?: string;
|
|
87
|
+
}): EnablePoolRoutingResult;
|
|
88
|
+
/**
|
|
89
|
+
* Disable pool routing: clear pool_routing.enabled and restore the non-pool
|
|
90
|
+
* config defaults (disable-cooling: true, round-robin, no affinity).
|
|
91
|
+
* Regenerates the CLIProxy config.yaml.
|
|
92
|
+
*
|
|
93
|
+
* IMPORTANT: disablePoolRouting MUST explicitly restore routing to round-robin
|
|
94
|
+
* and session_affinity to false. Simply clearing pool_routing.enabled is not
|
|
95
|
+
* sufficient because the upstream CLIProxy default for disable-cooling is false
|
|
96
|
+
* (cooling ON) when the key is absent. Leaving cooling ON for a user who has
|
|
97
|
+
* disabled pool routing would reintroduce the single-account blackout that v5
|
|
98
|
+
* (commit fb77d72a) fixed.
|
|
99
|
+
*
|
|
100
|
+
* Idempotent: calling when already disabled is a no-op.
|
|
101
|
+
*/
|
|
102
|
+
export declare function disablePoolRouting(port: number, options?: {
|
|
103
|
+
configPath?: string;
|
|
104
|
+
authDir?: string;
|
|
105
|
+
}): DisablePoolRoutingResult;
|
|
106
|
+
/**
|
|
107
|
+
* Pool routing mode summary surfaced alongside routing state for the dashboard.
|
|
108
|
+
* When pool routing is enabled the generator forces fill-first + session affinity
|
|
109
|
+
* + cooling, regardless of stored routing values.
|
|
110
|
+
*/
|
|
111
|
+
export interface CliproxyPoolRoutingState {
|
|
112
|
+
enabled: boolean;
|
|
113
|
+
maxRetryCredentials?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Whether CCS can manage pool routing for this target. enablePoolRouting only
|
|
116
|
+
* writes LOCAL config files, so a remote proxy is never affected by the local
|
|
117
|
+
* pool flag. For remote targets this is false and `enabled` reflects the local
|
|
118
|
+
* config only (not the remote proxy's behaviour). Omitted (treated as true)
|
|
119
|
+
* for local targets. Mirrors CliproxySessionAffinityState.manageable.
|
|
120
|
+
*/
|
|
121
|
+
manageable?: boolean;
|
|
122
|
+
/** Explanation surfaced when manageable is false (remote target). */
|
|
123
|
+
message?: string;
|
|
124
|
+
}
|
|
5
125
|
export interface CliproxyRoutingState {
|
|
6
126
|
strategy: CliproxyRoutingStrategy;
|
|
7
127
|
source: 'live' | 'config';
|
|
8
128
|
target: 'local' | 'remote';
|
|
9
129
|
reachable: boolean;
|
|
10
130
|
message?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Pool routing mode. For local targets `enabled` reflects the active proxy
|
|
133
|
+
* config. For remote targets `manageable` is false and `enabled` reflects only
|
|
134
|
+
* the local config (the remote proxy is not affected by it).
|
|
135
|
+
*/
|
|
136
|
+
poolRouting?: CliproxyPoolRoutingState;
|
|
11
137
|
}
|
|
12
138
|
export interface CliproxyRoutingApplyResult extends CliproxyRoutingState {
|
|
13
139
|
applied: 'live' | 'live-and-config' | 'config-only';
|
|
@@ -34,6 +160,12 @@ export declare function normalizeCliproxySessionAffinityTtl(value: unknown): str
|
|
|
34
160
|
export declare function getConfiguredCliproxyRoutingStrategy(): CliproxyRoutingStrategy;
|
|
35
161
|
export declare function getConfiguredCliproxySessionAffinitySettings(): Required<CliproxySessionAffinitySettings>;
|
|
36
162
|
export declare function fetchLiveCliproxyRoutingStrategy(): Promise<CliproxyRoutingStrategy>;
|
|
163
|
+
/**
|
|
164
|
+
* Read the pool routing mode from the unified config.
|
|
165
|
+
* Pool routing is proxy-wide opt-in; this reflects the persisted flag, not a
|
|
166
|
+
* live selector probe.
|
|
167
|
+
*/
|
|
168
|
+
export declare function getCliproxyPoolRoutingState(): CliproxyPoolRoutingState;
|
|
37
169
|
export declare function readCliproxyRoutingState(): Promise<CliproxyRoutingState>;
|
|
38
170
|
export declare function readCliproxySessionAffinityState(): Promise<CliproxySessionAffinityState>;
|
|
39
171
|
export declare function applyCliproxyRoutingStrategy(strategy: CliproxyRoutingStrategy): Promise<CliproxyRoutingApplyResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing-strategy.d.ts","sourceRoot":"","sources":["../../../src/cliproxy/routing/routing-strategy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routing-strategy.d.ts","sourceRoot":"","sources":["../../../src/cliproxy/routing/routing-strategy.ts"],"names":[],"mappings":"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"}
|