@kaitranntt/ccs 8.10.0-dev.2 → 8.10.0-dev.21
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 +17 -5
- package/claude-mods/ccs-notices/.claude-plugin/plugin.json +1 -0
- package/claude-mods/ccs-notices/hooks/hooks.json +1 -0
- package/claude-mods/ccs-notices/hooks/register.ts +67 -0
- package/claude-mods/ccs-notices/tsconfig.json +3 -0
- package/dist/cliproxy/accounts/account-safety.d.ts +3 -2
- package/dist/cliproxy/accounts/account-safety.d.ts.map +1 -1
- package/dist/cliproxy/accounts/account-safety.js +23 -35
- package/dist/cliproxy/accounts/account-safety.js.map +1 -1
- package/dist/cliproxy/accounts/claude-pool-policy-api.d.ts +12 -0
- package/dist/cliproxy/accounts/claude-pool-policy-api.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-api.js +74 -0
- package/dist/cliproxy/accounts/claude-pool-policy-api.js.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-lease.d.ts +11 -0
- package/dist/cliproxy/accounts/claude-pool-policy-lease.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-lease.js +55 -0
- package/dist/cliproxy/accounts/claude-pool-policy-lease.js.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-reconciliation.d.ts +13 -0
- package/dist/cliproxy/accounts/claude-pool-policy-reconciliation.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-reconciliation.js +215 -0
- package/dist/cliproxy/accounts/claude-pool-policy-reconciliation.js.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-runtime.d.ts +19 -0
- package/dist/cliproxy/accounts/claude-pool-policy-runtime.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-runtime.js +65 -0
- package/dist/cliproxy/accounts/claude-pool-policy-runtime.js.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-state.d.ts +37 -0
- package/dist/cliproxy/accounts/claude-pool-policy-state.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy-state.js +205 -0
- package/dist/cliproxy/accounts/claude-pool-policy-state.js.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy.d.ts +48 -0
- package/dist/cliproxy/accounts/claude-pool-policy.d.ts.map +1 -0
- package/dist/cliproxy/accounts/claude-pool-policy.js +401 -0
- package/dist/cliproxy/accounts/claude-pool-policy.js.map +1 -0
- package/dist/cliproxy/accounts/drain-order.d.ts +1 -1
- package/dist/cliproxy/accounts/drain-order.d.ts.map +1 -1
- package/dist/cliproxy/accounts/drain-order.js +17 -0
- package/dist/cliproxy/accounts/drain-order.js.map +1 -1
- package/dist/cliproxy/accounts/email-account-identity.d.ts.map +1 -1
- package/dist/cliproxy/accounts/email-account-identity.js +3 -1
- package/dist/cliproxy/accounts/email-account-identity.js.map +1 -1
- package/dist/cliproxy/accounts/pool-state.d.ts +1 -1
- package/dist/cliproxy/accounts/pool-state.d.ts.map +1 -1
- package/dist/cliproxy/accounts/registry-config.d.ts +4 -0
- package/dist/cliproxy/accounts/registry-config.d.ts.map +1 -0
- package/dist/cliproxy/accounts/registry-config.js +46 -0
- package/dist/cliproxy/accounts/registry-config.js.map +1 -0
- package/dist/cliproxy/accounts/registry.d.ts.map +1 -1
- package/dist/cliproxy/accounts/registry.js +38 -16
- package/dist/cliproxy/accounts/registry.js.map +1 -1
- package/dist/cliproxy/accounts/session-notices.d.ts +35 -0
- package/dist/cliproxy/accounts/session-notices.d.ts.map +1 -0
- package/dist/cliproxy/accounts/session-notices.js +147 -0
- package/dist/cliproxy/accounts/session-notices.js.map +1 -0
- package/dist/cliproxy/accounts/token-file-ops.d.ts +1 -2
- package/dist/cliproxy/accounts/token-file-ops.d.ts.map +1 -1
- package/dist/cliproxy/accounts/token-file-ops.js +2 -7
- package/dist/cliproxy/accounts/token-file-ops.js.map +1 -1
- package/dist/cliproxy/accounts/types.d.ts +1 -1
- package/dist/cliproxy/accounts/types.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js +10 -8
- package/dist/cliproxy/ai-providers/codex-plan-compatibility.js.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.d.ts +12 -2
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js +107 -88
- package/dist/cliproxy/ai-providers/codex-reasoning-proxy.js.map +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.js +1 -1
- package/dist/cliproxy/ai-providers/model-id-normalizer.js.map +1 -1
- package/dist/cliproxy/ai-providers/schema-sanitizer.d.ts +3 -1
- package/dist/cliproxy/ai-providers/schema-sanitizer.d.ts.map +1 -1
- package/dist/cliproxy/ai-providers/schema-sanitizer.js +3 -1
- package/dist/cliproxy/ai-providers/schema-sanitizer.js.map +1 -1
- package/dist/cliproxy/config/env-builder.d.ts.map +1 -1
- package/dist/cliproxy/config/env-builder.js +8 -1
- package/dist/cliproxy/config/env-builder.js.map +1 -1
- package/dist/cliproxy/config/fallback-chain-serializer.d.ts +8 -0
- package/dist/cliproxy/config/fallback-chain-serializer.d.ts.map +1 -0
- package/dist/cliproxy/config/fallback-chain-serializer.js +67 -0
- package/dist/cliproxy/config/fallback-chain-serializer.js.map +1 -0
- package/dist/cliproxy/config/generator.d.ts +9 -1
- package/dist/cliproxy/config/generator.d.ts.map +1 -1
- package/dist/cliproxy/config/generator.js +162 -10
- package/dist/cliproxy/config/generator.js.map +1 -1
- package/dist/cliproxy/config/thinking-config.js +5 -5
- 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 +7 -1
- package/dist/cliproxy/executor/account-resolution.js.map +1 -1
- package/dist/cliproxy/executor/claude-launcher.d.ts.map +1 -1
- package/dist/cliproxy/executor/claude-launcher.js +23 -3
- package/dist/cliproxy/executor/claude-launcher.js.map +1 -1
- package/dist/cliproxy/executor/claude-mods.d.ts +33 -0
- package/dist/cliproxy/executor/claude-mods.d.ts.map +1 -0
- package/dist/cliproxy/executor/claude-mods.js +121 -0
- package/dist/cliproxy/executor/claude-mods.js.map +1 -0
- package/dist/cliproxy/executor/env-resolver.js +1 -1
- package/dist/cliproxy/executor/env-resolver.js.map +1 -1
- package/dist/cliproxy/executor/index.d.ts.map +1 -1
- package/dist/cliproxy/executor/index.js +2 -1
- package/dist/cliproxy/executor/index.js.map +1 -1
- package/dist/cliproxy/executor/launch-settings.d.ts +6 -15
- package/dist/cliproxy/executor/launch-settings.d.ts.map +1 -1
- package/dist/cliproxy/executor/launch-settings.js +19 -119
- package/dist/cliproxy/executor/launch-settings.js.map +1 -1
- package/dist/cliproxy/executor/proxy-chain-builder.d.ts.map +1 -1
- package/dist/cliproxy/executor/proxy-chain-builder.js +4 -0
- package/dist/cliproxy/executor/proxy-chain-builder.js.map +1 -1
- package/dist/cliproxy/model-catalog.d.ts +1 -1
- package/dist/cliproxy/model-catalog.d.ts.map +1 -1
- package/dist/cliproxy/model-catalog.js +103 -10
- package/dist/cliproxy/model-catalog.js.map +1 -1
- package/dist/cliproxy/proxy/content-encoding.d.ts +20 -0
- package/dist/cliproxy/proxy/content-encoding.d.ts.map +1 -0
- package/dist/cliproxy/proxy/content-encoding.js +37 -0
- package/dist/cliproxy/proxy/content-encoding.js.map +1 -0
- package/dist/cliproxy/proxy/tool-sanitization-proxy.d.ts +7 -1
- package/dist/cliproxy/proxy/tool-sanitization-proxy.d.ts.map +1 -1
- package/dist/cliproxy/proxy/tool-sanitization-proxy.js +71 -109
- package/dist/cliproxy/proxy/tool-sanitization-proxy.js.map +1 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.d.ts +13 -0
- package/dist/cliproxy/proxy/upstream-response-timeout.d.ts.map +1 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.js +26 -1
- package/dist/cliproxy/proxy/upstream-response-timeout.js.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude-normalizer.d.ts +17 -4
- package/dist/cliproxy/quota/quota-fetcher-claude-normalizer.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude-normalizer.js +246 -153
- package/dist/cliproxy/quota/quota-fetcher-claude-normalizer.js.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude-probe-state.d.ts +47 -0
- package/dist/cliproxy/quota/quota-fetcher-claude-probe-state.d.ts.map +1 -0
- package/dist/cliproxy/quota/quota-fetcher-claude-probe-state.js +160 -0
- package/dist/cliproxy/quota/quota-fetcher-claude-probe-state.js.map +1 -0
- package/dist/cliproxy/quota/quota-fetcher-claude.d.ts +4 -4
- package/dist/cliproxy/quota/quota-fetcher-claude.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-fetcher-claude.js +188 -21
- package/dist/cliproxy/quota/quota-fetcher-claude.js.map +1 -1
- package/dist/cliproxy/quota/quota-label-sanitizer.d.ts +3 -2
- package/dist/cliproxy/quota/quota-label-sanitizer.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-label-sanitizer.js +6 -5
- package/dist/cliproxy/quota/quota-label-sanitizer.js.map +1 -1
- package/dist/cliproxy/quota/quota-manager.d.ts.map +1 -1
- package/dist/cliproxy/quota/quota-manager.js +3 -9
- package/dist/cliproxy/quota/quota-manager.js.map +1 -1
- package/dist/cliproxy/quota/quota-types.d.ts +17 -0
- package/dist/cliproxy/quota/quota-types.d.ts.map +1 -1
- package/dist/cliproxy/services/stats-fetcher.d.ts +4 -0
- package/dist/cliproxy/services/stats-fetcher.d.ts.map +1 -1
- package/dist/cliproxy/services/stats-fetcher.js +14 -1
- package/dist/cliproxy/services/stats-fetcher.js.map +1 -1
- package/dist/cliproxy/services/usage-compatibility-transformer.d.ts +5 -0
- package/dist/cliproxy/services/usage-compatibility-transformer.d.ts.map +1 -1
- package/dist/cliproxy/services/usage-compatibility-transformer.js +77 -6
- package/dist/cliproxy/services/usage-compatibility-transformer.js.map +1 -1
- package/dist/cliproxy/types/config-types.d.ts +3 -0
- package/dist/cliproxy/types/config-types.d.ts.map +1 -1
- package/dist/commands/api-command/help.d.ts.map +1 -1
- package/dist/commands/api-command/help.js +2 -0
- package/dist/commands/api-command/help.js.map +1 -1
- package/dist/commands/cliproxy/help-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/help-subcommand.js +9 -0
- package/dist/commands/cliproxy/help-subcommand.js.map +1 -1
- package/dist/commands/cliproxy/order-subcommand.d.ts.map +1 -1
- package/dist/commands/cliproxy/order-subcommand.js +86 -44
- package/dist/commands/cliproxy/order-subcommand.js.map +1 -1
- package/dist/commands/cliproxy/pool-state-renderer.d.ts.map +1 -1
- package/dist/commands/cliproxy/pool-state-renderer.js +9 -2
- package/dist/commands/cliproxy/pool-state-renderer.js.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand/claude-window-helpers.d.ts +1 -2
- package/dist/commands/cliproxy/quota-subcommand/claude-window-helpers.d.ts.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand/claude-window-helpers.js +5 -16
- package/dist/commands/cliproxy/quota-subcommand/claude-window-helpers.js.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand/sections/claude.d.ts.map +1 -1
- package/dist/commands/cliproxy/quota-subcommand/sections/claude.js +4 -1
- package/dist/commands/cliproxy/quota-subcommand/sections/claude.js.map +1 -1
- package/dist/config/schemas/cliproxy.d.ts +16 -1
- package/dist/config/schemas/cliproxy.d.ts.map +1 -1
- package/dist/config/schemas/cliproxy.js.map +1 -1
- package/dist/cursor/cursor-daemon-entry.d.ts.map +1 -1
- package/dist/cursor/cursor-daemon-entry.js +11 -49
- package/dist/cursor/cursor-daemon-entry.js.map +1 -1
- package/dist/cursor/cursor-daemon.d.ts.map +1 -1
- package/dist/cursor/cursor-daemon.js +7 -4
- package/dist/cursor/cursor-daemon.js.map +1 -1
- package/dist/dispatcher/flows/cliproxy-flow.d.ts.map +1 -1
- package/dist/dispatcher/flows/cliproxy-flow.js +1 -0
- package/dist/dispatcher/flows/cliproxy-flow.js.map +1 -1
- package/dist/dispatcher/flows/settings-flow.d.ts.map +1 -1
- package/dist/dispatcher/flows/settings-flow.js +3 -1
- package/dist/dispatcher/flows/settings-flow.js.map +1 -1
- package/dist/docker/docker-bootstrap.d.ts.map +1 -1
- package/dist/docker/docker-bootstrap.js +29 -5
- package/dist/docker/docker-bootstrap.js.map +1 -1
- package/dist/glmt/glmt-proxy.d.ts +0 -4
- package/dist/glmt/glmt-proxy.d.ts.map +1 -1
- package/dist/glmt/glmt-proxy.js +6 -21
- package/dist/glmt/glmt-proxy.js.map +1 -1
- package/dist/management/shared-manager/plugin-layout-internals.d.ts.map +1 -1
- package/dist/management/shared-manager/plugin-layout-internals.js +8 -0
- package/dist/management/shared-manager/plugin-layout-internals.js.map +1 -1
- package/dist/management/shared-manager/plugin-metadata-normalizer.d.ts.map +1 -1
- package/dist/management/shared-manager/plugin-metadata-normalizer.js +72 -21
- package/dist/management/shared-manager/plugin-metadata-normalizer.js.map +1 -1
- package/dist/management/shared-manager/shared-dir-linker.d.ts.map +1 -1
- package/dist/management/shared-manager/shared-dir-linker.js +5 -0
- package/dist/management/shared-manager/shared-dir-linker.js.map +1 -1
- package/dist/management/shared-manager/types.d.ts.map +1 -1
- package/dist/management/shared-manager/types.js +4 -1
- package/dist/management/shared-manager/types.js.map +1 -1
- package/dist/proxy/server/http-helpers.d.ts +6 -1
- package/dist/proxy/server/http-helpers.d.ts.map +1 -1
- package/dist/proxy/server/http-helpers.js +19 -77
- 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 +11 -5
- package/dist/proxy/server/messages-route.js.map +1 -1
- package/dist/shared/claude-pool-policy.d.ts +20 -0
- package/dist/shared/claude-pool-policy.d.ts.map +1 -0
- package/dist/shared/claude-pool-policy.js +3 -0
- package/dist/shared/claude-pool-policy.js.map +1 -0
- package/dist/shared/provider-preset-catalog.d.ts +1 -1
- package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
- package/dist/shared/provider-preset-catalog.js +80 -7
- package/dist/shared/provider-preset-catalog.js.map +1 -1
- package/dist/targets/droid-provider.d.ts.map +1 -1
- package/dist/targets/droid-provider.js +10 -8
- package/dist/targets/droid-provider.js.map +1 -1
- package/dist/ui/assets/{Trans-BFurXtDk.js → Trans-Dlb02vqu.js} +1 -1
- package/dist/ui/assets/{accounts-B_ik6YOD.js → accounts-NMmfEBnl.js} +1 -1
- package/dist/ui/assets/{alert-dialog-C6fhMbXC.js → alert-dialog-CLeTz0Di.js} +1 -1
- package/dist/ui/assets/{api-CxCFoBC0.js → api-DxGxeHbw.js} +2 -2
- package/dist/ui/assets/{auth-section-CtmO77JA.js → auth-section-AI2YNrUB.js} +1 -1
- package/dist/ui/assets/{backups-section-BYKnAWUa.js → backups-section-CxyuzCda.js} +1 -1
- package/dist/ui/assets/{channels-3uR41jWp.js → channels-SBcIEMn0.js} +1 -1
- package/dist/ui/assets/{checkbox-fCmjUiDn.js → checkbox-C1D6YcRy.js} +1 -1
- package/dist/ui/assets/{claude-extension-BplTVbCF.js → claude-extension-C3Ik79tl.js} +1 -1
- package/dist/ui/assets/cliproxy-BySCuRxu.js +4 -0
- package/dist/ui/assets/{cliproxy-ai-providers-D4OTiwA3.js → cliproxy-ai-providers-B8LPZhj3.js} +6 -6
- package/dist/ui/assets/{cliproxy-control-panel-DCyhsdm1.js → cliproxy-control-panel-Dsv31SI_.js} +1 -1
- package/dist/ui/assets/{codex-BGF20GsK.js → codex-CWZlSLEn.js} +5 -5
- package/dist/ui/assets/{confirm-dialog-BtMwDW6c.js → confirm-dialog-tpU9d5TR.js} +1 -1
- package/dist/ui/assets/{copilot-r1b0KLFf.js → copilot-C5uwBK-k.js} +1 -1
- package/dist/ui/assets/{cursor-BhVKTiz1.js → cursor-BwoYXKM4.js} +1 -1
- package/dist/ui/assets/{droid-lol9hAdK.js → droid-Cv6mZctn.js} +2 -2
- package/dist/ui/assets/{globalenv-section-B0gg-kuR.js → globalenv-section-CKc1Udhj.js} +1 -1
- package/dist/ui/assets/{health-Bu6RFYCP.js → health-Ctfcm6p0.js} +1 -1
- package/dist/ui/assets/{index-BbPI5sU_.js → index--TAxR0Iy.js} +1 -1
- package/dist/ui/assets/index-0hASk2BU.css +1 -0
- package/dist/ui/assets/{index-Pn_n_HFQ.js → index-C2ABCKof.js} +1 -1
- package/dist/ui/assets/{index-Djse8iLV.js → index-C5YaR--I.js} +1 -1
- package/dist/ui/assets/{index-BmjgsjcO.js → index-CBKaNavQ.js} +1 -1
- package/dist/ui/assets/{index-ptYEAEzZ.js → index-DnnSa3K6.js} +1 -1
- package/dist/ui/assets/{index-awbhDVzL.js → index-G9JzuSyw.js} +1 -1
- package/dist/ui/assets/index-gX7Mi5Ws.js +56 -0
- package/dist/ui/assets/{logs-B5Sbi4IG.js → logs-D6LiKkzU.js} +1 -1
- package/dist/ui/assets/{masked-input-BnrL_TdT.js → masked-input-CmtENW5h.js} +1 -1
- package/dist/ui/assets/proxy-status-widget-DqVBhfEP.js +1 -0
- package/dist/ui/assets/{raw-json-settings-editor-panel-PStRjNEl.js → raw-json-settings-editor-panel-C9-_RC57.js} +1 -1
- package/dist/ui/assets/{searchable-select-BDpwwNsP.js → searchable-select-BeEQJh2E.js} +1 -1
- package/dist/ui/assets/{separator-CJCyWDRS.js → separator-CB-e5SCL.js} +1 -1
- package/dist/ui/assets/{shared-6BrToCad.js → shared-GU9wziRt.js} +3 -3
- package/dist/ui/assets/{table-CnZev3Iu.js → table-BFrniqUJ.js} +1 -1
- package/dist/ui/assets/{updates-BiS0o8aM.js → updates-DYhBCREi.js} +1 -1
- package/dist/ui/assets/{use-accounts-89FOqhFc.js → use-accounts-xaNW9KeG.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/delegation-validator.d.ts.map +1 -1
- package/dist/utils/delegation-validator.js +29 -8
- package/dist/utils/delegation-validator.js.map +1 -1
- package/dist/utils/launch-settings.d.ts +51 -0
- package/dist/utils/launch-settings.d.ts.map +1 -0
- package/dist/utils/launch-settings.js +190 -0
- package/dist/utils/launch-settings.js.map +1 -0
- package/dist/utils/openai-compat-launch-settings.d.ts +13 -1
- package/dist/utils/openai-compat-launch-settings.d.ts.map +1 -1
- package/dist/utils/openai-compat-launch-settings.js +15 -58
- package/dist/utils/openai-compat-launch-settings.js.map +1 -1
- package/dist/utils/request-body.d.ts +40 -0
- package/dist/utils/request-body.d.ts.map +1 -0
- package/dist/utils/request-body.js +142 -0
- package/dist/utils/request-body.js.map +1 -0
- package/dist/web-server/index.d.ts +1 -1
- package/dist/web-server/index.d.ts.map +1 -1
- package/dist/web-server/index.js +4 -1
- package/dist/web-server/index.js.map +1 -1
- package/dist/web-server/jsonl-parser.d.ts +2 -0
- package/dist/web-server/jsonl-parser.d.ts.map +1 -1
- package/dist/web-server/jsonl-parser.js +54 -4
- package/dist/web-server/jsonl-parser.js.map +1 -1
- package/dist/web-server/model-pricing.d.ts.map +1 -1
- package/dist/web-server/model-pricing.js +99 -1
- package/dist/web-server/model-pricing.js.map +1 -1
- package/dist/web-server/routes/bar-pool-account-quota-adapter.d.ts.map +1 -1
- package/dist/web-server/routes/bar-pool-account-quota-adapter.js +1 -3
- package/dist/web-server/routes/bar-pool-account-quota-adapter.js.map +1 -1
- package/dist/web-server/routes/cliproxy-routing-routes.d.ts.map +1 -1
- package/dist/web-server/routes/cliproxy-routing-routes.js +16 -0
- package/dist/web-server/routes/cliproxy-routing-routes.js.map +1 -1
- package/dist/web-server/shutdown.d.ts +2 -3
- package/dist/web-server/shutdown.d.ts.map +1 -1
- package/dist/web-server/shutdown.js +16 -8
- package/dist/web-server/shutdown.js.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts +6 -0
- package/dist/web-server/usage/cliproxy-usage-transformer.d.ts.map +1 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.js +57 -1
- package/dist/web-server/usage/cliproxy-usage-transformer.js.map +1 -1
- package/dist/web-server/usage/codex-native-usage-collector.d.ts.map +1 -1
- package/dist/web-server/usage/codex-native-usage-collector.js +7 -4
- package/dist/web-server/usage/codex-native-usage-collector.js.map +1 -1
- package/dist/web-server/usage/native-quota-collector.d.ts.map +1 -1
- package/dist/web-server/usage/native-quota-collector.js +35 -67
- package/dist/web-server/usage/native-quota-collector.js.map +1 -1
- package/package.json +3 -1
- package/scripts/run-test-bucket.js +4 -0
- package/dist/ui/assets/cliproxy-BdW2ctsn.js +0 -4
- package/dist/ui/assets/index-DzFlVVV3.css +0 -1
- package/dist/ui/assets/index-pHOoeHgY.js +0 -56
- package/dist/ui/assets/proxy-status-widget-ColaQQXh.js +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="bun-types" />
|
|
3
|
+
import type { Settings } from '../types/config';
|
|
4
|
+
/**
|
|
5
|
+
* Environment keys that control provider routing/model selection and are read
|
|
6
|
+
* by Claude CLI. Overlaid by default when an active proxy chain is resolved.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LAUNCH_ROUTING_ENV_KEYS: readonly string[];
|
|
9
|
+
export interface UnifiedLaunchSettingsOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Key-value map of environment variables to overlay into the settings file's `env` block.
|
|
12
|
+
*/
|
|
13
|
+
overlayEnv?: NodeJS.ProcessEnv | Record<string, string | undefined>;
|
|
14
|
+
/**
|
|
15
|
+
* Keys to explicitly strip/delete from the settings file's `env` block.
|
|
16
|
+
* Runs AFTER overlayEnv, guaranteeing these keys are completely absent from the output.
|
|
17
|
+
*/
|
|
18
|
+
stripKeys?: readonly string[];
|
|
19
|
+
/**
|
|
20
|
+
* If true, also strip all default Anthropic routing keys via stripAnthropicRoutingEnv.
|
|
21
|
+
*/
|
|
22
|
+
stripAnthropicRouting?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* When true, snapshot the isolated settings to a durable, profile-scoped
|
|
25
|
+
* cache directory (~/.ccs/cache/isolated-settings/<hash>/) using atomic temp-and-rename.
|
|
26
|
+
* Required for background fleet daemon respawns (Issue #1734).
|
|
27
|
+
*/
|
|
28
|
+
durable?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* If false and no routing/strip changes occurred, ephemeral mode returns the original
|
|
31
|
+
* settingsPath without writing a temporary file. Defaults to false.
|
|
32
|
+
*/
|
|
33
|
+
forceWrite?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface UnifiedLaunchSettingsResult {
|
|
36
|
+
settingsPath: string;
|
|
37
|
+
cleanup: () => void;
|
|
38
|
+
changed: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Builds the modified settings JSON object by applying overlayEnv and stripKeys.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildUnifiedLaunchSettings(initialSettings: Settings | Record<string, unknown>, options?: UnifiedLaunchSettingsOptions): {
|
|
44
|
+
settings: Settings;
|
|
45
|
+
changed: boolean;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Prepares launch settings with unified overlay, strip, and durable/ephemeral isolation.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createUnifiedLaunchSettings(sourceSettingsPath: string, initialSettings?: Settings | Record<string, unknown>, options?: UnifiedLaunchSettingsOptions): UnifiedLaunchSettingsResult;
|
|
51
|
+
//# sourceMappingURL=launch-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-settings.d.ts","sourceRoot":"","sources":["../../src/utils/launch-settings.ts"],"names":[],"mappings":";;AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAShD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAIpD,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACpE;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnD,OAAO,CAAC,EAAE,4BAA4B,GACrC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAiD1C;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,MAAM,EAC1B,eAAe,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,OAAO,CAAC,EAAE,4BAA4B,GACrC,2BAA2B,CAoG7B"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.createUnifiedLaunchSettings = exports.buildUnifiedLaunchSettings = exports.LAUNCH_ROUTING_ENV_KEYS = void 0;
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const os = __importStar(require("os"));
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
const crypto_1 = require("crypto");
|
|
31
|
+
const config_manager_1 = require("./config-manager");
|
|
32
|
+
const shell_executor_1 = require("./shell-executor");
|
|
33
|
+
const extended_context_utils_1 = require("../shared/extended-context-utils");
|
|
34
|
+
/**
|
|
35
|
+
* Environment keys that control provider routing/model selection and are read
|
|
36
|
+
* by Claude CLI. Overlaid by default when an active proxy chain is resolved.
|
|
37
|
+
*/
|
|
38
|
+
exports.LAUNCH_ROUTING_ENV_KEYS = [
|
|
39
|
+
...shell_executor_1.ANTHROPIC_ROUTING_ENV_KEYS,
|
|
40
|
+
...shell_executor_1.ANTHROPIC_MODEL_ENV_KEYS,
|
|
41
|
+
...extended_context_utils_1.EXTRA_EXTENDED_CONTEXT_MODEL_ENV_KEYS,
|
|
42
|
+
];
|
|
43
|
+
function isRecord(value) {
|
|
44
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Builds the modified settings JSON object by applying overlayEnv and stripKeys.
|
|
48
|
+
*/
|
|
49
|
+
function buildUnifiedLaunchSettings(initialSettings, options) {
|
|
50
|
+
const base = JSON.parse(JSON.stringify(initialSettings));
|
|
51
|
+
let mergedEnv = isRecord(base.env) ? { ...base.env } : {};
|
|
52
|
+
let changed = false;
|
|
53
|
+
// 1. Apply overlayEnv if provided
|
|
54
|
+
if (options?.overlayEnv) {
|
|
55
|
+
const keysToCheck = exports.LAUNCH_ROUTING_ENV_KEYS;
|
|
56
|
+
for (const key of keysToCheck) {
|
|
57
|
+
const resolved = options.overlayEnv[key];
|
|
58
|
+
if (typeof resolved === 'string' && mergedEnv[key] !== resolved) {
|
|
59
|
+
mergedEnv[key] = resolved;
|
|
60
|
+
changed = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 2. Strip Anthropic routing keys if requested
|
|
65
|
+
if (options?.stripAnthropicRouting) {
|
|
66
|
+
const beforeCount = Object.keys(mergedEnv).length;
|
|
67
|
+
mergedEnv = Object.fromEntries(Object.entries((0, shell_executor_1.stripAnthropicRoutingEnv)(mergedEnv)).filter((entry) => typeof entry[1] === 'string'));
|
|
68
|
+
if (Object.keys(mergedEnv).length !== beforeCount) {
|
|
69
|
+
changed = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// 3. Apply explicit stripKeys (forced-absent keys, e.g. ANTHROPIC_API_KEY)
|
|
73
|
+
if (options?.stripKeys && options.stripKeys.length > 0) {
|
|
74
|
+
for (const key of options.stripKeys) {
|
|
75
|
+
if (key in mergedEnv) {
|
|
76
|
+
delete mergedEnv[key];
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Clean up empty env
|
|
82
|
+
if (Object.keys(mergedEnv).length > 0) {
|
|
83
|
+
base.env = mergedEnv;
|
|
84
|
+
}
|
|
85
|
+
else if ('env' in base) {
|
|
86
|
+
delete base.env;
|
|
87
|
+
changed = true;
|
|
88
|
+
}
|
|
89
|
+
return { settings: base, changed };
|
|
90
|
+
}
|
|
91
|
+
exports.buildUnifiedLaunchSettings = buildUnifiedLaunchSettings;
|
|
92
|
+
/**
|
|
93
|
+
* Prepares launch settings with unified overlay, strip, and durable/ephemeral isolation.
|
|
94
|
+
*/
|
|
95
|
+
function createUnifiedLaunchSettings(sourceSettingsPath, initialSettings, options) {
|
|
96
|
+
const noopResult = (changed) => ({
|
|
97
|
+
settingsPath: sourceSettingsPath,
|
|
98
|
+
cleanup: () => { },
|
|
99
|
+
changed,
|
|
100
|
+
});
|
|
101
|
+
let baseSettings = initialSettings ?? {};
|
|
102
|
+
if (!initialSettings && fs.existsSync(sourceSettingsPath)) {
|
|
103
|
+
try {
|
|
104
|
+
const parsed = JSON.parse(fs.readFileSync(sourceSettingsPath, 'utf8'));
|
|
105
|
+
if (isRecord(parsed)) {
|
|
106
|
+
baseSettings = parsed;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
baseSettings = {};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const { settings, changed } = buildUnifiedLaunchSettings(baseSettings, options);
|
|
114
|
+
// If no change and forceWrite is false and not durable, return original path
|
|
115
|
+
if (!changed && !options?.forceWrite && !options?.durable) {
|
|
116
|
+
return noopResult(false);
|
|
117
|
+
}
|
|
118
|
+
const contentStr = JSON.stringify(settings, null, 2) + '\n';
|
|
119
|
+
const fileName = path.basename(sourceSettingsPath) || 'settings.json';
|
|
120
|
+
// 1. Durable mode: stored in ~/.ccs/cache/isolated-settings/<hash>/
|
|
121
|
+
if (options?.durable) {
|
|
122
|
+
const pathHash = (0, crypto_1.createHash)('sha256')
|
|
123
|
+
.update(path.resolve(sourceSettingsPath))
|
|
124
|
+
.digest('hex')
|
|
125
|
+
.slice(0, 16);
|
|
126
|
+
const durableDir = path.join((0, config_manager_1.getCcsDir)(), 'cache', 'isolated-settings', pathHash);
|
|
127
|
+
fs.mkdirSync(durableDir, { recursive: true, mode: 0o700 });
|
|
128
|
+
fs.chmodSync(durableDir, 0o700);
|
|
129
|
+
const targetPath = path.join(durableDir, fileName);
|
|
130
|
+
const tempFile = path.join(durableDir, `.${fileName}.${(0, crypto_1.randomUUID)()}.tmp`);
|
|
131
|
+
let renamed = false;
|
|
132
|
+
try {
|
|
133
|
+
fs.writeFileSync(tempFile, contentStr, {
|
|
134
|
+
encoding: 'utf8',
|
|
135
|
+
mode: 0o600,
|
|
136
|
+
flag: 'wx',
|
|
137
|
+
});
|
|
138
|
+
fs.renameSync(tempFile, targetPath);
|
|
139
|
+
renamed = true;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
if (!renamed) {
|
|
143
|
+
try {
|
|
144
|
+
fs.unlinkSync(tempFile);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// ignore
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
settingsPath: targetPath,
|
|
153
|
+
cleanup: () => { },
|
|
154
|
+
changed,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// 2. Ephemeral mode: os.tmpdir() with 0o700 / 0o600
|
|
158
|
+
try {
|
|
159
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-launch-settings-'));
|
|
160
|
+
fs.chmodSync(tempDir, 0o700);
|
|
161
|
+
const runtimePath = path.join(tempDir, fileName);
|
|
162
|
+
fs.writeFileSync(runtimePath, contentStr, {
|
|
163
|
+
encoding: 'utf8',
|
|
164
|
+
mode: 0o600,
|
|
165
|
+
});
|
|
166
|
+
let cleanedUp = false;
|
|
167
|
+
const cleanup = () => {
|
|
168
|
+
if (cleanedUp) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
cleanedUp = true;
|
|
172
|
+
try {
|
|
173
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// ignore
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
return {
|
|
180
|
+
settingsPath: runtimePath,
|
|
181
|
+
cleanup,
|
|
182
|
+
changed,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return noopResult(changed);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.createUnifiedLaunchSettings = createUnifiedLaunchSettings;
|
|
190
|
+
//# sourceMappingURL=launch-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-settings.js","sourceRoot":"","sources":["../../src/utils/launch-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,17 @@ export interface OpenAICompatLaunchSettings {
|
|
|
3
3
|
settingsPath: string;
|
|
4
4
|
cleanup: () => void;
|
|
5
5
|
}
|
|
6
|
-
export
|
|
6
|
+
export interface OpenAICompatLaunchSettingsOptions {
|
|
7
|
+
/**
|
|
8
|
+
* When true, snapshot the isolated settings to a durable, profile-scoped
|
|
9
|
+
* cache directory (~/.ccs/cache/isolated-settings/<hash>/) using atomic temp-and-rename.
|
|
10
|
+
*/
|
|
11
|
+
durable?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates isolated launch settings for OpenAI-compatible profiles.
|
|
15
|
+
* Strips Anthropic routing variables and guarantees ANTHROPIC_API_KEY is absent
|
|
16
|
+
* so spawned processes route exclusively through proxyEnv without auth bypass.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createOpenAICompatLaunchSettings(settingsPath: string, settings: Settings, options?: OpenAICompatLaunchSettingsOptions): OpenAICompatLaunchSettings;
|
|
7
19
|
//# sourceMappingURL=openai-compat-launch-settings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compat-launch-settings.d.ts","sourceRoot":"","sources":["../../src/utils/openai-compat-launch-settings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-compat-launch-settings.d.ts","sourceRoot":"","sources":["../../src/utils/openai-compat-launch-settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAOhD,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,iCAAiC;IAChD;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,iCAAiC,GAC1C,0BAA0B,CAkB5B"}
|
|
@@ -1,66 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
3
|
exports.createOpenAICompatLaunchSettings = void 0;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fs.chmodSync(tempDir, 0o700);
|
|
40
|
-
const launchSettings = JSON.parse(JSON.stringify(settings));
|
|
41
|
-
const sanitizedEnv = Object.fromEntries(Object.entries((0, shell_executor_1.stripAnthropicRoutingEnv)({ ...(launchSettings.env ?? {}) })).filter((entry) => typeof entry[1] === 'string'));
|
|
42
|
-
if (Object.keys(sanitizedEnv).length > 0) {
|
|
43
|
-
launchSettings.env = sanitizedEnv;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
delete launchSettings.env;
|
|
47
|
-
}
|
|
48
|
-
const launchSettingsPath = path.join(tempDir, path.basename(settingsPath));
|
|
49
|
-
fs.writeFileSync(launchSettingsPath, JSON.stringify(launchSettings, null, 2) + '\n', {
|
|
50
|
-
encoding: 'utf8',
|
|
51
|
-
mode: 0o600,
|
|
52
|
-
});
|
|
53
|
-
let cleanedUp = false;
|
|
54
|
-
const cleanup = () => {
|
|
55
|
-
if (cleanedUp) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
cleanedUp = true;
|
|
59
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
4
|
+
const launch_settings_1 = require("./launch-settings");
|
|
5
|
+
/**
|
|
6
|
+
* Creates isolated launch settings for OpenAI-compatible profiles.
|
|
7
|
+
* Strips Anthropic routing variables and guarantees ANTHROPIC_API_KEY is absent
|
|
8
|
+
* so spawned processes route exclusively through proxyEnv without auth bypass.
|
|
9
|
+
*/
|
|
10
|
+
function createOpenAICompatLaunchSettings(settingsPath, settings, options) {
|
|
11
|
+
const unifiedOptions = {
|
|
12
|
+
stripAnthropicRouting: true,
|
|
13
|
+
stripKeys: ['ANTHROPIC_API_KEY'],
|
|
14
|
+
durable: options?.durable,
|
|
15
|
+
forceWrite: true,
|
|
60
16
|
};
|
|
17
|
+
const result = (0, launch_settings_1.createUnifiedLaunchSettings)(settingsPath, settings, unifiedOptions);
|
|
61
18
|
return {
|
|
62
|
-
settingsPath:
|
|
63
|
-
cleanup,
|
|
19
|
+
settingsPath: result.settingsPath,
|
|
20
|
+
cleanup: result.cleanup,
|
|
64
21
|
};
|
|
65
22
|
}
|
|
66
23
|
exports.createOpenAICompatLaunchSettings = createOpenAICompatLaunchSettings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compat-launch-settings.js","sourceRoot":"","sources":["../../src/utils/openai-compat-launch-settings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-compat-launch-settings.js","sourceRoot":"","sources":["../../src/utils/openai-compat-launch-settings.ts"],"names":[],"mappings":";;;AACA,uDAI2B;AAe3B;;;;GAIG;AACH,SAAgB,gCAAgC,CAC9C,YAAoB,EACpB,QAAkB,EAClB,OAA2C;IAE3C,MAAM,cAAc,GAAiC;QACnD,qBAAqB,EAAE,IAAI;QAC3B,SAAS,EAAE,CAAC,mBAAmB,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,UAAU,EAAE,IAAI;KACjB,CAAC;IAEF,MAAM,MAAM,GAAgC,IAAA,6CAA2B,EACrE,YAAY,EACZ,QAAQ,EACR,cAAc,CACf,CAAC;IAEF,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;AACJ,CAAC;AAtBD,4EAsBC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded request-body reader shared by the local CCS proxies.
|
|
3
|
+
*
|
|
4
|
+
* An oversized body must end in an HTTP 413, never a reset socket. A reset
|
|
5
|
+
* reaches Claude Code as a bare ECONNRESET that it retries silently for
|
|
6
|
+
* minutes. So past the limit we stop buffering but keep draining the body,
|
|
7
|
+
* and only give up on the connection once it passes DRAIN_CAP_MULTIPLIER
|
|
8
|
+
* times the limit.
|
|
9
|
+
*/
|
|
10
|
+
/// <reference types="node" />
|
|
11
|
+
/// <reference types="bun-types" />
|
|
12
|
+
/// <reference types="node" />
|
|
13
|
+
import type * as http from 'http';
|
|
14
|
+
import { type Logger } from '../services/logging';
|
|
15
|
+
export declare const MAX_BODY_ENV_VAR = "CCS_PROXY_MAX_BODY_MB";
|
|
16
|
+
/** Matches the Anthropic Messages API request size limit (32 MB). */
|
|
17
|
+
export declare const DEFAULT_MAX_BODY_MB = 32;
|
|
18
|
+
export declare const REQUEST_TOO_LARGE_ERROR_TYPE = "request_too_large";
|
|
19
|
+
export declare class RequestBodyTooLargeError extends Error {
|
|
20
|
+
readonly receivedBytes: number;
|
|
21
|
+
readonly limitBytes: number;
|
|
22
|
+
/** True when the whole body was read, so the connection can stay open. */
|
|
23
|
+
readonly drained: boolean;
|
|
24
|
+
constructor(receivedBytes: number, limitBytes: number, drained: boolean);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the body limit from CCS_PROXY_MAX_BODY_MB (MiB, 0 < n <= 1024).
|
|
28
|
+
* Invalid values fall back to the default and log one warning per value.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveMaxBodyBytes(env?: NodeJS.ProcessEnv): number;
|
|
31
|
+
/**
|
|
32
|
+
* Read the request body as UTF-8. Rejects with RequestBodyTooLargeError when
|
|
33
|
+
* it exceeds `limitBytes`; the socket is never destroyed here.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readRequestBody(req: http.IncomingMessage, limitBytes?: number): Promise<string>;
|
|
36
|
+
/** Log an oversized request at warn level: size, limit and path, never the body. */
|
|
37
|
+
export declare function logRequestTooLarge(log: Logger, req: http.IncomingMessage, error: RequestBodyTooLargeError): void;
|
|
38
|
+
/** Log the oversized request and answer it with an Anthropic-shaped 413. */
|
|
39
|
+
export declare function respondRequestTooLarge(req: http.IncomingMessage, res: http.ServerResponse, error: RequestBodyTooLargeError, log: Logger): void;
|
|
40
|
+
//# sourceMappingURL=request-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-body.d.ts","sourceRoot":"","sources":["../../src/utils/request-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,MAAM,CAAC;AAClC,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEhE,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AACxD,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,4BAA4B,sBAAsB,CAAC;AAchE,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;CAaxE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAoBhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,UAAU,GAAE,MAA8B,GACzC,OAAO,CAAC,MAAM,CAAC,CAsDjB;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,KAAK,EAAE,wBAAwB,GAC9B,IAAI,CAQN;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,KAAK,EAAE,wBAAwB,EAC/B,GAAG,EAAE,MAAM,GACV,IAAI,CAaN"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bounded request-body reader shared by the local CCS proxies.
|
|
4
|
+
*
|
|
5
|
+
* An oversized body must end in an HTTP 413, never a reset socket. A reset
|
|
6
|
+
* reaches Claude Code as a bare ECONNRESET that it retries silently for
|
|
7
|
+
* minutes. So past the limit we stop buffering but keep draining the body,
|
|
8
|
+
* and only give up on the connection once it passes DRAIN_CAP_MULTIPLIER
|
|
9
|
+
* times the limit.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.respondRequestTooLarge = exports.logRequestTooLarge = exports.readRequestBody = exports.resolveMaxBodyBytes = exports.RequestBodyTooLargeError = exports.REQUEST_TOO_LARGE_ERROR_TYPE = exports.DEFAULT_MAX_BODY_MB = exports.MAX_BODY_ENV_VAR = void 0;
|
|
13
|
+
const logging_1 = require("../services/logging");
|
|
14
|
+
exports.MAX_BODY_ENV_VAR = 'CCS_PROXY_MAX_BODY_MB';
|
|
15
|
+
/** Matches the Anthropic Messages API request size limit (32 MB). */
|
|
16
|
+
exports.DEFAULT_MAX_BODY_MB = 32;
|
|
17
|
+
exports.REQUEST_TOO_LARGE_ERROR_TYPE = 'request_too_large';
|
|
18
|
+
const MAX_ALLOWED_BODY_MB = 1024;
|
|
19
|
+
const DRAIN_CAP_MULTIPLIER = 4;
|
|
20
|
+
const BYTES_PER_MB = 1024 * 1024;
|
|
21
|
+
const logger = (0, logging_1.createLogger)('proxy:request-body');
|
|
22
|
+
let lastInvalidLimitValue;
|
|
23
|
+
function formatMb(bytes) {
|
|
24
|
+
const mb = bytes / BYTES_PER_MB;
|
|
25
|
+
return Number.isInteger(mb) ? String(mb) : mb.toFixed(1);
|
|
26
|
+
}
|
|
27
|
+
class RequestBodyTooLargeError extends Error {
|
|
28
|
+
constructor(receivedBytes, limitBytes, drained) {
|
|
29
|
+
const size = drained
|
|
30
|
+
? `Request is ${formatMb(receivedBytes)} MB`
|
|
31
|
+
: `Request is over ${formatMb(receivedBytes)} MB`;
|
|
32
|
+
super(`${size}, over the ${formatMb(limitBytes)} MB limit of the local ccs proxy ` +
|
|
33
|
+
`(${exports.MAX_BODY_ENV_VAR}). Run /compact or start a new session.`);
|
|
34
|
+
this.name = 'RequestBodyTooLargeError';
|
|
35
|
+
this.receivedBytes = receivedBytes;
|
|
36
|
+
this.limitBytes = limitBytes;
|
|
37
|
+
this.drained = drained;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RequestBodyTooLargeError = RequestBodyTooLargeError;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the body limit from CCS_PROXY_MAX_BODY_MB (MiB, 0 < n <= 1024).
|
|
43
|
+
* Invalid values fall back to the default and log one warning per value.
|
|
44
|
+
*/
|
|
45
|
+
function resolveMaxBodyBytes(env = process.env) {
|
|
46
|
+
const defaultBytes = exports.DEFAULT_MAX_BODY_MB * BYTES_PER_MB;
|
|
47
|
+
const raw = env[exports.MAX_BODY_ENV_VAR]?.trim();
|
|
48
|
+
if (!raw)
|
|
49
|
+
return defaultBytes;
|
|
50
|
+
const mb = Number(raw);
|
|
51
|
+
if (Number.isFinite(mb) && mb > 0 && mb <= MAX_ALLOWED_BODY_MB) {
|
|
52
|
+
return Math.floor(mb * BYTES_PER_MB);
|
|
53
|
+
}
|
|
54
|
+
if (lastInvalidLimitValue !== raw) {
|
|
55
|
+
lastInvalidLimitValue = raw;
|
|
56
|
+
logger.warn('request-body.invalid-limit', `Ignoring ${exports.MAX_BODY_ENV_VAR}="${raw}": expected a number of MB above 0 and at most ` +
|
|
57
|
+
`${MAX_ALLOWED_BODY_MB}. Using ${exports.DEFAULT_MAX_BODY_MB} MB.`, { value: raw, defaultMb: exports.DEFAULT_MAX_BODY_MB });
|
|
58
|
+
}
|
|
59
|
+
return defaultBytes;
|
|
60
|
+
}
|
|
61
|
+
exports.resolveMaxBodyBytes = resolveMaxBodyBytes;
|
|
62
|
+
/**
|
|
63
|
+
* Read the request body as UTF-8. Rejects with RequestBodyTooLargeError when
|
|
64
|
+
* it exceeds `limitBytes`; the socket is never destroyed here.
|
|
65
|
+
*/
|
|
66
|
+
function readRequestBody(req, limitBytes = resolveMaxBodyBytes()) {
|
|
67
|
+
const drainCapBytes = limitBytes * DRAIN_CAP_MULTIPLIER;
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
let chunks = [];
|
|
70
|
+
let total = 0;
|
|
71
|
+
const cleanup = () => {
|
|
72
|
+
req.off('data', onData);
|
|
73
|
+
req.off('end', onEnd);
|
|
74
|
+
req.off('error', onError);
|
|
75
|
+
req.off('close', onClose);
|
|
76
|
+
};
|
|
77
|
+
const onData = (chunk) => {
|
|
78
|
+
total += chunk.length;
|
|
79
|
+
if (total <= limitBytes) {
|
|
80
|
+
chunks.push(chunk);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Over the limit: free the buffer and keep draining so we can answer 413.
|
|
84
|
+
chunks = [];
|
|
85
|
+
if (total > drainCapBytes) {
|
|
86
|
+
cleanup();
|
|
87
|
+
// Keep the stream flowing so leftover bytes are discarded, not stalled.
|
|
88
|
+
req.resume();
|
|
89
|
+
reject(new RequestBodyTooLargeError(total, limitBytes, false));
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const onEnd = () => {
|
|
93
|
+
cleanup();
|
|
94
|
+
if (total > limitBytes) {
|
|
95
|
+
reject(new RequestBodyTooLargeError(total, limitBytes, true));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
resolve(Buffer.concat(chunks, total).toString('utf8'));
|
|
99
|
+
};
|
|
100
|
+
const onError = (error) => {
|
|
101
|
+
cleanup();
|
|
102
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
103
|
+
};
|
|
104
|
+
const onClose = () => {
|
|
105
|
+
cleanup();
|
|
106
|
+
reject(new Error('Request closed before the body was fully received'));
|
|
107
|
+
};
|
|
108
|
+
req.on('data', onData);
|
|
109
|
+
req.on('end', onEnd);
|
|
110
|
+
req.on('error', onError);
|
|
111
|
+
req.on('close', onClose);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
exports.readRequestBody = readRequestBody;
|
|
115
|
+
/** Log an oversized request at warn level: size, limit and path, never the body. */
|
|
116
|
+
function logRequestTooLarge(log, req, error) {
|
|
117
|
+
log.warn('request.body-too-large', error.message, {
|
|
118
|
+
method: req.method,
|
|
119
|
+
path: req.url,
|
|
120
|
+
receivedBytes: error.receivedBytes,
|
|
121
|
+
limitBytes: error.limitBytes,
|
|
122
|
+
drained: error.drained,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
exports.logRequestTooLarge = logRequestTooLarge;
|
|
126
|
+
/** Log the oversized request and answer it with an Anthropic-shaped 413. */
|
|
127
|
+
function respondRequestTooLarge(req, res, error, log) {
|
|
128
|
+
logRequestTooLarge(log, req, error);
|
|
129
|
+
if (res.headersSent || res.writableEnded || res.destroyed)
|
|
130
|
+
return;
|
|
131
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
132
|
+
// The rest of the body is still on the wire; ask the client to drop the connection.
|
|
133
|
+
if (!error.drained)
|
|
134
|
+
headers.Connection = 'close';
|
|
135
|
+
res.writeHead(413, headers);
|
|
136
|
+
res.end(JSON.stringify({
|
|
137
|
+
type: 'error',
|
|
138
|
+
error: { type: exports.REQUEST_TOO_LARGE_ERROR_TYPE, message: error.message },
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
exports.respondRequestTooLarge = respondRequestTooLarge;
|
|
142
|
+
//# sourceMappingURL=request-body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-body.js","sourceRoot":"","sources":["../../src/utils/request-body.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-server/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;;AAGH,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-server/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;;AAGH,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAerC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,GAAG,EAAE,eAAe,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAQD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAmLjF"}
|
package/dist/web-server/index.js
CHANGED
|
@@ -45,6 +45,7 @@ const sync_1 = require("../cliproxy/sync");
|
|
|
45
45
|
const aggregator_1 = require("./usage/aggregator");
|
|
46
46
|
const logging_1 = require("../services/logging");
|
|
47
47
|
const config_dashboard_host_1 = require("../commands/config-dashboard-host");
|
|
48
|
+
const claude_pool_policy_1 = require("../cliproxy/accounts/claude-pool-policy");
|
|
48
49
|
function getListenHost(options) {
|
|
49
50
|
return options.host || config_dashboard_host_1.DEFAULT_DASHBOARD_HOST;
|
|
50
51
|
}
|
|
@@ -144,11 +145,13 @@ async function startServer(options) {
|
|
|
144
145
|
const { cleanup: wsCleanup } = (0, websocket_1.setupWebSocket)(wss);
|
|
145
146
|
// Start auto-sync watcher (if enabled in config)
|
|
146
147
|
(0, sync_1.startAutoSyncWatcher)();
|
|
148
|
+
const stopClaudePoolPolicy = (0, claude_pool_policy_1.startClaudePoolPolicyController)();
|
|
147
149
|
// Combined cleanup function
|
|
148
|
-
const cleanup = () => {
|
|
150
|
+
const cleanup = async () => {
|
|
149
151
|
wsCleanup();
|
|
150
152
|
(0, sync_1.stopAutoSyncWatcher)().catch(() => { });
|
|
151
153
|
(0, aggregator_1.shutdownUsageAggregator)();
|
|
154
|
+
await stopClaudePoolPolicy();
|
|
152
155
|
};
|
|
153
156
|
// Start listening
|
|
154
157
|
return new Promise((resolve, reject) => {
|