Commit Graph
4504 Commits
Author SHA1 Message Date
Kai (Tam Nhu) Tran 8a0031e514 Merge pull request #1586 from kaitranntt/kai/chore/regen-throw-error-baseline
chore(lint): regenerate throw-error baseline
2026-06-22 16:33:53 -04:00
Tam Nhu Tran 6041c5ee73 chore(lint): regenerate throw-error baseline after request-transformer.ts line shift 2026-06-22 16:27:43 -04:00
Kai (Tam Nhu) Tran 2e702b1d35 Merge pull request #1574 from ReWiG/fix/stream-options-include-usage
fix(proxy): forward stream_options.include_usage to OpenAI-compatible upstreams
2026-06-22 16:16:40 -04:00
github-actions[bot] ca7757b712 chore(release): 8.5.0-dev.2 2026-06-22 20:15:34 +00:00
Kai (Tam Nhu) Tran 05c203aff2 Merge pull request #1575 from walker1211/codex/fix-cliproxy-provider-routes
Fix CLIProxy provider routes for original backend
2026-06-22 16:11:28 -04:00
github-actions[bot] a5149b39e9 chore(release): 8.5.0-dev.1 2026-06-22 17:43:36 +00:00
Kai (Tam Nhu) Tran 5f5d41948c Merge pull request #1583 from kaitranntt/kai/fix/cli-qa-ux-errors
fix(cli): UX and logistical fixes from a full feature-QA pass
2026-06-22 13:39:28 -04:00
Tam Nhu Tran 819d43914a fix(dispatch): restore copilot and legacy-cursor arg passthrough
Routing every non-flag token after 'copilot'/'legacy-cursor' to the subcommand
handler turned the legacy profile/prompt passthrough into an 'Unknown subcommand'
error. Route only known subcommands (matching prior behavior); other args pass
through to the copilot/cursor bridge flow. Bar keeps its unknown-subcommand exit
code (it has no passthrough).
2026-06-22 13:10:59 -04:00
Tam Nhu Tran d8cd2f94b5 fix(cliproxy): keep --help working for all subcommands
The earlier help-gating overcorrected: scoping global help to 'no real
subcommand' meant 'cliproxy status --help' (and list/quota) ran the command and
ignored --help. Restore global help on --help/-h anywhere (order-insensitive),
carving out only 'routing affinity --help', which renders its own help.
2026-06-22 13:10:59 -04:00
Tam Nhu Tran 310f4f6e52 fix(cliproxy): show global help regardless of flag order before --help
Top-level cliproxy help was order-sensitive: 'cliproxy --verbose --help' fell
through to dispatch instead of showing help. Fire global help whenever there is
no real subcommand (no args or a leading flag) and --help/-h appears anywhere;
real subcommands still handle their own --help.
2026-06-22 12:18:50 -04:00
Tam Nhu Tran 40d7617cc1 fix(auth): re-export interface-only barrel symbols as types for bun dev runs
The auth commands barrel re-exported 4 interface-only symbols (AuthCommandArgs,
ProfileOutput, ListOutput, CommandContext) via a value 'export {}', which bun's
per-file transpile cannot resolve at runtime (the tsc dist elides them, so users
were unaffected). Split them into 'export type {}' so 'bun run dev' / source runs
work.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 5e4a90b3e5 fix(cli): warn on tokens --variant without --api-key; list bar serve in help
'ccs tokens --variant <x>' without --api-key was a silent no-op; now it explains
that --variant only applies with --api-key. Add the existing 'serve' subcommand
to the bar help Commands list.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran a5feefe45a fix(cliproxy): honor status --verbose and document --provider/diag in help
handleProxyStatus now respects --verbose (was parsed but ignored). Document the
existing --provider option on default/pause/resume and the 'diag' alias for
doctor in the cliproxy help text.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 016c47ec9a chore(lint): refresh throw-error baseline for shifted and converted throws 2026-06-22 12:06:58 -04:00
Tam Nhu Tran e4c91d2853 fix(persist): accurate symlink guard message on backup read
The guard fires on the backup READ step; use a typed ConfigError whose message
matches the actual step (refusing to read), not a misleading 'refusing to write'.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 9d5b33382b fix(cliproxy): gate binary download log, fix pool message prefix and routing affinity help
Only log 'Binary not found, downloading...' when a download will actually happen
(after the allowInstall guard). Stop double-prefixing pool enable/disable
messages that already carry [OK]/[!]. Route 'cliproxy routing affinity --help'
to affinity help instead of the generic cliproxy help.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 8cfd13ba96 fix(doctor): keep diagnostics running on corrupt config or unreadable auth
loadUnifiedConfig() printed the YAML error on every call (3-4x per run); print it
once per path per process. Run each doctor check group defensively so a thrown
check (corrupt config, EACCES auth dir) records an error and the SUMMARY/ERRORS
sections with recovery hints still render instead of crashing mid-run. Trim
embedded parser snippets to one line so they no longer leak into the summary
table or repeat across checks.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 2900743767 fix(dispatch): route unknown bar/copilot/cursor subcommands and survive corrupt config
Pre-dispatch only routed known subcommand tokens, so unknown bar/copilot/cursor
subcommands never reached their handlers (no error, no non-zero exit). Route them
through. Also wrap autoMigrate() so a corrupt config.yaml no longer crashes
startup, and print only the first line of a best-effort recovery failure.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 9258aed1ff fix(cli): clearer profile/proxy/api errors and rich not-found suggestions
Move resolveProfileAndTarget() inside the try block in ccs.ts so a missing
profile shows suggestions/available-profiles instead of a generic error. Use a
typed ProfileError for proxy start on an unknown profile (drops the irrelevant
install hint). api create: honor --yes for the OpenRouter model browser, show
ccs-codex/ccsx aliases for --target codex, and allow ANTHROPIC_EXTRA_MODELS on
import.
2026-06-22 12:06:58 -04:00
Tam Nhu Tran 191396149f fix(auth): de-duplicate error output and validate legacy profiles in default
exitWithError() already prints '[X] <msg>', so the preceding console.log(fail())
calls double-printed every auth error. Remove the redundant logs and fold richer
hints (e.g. --force) into the single exitWithError message. Also make
'auth default' accept a profile registered only in legacy profiles.json under
unified mode.
2026-06-22 12:06:58 -04:00
semantic-release-bot e44babd8cc chore(release): 8.5.0 [skip ci]
## [8.5.0](https://github.com/kaitranntt/ccs/compare/v8.4.0...v8.5.0) (2026-06-21)

