better-ccflare 3.5.37 β 3.5.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -27
- package/dist/better-ccflare +0 -0
- package/package.json +56 -56
package/README.md
CHANGED
|
@@ -157,7 +157,7 @@ Continue to [Configure Claude SDK](https://github.com/tombii/better-ccflare#conf
|
|
|
157
157
|
|
|
158
158
|
### Environment Variables
|
|
159
159
|
|
|
160
|
-
better-ccflare supports several environment variables for configuration:
|
|
160
|
+
better-ccflare supports several environment variables for configuration. The most commonly used ones:
|
|
161
161
|
|
|
162
162
|
```bash
|
|
163
163
|
# Server Configuration
|
|
@@ -186,40 +186,18 @@ RETRY_ATTEMPTS=3 # Number of retry attempts
|
|
|
186
186
|
RETRY_DELAY_MS=1000 # Initial retry delay in milliseconds
|
|
187
187
|
RETRY_BACKOFF=2 # Retry backoff multiplier
|
|
188
188
|
|
|
189
|
-
# Overload retry (529 no-reset in-place retry before account cooldown)
|
|
190
|
-
CCFLARE_OVERLOAD_RETRY_ENABLED=true # Set to "false" to disable (default: true)
|
|
191
|
-
CCFLARE_OVERLOAD_RETRY_MAX_ATTEMPTS=2 # Total attempts incl. original (default: 2)
|
|
192
|
-
CCFLARE_OVERLOAD_RETRY_BASE_MS=750 # Backoff base in ms; 0 = no sleep (default: 750)
|
|
193
|
-
CCFLARE_OVERLOAD_RETRY_MAX_MS=3000 # Backoff ceiling in ms (default: 3000)
|
|
194
|
-
|
|
195
|
-
# Health endpoint
|
|
196
|
-
HEALTH_DETAIL_ENABLED=false # Enable ?detail=1 on /health to expose per-account status (default: off, set true for internal monitoring)
|
|
197
|
-
|
|
198
|
-
# Agent Discovery
|
|
199
|
-
BETTER_CCFLARE_DISCOVER_PLUGIN_AGENTS=false # Set to true to discover agents distributed by Claude Code plugins
|
|
200
|
-
# (reads ~/.claude/plugins/installed_plugins.json)
|
|
201
|
-
|
|
202
189
|
# Storage
|
|
203
190
|
STORE_PAYLOADS=false # Disable storing request/response bodies (reduces DB size and memory usage)
|
|
204
191
|
# Token counts, costs, model, status and timing are still recorded
|
|
205
|
-
|
|
206
|
-
# Payload encryption at rest (optional)
|
|
207
|
-
# When set, request/response payloads are encrypted with AES-256-GCM before
|
|
208
|
-
# being written to `request_payloads`. Existing plaintext rows remain readable.
|
|
209
|
-
# Generate with: openssl rand -hex 32
|
|
210
|
-
PAYLOAD_ENCRYPTION_KEY= # 64-character hex (32 bytes / AES-256). Unset = plaintext storage.
|
|
211
192
|
```
|
|
212
193
|
|
|
213
|
-
**Encryption notes**:
|
|
214
|
-
- Without a key, payloads are stored as plaintext (no behavior change from prior versions).
|
|
215
|
-
- Losing the key makes encrypted rows unreadable β payload reads throw rather than silently returning garbage. Back the key up alongside the database.
|
|
216
|
-
- The key is read once at process start (and once per Bun worker). Rotating it requires a re-encrypt migration; not yet built.
|
|
217
|
-
|
|
218
194
|
**Security Notes**:
|
|
219
195
|
- Use `BETTER_CCFLARE_HOST=127.0.0.1` to bind only to localhost for better security
|
|
220
196
|
- Never commit `.env` files containing sensitive values to version control
|
|
221
197
|
- Use environment-specific configuration for production deployments
|
|
222
198
|
|
|
199
|
+
π **See [docs/configuration.md](docs/configuration.md) for the complete list** β overload/rate-limit retry tuning, health endpoint detail, agent discovery, payload encryption at rest, model catalog refresh, PostgreSQL pooling, Codex prompt-cache keys, and more.
|
|
200
|
+
|
|
223
201
|
### Using .env Files
|
|
224
202
|
|
|
225
203
|
better-ccflare automatically supports `.env` files for easy configuration management. You can create a `.env` file in your project directory:
|
|
@@ -803,7 +781,7 @@ Full documentation available in [`docs/`](docs/):
|
|
|
803
781
|
**Not supported:**
|
|
804
782
|
- ARM32 devices (Raspberry Pi Zero, Pi 1, Pi 2, or 32-bit OS)
|
|
805
783
|
|
|
806
|
-
##
|
|
784
|
+
## Acknowledgements
|
|
807
785
|
|
|
808
786
|
Inspired by [snipeship/ccflare](https://github.com/snipeship/ccflare) - thanks for the original idea and implementation!
|
|
809
787
|
|
|
@@ -824,7 +802,7 @@ Inspired by [snipeship/ccflare](https://github.com/snipeship/ccflare) - thanks f
|
|
|
824
802
|
- [@CorentinLumineau](https://github.com/CorentinLumineau) - Plugin agent discovery scanning Claude Code plugin directories for agent definitions alongside the built-in agents path, with manifest parsing, name validation, and dashboard display (PR #197)
|
|
825
803
|
- [@d4rken](https://github.com/d4rken) - fixed dashboard "Active" badge showing the most-recently-used account instead of the one the load balancer would actually pick next β introduced a side-effect-free `peek()` to `LoadBalancingStrategy` (shared `peek-availability.ts` mirrors auto-unpause logic without DB writes), dashboard accounts endpoint stamps `isPrimary: true` on the predicted pick, badge renamed from "Active" to "Primary"; also inlined the account-row controls previously hidden behind a `MoreHorizontal` dropdown into flat action buttons (PR #218); Dashboard account row reorganization into wrap-friendly multi-row layout with overflow kebab menu, restored tooltip context for moved actions, and deduped re-auth condition (PR #204); surfaced API key mutation errors inline in create/delete/toggle dialogs, prevented first-key lockout by disabling admin checkbox during loading with fail-safe isFirstKey guard, and added dismissible error banner for role/toggle failures (PR #205); fixed OAuth account creation silently discarding the priority value by adding a priority column to oauth_sessions and threading it through init β session β callback β account creation, plus replaced the constraint-dropping `CREATE TABLE β¦ AS SELECT` tier-drop rebuild with an explicit schema-preserving migration (PR #206); surfaced update-check failure reason in dashboard tile by including the underlying error message in the backend 500 response body, switching to structured Logger, and displaying the error message under "Check Failed" in the frontend sidebar tile (PR #207); exempted /api/version/check from authentication so the dashboard update tile works correctly when API keys are configured (PR #208); replaced bare error-code list with grouped error UI featuring per-(errorCode, account) dismissal, time-window selector (1h/24h/7d/all) persisted in localStorage, clickable rows opening a details modal with human-readable descriptions and recovery info, and a CTE+window-function backend query joining account rate-limit state (PR #209); added combined-quota "5h Pool" and "7d Pool" metric tiles to the Overview dashboard aggregating per-account utilization across all eligible accounts, with worst-account subline, popover breakdown by contributing/exhausted/excluded/fallback accounts, at-risk projection, and next-reset time (PR #210); fixed SIGTERM race where interval-manager's synchronous process.exit(0) short-circuited async shutdown, dropping in-flight requests and pending DB writes β removed the early exit, added HTTP drain via serverInstance.stop(), reordered shutdown sequence (schedulers β HTTP drain β usage worker β DB flush), and added a 30s watchdog to bound total shutdown time (PR #214); fixed API key copy button silently failing on plain-HTTP hosts by adding a `copyText` helper that prefers the async Clipboard API and falls back to an off-screen textarea + `execCommand` for non-secure contexts, and routed `CopyButton` and the inline copy buttons in `ApiKeysTab` through it so the checkmark animation works in both cases (PR #215); fixed post-processor worker timing out on large databases (multi-GB) by passing `fastMode=true` to skip the redundant PRAGMA integrity_check β the main thread already ran it, and re-running it in the worker blew past the 10s startup deadline causing silent request loss (PR #220); replaced the bare recent-errors string list with a grouped error card featuring per-(errorCode, account) dismissal, time-window selector (1h/24h/7d/all), clickable rows opening a details modal with human-readable descriptions, recovery info, and provider-aware copy for model_fallback_429 that escalates to error only when no other accounts are available (PR #212); redesigned request history row layout into a two-row card that never wraps the top-line summary, switched the list view to the summary-only endpoint to eliminate the ~12MB per-page-load body fetch, and fixed the API key and account filter dropdowns to source options from dedicated endpoints so deleted-but-historical entries remain selectable (PR #221); replaced fs.copyFileSync migration backup with VACUUM INTO + atomic rename via a .partial temp file, producing a defragmented consistent snapshot and ensuring the named backup only appears complete (PR #222); added bounded backup retention β after each migration backup, prunes `.backup.<ts>` files to keep the newest N (default 3, configurable via `BETTER_CCFLARE_MIGRATION_BACKUP_KEEP`, 0 to disable), sorting by name-embedded timestamp to survive rsync/clock-drift, skipping operator-renamed files with non-integer suffixes (PR #223); bumped the post-processor worker startup timeout from 10s to 60s and made it overridable via `CF_WORKER_STARTUP_TIMEOUT_MS`, preventing silent analytics loss on large (multi-GB) databases where the per-handle PRAGMA work blew past the old deadline (PR #224); narrowed the migration backup gate from a 41-condition OR to only the three genuinely irreversible operations (refresh_token NOT NULL rebuild, account_tier drop, oauth_sessions.tier drop), eliminating multi-GB backup copies on every restart when only additive ALTER TABLE ADD COLUMN migrations are pending (PR #225); resolved all 42 error-level Biome diagnostics across dashboard components, hooks, and openai-formats tests β replaced `noNonNullAssertedOptionalChain` patterns in tests with explicit non-null assertions after `toBeDefined()`, converted `forEach` callbacks to `forβ¦of` to fix `useIterableCallbackReturn`, added scoped `biome-ignore` comments with explanations for `noArrayIndexKey` cases where stable ids aren't available, and fixed two a11y errors in ErrorBoundary (SVG role/aria-label/title, button type attribute) (PR #226); replaced the blocking startup `PRAGMA integrity_check` (which froze the event loop for 94s on a 7.6 GiB DB) with a dual-timer background scheduler running `quick_check` every 6h and a full `integrity_check` + `foreign_key_check` every 24h in a dedicated `bun:sqlite` worker, added a sticky-corrupt rule so a quick `ok` cannot mask a full corruption finding, exposed the status via an expanded `/api/storage` response and a new `POST /api/storage/integrity/check` on-demand endpoint, and surfaced it in the Overview dashboard via a `StorageIntegrityCard` and sticky `StorageIntegrityBanner` on corruption β also adds `foreign_key_check` to the full probe since `integrity_check` per SQLite docs does not verify foreign keys (PR #227); fixed Logger.{error,warn,info,debug} silently emitting `{}` for Error instances by normalizing Errors to plain objects with name/message/stack/cause before serialization β affects 159 call sites including the "Failed to intercept/modify request" line in agent-interceptor β and demoted all per-request INFO logs in agent-interceptor and extractSystemPrompt to DEBUG, plus skipped the spurious `~/.claude/.claude/agents` path construction for global CLAUDE.md entries since global agents are already loaded unconditionally by AgentRegistry (PR #228); fixed `LOG_LEVEL=DEBUG` being silently ignored β `LogLevel.DEBUG === 0` is falsy so `getLogLevelFromEnv() || level` fell back to the constructor default (INFO), suppressing all debug output even when explicitly configured; switched to `??` so the env override applies for DEBUG too, and added regression tests covering DEBUG/WARN/ERROR/unset/unknown values plus the `silentConsole` side-effect (PR #229); eliminated the blocking full VACUUM trap β hourly retention cleanup and "Compact now" called `incrementalVacuum` which silently fell back to a live full VACUUM on existing DBs (auto_vacuumβ INCREMENTAL), freezing the proxy for minutes every hour β replaced with: `configureSqlite` and `ensureSchema` set `PRAGMA auto_vacuum = INCREMENTAL` on fresh DBs, new `bootstrapAutoVacuum()` migrates existing mode-0 DBs once at startup before HTTP binds (one-time VACUUM cost, never blocks live traffic), `incrementalVacuum()` now dispatches `PRAGMA incremental_vacuum(N)` to a worker thread on mode-2 DBs or logs and returns otherwise (no destructive fallback), drops hourly N from 200000 to 8000 (~32 MiB) to keep writer-slot hold sub-100ms, adds consecutive-skip escalation after 3 missed ticks, and gates the auto_vacuum PRAGMA on mode=0 only to preserve operator-set FULL mode; also removed the dashboard "Compact now" button/endpoint (same hang trap from a different surface) while retaining `bun run cli --compact` with a writer-lock probe that refuses if a running service holds it; and dropped the stale `fastMode` constructor arg from DatabaseOperations after PR #227's integrity-scheduler rework made it redundant (PR #230); fixed `mmapSize=0` being silently ignored in `configureSqlite` β the `> 0` guard meant the default `mmapSize: 0` fell through to bun:sqlite's built-in mmap default (~15 GiB observed on a 15 GiB DB), causing the OOM-killing VACUUM scenario from #230 to recur; also applied memory-bounded PRAGMAs (`mmap_size=0`, `cache_size=-2000`, `temp_store=FILE`) to the full-VACUUM worker thread opened by `compact()` / `--compact`, which had the same gap (PR #231); bounded AsyncDbWriter retention to stop a post-processor worker memory leak β split the single job queue into separate metadata (count-capped at 2000) and payload (count-capped at 1000, byte-capped at 100 MB) queues, added a MAX_JOBS_PER_TICK=50 / MAX_DRAIN_MS_PER_TICK=250ms dual budget so processQueue yields to the event loop instead of monopolizing it, added round-robin scheduling to prevent starvation between queue types, added canAcceptPayload() preflight to skip serialization under backpressure, and surfaced per-queue lengths, byte budget, oldest-job age, and per-kind drop counters in getHealth() (PR #234); enabled the refresh-usage button for Codex OAuth accounts β sends one minimal `/responses` request (bounded to `max_output_tokens: 1`, `reasoning.effort: "minimal"`) to capture `x-codex-*` rate-limit headers, cancels the response body after the header snapshot, deduplicates concurrent clicks per-account with a shared in-flight promise, and wires the result into the existing usageCache + accounts.rate_limit_reset flow; polling intentionally excluded to avoid burning quota at 90s cadence (PR #219); added "Avg / day" and "Avg / week" burn-rate sub-rows to the Plan Value metric card on the Overview dashboard β computed server-side from fixed 7-day and 30-day windows (filter-independent) with a clamped divisor via `effectiveBurnRateDays` so thin history doesn't inflate averages, plus a generic `subRows` prop on `MetricCard` for the UI (PR #235); routed Anthropic 529 overloaded_error responses through the existing rate-limit failover machinery so configured fallback providers take over during an overload instead of forwarding the 529 directly to the client β `parseRateLimit` treats 529 as rate-limited, parsing Retry-After (delta-seconds and HTTP-date) and x-ratelimit-reset with a `clampResetTime` helper that caps reset times to 24h to prevent hostile headers from permanently disabling an account; mid-stream `SseRateLimitSniffer` fires on `overloaded_error` frames for Anthropic-shape providers (anthropic/claude-oauth) only with a line-anchored regex to prevent false positives; two new `RateLimitReason` values (`upstream_529_overloaded_with_reset` / `upstream_529_overloaded_no_reset`) surface accurate audit attribution in the dashboard; `returnRateLimitedResponseOnExhaustion` forwards the original 529 upstream response to the client when the full account pool is exhausted so callers see the real error instead of a generic 503 (PR #236); fixed auto-refresh scheduler probing manually-paused accounts in an endless loop β the eligibility SQL excluded paused accounts only when `auto_pause_on_overage_enabled=0`, ignoring `pause_reason`, while the auto-resume guard in `sendDummyMessage` only un-pauses accounts where `pause_reason IN (NULL,'overage')`; aligned the SQL eligibility query to a positive allowlist (`paused=0 OR (overage_enabled=1 AND pause_reason IN (NULL,'overage'))`) and tightened `isOveragePaused` in `account-selector.ts` to require the same condition, so manual, failure-threshold, and peak_hours pauses are left completely alone; adds a regression test that re-executes the live scheduler SQL against a seeded in-memory SQLite DB covering all seven pause-reason scenarios (PR #237); replaced flat per-account 429 cooldown with adaptive exponential backoff β `consecutive_rate_limits` counter increments atomically in SQL on each 429 and drives `min(upstream_reset, BASE Γ 2^(nβ1))` cooldown (capped at MAX, default 30s base / 5min max), counter resets after 5min of clean operation or on successful token refresh, all four 429 paths (response-processor, model_fallback_429, all_models_exhausted_429, mid-stream SSE sniffer) route through a single `applyRateLimitCooldown` helper, tunables overridable via `CCFLARE_RATE_LIMIT_BACKOFF_BASE_MS` / `CCFLARE_RATE_LIMIT_BACKOFF_MAX_MS` / `CCFLARE_RATE_LIMIT_RESET_STABILITY_MS` (PR #213)
|
|
826
804
|
- [@zionts](https://github.com/zionts) β fix false "integrity check failed" banner on large DBs; adaptive incremental vacuum; payload retention default reduction ([#259](https://github.com/tombii/better-ccflare/pull/259)); session-affinity load-balancing strategy for per-client sticky routing with least-used spread ([#285](https://github.com/tombii/better-ccflare/pull/285))
|
|
827
|
-
- [@StartupBros](https://github.com/StartupBros) β surface Codex SSE `error`/`response.failed` events to clients instead of fabricating empty success turns ([#274](https://github.com/tombii/better-ccflare/pull/274)); synthesize safe `count_tokens` responses for Codex without upstream calls or OAuth refresh ([#275](https://github.com/tombii/better-ccflare/pull/275)); sanitize Codex tool-call inputs at the Anthropic compatibility boundary ([#277](https://github.com/tombii/better-ccflare/pull/277)); align Codex tool-call semantics so tool loops work correctly with Anthropic-compatible clients ([#278](https://github.com/tombii/better-ccflare/pull/278)); inject a continuation nudge after Codex replays Skill tool results so the model resumes the original request instead of stalling ([#279](https://github.com/tombii/better-ccflare/pull/279)); add native xAI/Grok OAuth provider with token refresh, Grok Build credits polling via gRPC-web, and full dashboard integration ([#281](https://github.com/tombii/better-ccflare/pull/281)); session volume circuit breaker guarding against runaway subagent fan-out β per-session rolling-hour request counting with a warn threshold (default 300/h) and opt-in reject threshold, Anthropic-shaped 429 before account selection burns upstream quota, and Codex Responses session-identity propagation so `/v1/responses` traffic is governed too ([#303](https://github.com/tombii/better-ccflare/pull/303)); opt-in OpenAI `prompt_cache_key` for Codex requests with per-conversation partitioning (session id + instructions + first input item) to keep concurrent subagent conversations from thrashing a single cache key, gated to OpenAI's own hosts so custom/self-hosted OpenAI-compatible endpoints are unaffected ([#306](https://github.com/tombii/better-ccflare/pull/306))
|
|
805
|
+
- [@StartupBros](https://github.com/StartupBros) β surface Codex SSE `error`/`response.failed` events to clients instead of fabricating empty success turns ([#274](https://github.com/tombii/better-ccflare/pull/274)); synthesize safe `count_tokens` responses for Codex without upstream calls or OAuth refresh ([#275](https://github.com/tombii/better-ccflare/pull/275)); sanitize Codex tool-call inputs at the Anthropic compatibility boundary ([#277](https://github.com/tombii/better-ccflare/pull/277)); align Codex tool-call semantics so tool loops work correctly with Anthropic-compatible clients ([#278](https://github.com/tombii/better-ccflare/pull/278)); inject a continuation nudge after Codex replays Skill tool results so the model resumes the original request instead of stalling ([#279](https://github.com/tombii/better-ccflare/pull/279)); add native xAI/Grok OAuth provider with token refresh, Grok Build credits polling via gRPC-web, and full dashboard integration ([#281](https://github.com/tombii/better-ccflare/pull/281)); session volume circuit breaker guarding against runaway subagent fan-out β per-session rolling-hour request counting with a warn threshold (default 300/h) and opt-in reject threshold, Anthropic-shaped 429 before account selection burns upstream quota, and Codex Responses session-identity propagation so `/v1/responses` traffic is governed too ([#303](https://github.com/tombii/better-ccflare/pull/303)); opt-in OpenAI `prompt_cache_key` for Codex requests with per-conversation partitioning (session id + instructions + first input item) to keep concurrent subagent conversations from thrashing a single cache key, gated to OpenAI's own hosts so custom/self-hosted OpenAI-compatible endpoints are unaffected ([#306](https://github.com/tombii/better-ccflare/pull/306)); enabled the GPT-5.6 model family (sol/terra/luna) on the Codex provider by advertising codex-cli 0.144.1 in request headers and adding context-window metadata (372k for 5.6, 272k for 5.5, 128k for 5.3-codex-spark) with longest-prefix fallback so dated/suffixed model variants still resolve to their family's window ([#304](https://github.com/tombii/better-ccflare/pull/304))
|
|
828
806
|
- [@robsonek](https://github.com/robsonek) β Usage History dashboard tab: per-account, per-window usage utilization time series with server-computed exhaustion prediction, persisted via a callback-injected snapshot hook on the existing `/oauth/usage` poll (no new Anthropic API calls), dual SQLite/PostgreSQL migration, retention pruning, and jitter-tolerant window segmentation ([#294](https://github.com/tombii/better-ccflare/pull/294))
|
|
829
807
|
|
|
830
808
|
## Contributing
|
package/dist/better-ccflare
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
2
|
+
"name": "better-ccflare",
|
|
3
|
+
"version": "3.5.39",
|
|
4
|
+
"description": "Load balancer proxy for Claude API with intelligent distribution across multiple OAuth accounts to avoid rate limiting",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/tombii/better-ccflare.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/tombii/better-ccflare#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/tombii/better-ccflare/issues"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"better-ccflare": "dist/better-ccflare"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "bun run src/main.ts",
|
|
20
|
+
"build": "mkdir -p dist && bun -e \"const fs=require('fs'); if (!fs.existsSync('../../packages/database/src/inline-vacuum-worker.ts')) { fs.writeFileSync('../../packages/database/src/inline-vacuum-worker.ts', 'export const EMBEDDED_VACUUM_WORKER_CODE = \\\"\\\";'); }\" && bun -e \"const fs=require('fs'); if (!fs.existsSync('../../packages/database/src/inline-incremental-vacuum-worker.ts')) { fs.writeFileSync('../../packages/database/src/inline-incremental-vacuum-worker.ts', 'export const EMBEDDED_INCREMENTAL_VACUUM_WORKER_CODE = \\\"\\\";'); }\" && bun -e \"const fs=require('fs'); if (!fs.existsSync('../../packages/database/src/inline-integrity-check-worker.ts')) { fs.writeFileSync('../../packages/database/src/inline-integrity-check-worker.ts', 'export const EMBEDDED_INTEGRITY_CHECK_WORKER_CODE = \\\"\\\";'); }\" && bun build ../../packages/database/src/vacuum-worker.ts --outfile dist/vacuum-worker.js --target=bun --minify && bun -e \"const fs=require('fs'); const code=fs.readFileSync('dist/vacuum-worker.js','utf8'); const encoded=Buffer.from(code).toString('base64'); fs.writeFileSync('../../packages/database/src/inline-vacuum-worker.ts', 'export const EMBEDDED_VACUUM_WORKER_CODE = \\\"' + encoded + '\\\";');\" && bun build ../../packages/database/src/incremental-vacuum-worker.ts --outfile dist/incremental-vacuum-worker.js --target=bun --minify && bun -e \"const fs=require('fs'); const code=fs.readFileSync('dist/incremental-vacuum-worker.js','utf8'); const encoded=Buffer.from(code).toString('base64'); fs.writeFileSync('../../packages/database/src/inline-incremental-vacuum-worker.ts', 'export const EMBEDDED_INCREMENTAL_VACUUM_WORKER_CODE = \\\"' + encoded + '\\\";');\" && bun build ../../packages/database/src/integrity-check-worker.ts --outfile dist/integrity-check-worker.js --target=bun --minify && bun -e \"const fs=require('fs'); const code=fs.readFileSync('dist/integrity-check-worker.js','utf8'); const encoded=Buffer.from(code).toString('base64'); fs.writeFileSync('../../packages/database/src/inline-integrity-check-worker.ts', 'export const EMBEDDED_INTEGRITY_CHECK_WORKER_CODE = \\\"' + encoded + '\\\";');\" && rm -f dist/better-ccflare && bun build src/main.ts --compile --outfile dist/better-ccflare --target=bun --minify --define __BETTER_CCFLARE_VERSION__='\\\"'$(node -p \"require('./package.json').version\")'\\\"' && rm -f dist/vacuum-worker.js dist/incremental-vacuum-worker.js dist/integrity-check-worker.js",
|
|
21
|
+
"build:multi": "bun run build-multi-arch.ts",
|
|
22
|
+
"build:linux-amd64": "bun run build && bun build src/main.ts --compile --outfile dist/better-ccflare-linux-amd64 --target=bun-linux-amd64 --minify",
|
|
23
|
+
"build:linux-arm64": "bun run build && bun build src/main.ts --compile --outfile dist/better-ccflare-linux-arm64 --target=bun-linux-arm64 --minify",
|
|
24
|
+
"build:macos-x86_64": "bun run build && bun build src/main.ts --compile --outfile dist/better-ccflare-macos-x86_64 --target=bun-darwin-x64 --minify",
|
|
25
|
+
"build:macos-arm64": "bun run build && bun build src/main.ts --compile --outfile dist/better-ccflare-macos-arm64 --target=bun-darwin-arm64 --minify",
|
|
26
|
+
"build:windows-x64": "bun run build && bun build src/main.ts --compile --outfile dist/better-ccflare-windows-x64.exe --target=bun-windows-x64 --minify",
|
|
27
|
+
"prepublishOnly": "cp ../../README.md . && bun run --cwd ../.. build:dashboard && bun run build && jq 'del(.dependencies[\"@better-ccflare/cli-commands\", \"@better-ccflare/config\", \"@better-ccflare/core\", \"@better-ccflare/core-di\", \"@better-ccflare/database\", \"@better-ccflare/logger\", \"@better-ccflare/server\"])' package.json > package.json.tmp && mv package.json.tmp package.json",
|
|
28
|
+
"postpublish": "chmod +x dist/better-ccflare"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.0.0"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"dotenv": "^17.4.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist/better-ccflare",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"keywords": [
|
|
44
|
+
"claude",
|
|
45
|
+
"anthropic",
|
|
46
|
+
"api",
|
|
47
|
+
"proxy",
|
|
48
|
+
"load-balancer",
|
|
49
|
+
"rate-limiting",
|
|
50
|
+
"oauth",
|
|
51
|
+
"cli",
|
|
52
|
+
"analytics",
|
|
53
|
+
"monitoring"
|
|
54
|
+
],
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
}
|
|
58
58
|
}
|