Skip to content

fix(config): preserve raw config.yaml fields when saving dashboard changes#165

Merged
itsmylife44 merged 2 commits intoitsmylife44:mainfrom
smart-tinker:fix/config-yaml-roundtrip
Apr 6, 2026
Merged

fix(config): preserve raw config.yaml fields when saving dashboard changes#165
itsmylife44 merged 2 commits intoitsmylife44:mainfrom
smart-tinker:fix/config-yaml-roundtrip

Conversation

@smart-tinker
Copy link
Copy Markdown
Contributor

@smart-tinker smart-tinker commented Apr 5, 2026

Summary

This fixes a config save regression where the dashboard could silently drop valid
fields from config.yaml while saving unrelated settings.

The core issue was that the dashboard used the reduced management /config JSON
response as the merge base for rewriting config.yaml. That response is not a
lossless representation of the YAML file, so fields that exist in YAML but are not
serialized in /config could disappear on save.

Problem

A save from /dashboard/config could remove untouched fields from config.yaml.

One concrete example is host / port. If those values disappear, OAuth flows that
rely on callback forwarding can stop working because the callback target can no
longer be resolved correctly.

Root Cause

The previous flow was:

  1. Read /api/management/config
  2. Merge dashboard changes into that JSON object
  3. Serialize the result back to /api/management/config.yaml

That approach assumes /config is a round-trippable representation of the YAML
configuration, which is not true.

What This Changes

The save flow now:

  1. Fetches the current raw config.yaml
  2. Parses the YAML
  3. Applies only the changed dashboard-managed fields
  4. Writes the merged YAML back

This preserves untouched YAML-only fields such as host and port.

As a small follow-up improvement, invalid YAML now surfaces as a specific parse error
instead of showing a generic network failure.

Before / After

Before:

  • saving an unrelated field could remove YAML-only config fields
  • invalid YAML during save showed up as a vague network error

After:

  • unchanged YAML fields are preserved
  • invalid YAML produces a specific and actionable error message

How To Test

  1. Start with a config.yaml that contains fields not present in /config, for example host and port
  2. Open /dashboard/config
  3. Change an unrelated YAML-backed setting and save
  4. Inspect config.yaml

Expected result:

  • untouched fields such as host and port remain present
  • the changed field is updated

Optional validation:

  • make the YAML invalid and save again
  • confirm the UI reports a parse error instead of a generic network failure

Verification

  • added focused tests for the raw YAML merge helper
  • verified the helper preserves untouched YAML-only fields
  • verified the dashboard save path works with the raw-YAML merge approach
  • verified invalid YAML now produces a specific error message

Targeted test run:

  • npm test -- config-yaml.test.ts

Scope

This PR intentionally does not change deployment manifests or local environment
setup. It only fixes dashboard save behavior.

Notes

Broader repository validation is currently blocked by pre-existing issues on main
unrelated to this change set:

  • npm run lint crashes inside the repo's ESLint/Next.js stack before linting completes
  • npx tsc --noEmit reports existing type errors outside this PR
  • npm run build is currently blocked by existing generated Prisma client/module issues

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression in the dashboard config save flow where rewriting config.yaml from the reduced /config JSON response could silently drop YAML-only fields (e.g., host/port). The new flow fetches and parses the current config.yaml, applies only dashboard-managed changes, and writes back merged YAML; it also surfaces YAML parse failures as actionable errors.

Changes:

  • Added a config.yaml parse/merge helper (parseConfigYaml / mergeConfigYaml) based on js-yaml.
  • Updated /dashboard/config save logic to use the raw config.yaml as the merge base (instead of /config JSON).
  • Added focused unit tests for the YAML merge helper.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
dashboard/src/lib/config-yaml.ts Introduces YAML parse + merge utilities used to preserve YAML-only fields during dashboard saves.
dashboard/src/lib/tests/config-yaml.test.ts Adds tests validating that the merge preserves omitted YAML fields and works from an empty file.
dashboard/src/app/dashboard/config/page.tsx Switches YAML save flow to fetch/merge raw config.yaml and improves surfaced error messages.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dashboard/src/lib/config-yaml.ts Outdated
Comment on lines +17 to +22
return {};
}

return parsed;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseConfigYaml returns {} when the YAML parses successfully but the root value is not a mapping (e.g., a list, scalar, or null). On save, this would treat an existing non-empty config.yaml as empty and can silently overwrite it, losing data. Consider throwing a parse/shape error when rawYaml is non-empty and the root is not an object (with an actionable message like “expected a mapping at the document root”).