### Features

* **api:** add Fireworks AI provider preset ([#1543](https://github.com/kaitranntt/ccs/issues/1543)) ([a472c44](https://github.com/kaitranntt/ccs/commit/a472c440156fc549c500c649ea0033220fb97e61))
* **bar:** live Codex usage sync with force refresh and spend-chart periods ([6ed5b2d](https://github.com/kaitranntt/ccs/commit/6ed5b2d62b8a3c08a2e23478c6d4078e2ebf501c))
* **config:** add opt-in output limits for spawned CLI ([#1544](https://github.com/kaitranntt/ccs/issues/1544)) ([499aec8](https://github.com/kaitranntt/ccs/commit/499aec8a9ba9eeb27c1d183a27b3336f4e8794e8))
* **errors:** P4 typed-error taxonomy adoption (0->91% locked) + erasable-syntax fix ([7234ef8](https://github.com/kaitranntt/ccs/commit/7234ef8fcf5e3cba0c42f2bf48e075dbe33b00d4))
* **hardening:** P1 maintainability metrics baseline + freshness gate ([#1561](https://github.com/kaitranntt/ccs/issues/1561)) ([95a2864](https://github.com/kaitranntt/ccs/commit/95a2864ef3492f96098c689e16086f6e1db012d2))
* **lint:** P7 enforcement gates (no-new-throw-error + max-lines) + docs ([2f94f35](https://github.com/kaitranntt/ccs/commit/2f94f35ec35bc3710c3ab1d6f1019f704e58d4c7))
* **logging:** P2 traceability foundation - requestId wrap, daemon forwarding (#NNN) ([5e1b864](https://github.com/kaitranntt/ccs/commit/5e1b8640ab517109732affd32b430ca0b769996a)), closes [#NNN](https://github.com/kaitranntt/ccs/issues/NNN)
* **logging:** P3 hotpath console.error migration + redaction gate (928->267) ([87aeb8f](https://github.com/kaitranntt/ccs/commit/87aeb8f19331b07ed056ec49913a23b5dad417e6))

### Bug Fixes

* avoid echoing invalid channel token values ([#1542](https://github.com/kaitranntt/ccs/issues/1542)) ([e3566ed](https://github.com/kaitranntt/ccs/commit/e3566ed7650b6930fd5515527831c4a3f0924cbb))
* avoid quadratic cliproxy usage hydration ([#1537](https://github.com/kaitranntt/ccs/issues/1537)) ([f74561f](https://github.com/kaitranntt/ccs/commit/f74561fe9b48c478c002daec39b8797f1dd0ede6))
* **bar:** authenticate reused local server probes ([#1546](https://github.com/kaitranntt/ccs/issues/1546)) ([f25a101](https://github.com/kaitranntt/ccs/commit/f25a1015ed35df91ed6f145e29eaa111da6b8727))
* **bar:** avoid blocking on lower-priority probes ([#1548](https://github.com/kaitranntt/ccs/issues/1548)) ([8bd289b](https://github.com/kaitranntt/ccs/commit/8bd289bfae3e60c460ad4442d5ef46da51d43d14))
* **bar:** distinguish native Codex subscription rows ([#1552](https://github.com/kaitranntt/ccs/issues/1552)) ([ba7a2ab](https://github.com/kaitranntt/ccs/commit/ba7a2abb799515447c30c99b75ef43b9362793ea))
* **bar:** preserve Gatekeeper quarantine on install ([#1534](https://github.com/kaitranntt/ccs/issues/1534)) ([c776e18](https://github.com/kaitranntt/ccs/commit/c776e184344132ad9b5bf6d7fcca88d8251e9414))
* **bar:** tolerate duplicate rows in alert pruning ([#1553](https://github.com/kaitranntt/ccs/issues/1553)) ([84ff4d5](https://github.com/kaitranntt/ccs/commit/84ff4d57a4a03ce3dfe105fab3b25c95bc45c0e5))
* **bar:** verify CCS Bar release archive digest ([#1532](https://github.com/kaitranntt/ccs/issues/1532)) ([d2848d3](https://github.com/kaitranntt/ccs/commit/d2848d39317950b36ac7038fcf22cb8e953787f9))
* bound Codex rollout tail reads ([#1547](https://github.com/kaitranntt/ccs/issues/1547)) ([06e8309](https://github.com/kaitranntt/ccs/commit/06e83091bec3cf4dff344019d02f836fdb7d2c13))
* **browser:** preserve profile-bound DevTools discovery ([#1541](https://github.com/kaitranntt/ccs/issues/1541)) ([ab6c59b](https://github.com/kaitranntt/ccs/commit/ab6c59ba354361d011e3004b9706a5ebe05ebf76))
* **cliproxy:** guard unsupported Qwen account auth ([b6ef4e5](https://github.com/kaitranntt/ccs/commit/b6ef4e5782f0dcd6dda3419c9b545dea6bfa1dcb))
* **cliproxy:** use root URL for Claude provider ([#1554](https://github.com/kaitranntt/ccs/issues/1554)) ([49a7b9d](https://github.com/kaitranntt/ccs/commit/49a7b9dc857bce7525e0b9a6be8d797b6841ca1f))
* **codex:** sanitize config override probes ([#1535](https://github.com/kaitranntt/ccs/issues/1535)) ([db44845](https://github.com/kaitranntt/ccs/commit/db44845857b62352058b07900de6c04c36c5ba27))
* **config:** update provider default models ([20e315b](https://github.com/kaitranntt/ccs/commit/20e315ba3f5f165602ec89a38e94b2c9249e7ab8))
* **cursor:** redact daemon token from dashboard start ([#1540](https://github.com/kaitranntt/ccs/issues/1540)) ([b85a3de](https://github.com/kaitranntt/ccs/commit/b85a3de26e45ffcfcd4db0f3216a41326a05f285))
* degrade WebSearch launch provisioning failures ([#1571](https://github.com/kaitranntt/ccs/issues/1571)) ([1a03985](https://github.com/kaitranntt/ccs/commit/1a0398579a974efa8adaa65446c51c5f512efa77))
* enforce tier lock during quota preflight ([#1550](https://github.com/kaitranntt/ccs/issues/1550)) ([361328c](https://github.com/kaitranntt/ccs/commit/361328c788e13fa471a1f6ced5c44411a131d503))
* handle auth-protected bar launch probes ([#1551](https://github.com/kaitranntt/ccs/issues/1551)) ([c040986](https://github.com/kaitranntt/ccs/commit/c0409862d2ab89682dae0987f872db745d798763))
* harden macOS bar launch descriptor ([#1533](https://github.com/kaitranntt/ccs/issues/1533)) ([10aff10](https://github.com/kaitranntt/ccs/commit/10aff10a67fbe7f4a9835aca8e394e3b62ae2a0c))
* harden release issue parsing ([#1536](https://github.com/kaitranntt/ccs/issues/1536)) ([74dd2f3](https://github.com/kaitranntt/ccs/commit/74dd2f38ccc1adcb4c7cd7fb825f14121b0d96b2))
* honor default target for Claude passthrough ([#1539](https://github.com/kaitranntt/ccs/issues/1539)) ([473aa08](https://github.com/kaitranntt/ccs/commit/473aa082f66a843edcea0d7ab9e9f94a2b585b67))
* ignore malformed bar analytics date keys ([#1556](https://github.com/kaitranntt/ccs/issues/1556)) ([e37a87c](https://github.com/kaitranntt/ccs/commit/e37a87c3a250c5f08793b119d7c0d41e1227bbcd))
* **logging:** harden structured trace redaction ([1462823](https://github.com/kaitranntt/ccs/commit/1462823be8c67895e81009aab0259263ae8b4097))
* **macos-bar:** launch dashboard without shell ([#1549](https://github.com/kaitranntt/ccs/issues/1549)) ([50f136a](https://github.com/kaitranntt/ccs/commit/50f136a1f0223fd4c39789ffdd273c30b1ad6b06))
* **proxy:** keep undici timeouts above the upstream request timeout ([#1524](https://github.com/kaitranntt/ccs/issues/1524)) ([8f9795b](https://github.com/kaitranntt/ccs/commit/8f9795bce24123786722d592d18dff8be59cc8d0))
* **usage:** price updated provider defaults ([34123a6](https://github.com/kaitranntt/ccs/commit/34123a62a69c7e5acd621fc54da901a6975f1709))

### Documentation

* **hardening:** finalize epic metrics + progress log (P1-P7) ([2d48488](https://github.com/kaitranntt/ccs/commit/2d484884752a6fd79ca1a891c62450333c15a4fe))

### Code Refactoring

* P5 god-file splits (test-backed, public API preserved) ([919be3c](https://github.com/kaitranntt/ccs/commit/919be3c722eed9f56f028a4929bf2ac8944d080d))
* P6 god-file splits (quota-fetcher + quota-fetcher-gemini-cli; 4 deferred) ([aecc1f7](https://github.com/kaitranntt/ccs/commit/aecc1f7217d192383d18c059690e38b47985ba18))

### Tests

* **bar:** harden bar-probe auth coverage; drop dead proxy shim ([#1555](https://github.com/kaitranntt/ccs/issues/1555)) ([3fa4a34](https://github.com/kaitranntt/ccs/commit/3fa4a342f974c3a346ba9b9d2ad3f429ae1eda0c))

### CI

* **bar:** auto-build and publish CCS Bar on main via self-hosted macOS runner ([b3a9abf](https://github.com/kaitranntt/ccs/commit/b3a9abffbce1c62957720e3fda9a83204f34757f))
2026-06-21 17:41:16 +00:00
Kai (Tam Nhu) Tran f9047d00a8 Merge pull request #1580 from kaitranntt/dev
feat: promote dev to main (CCS Bar v1.7.0, maintainability epic, provider fixes)
2026-06-21 13:37:22 -04:00
github-actions[bot] f43cad0fbc chore(release): 8.4.0-dev.17 2026-06-21 02:27:10 +00:00
Kai (Tam Nhu) Tran c97037230a Merge pull request #1579 from kaitranntt/kai/ci/bar-auto-release
ci(bar): auto-build and publish CCS Bar on main via self-hosted macOS runner
2026-06-20 22:23:02 -04:00
Tam Nhu Tran b3a9abffbc ci(bar): auto-build and publish CCS Bar on main via self-hosted macOS runner
Releasing the macOS bar app was fully manual (run package_app.sh on a Mac, then
gh release upload --clobber), so Swift-side changes never reached users until
someone remembered to rebuild and re-upload the floating ccs-bar-latest asset.

Add a tightly-scoped Bar Release workflow that does it automatically:
- triggers ONLY on push to main touching macos-bar/**, or manual dispatch, so
  regular PRs, dev pushes, and non-bar changes never start it
- runs ONLY on the dedicated self-hosted macOS runner (label ccs-bar); the Linux
  CI runners never match it and it never competes for them
- least-privilege contents:write, single-flight via concurrency

Version is sourced from a new macos-bar/VERSION single-line file (the workflow
reads it; the asset is always the latest build regardless). package_app.sh now
defaults to that file when no version arg is passed, so the local manual path and
CI share one source of truth. Documents the release process in docs/ccs-bar.md.
2026-06-20 22:17:40 -04:00
github-actions[bot] a843709135 chore(release): 8.4.0-dev.16 2026-06-20 23:58:01 +00:00
Kai (Tam Nhu) Tran 458f836a07 Merge pull request #1578 from kaitranntt/kai/feat/ccs-bar-codex-sync-spend-chart
feat(bar): live Codex usage sync with force refresh and spend-chart periods
2026-06-20 19:54:00 -04:00
Tam Nhu Tran 6ed5b2d62b feat(bar): live Codex usage sync with force refresh and spend-chart periods
Codex quota in the menu bar came only from frozen local session logs, so it
showed stale data ("older session") that no refresh could update. Fetch it live
from the same source the dashboard uses, under the existing Claude-style safety
controls (10-min TTL, in-flight coalescing, 429 backoff, circuit breaker,
serve-stale), falling back to local logs when offline or rate-limited. A success
with no usable 5h/weekly window keeps the local reading rather than caching a
contentless row. The footer refresh and a new inline button on the Codex card
force a live pull past the open debounce, and a forced /summary re-pulls native
rows while serving the last-known cached rows if the live pull overruns its
budget, so the Claude/Codex cards never blank mid-refresh.

The spend strip gains a Today / 7d / 30d selector (default 7d), a taller chart,
and bottom time-axis labels (local hours for today, weekday for 7d, dates for
30d). The analytics endpoint now exposes a 24-bucket hourly series for today,
converted from the pipeline's UTC hour keys to the user's local clock so the
intra-day chart matches the dashboard.
2026-06-20 18:37:18 -04:00
github-actions[bot] 9977c49fab chore(release): 8.4.0-dev.15 2026-06-20 20:27:30 +00:00
Kai (Tam Nhu) Tran e37a87c3a2 fix: ignore malformed bar analytics date keys (#1556)
* fix: ignore malformed bar analytics date keys

* style: apply prettier formatting to dynamic imports
2026-06-20 16:23:22 -04:00
walker1211 70a5f68a22 chore(ci): 重新触发 PR checks 2026-06-20 13:59:55 +08:00
walker1211 66251c5278 fix(build): 使用 type-only 导入平台类型 2026-06-20 13:49:16 +08:00
walker1211 99ed8090b1 fix(cliproxy): 按 backend 生成 provider 路由 2026-06-20 13:40:23 +08:00
ReWiG 2aaad43fd7 fix(proxy): forward stream_options.include_usage to OpenAI-compatible upstreams
Claude Code's status line and the session log showed 0 tokens for every
streaming response routed through the OpenAI-compatible proxy. The root
cause was that the upstream request did not include
`stream_options: { include_usage: true }`, so the provider (LiteLLM and
other OpenAI-compatible endpoints) never emitted the final SSE chunk
that carries `usage`. The proxy's stream parser was already wired to
forward that chunk into an Anthropic-shaped `message_delta` event but
had nothing to forward.

Set `stream_options.include_usage` whenever the incoming Anthropic
request is streamed. Non-streamed requests are unaffected.

Ref: https://platform.openai.com/docs/api-reference/chat-streaming
     (search 'include_usage')
2026-06-19 21:45:47 +03:00
github-actions[bot] b811cacaef chore(release): 8.4.0-dev.14 2026-06-19 14:04:17 +00:00
Kai (Tam Nhu) Tran 6e64a3ac6e Merge pull request #1573 from tiennm99/fix/update-provider-model-templates
fix(config): update provider default models
2026-06-19 10:00:20 -04:00
Tam Nhu Tran 34123a62a6 fix(usage): price updated provider defaults 2026-06-19 09:57:49 -04:00
tiennm99 20e315ba3f fix(config): update provider default models 2026-06-19 17:36:06 +07:00
github-actions[bot] 48e1c8976d chore(release): 8.4.0-dev.13 2026-06-19 03:00:30 +00:00
Kai (Tam Nhu) Tran 1a0398579a fix: degrade WebSearch launch provisioning failures (#1571) 2026-06-18 22:56:20 -04:00
github-actions[bot] 813a7a043a chore(release): 8.4.0-dev.12 2026-06-19 01:38:29 +00:00
Kai (Tam Nhu) Tran b6ef4e5782 fix(cliproxy): guard unsupported Qwen account auth 2026-06-18 21:34:27 -04:00
github-actions[bot] 5b6c3e87e9 chore(release): 8.4.0-dev.11 2026-06-18 23:52:27 +00:00
Kai (Tam Nhu) Tran 2a14904a23 Merge pull request #1568 from kaitranntt/kai/feat/maintainability-traceability-epic
Maintainability & Traceability Epic (P1-P7)
2026-06-18 19:48:25 -04:00
Tam Nhu Tran 1462823be8 fix(logging): harden structured trace redaction
Redact StageOptions error payloads and summarize debug launch args.

Propagate request IDs through Cursor daemon and dashboard completion logs.

Mark remaining P2/P3 maintainability targets as partial instead of overclaiming.
2026-06-18 18:48:13 -04:00
Tam Nhu Tran 2d48488475 docs(hardening): finalize epic metrics + progress log (P1-P7) 2026-06-18 18:48:13 -04:00
Tam Nhu Tran aecc1f7217 refactor: P6 god-file splits (quota-fetcher + quota-fetcher-gemini-cli; 4 deferred)
Epic P6 (partial: 2 of 6 targets). These two files have strong existing
per-provider test coverage, so the characterization-first requirement is met
by the safety net; both are split test-backed.

- src/cliproxy/quota/quota-fetcher.ts (1106 -> barrel 29 + 9 submodules, max
  254 LOC): status-classifier (the clean extract), http-client, auth-file-reader,
  project-lookup, available-models-fetcher, account-quota-fetcher,
  all-accounts-fetcher, types, constants.
- src/cliproxy/quota/quota-fetcher-gemini-cli.ts (1179 -> barrel 27 + 11
  submodules, max 334 LOC): token-parsing, auth-file-discovery,
  supplementary-metadata, error-parsing, bucket-building, managed-request,
  shared-utils, types, constants, index.

Public API preserved verbatim (incl. __testExports). All P3 structured logging
preserved through the splits. Regenerated eslint-rules/throw-error-baseline.json
(throws moved to new module paths).

Remaining P6 targets (characterization-first, deferred): oauth-handler.ts,
cursor-executor.ts, tool-sanitization-proxy.ts, + 1. Each needs dedicated
characterization-test work before splitting; tracked in the epic plan.

Metric: files > 400 LOC 91 -> 89. validate + validate:ci-parity green.
2026-06-18 18:48:13 -04:00
Tam Nhu Tran 2f94f35ec3 feat(lint): P7 enforcement gates (no-new-throw-error + max-lines) + docs
Epic P7. Locks in the epic's gains with ESLint gates so the adoption work
does not regress.

- ccs/no-new-throw-error (error): custom flat-config rule that flags NEW
  throw new Error(...) outside a generated baseline allowlist. Forces the
  typed-error taxonomy (src/errors/error-types.ts). Existing 338 sites are
  grandfathered in eslint-rules/throw-error-baseline.json; only NEW violations
  error. Rule normalizes the filename to repo-root-relative to match baseline
  keys regardless of how ESLint reports paths.
- max-lines (warn, 400, skipBlankLines/skipComments): warns on files over
  400 LOC (goal of P5/P6 god-file splits). Currently 51 warnings on the
  not-yet-split god-files (P6 territory).
- scripts/generate-throw-error-baseline.js: emits the allowlist from raw
  source (superset of real throws; never undercounts). Run after intentionally
  grandfathering a site, or quarterly to prune.
- tests/unit/eslint-rules/no-throw-new-error.test.ts: rule logic (flags
  off-allowlist, passes on-allowlist/typed/rethrow, line-sensitivity).
- docs/code-standards.md: Lint Enforcement Gates section.
- docs/logging-contract.md: error.code -> ExitCode table (from P4).

validate + validate:ci-parity green.
2026-06-18 18:48:13 -04:00
Tam Nhu Tran 919be3c722 refactor: P5 god-file splits (test-backed, public API preserved)
Epic P5. Splits 4 test-backed god-files into focused submodules using the
Monster File Splitting methodology; each original file is now a thin barrel
re-exporting the full public surface, so consumers are unchanged.

- src/management/shared-manager.ts (1631 -> barrel 21 + 10 submodules,
  max 337 LOC): fs-helpers, symlink-helpers, plugin-metadata-normalizer,
  plugin-layout-internals, shared-dir-linker, project-context-sync,
  project-memory-sync, migrations, orchestrator, types.
- src/web-server/routes/cliproxy-stats-routes.ts (1216 -> barrel 23 + 8
  submodules, max 290 LOC): shared, quota-helpers, version-helpers,
  restart-route, quota-routes, error-log-routes, config-routes, router.
- src/commands/persist-command.ts (1071 -> barrel + 8 submodules, max 258):
  types, arg-parsing, secure-file, backup-rotation, secret-detection,
  receipt, help, handler.
- src/commands/cliproxy/quota-subcommand.ts (1130 -> barrel + 14 submodules,
  max 303): types, format-helpers, codex/claude-window-helpers, provider-runtime,
  handlers, per-provider sections.

Public API preserved verbatim (default + named exports). All P3 structured
logging and P4 typed errors preserved through the splits. Each resulting file
< 400 LOC. Existing tests (shared-manager x4, cliproxy-stats x4, persist x2,
quota-subcommand x1) green, unchanged.

Metric: files > 400 LOC 95 -> 91. validate + validate:ci-parity green.
2026-06-18 18:48:13 -04:00
Tam Nhu Tran 7234ef8fcf feat(errors): P4 typed-error taxonomy adoption (0->91% locked) + erasable-syntax fix
Epic P4. Migrates plain throw new Error to the typed-error classes in the four
locked subdomains, and makes the taxonomy erasable-syntax-compatible so it can
be adopted across UI-reachable code.

Migration (cliproxy/auth, web-server/routes, auth):
- 21 of 23 throws in the locked subdomains now use typed subclasses
  (ProfileError, AuthError, ConfigError, ValidationError, ProviderError).
- Typed adoption in locked subdomains: 0/23 -> 21/23 (91.3%), > 40% target.
- Overall typed adoption: 0.9% -> 8.6%.
- Messages preserved exactly (message-based tests stable). Exit codes now
  differentiate via handleError (ProfileError=7, AuthError=4, ConfigError=2,
  ProviderError=6). ccs doctor 0/1 contract untouched (outside scope).

Erasable-syntax fix (unblocks the migration in the UI build graph):
- exit-codes.ts: enum ExitCode -> const object + union type (value and type
  usage both preserved; no Object.values(ExitCode) consumers).
- error-types.ts: constructor parameter properties -> explicit readonly field
  declarations + body assignment.
- The web UI build enforces erasableSyntaxOnly (ui/tsconfig.app.json) and
  reaches src/errors via the @shared -> src/auth graph; pre-erasable
  error-types blocked the build once profile-registry adopted typed errors.

Compat audit: docs/reports/typed-error-exit-code-compat-audit.md (Q1 resolved:
migrate freely; only documented contract is ccs doctor, which is untouched).
Behavior-lock: src/errors/__tests__/typed-error-migration-exit-codes.test.ts
(taxonomy -> exit-code mapping, instanceof chains, context fields).

validate + validate:ci-parity green (incl. UI build).
2026-06-18 18:48:12 -04:00