Changelog
Read from the repository’s own CHANGELOG.md at build time. Nothing on this page is written by hand, which is the only way a changelog stays true.
Unreleased
Added
- Root governance documents:
README.md,CHANGELOG.md,VERSION,.github/{CONTRIBUTING,SECURITY,CODE_OF_CONDUCT}.md, with the per-tool rule files folded into a singleAGENTS.mdon 2026-07-26. .claude/rules and skills so agent-assisted development follows the same conventions as human contributors.- CI workflow: gofmt check,
go vet,go test -race, and the web dashboard build. - Test suites for
internal/auth,internal/store,internal/clitools,internal/proxy,internal/server, andinternal/translator(stdlibtesting, table-driven, race-enabled). .gitattributesfor consistent line-ending and diff behavior across platforms.
Removed
- Repo hygiene: untracked the ~16 MB compiled binary and 2,453
web/node_modulesfiles from git;.gitignoreupdated to keep build artifacts and dependencies out of history.
Fixed
- CI on windows-latest (#12) —
internal/webui.serveGzippednow pins the MIME map for.js,.mjs,.css,.json,.svg,.wasmat package init. On Windows Go'smime.TypeByExtensionreads from the registry, which maps.js→application/javascript; RFC 9239 makestext/javascriptthe standard everywhere else. Content-Type is now identical across OSes. - CI on windows-latest (#13) —
TestResClsHugeBodyIsCheapceiling raised from 2 s → 30 s. The classifier IS bounded (boundedEvidencecaps atMaxBodyScan); the 2 s ceiling flaked on windows-latest under-race + -coverwhere the per-call constant work is ~80 ms. A real body-linear regression would still trip the new ceiling (200 × 4 MiB ≈ 800 MB of scan work is 160+ s). - Gemini tool-call identity (#1, #2, #3) —
functionResponse.Namenow resolves the real function name from the request's assistanttool_calls(Gemini keys tool results on name, not id); streaming gives everyfunctionCallits own tool index and id+name header frame; non-streaming ids are mintedcall_<name>_<n>so duplicate function names no longer collide. - Translator null content (#10) — user messages with no convertible parts are dropped instead of being forwarded as
"content": null, which Anthropic rejects with a 400. - Model routing (#5, #16) — provider alias matching is case-insensitive (
Claude/...no longer silently reroutes to OpenRouter with the wrong quota burned), ando1/o3/o4prefixes require a word boundary soo1x-custom/o365-connectorno longer misroute to ChatGPT. - Proxy error paths (#17, #18) —
writeErrormaps status codes to proper per-dialect error types (429 →rate_limit_error, 529 →overloaded_error, 5xx →api_error/server_error, …) so clients can tell retryable failures from caller mistakes;rewriteModelreturns an error instead of panicking on a JSONnullbody. - Store error handling (#6, #7, #8, #14) —
ValidKeycompares keys in constant time and surfaces real DB errors (andproxyAuthnow answers 500 rather than 401 on storage failure);EnsureInternalKeyonly creates a key on genuinesql.ErrNoRows, preventing duplicate rows; corrupted connection rows error with a remediation hint instead of yielding silent empty tokens;LatestCLIBackupbreaks same-second timestamp ties by insert order. - CLI tools config safety (#4, #13, #15) — Disable restores the byte-exact pre-Enable backup (JSONC/TOML comments and formatting survive) when only ShareQuota's managed keys drifted, keeping the surgical value-restore for user edits;
isLoopbackURLparses the URL and classifies the hostname correctly ([::1]is loopback,localhost.example.comis not); disabling on a machine without the CLI removes the stub config soStatus.Installedis truthful again. - Auth (#11, #12) —
EnsureFreshperforms allconn.Datareads and writes inside the per-connection lock (race-detector-verified);fetchGeminiProjectID's doc comment now matches its error-propagation behavior. - Server (#9, #19) —
Versionis avarso release-ldflags -Xinjection works instead of silently no-oping;GET /api/healthis localhost-only, no longer leaking the version fingerprint to the LAN.
- Root governance documents:
0.1.0
Added
- Multi-provider quota-sharing proxy — single Go binary exposing an Anthropic-compatible
POST /v1/messagesand an OpenAI-compatiblePOST /v1/chat/completionson port 20130, guarded by an internalsq-API key, plusGET /v1/models. - Five providers — Claude (Anthropic), ChatGPT (OpenAI), DeepSeek, OpenRouter, and Gemini (Google), with API-key auth everywhere and OAuth for Claude, ChatGPT, and Gemini.
- Model routing — explicit
provider/modelsyntax, provider aliases, and prefix inference (claude-,gpt-/o1/o3/o4,gemini-/gemma-,deepseek-, namespaced ids → OpenRouter). - OAuth 2.0 PKCE flows — loopback callback listener, S256 challenge, provider-specific quirks handled (Claude
code#statecallback, insertion-ordered auth URL params), automatic token refresh with rotation persistence andinvalid_grantdeactivation. - Format translation — Anthropic↔OpenAI request/response mappers and SSE stream re-emitters, plus an OpenAI↔Gemini path including the Cloud Code envelope.
- Embedded React dashboard — connection management, OAuth logins, CLI tool toggles, and internal-key management, served from the binary via
go:embed. - CLI tools integration — reversible Claude Code (
~/.claude/settings.json, JSONC-tolerant) and Codex (~/.codex/config.toml) configuration with backup-before-first-write and restore-on-disable. - Local storage — SQLite database in
~/.sharequota(override withSHAREQUOTA_DATA_DIR), localhost-only management API under/api/*.
- Multi-provider quota-sharing proxy — single Go binary exposing an Anthropic-compatible
Source: CHANGELOG.md · Keep a Changelog 1.1.0 · semantic versioning