mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 16:17:02 +00:00
fix(cliproxy): harden account pools per pre-merge usefulness review
- pool --enable/--disable: refuse remote targets with manual config guidance; resolve the lifecycle port instead of assuming 8317 - enablePoolRouting: roll back the pool flag when config regeneration fails; already-enabled path re-runs regeneration (repairable state) - pool opt-in prompt: gate on hasUnifiedConfig (legacy installs skip); never auto-accept consent under --yes/CCS_YES - order show (file mode): render selector pick order incl. residual on-disk priorities and surface drift instead of alphabetical order - order --reset: clear residual priority fields via management-API PATCH when proxy runs, atomic direct write when stopped - quota pool section: classify in-proxy 429 cooldowns as cooling with reset times (graceful degradation when proxy or endpoint is absent); honest paused label plus resume hint - routing state: remote targets report pool as not manageable instead of echoing the local flag; strategy/affinity apply warns when pool routing overrides the change (CLI, API message, and dashboard) - claude model-neutral: --config explicit pins survive the stale-pin migration; remote env path filters historical default pins read from claude.settings.json without mutating the file - cross-lane guard: also checks account-profile CLAUDE_CONFIG_DIR lanes for email overlap, not only the ambient ~/.claude login - onboarding hint: opt-in copy naming ccs cliproxy pool --enable - dashboard card: pool-ON shows drain-order pointer, pool-OFF shows the enable command, local-only note for remote proxies (i18n x5)
This commit is contained in:
1 parent
2b7cfa32c8
commit
1c90388b5d
25 files changed
+2489
-125
No files matched your search
@@ -48,6 +48,12 @@ export function RoutingGuidanceCard({
|
||||
const currentStrategy = state?.strategy ?? 'round-robin';
|
||||
const poolEnabled = state?.poolRouting?.enabled ?? false;
|
||||
const poolMaxRetry = state?.poolRouting?.maxRetryCredentials;
|
||||
// Undefined manageable means local (managed); only false signals a remote
|
||||
// proxy where the local pool flag may not reflect the running proxy.
|
||||
const poolManageable = state?.poolRouting?.manageable ?? true;
|
||||
const poolLocalOnly = !poolManageable;
|
||||
const poolLocalOnlyMessage =
|
||||
state?.poolRouting?.message ?? t('routingGuidance.poolRoutingLocalOnly');
|
||||
const currentAffinityEnabled = sessionAffinityState?.enabled ?? false;
|
||||
const currentAffinityTtl = sessionAffinityState?.ttl ?? '1h';
|
||||
const sessionAffinityManageable = sessionAffinityState?.manageable ?? true;
|
||||
@@ -174,26 +180,45 @@ export function RoutingGuidanceCard({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{poolEnabled && poolManageable ? (
|
||||
<div
|
||||
role="status"
|
||||
className="rounded-lg border border-amber-500/40 bg-amber-500/10 px-2 py-1.5 text-[10px] leading-4 text-amber-700 dark:text-amber-300"
|
||||
>
|
||||
{t('routingGuidance.poolRoutingApplyWarning')}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="flex items-center justify-between gap-2 rounded-lg border border-border/60 bg-muted/20 px-2 py-1.5">
|
||||
<div className="min-w-0">
|
||||
<div className="text-[10px] font-medium text-foreground">
|
||||
{t('routingGuidance.poolRouting')}
|
||||
</div>
|
||||
<div className="text-[10px] text-muted-foreground">
|
||||
{poolEnabled && poolMaxRetry !== undefined
|
||||
? t('routingGuidance.poolMaxRetry', { count: poolMaxRetry })
|
||||
: t('routingGuidance.drainOrderHint')}
|
||||
{poolLocalOnly
|
||||
? poolLocalOnlyMessage
|
||||
: poolEnabled
|
||||
? t('routingGuidance.drainOrderHint')
|
||||
: t('routingGuidance.poolRoutingOffHint')}
|
||||
</div>
|
||||
</div>
|
||||
<Badge
|
||||
variant={poolEnabled ? 'secondary' : 'outline'}
|
||||
variant={poolLocalOnly ? 'outline' : poolEnabled ? 'secondary' : 'outline'}
|
||||
title={
|
||||
poolEnabled
|
||||
? t('routingGuidance.poolRoutingManaged')
|
||||
: t('routingGuidance.poolRoutingOffHint')
|
||||
poolLocalOnly
|
||||
? poolLocalOnlyMessage
|
||||
: poolEnabled
|
||||
? t('routingGuidance.poolRoutingManaged')
|
||||
: t('routingGuidance.poolRoutingOffHint')
|
||||
}
|
||||
>
|
||||
{poolEnabled ? t('routingGuidance.poolRoutingOn') : t('routingGuidance.poolRoutingOff')}
|
||||
{poolLocalOnly
|
||||
? t('routingGuidance.localOnly')
|
||||
: poolEnabled
|
||||
? `${t('routingGuidance.poolRoutingOn')} · ${t('routingGuidance.poolMaxRetry', {
|
||||
count: poolMaxRetry ?? 0,
|
||||
})}`
|
||||
: t('routingGuidance.poolRoutingOff')}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -267,18 +292,22 @@ export function RoutingGuidanceCard({
|
||||
{state ? <Badge variant="outline">{state.target}</Badge> : null}
|
||||
{state ? (
|
||||
<Badge
|
||||
variant={poolEnabled ? 'secondary' : 'outline'}
|
||||
variant={poolLocalOnly ? 'outline' : poolEnabled ? 'secondary' : 'outline'}
|
||||
title={
|
||||
poolEnabled
|
||||
? t('routingGuidance.poolRoutingManaged')
|
||||
: t('routingGuidance.poolRoutingOffHint')
|
||||
poolLocalOnly
|
||||
? poolLocalOnlyMessage
|
||||
: poolEnabled
|
||||
? t('routingGuidance.poolRoutingManaged')
|
||||
: t('routingGuidance.poolRoutingOffHint')
|
||||
}
|
||||
>
|
||||
{t('routingGuidance.poolRouting')}:{' '}
|
||||
{poolEnabled
|
||||
? t('routingGuidance.poolRoutingOn')
|
||||
: t('routingGuidance.poolRoutingOff')}
|
||||
{poolEnabled && poolMaxRetry !== undefined
|
||||
{poolLocalOnly
|
||||
? t('routingGuidance.localOnly')
|
||||
: poolEnabled
|
||||
? t('routingGuidance.poolRoutingOn')
|
||||
: t('routingGuidance.poolRoutingOff')}
|
||||
{!poolLocalOnly && poolEnabled && poolMaxRetry !== undefined
|
||||
? ` · ${t('routingGuidance.poolMaxRetry', { count: poolMaxRetry })}`
|
||||
: ''}
|
||||
</Badge>
|
||||
@@ -339,6 +368,14 @@ export function RoutingGuidanceCard({
|
||||
{isSaving ? 'Saving...' : `Use ${selected}`}
|
||||
</Button>
|
||||
</div>
|
||||
{poolEnabled && poolManageable ? (
|
||||
<p
|
||||
role="status"
|
||||
className="max-w-xs text-[11px] leading-4 text-amber-700 dark:text-amber-400 xl:text-right"
|
||||
>
|
||||
{t('routingGuidance.poolRoutingApplyWarning')}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-muted-foreground xl:col-span-2">
|
||||
|
||||
Reference in new issue
Block a user