Commit Graph
202 Commits
Author SHA1 Message Date
Tam Nhu Tran 7d3a11a452 fix(bar): resolve pre-dev review findings (security gate, honesty, correctness)
Gate /api/bar/* behind the localhost-when-auth-disabled guard (single DRY
choke point) so native quota/tier/cost can't leak on a non-loopback bind with
auth disabled; add a guard test. Delete the dishonest maxRedirections test that
asserted the opposite of the production redirect hardening. Key per-account
today-cost on the local day (matching analytics) instead of UTC. Stop the
inner 429 retry in the Claude usage fetch so the outer cache + circuit breaker
honor Retry-After. Narrow the usage-transformer map type and fix stale
doc-comments; clarify the one-alert-per-reset-window quota rule; gitignore the
local demo scaffolding.
2026-06-09 18:04:31 -04:00
Tam Nhu Tran e96967c224 feat(bar): per-window subscription quota detail + codex multi-session scan
Expose per-window detail (5h / weekly / Opus / Sonnet) on native subscription
rows instead of collapsing to a single percentage, so the bar can show the
binding window, resets, and a burn-rate pace line. Fix the Codex collector to
scan recent session rollouts newest-first for the latest non-null rate_limits
(today's exec-mode session is null) and mark the result stale with its source
time, so Codex quota appears instead of silently vanishing.
2026-06-09 14:39:41 -04:00
Tam Nhu Tran dbeb0c543a feat(bar): native Claude Code + Codex subscription quota (safe, server-side)
Surface the logged-in Claude Code and Codex subscription quota as first-class
summary rows so the existing gauge and alert engine render them with no new UI.

Claude Code: read the native token (~/.claude/.credentials.json, macOS Keychain
fallback) and reuse the existing Anthropic usage fetch+normalize via a new
token-fed entry point. The /oauth/usage endpoint is hostile to polling, so the
fetch is server-side only behind a 10-minute on-demand cache, in-flight
coalescing, Retry-After + exponential backoff with jitter, a 3-strike circuit
breaker with a 15-minute cooldown, and serve-stale-on-failure; logged-out or
unsupported subscriptions never spend a token call. Codex: zero-network read of
the latest rate_limits from local session rollouts, omitted when absent.
Native rows side-load bounded so a slow or failed fetch degrades to CLIProxy
rows, never an error.
2026-06-09 13:37:38 -04:00
Tam Nhu Tran 68f0231f48 feat(bar): add calendar month-to-date spend to analytics
monthToDate (calendar 1st-of-month to now, local) on BarAnalytics in both
compute paths, kept distinct from the rolling last30d so a fresh month resets
toward zero. Feeds the monthly-spend alert and the month-spend glance without
a rolling-window false breach.
2026-06-09 13:03:25 -04:00
Tam Nhu Tran 5f850c4899 feat(bar): honest quota state and merged multi-source analytics
Derive a tri-state quotaStatus (ok|unsupported|error) per account so a
provider with no quota API renders as 'no quota' with a healthy dot instead
of an alarming bare dash, and treat unsupported as healthy in deriveHealth.

Switch the analytics endpoint off the CLIProxy snapshot, which freezes
whenever the proxy restarts (usage is in-memory only), and onto the merged
daily/hourly usage the dashboard uses. Recent activity from Claude Code,
Codex, and Droid now shows, and a per-surface breakdown answers where usage
goes. Add lastActivityAt, daysSinceLastActivity, hasRecentData and a 30-day
series; per-account today_cost reads null (unknown) rather than a misleading 0.
2026-06-09 11:49:36 -04:00
Tam Nhu Tran 78f9fc7c0b feat(bar): harden summary against provider hangs and add analytics endpoint
Summary aggregator could block indefinitely: it ran the full system health
audit (a synchronous execSync) on every request and had no per-account or
request-level timeout. Now:
- per-account fetch is bounded; whole response is raced against a deadline
- health is derived per-account from each quota result (no blocking audit)
- stale-while-revalidate keeps the last value when a refresh is slow/fails

Adds GET /api/bar/analytics plus a pure, tested aggregator rolling up
today/7d/30d/all-time spend, a 7-day sparkline, and top models.
2026-06-08 09:31:18 -04:00
Tam Nhu Tran b9a1084bd4 fix(quota): reject tier-lock for non-managed providers
Only managed-quota providers (agy/claude/codex/gemini/ghcp) enforce tier_lock;
validate the provider against that set so locking a non-managed provider returns
400 instead of persisting a silently-unenforced config entry.
2026-06-07 16:38:18 -04:00
Tam Nhu Tran cc7ac553e3 fix(usage): correct per-account cost attribution
Drop the detail.source fallback and dead numeric-key lookup in the usage
transformer so unmapped auth_index rows go to the 'unknown' bucket instead of
mis-keying cost; null out today_cost when an email cost-key is shared by more
than one account (duplicate-email providers) instead of double-displaying the
combined spend.
2026-06-07 16:37:59 -04:00
Tam Nhu Tran 40f32ebbf0 feat(quota): add per-provider tier-lock account selection
Make tier_lock a per-provider map and honor it in findHealthyAccount and
preflightCheck for the selected provider only, so locking one provider never
disables failover for others. Add POST /api/accounts/tier-lock with tier
validation against known tiers, and serialize quota_management on config write
so the lock persists.
2026-06-07 15:32:40 -04:00
Tam Nhu Tran 6d3fde9ed3 feat(web-server): add /api/bar/summary aggregator with force-fresh
Single endpoint merging per-account quota, tier, paused, health and today cost
for the menu bar. Cached by default; ?refresh=true invalidates the quota cache
and pulls live server-side, debounced ~15s. Per-account errors degrade one row
without failing the payload; force-fresh skips paused accounts and caps fetch
concurrency.
2026-06-07 15:32:29 -04:00
Tam Nhu Tran 1867116472 feat(usage): attribute CLIProxy usage to accounts for per-account cost
Carry the CLIProxy auth_index through the usage transformer and aggregator,
build an auth_index->account map from the auth files, and wire it into the
usage syncer so persisted snapshots stamp accountId. Adds getTodayCostByAccount
and a snapshot detail reader. Backward-compatible: accountId is optional and
profile-based aggregation is unchanged.
2026-06-07 15:32:19 -04:00
Tam Nhu Tran ced9317565 Merge remote-tracking branch 'origin/dev' into codex/fix-cliproxy-v3-snapshot-migration-issue
# Conflicts:
#	src/web-server/usage/cliproxy-usage-transformer.ts
#	tests/unit/web-server/cliproxy-usage-transformer.test.ts
2026-05-30 16:13:49 -04:00
Kai (Tam Nhu) TranandGitHub e7db1d65f5 Merge pull request #1452 from kaitranntt/codex/propose-fix-for-codex-target-rejection
Mark Codex as a persisted target and align UI/validation
2026-05-30 16:12:03 -04:00
Kai (Tam Nhu) TranandGitHub d028329d2c Merge pull request #1426 from kaitranntt/codex/fix-cliproxy-usage-cache-vulnerability
fix(cliproxy): avoid persisting account identifiers and harden usage cache permissions
2026-05-30 16:08:26 -04:00
Kai (Tam Nhu) TranandGitHub ee50c0c59a Merge pull request #1422 from kaitranntt/codex/fix-codex-usage-cache-permissions
fix: restrict Codex usage cache permissions
2026-05-30 16:01:00 -04:00
Kai (Tam Nhu) TranandGitHub 484f0a0427 Merge pull request #1427 from kaitranntt/codex/propose-fix-for-local-runtime-probe-vulnerability
fix: restrict local runtime readiness probes
2026-05-30 15:51:43 -04:00
Kai (Tam Nhu) TranandGitHub 5151d6d24e Merge pull request #1433 from kaitranntt/codex/fix-issue-with-profile-query-handling
fix: validate usage profile query type
2026-05-30 15:46:47 -04:00
Kai (Tam Nhu) TranandGitHub f815db391d Merge pull request #1308 from simonsmh/feat/add-qoder-provider
feat(cliproxy): Qoder provider
2026-05-30 15:35:55 -04:00
Kai (Tam Nhu) TranandTam Nhu Tran 901bad2ec7 fix: validate usage profile query type 2026-05-30 15:20:15 -04:00
Kai (Tam Nhu) TranandTam Nhu Tran 9a7b26eab7 fix: restrict local runtime readiness probes 2026-05-30 15:19:38 -04:00
Kai (Tam Nhu) TranandTam Nhu Tran 6bba193cdd fix: harden cliproxy usage cache 2026-05-30 15:18:11 -04:00
Kai (Tam Nhu) TranandTam Nhu Tran c630ce878e fix: restrict Codex usage cache permissions 2026-05-30 15:17:13 -04:00
Kai (Tam Nhu) Tran 04dc97aaa4 fix: persist codex target selections 2026-05-30 14:57:07 -04:00
Kai (Tam Nhu) Tran 65adab5bec fix: normalize cliproxy v3 usage snapshots 2026-05-30 14:56:18 -04:00
Kai (Tam Nhu) TranandGitHub 5f1976f69c fix: add CLIProxy account reauthentication 2026-05-27 10:13:03 -04:00
Kai (Tam Nhu) TranandGitHub b35a23a6e4 fix: reject unsupported image analysis backends (#1387)
* fix: reject unsupported image analysis backends

* style: apply prettier formatting
2026-05-23 22:37:44 -04:00
Kai (Tam Nhu) TranandGitHub 0db9705d75 fix(claude-extension): enforce private permissions for settings writes (#1378) 2026-05-23 21:45:07 -04:00
Kai (Tam Nhu) TranandGitHub e6f764c79b fix(cursor): block cross-origin runtime probe requests (#1371) 2026-05-23 21:44:50 -04:00
Kai (Tam Nhu) TranandGitHub 9a420988bc fix(analytics): support sqlite3 path resolution on Windows and NixOS (#1354)
- Add CCS_SQLITE_BIN env-var override; validated with fs.realpathSync so
  symlinks are fully resolved before prefix check
- Reject any override whose realpath does not start under a trusted system
  prefix (prevents PATH-hijack reintroduction from #1347)
- Add TRUSTED_PREFIX_UNIX covering /nix/store/, /opt/local/ (MacPorts),
  /snap/, /run/current-system/ in addition to existing /usr/* and
  /opt/homebrew/ entries
- Add TRUSTED_PREFIX_WINDOWS covering Program Files, System32, and the
  Chocolatey managed bin dir (no canonical winget/Scoop path exists)
- Keep TRUSTED_SQLITE_PATHS_WINDOWS empty — Windows users set CCS_SQLITE_BIN
- Pass env as optional third param to querySqliteJson (backward compatible)
- Add 16-test suite covering env-var acceptance, /tmp rejection, symlink
  traversal, NixOS paths, MacPorts, Windows fallback, and prefix safety
2026-05-23 17:29:52 -04:00
Tam Nhu Tran fc5851e3a2 fix: ensure dashboard cliproxy restart waits for recovery 2026-05-22 13:37:21 -04:00
Kai (Tam Nhu) TranandGitHub fa17ad5af1 Merge pull request #1318 from kaitranntt/kai/feat/1255-analytics-profile-filter
feat: filter analytics dashboard by profile
2026-05-22 12:38:50 -04:00
Tam Nhu Tran f1d655e425 feat: filter analytics by profile 2026-05-22 11:24:21 -04:00
Tam Nhu Tran e2f2c7dc2e fix: redact Codex diagnostics metadata 2026-05-22 11:12:20 -04:00
Simon Shi 43c830469a feat(cliproxy): add Qoder as a CLIProxy provider channel
Add Qoder AI coding assistant as a supported CLIProxy provider:
- Device code OAuth flow with --qoder-login flag
- Plus-only backend (CLIProxyAPIPlus required)
- No built-in token refresh (unsupported, like Kilo)
- Auth URL: https://qoder.com/device/selectAccounts
- Auth file prefix: qoder-
- Token type: qoder
2026-05-21 01:35:08 +09:00
Kai (Tam Nhu) TranandGitHub 3b2016462a fix(persist): block codex claude settings bridge 2026-05-19 07:32:04 -04:00
Kai (Tam Nhu) TranandGitHub db175b6807 fix(security): require localhost for Claude extension /setup when dashboard auth is disabled (#1270)
* fix(security): restrict Claude extension setup endpoint

* style: apply prettier formatting
2026-05-16 13:58:57 -04:00
Kai (Tam Nhu) TranandGitHub 14cbe8fb67 fix(security): reject 127-prefixed websocket origins (#1263)
* fix(security): reject 127-prefixed websocket origins

* style: apply prettier formatting
2026-05-16 13:56:10 -04:00
Kai (Tam Nhu) TranandGitHub 349db830df fix(settings): confine dashboard settings paths (#1231) 2026-05-12 18:13:26 -04:00
Kai (Tam Nhu) TranandGitHub d61469edcb fix(config): bind dashboard to loopback by default 2026-05-12 10:59:49 -04:00
Kai (Tam Nhu) TranandGitHub f09cdfcf2b fix(security): protect dashboard WebSocket upgrades 2026-05-12 10:42:05 -04:00
Kai (Tam Nhu) TranandGitHub bd588a271d fix(codex): require local access for dashboard config routes 2026-05-12 10:24:25 -04:00
Kai (Tam Nhu) TranandGitHub 29da75c0d4 fix(cliproxy): explain headless Codex OAuth recovery
Closes #1213
2026-05-11 14:25:34 -04:00
Tam Nhu Tran a983332016 refactor(web-server): modularize shared-routes and Windows-aware symlink status 2026-05-10 22:15:33 -04:00
Tam Nhu Tran 8b34060294 fix(dashboard): show real shared plugin registry state 2026-05-09 03:18:20 -04:00
Tam Nhu Tran 2a422b3bd3 feat(dashboard): add shared resource controls 2026-05-09 02:29:08 -04:00
Tam Nhu Tran 64e1d1f815 feat(auth): add shared resource controls 2026-05-08 11:15:28 -04:00
Kai (Tam Nhu) TranandGitHub 8b681df455 fix: route Cursor auth through browser polling
Closes #1194
2026-05-07 11:25:17 -04:00
Tam Nhu Tran 3862411bb7 fix(cliproxy): harden custom local port handling 2026-05-03 14:07:31 -04:00
walker1211andGitHub 11b12f146d fix(analytics): cache native Codex usage scans
Cache parsed native Codex rollout usage entries per file fingerprint to avoid repeated full-history JSONL parsing on dashboard refreshes.

Add regression coverage for cache reuse, invalid cache fallback, cliproxy cache separation, and scoped cache fixtures.
2026-05-02 21:16:07 -04:00
Tam Nhu Tran 31dc18657c fix(cliproxy): fix base-config-loader __dirname path and stale mock.module paths
- base-config-loader.ts moved from src/cliproxy/ to src/cliproxy/config/,
  so __dirname relative path needs one more .. to reach config/ dir
- Update mock.module paths for proxy-detector and routing-strategy
  in non-colocated test files
2026-04-29 17:40:33 -04:00