Address UX review: the bare login (e.g. ~/.codex) is the default way of running a
surface, not a profile. Rename it from 'personal' to 'default' and present it as
the base command ('ccsx') with a 'default' badge, while named profiles show their
name ('ck') plus the owning surface tag ('ccsx'). Order each provider carousel so
the default account leads, then by tightest quota window.
Group native subscription rows by provider and render each provider as its own
horizontally paged carousel of profile cards (one profile per page, swipe
between a provider's profiles, page dots indicate count). Add a surface tag
chip (ccs/ccsx) and dim parked profiles. Switch the native-vs-pool split to the
is_subscription flag so pool codex accounts are not misclassified. Raise the
deployment target to macOS 14 for the native scroll paging APIs and bump the
Bar version to 1.9.0.
Replace single-account native quota collection with per-profile enumeration:
read ccs auth (Claude) and ccsx auth (Codex) profile registries plus the bare
~/.codex login, fetch each profile's quota under the existing TTL cache,
per-profile circuit breaker and 2.5s summary deadline. Emit surface, profile
and is_subscription wire fields; account_id becomes "<surface>:<profile>".
Active profiles (valid token) are live-polled and shown undimmed regardless of
default status; profiles without resolvable on-disk credentials are parked
(cache-only, dimmed). Claude per-profile credentials are read from disk only --
no macOS Keychain access -- so a profile without a credentials file renders as
needs-reauth instead of triggering a keychain prompt.
Use a private safe ccs.js shim for native CCS Bar launch descriptors so symlinked Bun installs do not fall back to an app environment without node on PATH.
Adds a lightweight self-update path to the CCS Bar menu-bar app so users are
told when a newer build is available and can update with one click.
- App: BarUpdateChecker fetches the published version.txt and compares it to
the running bundle version (numeric semver). A throttled background check
(post-launch, then every 6h) surfaces an "Update available" row in the menu;
"Update Now" spawns `ccs bar install --launch --await-quit` then quits so the
installer can swap the locked bundle and relaunch. A Settings toggle gates
the auto-check (default on). Offline checks degrade silently.
- CLI: `ccs bar install --await-quit` waits for a running CCS Bar to quit
(300ms poll, 15s cap) before swapping, enabling the one-click relaunch.
- Release: bar-release publishes a machine-readable version.txt asset beside
the app zip so the check is cheap (no full download just to compare).
- Shares the ccs-binary resolver between DashboardLauncher and the updater.
- Bumps bar VERSION to 1.8.0; adds isNewer assertions to ccs-bar-check.
Closes#1588
Routing every non-flag token after 'copilot'/'legacy-cursor' to the subcommand
handler turned the legacy profile/prompt passthrough into an 'Unknown subcommand'
error. Route only known subcommands (matching prior behavior); other args pass
through to the copilot/cursor bridge flow. Bar keeps its unknown-subcommand exit
code (it has no passthrough).
The earlier help-gating overcorrected: scoping global help to 'no real
subcommand' meant 'cliproxy status --help' (and list/quota) ran the command and
ignored --help. Restore global help on --help/-h anywhere (order-insensitive),
carving out only 'routing affinity --help', which renders its own help.
Top-level cliproxy help was order-sensitive: 'cliproxy --verbose --help' fell
through to dispatch instead of showing help. Fire global help whenever there is
no real subcommand (no args or a leading flag) and --help/-h appears anywhere;
real subcommands still handle their own --help.
The auth commands barrel re-exported 4 interface-only symbols (AuthCommandArgs,
ProfileOutput, ListOutput, CommandContext) via a value 'export {}', which bun's
per-file transpile cannot resolve at runtime (the tsc dist elides them, so users
were unaffected). Split them into 'export type {}' so 'bun run dev' / source runs
work.
'ccs tokens --variant <x>' without --api-key was a silent no-op; now it explains
that --variant only applies with --api-key. Add the existing 'serve' subcommand
to the bar help Commands list.
handleProxyStatus now respects --verbose (was parsed but ignored). Document the
existing --provider option on default/pause/resume and the 'diag' alias for
doctor in the cliproxy help text.
The guard fires on the backup READ step; use a typed ConfigError whose message
matches the actual step (refusing to read), not a misleading 'refusing to write'.
Only log 'Binary not found, downloading...' when a download will actually happen
(after the allowInstall guard). Stop double-prefixing pool enable/disable
messages that already carry [OK]/[!]. Route 'cliproxy routing affinity --help'
to affinity help instead of the generic cliproxy help.
loadUnifiedConfig() printed the YAML error on every call (3-4x per run); print it
once per path per process. Run each doctor check group defensively so a thrown
check (corrupt config, EACCES auth dir) records an error and the SUMMARY/ERRORS
sections with recovery hints still render instead of crashing mid-run. Trim
embedded parser snippets to one line so they no longer leak into the summary
table or repeat across checks.
Pre-dispatch only routed known subcommand tokens, so unknown bar/copilot/cursor
subcommands never reached their handlers (no error, no non-zero exit). Route them
through. Also wrap autoMigrate() so a corrupt config.yaml no longer crashes
startup, and print only the first line of a best-effort recovery failure.
Move resolveProfileAndTarget() inside the try block in ccs.ts so a missing
profile shows suggestions/available-profiles instead of a generic error. Use a
typed ProfileError for proxy start on an unknown profile (drops the irrelevant
install hint). api create: honor --yes for the OpenRouter model browser, show
ccs-codex/ccsx aliases for --target codex, and allow ANTHROPIC_EXTRA_MODELS on
import.
exitWithError() already prints '[X] <msg>', so the preceding console.log(fail())
calls double-printed every auth error. Remove the redundant logs and fold richer
hints (e.g. --force) into the single exitWithError message. Also make
'auth default' accept a profile registered only in legacy profiles.json under
unified mode.