Suggested change
return {};
}
return parsed;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error("Invalid current config.yaml: expected a mapping at the document root");
}
return parsed;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (message.startsWith("Invalid current config.yaml:")) {
throw new Error(message);
}

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +28
expect(merged).toContain("host: ''");
expect(merged).toContain("port: 8317");
expect(merged).toContain("auth-dir: ~/.cli-proxy-api");
expect(merged).toContain("debug: true");
expect(merged).toContain("enable: true");
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions depend on the exact YAML string formatting produced by js-yaml (quotes, ordering, spacing), which can change across versions/options and make the test flaky. A more robust approach is to parse merged back with js-yaml and assert on the resulting object shape/values (including that omitted fields are still present).

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +6
describe("mergeConfigYaml", () => {
it("preserves fields omitted from /config JSON such as host and port", () => {
const rawYaml = [
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description mentions surfacing invalid YAML as a specific parse error, but the test suite doesn’t currently cover the invalid-YAML path (e.g., mergeConfigYaml throwing with the expected message prefix). Adding a focused test for malformed YAML would prevent regressions in that UX improvement.

Copilot uses AI. Check for mistakes.
- parseConfigYaml: throw on non-object YAML root instead of silently
  returning {} (prevents data loss when config.yaml has unexpected
  structure)
- executeSave: only reset dirty state when all saves succeed so the
  form stays dirty on partial failures and the user can retry
- auth-dir guard: use key-presence check instead of truthiness to
  avoid overwriting intentional empty-string values
- config-yaml tests: expand from 2 to 13 covering invalid YAML,
  non-object root, array replacement, null handling, new-key addition
Copy link
Copy Markdown
Owner

@itsmylife44 itsmylife44 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — PR #165: config.yaml roundtrip fix

Overview

The core approach is sound — fetching raw YAML, parsing, merging only changed fields, and writing back preserves untouched fields that the /config JSON endpoint doesn't serialize. Good fix for a real data-loss regression.


🔴 BLOCKER (1)

1. parseConfigYaml() silently returns {} for non-object YAML roots — data loss risk

config-yaml.ts:15-18 — If config.yaml contains valid YAML but the root is not a mapping (e.g. a YAML array [] or scalar "oops"), parseConfigYaml silently returns {}. Then mergeConfigYaml writes back only the changed fields, effectively destroying the entire original config.

For a PR whose purpose is "preserve untouched YAML fields," this is still a silent data-loss path.

Fix: Throw an error instead of returning {}:

if (!isPlainObject(parsed)) {
  throw new Error("Invalid current config.yaml: root value is not a YAML mapping");
}

Also: move the isPlainObject check outside the try/catch to avoid double-wrapping the error message ("Invalid current config.yaml: Invalid current config.yaml: ...")


🟡 IMPORTANT (3)

2. executeSave() resets dirty state even on partial save failure

page.tsx:398setOriginalConfig(config) runs unconditionally after the save loop, even when errors.length > 0. This means if YAML fetch fails or YAML PUT fails, the toast shows an error but the form is no longer "dirty" — the user loses visibility that some changes weren't persisted and can't retry via the Save button.

Fix: Only reset state when all saves succeed:

if (errors.length === 0) {
  setOriginalConfig(config);
  setRawJson(JSON.stringify(stripOAuthIds(config), null, 2));
}

3. auth-dir guard uses truthiness, not key presence

page.tsx:359!liveConfig["auth-dir"] is a truthiness check. If auth-dir is intentionally set to empty string "", it's treated as "not present" and gets overridden with "~/.cli-proxy-api".

Fix: Use in operator:

if (liveConfig && !("auth-dir" in liveConfig) && !("auth-dir" in yamlChanges)) {

4. Test coverage too narrow for a data-integrity function

Only 2 happy-path tests. Missing:

  • Invalid YAML syntax → throws
  • Non-object YAML root → throws (the blocker above)
  • Array values are replaced wholesale, not merged
  • null values round-trip correctly
  • New keys added to existing YAML

🟢 NIT (2)

5. yaml.load() default schema is safe in js-yaml v4
!!js/function etc. were removed from the default schema in v4. No action needed, but CORE_SCHEMA would be a hardening option if desired.

6. Merge is 1-level deep only
Sufficient for current config shapes, but worth documenting. If nested objects gain sub-keys edited independently in the future, this will need recursive merge.


✅ What's good

  • The raw-YAML-based merge approach correctly solves the original regression
  • getErrorMessage() helper improves error surface area over generic strings
  • YAML parse errors now produce actionable messages
  • The auth-dir persistence guard is a good defensive measure

Fix commit available

I've pushed the fixes to branch fix/config-yaml-roundtrip on origin (commit 7c307e0):

  • parseConfigYaml throws on non-object root
  • executeSave only resets dirty state on success
  • auth-dir guard uses key-presence checks
  • Tests expanded from 2 → 13 (parseConfigYaml + mergeConfigYaml edge cases)

All 13 config-yaml tests pass, build succeeds (71 pages, 0 errors).

@itsmylife44 itsmylife44 merged commit 44b07c9 into itsmylife44:main Apr 6, 2026
itsmylife44 pushed a commit that referenced this pull request Apr 6, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.68](dashboard-v0.1.67...dashboard-v0.1.68)
(2026-04-06)


### Features

* update to OhMyOpenAgent with presets, advanced options, and config
management
([#164](#164))
([ae80424](ae80424))


### Bug Fixes

* **build:** make clean-checkout dashboard builds reproducible
([#167](#167))
([bd79d3b](bd79d3b))
* **config:** preserve raw config.yaml fields when saving dashboard
changes
([#165](#165))
([44b07c9](44b07c9))
* **lint:** align eslint tooling and clear dashboard warnings
([#168](#168))
([0f582d9](0f582d9))
* **oauth:** use manual launch flow when incognito mode is enabled
([#166](#166))
([2bc8566](2bc8566))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
itsmylife44 pushed a commit that referenced this pull request Apr 12, 2026
:robot: I have created a release *beep* *boop*
---


##
[0.1.73](https://github.com/itsmylife44/cliproxyapi-dashboard/compare/dashboard-v0.1.72...dashboard-v0.1.73)
(2026-04-12)


### Features

* add admin force logout all users control
([012b8ee](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/012b8ee0ac23e7aa1b00d118475d232175f0b13d))
* add auto-update popup notification for admins
([dc3ade7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/dc3ade741233edc2a6e83bbac6205bae7c1954b7))
* add auto-update popup notification for admins
([77ac83d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/77ac83dcb0d7fd56a21ec2b2fdb240b638036422))
* add client-side pagination to logs page
([e61b268](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e61b268da95837d0c7dc022e8c5ba78833d8cf9b))
* add CLIProxyAPIPlus, Copilot and Kiro providers support
([6dc06a0](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6dc06a078777de94a7f8c30c4259b168a9fdccf8))
* add Copilot quota tracking and improve model grouping by provider
([01dcb6f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/01dcb6f5cbecd0859bbee0041377d83da383fa47))
* add dashboard deployment via webhook from admin settings
([0da0cfa](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0da0cfa67a5b7a117b2f55094c1ca619f0db0621))
* add dashboard UX improvements and Telegram quota alerts
([#108](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/108))
([6ec4da7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6ec4da766e51fb8893ee55896069aaabfca1ad77))
* add estimated cost tracking per model in Usage Analytics
([#175](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/175))
([081fe04](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/081fe042f521878e9e6ba3e018466c9cf69db653))
* add fullscreen update overlay with progress animation and auto-reload
([#97](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/97))
([0248de2](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0248de28e057a0c5d47a828ca97da92717e68ee3))
* add get-status.sh and get-log.sh helper scripts for webhook
([c7bba14](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c7bba149c7ca862f026425f3f59d3c6c4c82382a))
* add global-error boundary and metadata title template
([54657d2](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/54657d2901b3a303a97e72ceba8146ac94341e27))
* add iFlow, Kimi, and Qwen OAuth provider support
([3e83485](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3e83485b51583ae1a83fd2b719581f2bf2da8cc8))
* add iFlow, Kimi, and Qwen OAuth provider support
([68ea9b4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/68ea9b4b6ca76e02d2c9b5ea72d0ae250ade4aaf))
* add Kimi quota support and update provider docs
([ca3cf4d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ca3cf4daf51a03f1d8a0f6e246aee58b4f9c18ed))
* add local setup for macOS/Windows/Linux via Docker Desktop
([14eadcc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/14eadcc320d9cec2480e589942d0289538ef9f3c))
* add local setup for macOS/Windows/Linux via Docker Desktop
([#36](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/36))
([27bb36a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/27bb36acc7fb8190c28c4a6453da110d4fe4112f))
* add logs viewer from PR
[#1](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/1)
([b5c2bf5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b5c2bf50db7cdaa72ad299133f3a77b43bc643ac))
* add missing Perplexity Pro web UI models to sidecar
([b606493](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b6064930d3b860bfb08cde95285e587294ff3554))
* add model auto-discovery for custom providers
([#32](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/32))
([ffc0a9b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ffc0a9b5c72b5378d8db74bddaa856ec2943e5f3))
* add multi-arch Docker build (amd64 + arm64) for Apple Silicon support
([61d455c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/61d455c4d9918c9ff11da91fd3137de3c1897edc))
* add OAuth account enable/disable toggle
([d6ad7ef](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d6ad7ef4c2af78ff396b807a1230e1a6a410fc4e))
* add OAuth health status badges and fix alias model override priority
([ce1084a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ce1084ac24c6b09359505f88c936c5c6e6da34f9))
* add oh-my-opencode-slim support with variant toggle
([#143](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/143))
([152dc42](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/152dc42e682f81eca90a1016ec18c1cffa544175))
* add optional webhook deploy service installation to install.sh
([ea73737](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ea7373761b80f87eeee4c40e0633f578f298f5a7))
* add Perplexity Pro sidecar with dashboard cookie management
([#54](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/54))
([69fc1a5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/69fc1a5ebf6bfe5060a76aa1e7c8f5ee8bc25d78))
* add persistent dashboard header with live status pulse and user panel
([#99](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/99))
([46c86de](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/46c86de4e806a575a023441cefdcd873bf56f421))
* add persistent usage tracking with per-user views and time filters
([5cf088e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5cf088ec26033d0806136887f742c4047b82e2f4))
* add provider group management and priority ordering
([#84](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/84))
([a2d540b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a2d540b88f276e3623917bb7559b33b2f314be2b)),
closes
[#78](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/78)
* add provider key naming, fix OAuth ownership registration and ID
anonymization
([ac5a28b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ac5a28b43c153fbacd78ab2c193e4f0b3bd74696))
* add qwen and iflow oauth provider support
([b3fafeb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b3fafeb35044228fd2cbac8af2ff51d390e1d9ce))
* add qwen code and iflow oauth provider flows
([4f5ab3c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4f5ab3c2b3d89b270fdca289db46194986db7701))
* add real Kimi quota tracking via /v1/usages endpoint
([26523e8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/26523e818fdbfb58daecc253098e3c206ffcadb7))
* add real Kimi quota tracking via /v1/usages endpoint
([1905012](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1905012c0f03a27c6d98e5ee07a6d6d7561b0a46))
* add recharts visualizations to dashboard pages
([#106](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/106))
([850b389](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/850b389c30d6c431e7e7ccd3ec33f48beb9f0d11))
* add separate proxy update notification component
([21627df](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/21627df6de73d90f3325271ea186bebb15fd1b81))
* add server-side session revocation with sessionVersion
([4e75221](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4e752212a0081fa38910d815f05f443d97d1046f))
* add server-side session version revocation
([317ae1e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/317ae1e4c8be9533c8a408c2f0adccea26d0455f))
* add setup wizard with inline forms and sequential step locking
([12e597b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/12e597b14dc6cdef48cf63aea5e3b086bee22eea))
* add variant, temperature, prompt_append, description to agent/category
configs
([54e1a5f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/54e1a5f1f4b1ff213e1fc30dc1c425b35e57e144))
* add Windows PowerShell dev-local script for local development
([6e812bb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6e812bb5865b0a9a55128060b85a37384c1d7412))
* allow non-admin users to view their own usage stats
([6fc67a3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6fc67a3fdf6437c11c3dca510674ed8101543ea2))
* **api:** add custom provider CRUD endpoints
([1379c57](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1379c577ab9ca4144854539357b8ee2814320907))
* **api:** add usage collector endpoint with deduplication
([82dbe87](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/82dbe87bc68f0549644dfafab21abb0bf2d84bd5))
* **api:** add usage history query endpoint with time filters and
role-based access
([5e8207c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5e8207ca07a96a73ad794fe5e4f32908f1af034e))
* **api:** expose background sync failures to users
([aeccd5f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/aeccd5fc6458e8c24e5e27e587d922d310b0383b))
* **api:** standardize error response format
([6b333dc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6b333dcb41c3827ae6175e08bb54f9451d845373))
* apply advanced Tailwind CSS layout techniques across dashboard
([72c3673](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/72c3673e75abdf32a19f85d8a91e9643629b39be))
* **config:** add environment variable validation
([b21b630](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b21b630f6c8198ec01cd2ba08fe5c72a787d2fab))
* **config:** add proxy-url validation and emergency recovery
([797fb6c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/797fb6c8d033388b07b86c21522855c0b82ef375))
* **config:** include custom providers in config generators
([86b9106](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/86b9106f7383ce73979f25d6fa844d5ef9f7dbf9))
* **config:** restart CLIProxyAPI container after saving config
([5f5c7ac](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5f5c7ace22a8ab408d2a5b73fd900e089537ee25))
* Dashboard deployment via webhook from admin settings
([579acb4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/579acb4e9e962d1527c5e80c52d8ada9c3e9e6f1))
* **db:** add ConfigTemplate and ConfigSubscription models for config
sharing
([beda365](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/beda36544e5ac430fdbb19e6b15819f2545b869f))
* **db:** add custom provider schema with model mappings
([633cf60](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/633cf603c9544365a99ee83ce4020bea7db53e2b))
* **db:** add custom provider tables to entrypoint schema
([38e6c49](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/38e6c49391ca290046f7daead7df2382bed903cd))
* **db:** add custom providers migration and update dev-local.sh
([2ce880a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2ce880a999e9a62da591340261d132a4fa8df4e9))
* **db:** add UsageRecord and CollectorState models for persistent usage
tracking
([3a3cf37](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3a3cf37d97d13b83a876b32c780f6e562c8be49e))
* **design:** migrate dashboard to modern light design system
([802af62](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/802af62cdb73462e55c39c8bfdb171c6f0f76805))
* **dev:** add SKIP_AUTH=1 bypass for UI-only testing
([72a4262](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/72a4262655d63ed1f6a546a5f15c235a4e911174))
* enable usage page for all users with input/output token breakdown
([d358c6a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d358c6a021fcddb7e2207eabc84322ecc660de76))
* encrypt custom provider API keys for auto-resync after proxy restart
([d194d0d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d194d0d844eef391c7ee9f00484e037bb0f59f2e))
* expose all CLIProxyAPIPlus config fields in dashboard
([#116](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/116))
([77c3083](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/77c30837f8b42151aaca50f011a4ed0f0c55f166))
* **i18n:** add multi-language support with English and German
([#178](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/178))
([4201006](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/42010064d32ea11b7ae97f6fa7a086f2e4244e04))
* improve settings and usage pages UI
([34e8670](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/34e867034590ddf587a8a16e6f57951d16173fda))
* **install:** auto-generate COLLECTOR_API_KEY and install usage
collector cron job
([e46dcb1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e46dcb136f70326477ed71e9e92894e246a765f2))
* **lib:** add share-code generation utility for config sharing
([df2b48f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/df2b48fe13d0f6aa822bb36a65d588206eda816b))
* make Perplexity Pro Sidecar opt-in during setup
([#160](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/160))
([a6a52ad](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a6a52ad4f74905287f6dbcb15c1d58d59c3e7983))
* make Telegram check interval and cooldown configurable via settings
([f83eb1d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f83eb1dc85178ea310a5497c78f6550252b75c39))
* notification bell and latency indicator in header
([#130](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/130))
([56d7196](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/56d719637c94196d6225601ecbbddb664be8dbe5))
* **observability:** implement structured logging with Pino
([22f4ef9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/22f4ef9a7f869895f58f121605a0f94aeb581a68))
* parse Codex quota into graphical progress bars instead of raw JSON
dump
([7e55a3a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7e55a3a896e2becafb50d5466ba54212436e0352))
* per-user provider ownership, config sharing, and MCP type fixes
([986dadd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/986dadd727f281e6b5aadafada682135ff7c5dfa))
* **perf:** add pagination to admin APIs
([080e02a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/080e02a6f572d0b20d6698d4de7671d33281e65d))
* **perf:** implement in-memory LRU cache for expensive operations
([f527103](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f527103a8636ba3786be1b8df75729749afded4d))
* provider-grouped quota aggregation with weighted availability formula
([f715ab4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f715ab4d454b218e71e751f5ed19e207fa26d0ad))
* **providers:** add Cursor and CodeBuddy OAuth provider support
([20eb8ae](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/20eb8ae328338113c6aec754a71848e3e967407a))
* **providers:** add Cursor and CodeBuddy OAuth provider support
([#147](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/147))
([c0c2c96](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c0c2c96905626dac6c07f4e876b43ed7b65d0e09))
* **quota:** add model-first Antigravity snapshots with i18n
([#180](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/180))
([404b354](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/404b3544d7a706a6c85764b2ecdea8651c56c7ac))
* **quota:** replace weighted average with per-window capacity bars and
long-term priority display
([db537bb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/db537bb4676170ad3abe3d95f6d8bc083903b923))
* redesign MCP server management for complex configurations
([#79](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/79))
([0021ebb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0021ebb4510af79ec0f00384b476c182191bbd9f))
* Release pipeline with GitHub Actions, GHCR, and Docker Socket Proxy
([#19](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/19))
([37a1ea7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/37a1ea7629d721c93a5bdd266237dfba43d87f24))
* **reliability:** add timeout handling to AsyncMutex fetch calls
([cfe0c6c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/cfe0c6c6164b03fa135bb720b7ef90d4c350f9e3))
* reorganize quick start flows and assignment model selection
([d7a7c8a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d7a7c8a62e62129a5462c6091af5155cf9fd0d7e))
* replace GitHub API with version.json for update checks and show
release notes inline
([#114](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/114))
([cbb8eaa](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/cbb8eaa7b8858b4d84e6d222fdc078b92935bc7d))
* rewrite perplexity sidecar with auto model discovery and auto-update
([9c204ad](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/9c204ad910845924d49fe0684c22ac89f2cf8d65))
* **security:** add path traversal protection to management proxy
([d00f0d5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d00f0d587b7533a372f38ed420dea86597de7089))
* **security:** extend rate limiting to sensitive endpoints
([456bb70](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/456bb70dbe214ed0fde5a60caa1e5c2204620805))
* support importing local OAuth JSON credentials from dashboard UI
([#120](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/120))
([cfd140c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/cfd140cca515e0f2adf0e87f9420734dd62cf475))
* switch to CLIProxyAPIPlus, add Copilot & Kiro providers, fix OAuth
delete 403
([#67](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/67))
([00438e4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/00438e4c8ea8a06e5fc629cf9dc060e22f33ce37))
* **theme:** add browser verification harness and root theme bootstrap
([474a7fd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/474a7fd7cd8aa721d3fb4dc67959a272eaa98386))
* **theme:** add toggle, theme-aware primitives, and chart adapter
([68e5537](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/68e5537a61c8390382f50d09c7a66ac45d021014))
* **theme:** convert all remaining shared components to CSS variable
tokens
([7b54c07](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7b54c07d39db033662f0cf1b70ee427a1c0c239a))
* **theme:** convert all routes, loading skeletons, and system pages to
dark mode
([4329209](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4329209075f12db3306704c4cb22958c8fb3f72a))
* **theme:** migrate chart consumers to useChartTheme hook, convert
first batch of shared components
([c313611](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c3136115a78e9b64f55e795c939420463dfcf62d))
* **ui:** add custom provider management interface
([2446076](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2446076b60254aa913f1aa20a5eecdddbca288ae))
* **ui:** rewrite usage page with persistent data, time filters, and
admin/user views
([15e55f8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/15e55f849d664d62829b95a3921ff95b83ffeffa))
* update to OhMyOpenAgent with presets, advanced options, and config
management
([#164](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/164))
([ae80424](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ae80424751f311322c55434384c6ddbdca78bb2a))
* **usage:** add COLLECTOR_API_KEY for external cron-based usage
collection
([0e48a9b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0e48a9bd8c65d96c3bb0e53ec93d24d083988924))
* **usage:** add latency tracking to usage records and enhance dashbo…
([#138](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/138))
([c56a657](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c56a6573413bcd860c7e072989f913a4c9c1f421))
* **usage:** deprecate live usage endpoint in favor of persistent DB
tracking
([e9c5d35](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e9c5d350a3a233f0647cfb29bd88d2f72f689db8))
* use models.dev as source for model context/output limits instead of
hardcoded heuristics
([81ffcc0](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/81ffcc0024b504b0fda98df7f14f17aa4eb92578))
* use pre-built GHCR images instead of local Docker builds
([73b487d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/73b487d90fad7e48129216f48984c6f5728701b8))
* use pre-built GHCR images instead of local Docker builds
([80d8807](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/80d8807eb0176125bc8927a8ce346ce4eaf7b8ff))
* **validation:** standardize input validation with Zod
([71f59e5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/71f59e5ee95eac4a7b8483aa3b712ed0ef81efd0))


### Bug Fixes

* abort config save if current config fetch fails to prevent data loss
([e2c4819](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e2c4819714d7fe24b641d077b24c8f2fc83a2bab))
* accept valid docker tags for proxy update versions
([4078831](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/407883189631384b0ff3253b44625d2906b2c715))
* add all management endpoints to proxy allowlist to unblock config
saves
([27b9e8b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/27b9e8bc91839bb079360bd5bfa378dc3774ffec))
* add apiKeyEncrypted migration to entrypoint.sh and
PROVIDER_ENCRYPTION_KEY to install.sh
([082362c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/082362c043ac009ad4d52c628a8091a51dc33d3b))
* add auth-dir default to prevent CLIProxyAPI crash on startup
([f598989](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f598989ce812f9e9d5656a41a7ae4d267ec1bf3b))
* add build-time env placeholders for Next.js validation
([79c29bc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/79c29bc2765e8c209c2b3d20fcf7be659a78f2ba))
* add CLIProxyAPI config.yaml generation and auth-dir for local setup
([b2c05d6](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b2c05d6f9013e0d1e1c997a1851e79aa3619b4bb))
* add Gemini CLI quota support to dashboard
([#127](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/127))
([e3f6704](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e3f6704584c3aba512c54980bc6ae96b6899dbb9))
* add latencyMs column to usage_records in entrypoint migration
([c13f5d0](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c13f5d04107d232dd79219b3f9af84272ad2bb21))
* add LOG_LEVEL to install.sh env template
([8f6796b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8f6796bd46946115ccfed15e5413b75c37562c15))
* add missing migrations to bootstrap scripts
([15b387e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/15b387ec9159a9c1581fd60f70a5837c7df68697))
* add missing tables to entrypoint.sh for existing installs
([dd5e2c9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/dd5e2c94dc7e6dcb062419d171f96247def3faa7))
* address Cubic code review feedback
([3214c1c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3214c1c7376e2bd886b648cdc95274c698707695))
* address Cubic code review findings
([a48765f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a48765f56048832fd9a878f0bab43172c869e51d))
* address diffray code review issues
([edb15dc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/edb15dcc690b02926dee26a08e1c6814699fa7e9))
* address oracle review findings
([075b256](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/075b2560ae6b38af6ae13b2be229a5a84a8aed7f))
* address react-doctor findings to improve score from 84 to 94
([174ec4b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/174ec4b3076eb2daa5bb40a84955555442db871f))
* address remaining Cubic review feedback
([5c4f66d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5c4f66d056ea9cd5cc1930a56140e100b6316a9e))
* address remaining diffray code review issues
([0a6a104](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0a6a104b0236d393d82a41430ad60c0fc080f696))
* address second Cubic review round
([7322596](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/73225961fbdcb49c2ac77bd25e68ddbd0ea08378))
* **agent-config:** dedupe and sort available model IDs
([11c6df4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/11c6df4e26a57c203d4298d68453a34d9f588ffc))
* allow http:// base URLs for internal Docker service providers
([e36ad15](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e36ad15a74c45ede58d1464f3f0c44617a217119))
* allow non-admin OAuth management read endpoints
([2e1e9f7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2e1e9f72c12a79975a8a5d9b703e73d9627e19f2))
* apply provider filter to charts and stats on quota page
([1b99157](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1b99157fda2a48f917699ed316efefc07625ee50))
* avoid long blocking qwen oauth callback polling
([8483c80](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8483c804362214b92cf6a42c70847721b3359efa))
* backend hardening — rate limiting, error standardization, security
([#122](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/122))
([e2bed94](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e2bed948ef07d3d219e0170abdb9443e0704e9f3))
* bind all ports to localhost and write BOM-less UTF-8 .env on Windows
([920e2d5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/920e2d506962b3001bd311e85b0cd737edd36703))
* block SSRF redirect bypass in fetch-models endpoint
([#40](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/40))
([bedaa7a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bedaa7abd66a233d792ae08be3f321b5a37f7ecf))
* **branding:** switch normal OMO naming to Open Agent
([28f30f1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/28f30f1b8b0c08bcd279e03d6679ec1cc7aa7efa))
* **build:** make clean-checkout dashboard builds reproducible
([#167](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/167))
([bd79d3b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bd79d3bc1a6980f263c6928f088e5b6e1a83c1f5))
* capture provider OAuth ownerships after successful callback
([268c412](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/268c41272916c06b5714881db4d16a41f3370811))
* **ci:** decouple tag-contributors from build pipeline
([d4914cd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d4914cdc2d6164e61e6941b537346d16c605c416))
* **ci:** handle missing releases in tag-contributors job
([06b9941](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/06b994118d7a0ff16227155cd5e9c567fafb5025))
* **ci:** reliable Docker build trigger with output fallback and
workflow_dispatch
([eb620c1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/eb620c1c91bc5389e79f0f773cec1a689657a053))
* **ci:** reliable Docker build trigger with output fallback and
workflow_dispatch
([035d979](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/035d979b8be7a53e0f108e6414e13cfc44411791))
* **ci:** use correct all-contributors-auto-action
([86770ea](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/86770ea3b5c47830effbaefcb0e2463c86d0fcf4))
* clarify uptime label as proxy uptime in dashboard header
([912cf7b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/912cf7b175cc675b00d9d23766108c9027e51197))
* Claude OAuth quota fallback — handle 429, update model, parse unified
headers
([a06327e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a06327ee827df20797973c25549a2204475c5929))
* clean stale digests on self-hosted runner before export
([df10ecd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/df10ecd23caeeade41441e10029547c6d3c10fb7))
* clear update state when auth fails or user is not admin
([ca46861](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ca468619b6945b92c05ca22b5d59956f02015c2d))
* collapse non-admin usage to single owned key when only one key exists
([09e89f8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/09e89f8447495d31b9f22bc2e9d61d0c34457711))
* **config-sync:** await lastSyncedAt update for subscribers
([fb5c282](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/fb5c2828310b1105842bba253a69c40d627d95f6))
* **config-sync:** use deterministic hash for stable version detection
([c303ee1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c303ee176b05d7d7b2ecd2aa37631c495d951d0b))
* **config:** always persist auth-dir on config save
([#149](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/149))
([18cf244](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/18cf2442c7556a41035d4eb7fba37a993b2d17bf))
* **config:** force-quote YAML strings to prevent special char issues
([5e7fa64](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5e7fa64e5b9db4a019b2ff6c3868c1e5b9562305))
* **config:** preserve raw config.yaml fields when saving dashboard
changes
([#165](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/165))
([44b07c9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/44b07c9d4de40559b10c4e70f8cc84dc2b89fca3))
* **config:** preserve unmanaged fields on save via GET-then-merge
([2565aca](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2565acac07e0f8eabb0337f179fceec2493476bf))
* **config:** retry on load failure and re-fetch after save
([5b0558d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5b0558dd03243f14f1c01fad11dd0dc57fb997f2))
* **config:** use deep merge to preserve nested unmanaged fields
([d8e1413](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d8e1413e8cb1c2fc7c16a88beac427cc81dd2578))
* connect logger to log-storage for UI display
([7d7636e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7d7636e8b8c405e749f2c5f2674f5dbb7b22a3ec))
* containers page responsive table layout
([e308ec3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e308ec350b15a3356c9f5b4c60d91b08ff8ebedf))
* correct custom provider re-save state and URL validation
([248764f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/248764f9eb4c7e726a60463a46739c972870ded6))
* correct foreground argument parsing in deploy script
([a096a64](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a096a646e360cd674c661040188710a4d4dac4de))
* correct model-to-provider heuristics and add missing provider mappings
([#87](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/87))
([27d2df2](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/27d2df2af5b44105eb3c0d91bc89528f5f256ecc))
* correct plugin config paths and add OCX profile setup in Config Sync
instructions
([14bd5a8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/14bd5a8f9170cf0845252ffa48a9c1ad816a8f9a))
* dashboard UI consistency - remove glassmorphism, standardize to
blue/slate theme
([e3f8dfd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e3f8dfdc1269bcb6cf0d8906ed05bd648cba9c1c))
* **db:** add slim_overrides column migration to agent_model_overrides
([4812b91](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4812b91959de20fe8d9ab3c897049818304dcdf6))
* deduplicate model IDs to prevent duplicate React keys in ModelSelector
([dca83b4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/dca83b4ae09aba3cd54606663ef2a8323ab483ff))
* deduplicate proxy models, suppress chart warnings, and fix 24h time
format
([e41d27c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e41d27c231be545418c5f435839d7323f5b28a14))
* defer API_URL check to runtime so Docker build succeeds without env
vars
([4c49853](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4c49853a5d7841df2dffbfd863873c5fca3fe0ce))
* disable quota group drilldown and lock turbopack root
([5612ba5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5612ba50c1c53f215d0a8a3a768e27a27ccb5033))
* **docker:** copy messages directory for i18n support
([d7298d5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d7298d51ca7c86e36652a458575ffc18cdc42ffd))
* eliminate Edge Runtime warnings by splitting instrumentation into
Node.js-only module
([48a5bda](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/48a5bda8aee83650e206b6a46cba4a7faab703c7))
* eliminate fetch response leaks and clear dashboard lint blockers
([#65](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/65))
([ce5fc17](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ce5fc175b153b2de4fde461808c9dd9754c339f9))
* enable NETWORKS in docker-socket-proxy for container update flow
([054275f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/054275f0dfec697db3678481b8bbe947c6511cb1))
* enforce admin-only system actions and handle null provider keys
([283b599](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/283b599f783b9a31ddf8e78eb32a8aa9e46e9b59))
* ensure DEFAULT_PLUGINS used when no saved plugins exist
([f775903](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f775903b6477b3ab7f2f48dc35ccaf83ed5616bf))
* ensure first model selection change triggers autosave
([6d350f8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6d350f83673d2a5ba749d8ac67f5bb1588d985f9))
* explicitly pass API_URL and DASHBOARD_URL to dashboard container
([3baaf53](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3baaf5375354628370f5c73e82336bcfceadcec1))
* fallback proxy update when compose is unavailable
([84c675f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/84c675fa714536fdc052a529f22510226f9bb8dd))
* filter usage page to only show dashboard-generated API keys, exclude
OAuth auth-file indices
([d2a9ad6](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d2a9ad6f85cfe320cee5ae343824746f6d8c03aa))
* filter usage to dashboard API keys only, add quota cache (2min TTL)
and handle Claude 429 rate limits
([d329a3b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d329a3bacd6ef02a2bc694a6b78d041d5aef9993))
* generate URL-safe postgres password in install flow
([be8e5bc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/be8e5bc642f31b7421b6e007e57c735870551435))
* group usage by API key instead of endpoint
([64be3a3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/64be3a3cc14eb6593601587e7c7762e06836be6c))
* handle 'completed'/'failed' status values from deploy script
([f086739](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f0867393d0dae3734d1900bc17b04868a78a30fa))
* handle dashboard-v prefix in semver parsing for release tags
([8dc88ce](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8dc88ce7b068ea5db102bf6ba01c0ad3f5f0f15c))
* handle Kiro device_code OAuth flow without initial URL
([4e219cc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4e219cc952444bc0040a5812188cd7d81c9d4d97))
* harden collector concurrency and reduce proxy/dashboard load
([#81](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/81))
([e6c2d6a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e6c2d6a7259470c1efeb4305646168930cc070e6))
* harden cost estimation component
([f505d15](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f505d15f2f42113d92cad963a1568e2d27080855))
* harden Docker setup with security and resource improvements
([71dae30](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/71dae30549128222add769ed0b071287af208477))
* **health:** use GET instead of HEAD for proxy healthcheck
([#63](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/63))
([ca90255](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ca9025523157225b6de4c98c2b9a8813de4f7a0c))
* **health:** use proxy root endpoint instead of /v0/management for
healthcheck
([#61](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/61))
([50ab3e3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/50ab3e3cc97abe5791f4f5ccfbef5bdc18ec04d2))
* ignore null quota fractions in capacity calculations
([87ed48a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/87ed48a3cc408e9cfa2802c44fbb533bf648f3b6))
* improve dashboard UX with tooltips, consistent spacing, and proper
navigation
([c2f056a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c2f056a8dff33d724fde7ad72e6129f9259b834c))
* improve PostgreSQL password auth error handling and documentation
([#135](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/135))
([1dbed04](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1dbed043fd32079bdc45fbec6b390f744cbb9b78))
* improve resilience and UX across dashboard
([16ea6e1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/16ea6e1a2f2d60ec81db8bd24f40c77197a2a443))
* improve stale lock detection in deploy script
([9f1d9de](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/9f1d9de6573306b71f27f191fbc8a78064b2d082))
* include custom provider models in agent assignment model selector
([#155](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/155))
([5369dd3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5369dd37a22c212a2855e9b4c7c3ffdedcb859d3))
* include custom provider models in generated config bundle
([6584815](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/65848158891ab3f27afd1f30510603903f6444c3))
* include docker-proxy in install script and deploy flow
([c5478bf](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c5478bfdee63318b02da7ae75e3099febe9a1967))
* include sessionVersion schema updates in bootstrap scripts
([44d2306](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/44d2306805b1f261248cfc20e20387a7d32d40fe))
* include user source matching in non-admin usage filter
([9170de3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/9170de304eb76a54f775de512bd648f9caa96730))
* increase CLIProxyAPI wait timeout to 60s for cold starts
([0417b74](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0417b744caa8ee7e4847ec120ea292417b7ca124))
* increase GitHub API cache TTLs to avoid rate limiting and remove
duplicate password change
([32aaa30](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/32aaa300f296677dfb25f961e6eadc003611c9bc))
* **install:** avoid unbound CADDY_MODE when skipping Caddy auto-apply
([d2e4b47](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d2e4b47bd7877801872c840c146c0a01c86ee4b7)),
closes
[#102](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/102)
* **install:** use public dashboard URL for collector cron in default
mode, localhost only for external-proxy
([5f35104](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5f351041b14a43491dd61bb4a00ad231bc832115))
* keep proxy updates and dashboard deploy compose-managed
([1ea7abd](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1ea7abd651b07ea01dd7a3f8c0af0b7c72950057))
* **lint:** align eslint tooling and clear dashboard warnings
([#168](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/168))
([0f582d9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0f582d9da005aba9825b3b9c35d551652d694b1c))
* **lint:** remove unused params and replace unsafe management any types
([bcf7e68](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bcf7e683d6198d68f1e59b1bac245ac28f109b08))
* logger now stores logs in both dev and prod mode
([f616587](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f61658757e2f09ecf486e1a63d79e7502bc163ea))
* make PROXY_URL configurable via CLIPROXYAPI_PROXY_URL env var
([3f033c5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3f033c5835ca8ad99d297a9e400440c0c394f8a7))
* match github-copilot provider name for Copilot quota tracking
([d0e127d](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d0e127d4c9d35d4a3fd382992d334aaabe32cdd1))
* match non-admin usage by oauth source identifiers
([73fd4a7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/73fd4a7ff0d14758e32ecdededeb494d69d84223))
* memory leaks, unbounded queries, error disclosure, and performance
improvements
([#49](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/49))
([e470db5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e470db5fdc2936f96a9355ebb99d46d3792de339))
* merge docker build into release workflow to fix GITHUB_TOKEN trigger
limitation
([8c73584](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8c735849249576f94da7ab70e67c6abc57918f85))
* minor code quality improvements
([3250534](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/32505347203fc13bc668890151bbf64a1ebbae2a))
* modal styling and animation - replace glassmorphism with solid dark
background, add keyframe animations
([bd81737](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bd817378e1ae3e8fc12182329a57f6ec8627bed1))
* move dynamic imports with ssr:false into client wrapper components
([7d4b815](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7d4b8151d4821ea43e59e5d3270406d38710fb3d))
* move pino dependencies to dashboard package
([df983d2](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/df983d27a5dba10735ccb801f34813bc9f90ab46))
* normalize deploy status payload and API response shape
([9473adc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/9473adc4123fd97a15d0dcf95102b11506ff85a3))
* normalize OAuth provider aliases in ownership migration
([#151](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/151))
([ebca654](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ebca654cb36b6feb3e714bd8634edb0888ac767b))
* normalize opencode-cliproxyapi-sync to
[@latest](https://github.com/latest) when loading saved plugins
([dc92958](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/dc92958dab051b45a5213fdd614556715f26276c))
* **notifications:** mark header notifications as read on click
([3541586](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3541586c98ebf8c88d345c655b5f2faf1a0ea024))
* **notifications:** persist dismissed header notifications
([6976715](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/69767155a01064d1cfc5892b474a86c7fb61cc8b))
* **oauth:** use manual launch flow when incognito mode is enabled
([#166](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/166))
([2bc8566](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2bc85664cec4ca96e50d2b6e01e2782c0838ca67))
* **oauth:** use snapshot-diff for ownership claim instead of
state-in-filename matching
([#142](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/142))
([a788d19](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a788d19992f3e3f27f636524305b1552a19df09f))
* pass proxyUrl as prop from server to client components instead of
reading process.env in browser
([156b990](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/156b990bf080c73de16ad6a66c644d0981e2d031))
* perplexity sidecar home for pip, optional auto-update, oauth config
docs
([f4e0d73](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f4e0d735ecd63da6c5ed2e03f6122b655dc8e653))
* preserve original model IDs from proxy instead of transforming to
dot-notation
([349f35b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/349f35b34633c3f1c72f3571aabd8b1d10001db6)),
closes
[#179](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/179)
* prevent agents from disappearing when preset models unavailable
([7b726aa](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7b726aad51f7a89f1cd0ff0b4f97e656dad0b835))
* prevent grid row stretch when expanding quota cards (items-start)
([da1f18e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/da1f18eccb66d3d28671eaf0086761ee0b2c7c6a))
* prevent PowerShell from treating Docker stderr progress as errors
([82843e5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/82843e5b9264b3ca6363efebc9f1898621ec93b8))
* prevent quota crash for kimi accounts
([d665d11](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d665d117a7c66c9ba8f92975591c975761257dab))
* prevent quota crash for missing account email
([c553444](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c5534444bdd72e576e91a85fa49bf8a6104660ac))
* **providers:** allowlist Docker service hostnames in SSRF check
([#57](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/57))
([370c80f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/370c80f9b5463019bd28c9a360eda1048ea2551f))
* **quota:** avoid unknown display labels for inferred providers
([6eacdfb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6eacdfbc58159a574b78bbbce1239942264418ef))
* **quota:** infer provider for unknown auth file entries
([e121c21](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e121c21c4e2db3dcf3d89d553e6790ba0db93a97))
* **quota:** normalize imported provider support mapping
([0de46ca](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0de46cadb2f3c45a2b7d80004d55a6bde835bafc))
* race conditions in provider key contribution, removal, and OAuth
callback ownership
([0637049](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/063704954f59504084f7f723ffd504b6c5479c34))
* rebalance quota capacity and tighten publisher settings density
([7aa67dc](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7aa67dc739f9ee75fc9c33fdc439800ee18e68bf))
* remove CitationMode enum usage for perplexity-webui-scraper 0.7.0
([6ad7582](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6ad7582db98e13a17a4808302d06596e253e0c68))
* remove custom provider credentials and redundant models from opencode
config
([88845bf](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/88845bffdf19d216f8e0dbbe7c1a17613ff3e201))
* remove duplicate code block in deploy script
([b672e9b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b672e9b4321451e533bae0f0ef0a9c45c6d84fe6))
* remove duplicate model list from OpenCode config section
([bf7d5be](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bf7d5be8607d7362cb1f5edddfb1a73c49dbe9a2))
* remove forceQuotes from yaml dump to preserve boolean/number types
([b7f98a8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b7f98a88ca4dc088c3044e61a75047c70784c751))
* remove git pull from deploy script to prevent update failures
([f9501f7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f9501f7ead9f0cf2f3acd9210859960189109a0e))
* remove incompatible thinking/reasoning options from generated config
([#90](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/90))
([5cacb1b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5cacb1b142e844021bef4f0f57a452951a924cde))
* remove misleading version parameter from dashboard update endpoint
([e25b30c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e25b30cbc4e162e1b470a6488c8a015d80a153c8))
* remove oversized touch-target from HelpTooltip button
([e348d45](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e348d4539a0d966ea1a3dff43168b48459b7e348))
* remove throw on missing API_URL, use empty string fallback for Docker
compatibility
([4c5d13e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4c5d13e1ebb1b13abb127cb50722b9ba325236bf))
* remove turbopack.root that broke CSS module resolution
([65d097b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/65d097bbc4197b5eb4ce240bc56055ceb01f51f8))
* replace duplicate provider capacity table with enhanced chart showing
long-term and short-term
([3f71127](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3f711273a666b2f72a968e9fc3f1eefffdd14cdb))
* resolve build errors from dual-write syntax and TS 5.9.3 type
incompatibility
([225e8c8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/225e8c84769e1578b24decfb81af00afeff9034e))
* resolve login failure on HTTP setups and /app/logs permission denied
([e3631f4](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e3631f4ad4c11e3f895b52b674aab0a7b07713cd))
* restore CLIProxyAPI proxy update routes alongside new dashboard update
routes
([0316703](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/0316703503a6a0c48160a7a44ffffb18a03c343e))
* retry Claude OAuth usage endpoint before falling back to messages
([a43522a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a43522a11a0f63ebce1fbfc04d593e00edc4fd73))
* revert provider key naming, add name input to user API keys page
([6afb7da](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6afb7da498f87b1904fe55a38b504c802fedf07b))
* run deploy script in background to avoid webhook timeout
([8e17543](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8e175433062a6227b348e7fb42734b02457e48e1))
* save config via PUT config.yaml instead of non-existent PUT config
JSON
([#115](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/115))
([8e9b150](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/8e9b150adf27b94baa81cb1c16d5b234ac444849))
* **security:** harden SSRF, CSRF, timing, error leakage + lint cleanup
([#94](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/94))
([5804f14](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5804f14ab7531fa2f6fc8000847b1cfe4ed04894))
* **security:** prevent race condition in setup wizard
([3e2353e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3e2353ee2e5c9a3335cd9fab3d04b3e7055ccb56))
* send raw array to PUT openai-compatibility (not wrapped object)
([580798e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/580798e536bc1fb735405b9a26afe691b697ee17))
* session secure flag falls back to NODE_ENV when X-Forwarded-Proto
absent, stop trimming textarea on every keystroke
([223ae08](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/223ae08c0a22b12e9ef5ad39012291e8649418db))
* **settings:** correct key name from plugins to plugin
([4a909d3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4a909d3044c4d57912b417f1725f1797f57bd374))
* **setup:** remove obsolete API key modal after account creation
([1393d0a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/1393d0af1e9c08cb8ec51ae4878610f9a0f846e2))
* **setup:** repair wizard polling, locked logic, and broken CSS value
([3e6e3d8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3e6e3d88a827c9feadd975e0b661617260eae53d))
* show actual version instead of 'latest' in update popup
([ba0f7eb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ba0f7eb755539ee7910cbe172b18857a3dbfb745))
* show days in quota reset time instead of only hours
([072e8e0](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/072e8e0743eaa2f77dfd223a017c39ae0fea27b4))
* show device authorization code for Copilot and other device-flow
providers
([527de1f](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/527de1f8df061d28ca35ee40298fbc4112727df0))
* show prisma db push output instead of silencing it
([4bae2d5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/4bae2d5a8dd5ab5ab6e93318fc7946dbceeba7f1))
* show release notes inline from version.json instead of linking to
GitHub
([9551448](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/955144838b373204f2caff54a58769ead54b9cdb))
* skip lock check for forked child process to prevent self-blocking
([6d5cde7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6d5cde70cbc685c2bb6c1cdabb29171026153ead))
* stabilize quota account identifiers
([c3d0c6e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c3d0c6e4a8310bdbc9fc480b66ddf059fe69bf6d))
* stabilize recharts container sizing to avoid width -1 warnings
([9becd61](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/9becd613a6b99b4b92d4727f40b34a22469c93a2))
* support oauth deletion by account id/name and admin owner visibility
([7766069](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7766069f349238598271034ecfb24a5afe877974))
* suppress update popups while github actions build is in progress
([#52](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/52))
([2047647](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2047647228c1fa1cc3ec80ceef782810ae6c25c3))
* surface OAuth start errors and refresh codemaps
([ceb5f95](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ceb5f95a7f05db66ef7070f525043ad9f5ad9881))
* **theme:** convert remaining hardcoded colors to opacity-based tokens
([85cfe8c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/85cfe8c0868143f438b68683b17496faf4572ae2))
* **theme:** resolve hydration mismatch with useSyncExternalStore
([b57fdeb](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b57fdeb035b64ded22d54ae7f9e1e9677849b30a))
* tmux config defaults not persisted when enabling via dashboard
([a223281](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a22328175a68db1404fba04ea1cf12508519c90d))
* track all repo paths in release-please, not just dashboard/
([54fd32e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/54fd32e47b2ac914afe00dba2cf36e4f0881e15a))
* two bug fixes from recent PR scan (slim chains + Cursor OAuth claim
latency)
([#153](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/153))
([a2b8438](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a2b8438a42d96d102a598bb405b54b69fc4b4973))
* **ui:** improve native dropdown and date/time contrast
([c452127](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c4521276fe0fd409973ffa2efca25390dc9d8500))
* **ui:** use named Tailwind groups to prevent tooltip bleed in details
sections
([cd557f2](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/cd557f229164371dc325b4bebe94206cffa8335a))
* unify model grouping logic across model selector and config generators
([c6ec7a8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c6ec7a8cef63e26983e7e54d39ecda0828d81cfe))
* unify model grouping logic across model selector and config generators
([150fec7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/150fec7517139f7faeb6b503950015e4b48cf7c6))
* update API key lastUsedAt on config sync and fix mobile responsive
([#44](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/44))
([be3c3f1](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/be3c3f149a47f8eb6700440fafb6118b4ead5866))
* update lastSyncedAt timestamp when subscriber fetches config bundle
([e88797b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e88797b5acea5d20b264e19600c29f145f430e61))
* upgrade perplexity-webui-scraper to 0.7.0 and adapt to new API
([78a1141](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/78a1141d34c47a26e3df4e306772f1900aa4fe60))
* usage aggregation, race conditions, data loss, and client cleanup
([#46](https://github.com/itsmylife44/cliproxyapi-dashboard/issues/46))
([a48e35a](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a48e35acf59c1abfb9190ddc950507e7373854a7))
* usage API type guards to match actual CLIProxyAPI response format
([3f8c2f5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/3f8c2f53811a868ffc74d52d15869b3a86af6abe))
* usage page reads data.data instead of data.usage
([b6e7668](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b6e7668bd986b2c42f2c4c73252fbd95ab0183a4))
* **usage:** group usage by apiKeyId/userId instead of authIndex to
merge per-user entries
([bfc9df8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bfc9df84ecca6630884d9b4f84b16d476860439b))
* **usage:** resolve auth_index via /auth-files endpoint for robust user
matching
([b177de7](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b177de78c88f450d934e292f0044e97a5a38423a))
* **usage:** resolve userId via source/OAuth matching instead of broken
authIndex prefix
([ce69be3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/ce69be3b5206c8ed5514be4803e935b31069befc))
* **usage:** strict YYYY-MM-DD date validation, fix end-of-day boundary
for to-date
([77ff899](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/77ff899f801dc8bf514ab7746a0c0136fee9bbf2))
* **usage:** use local dates for filters, strict date validation, fetch
timeout, reset recordsStored on error
([5a47457](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/5a474571796edd41fb1ba742594d0812e7f244e4))
* use [@latest](https://github.com/latest) tag for
opencode-cliproxyapi-sync in all default plugin lists
([c8e8b64](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c8e8b64afc5e0cb9ba0de20a32e69c20608d31a6))
* use [@latest](https://github.com/latest) tag in quick-start config
section
([729d666](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/729d666707041ca6698983dce1fa7ca3351a55be))
* use API_URL env variable for proxy URL instead of non-existent
CLIPROXYAPI_PROXY_URL
([be13f4c](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/be13f4ca85a0d751b5a831096377c78c6f28b103))
* use base URL directly for /models instead of hardcoding /v1 prefix
([a5089f3](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a5089f3ae28b9566aecdd59b28da1f2bcde1485b))
* use build ARG placeholders that pass env validation
([a253fcf](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/a253fcf52ec9388c57179f02a7907066f355bd42))
* use curl.exe instead of Invoke-WebRequest for API health check
([7054abe](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/7054abed148819f6754608d4426df292582066d4))
* use empty api-keys array instead of placeholder
([2bfa0ad](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2bfa0adf47fb6e61f833614633da79bea8e9a5b8))
* use explicit tailwindcss/index.css for Turbopack compatibility
([c1dba01](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c1dba01e80269560c90ce535e295df3243935c4f))
* use explicit tailwindcss/index.css import path
([51a4918](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/51a4918193d26f880a4efec1566fb4ac81341fcd))
* use internal URL for server-side proxy model fetching
([e2a01db](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e2a01db34ca2c32d1ad9e37fd3d1202601cb071c))
* use NextRequest type for validateOrigin compatibility
([f85a360](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f85a360a791269fd4abbebb34fc1e685e379e5f6))
* use no-store cache and versioned user-agent for GitHub API calls
([e0079f5](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/e0079f5ae3fbc58c8c59058fb5c8576433c1a4c8))
* use port 5433 to avoid conflicts with local Postgres and fix -Help
param
([b1383de](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/b1383de3aa87ec3580d0db8ac6956498125ce143))
* use proxy API key grouping for accurate user attribution in collector
([95bc042](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/95bc042d6b9958de81a395ce2da4a9eff77bcf63))
* use Sonnet model for quota fallback, parse 7d_sonnet unified header
([6cfc219](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6cfc219fc906bdbae70e62e4929463f32af0bcaa))
* use time-based stale lock detection (10 min timeout)
([2239a98](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2239a98cc57abf70cabd193f1ebd720b0b3086fb))
* use webhook for dashboard self-update instead of docker compose
([c87f4e8](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/c87f4e82e49a199f08fbdacdfad3367ff5d5eefa))
* use webhook for dashboard self-update instead of docker compose
([074b618](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/074b618af2e8e1a1051cf8e37fb7eb5cda278da4))
* user list reads data.data instead of data.users
([2a5198b](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/2a5198b7b0e97a6f3febb3e40deeab5b8461184d))
* wrap PUT body in openai-compatibility object and handle update on
empty list
([6504aa9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/6504aa97b468cd20c16f501e793c00ce79a3dc79))


### Performance Improvements

* **db:** add composite index for provider key lookups
([103101e](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/103101e025ea34ebf93e7b52aec72bff52135064))
* **db:** add index on SyncToken.tokenHash
([bba0ba9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/bba0ba96f577bb14b9a228ee4f5f34032f85a911))
* **db:** optimize Prisma queries with select clauses
([f7e7ae9](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/f7e7ae9551f5119ad692e861dfc9144dba34baf1))
* improve React performance across dashboard
([d903568](https://github.com/itsmylife44/cliproxyapi-dashboard/commit/d90356887cb19aa24e582540648dc460d9350eec))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants