fest-gateway 0.1.0

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.
Files changed (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/dist/cli/claude.js +326 -0
  4. package/dist/cli/claude.js.map +1 -0
  5. package/dist/cli/config.js +59 -0
  6. package/dist/cli/config.js.map +1 -0
  7. package/dist/cli/login.js +130 -0
  8. package/dist/cli/login.js.map +1 -0
  9. package/dist/cli/logout.js +20 -0
  10. package/dist/cli/logout.js.map +1 -0
  11. package/dist/cli/whoami.js +34 -0
  12. package/dist/cli/whoami.js.map +1 -0
  13. package/dist/server/adapters/anthropic.js +74 -0
  14. package/dist/server/adapters/anthropic.js.map +1 -0
  15. package/dist/server/adapters/fireworks.js +54 -0
  16. package/dist/server/adapters/fireworks.js.map +1 -0
  17. package/dist/server/adapters/index.js +16 -0
  18. package/dist/server/adapters/index.js.map +1 -0
  19. package/dist/server/adapters/registry.js +38 -0
  20. package/dist/server/adapters/registry.js.map +1 -0
  21. package/dist/server/adapters/rewrite.js +152 -0
  22. package/dist/server/adapters/rewrite.js.map +1 -0
  23. package/dist/server/adapters/url.js +24 -0
  24. package/dist/server/adapters/url.js.map +1 -0
  25. package/dist/server/api/auth.js +213 -0
  26. package/dist/server/api/auth.js.map +1 -0
  27. package/dist/server/api/live.js +108 -0
  28. package/dist/server/api/live.js.map +1 -0
  29. package/dist/server/api/models.js +129 -0
  30. package/dist/server/api/models.js.map +1 -0
  31. package/dist/server/api/oauth.js +300 -0
  32. package/dist/server/api/oauth.js.map +1 -0
  33. package/dist/server/api/routes.js +164 -0
  34. package/dist/server/api/routes.js.map +1 -0
  35. package/dist/server/api/routing-view.js +47 -0
  36. package/dist/server/api/routing-view.js.map +1 -0
  37. package/dist/server/auth/accounts.js +111 -0
  38. package/dist/server/auth/accounts.js.map +1 -0
  39. package/dist/server/auth/gateway-401.js +85 -0
  40. package/dist/server/auth/gateway-401.js.map +1 -0
  41. package/dist/server/auth/guard.js +74 -0
  42. package/dist/server/auth/guard.js.map +1 -0
  43. package/dist/server/auth/oauth.js +43 -0
  44. package/dist/server/auth/oauth.js.map +1 -0
  45. package/dist/server/auth/password.js +104 -0
  46. package/dist/server/auth/password.js.map +1 -0
  47. package/dist/server/auth/posture.js +145 -0
  48. package/dist/server/auth/posture.js.map +1 -0
  49. package/dist/server/auth/session.js +161 -0
  50. package/dist/server/auth/session.js.map +1 -0
  51. package/dist/server/bin/fest.js +589 -0
  52. package/dist/server/bin/fest.js.map +1 -0
  53. package/dist/server/config.js +109 -0
  54. package/dist/server/config.js.map +1 -0
  55. package/dist/server/credentials/provider.js +70 -0
  56. package/dist/server/credentials/provider.js.map +1 -0
  57. package/dist/server/credentials/resolve.js +89 -0
  58. package/dist/server/credentials/resolve.js.map +1 -0
  59. package/dist/server/http/body.js +66 -0
  60. package/dist/server/http/body.js.map +1 -0
  61. package/dist/server/http/errors.js +144 -0
  62. package/dist/server/http/errors.js.map +1 -0
  63. package/dist/server/http/headers.js +189 -0
  64. package/dist/server/http/headers.js.map +1 -0
  65. package/dist/server/http/pipe.js +97 -0
  66. package/dist/server/http/pipe.js.map +1 -0
  67. package/dist/server/http/server.js +226 -0
  68. package/dist/server/http/server.js.map +1 -0
  69. package/dist/server/http/sse.js +167 -0
  70. package/dist/server/http/sse.js.map +1 -0
  71. package/dist/server/http/static.js +138 -0
  72. package/dist/server/http/static.js.map +1 -0
  73. package/dist/server/ingest/live-bus.js +67 -0
  74. package/dist/server/ingest/live-bus.js.map +1 -0
  75. package/dist/server/ingest/sink.js +141 -0
  76. package/dist/server/ingest/sink.js.map +1 -0
  77. package/dist/server/log.js +31 -0
  78. package/dist/server/log.js.map +1 -0
  79. package/dist/server/pipeline/count-tokens.js +48 -0
  80. package/dist/server/pipeline/count-tokens.js.map +1 -0
  81. package/dist/server/pipeline/dispatch.js +138 -0
  82. package/dist/server/pipeline/dispatch.js.map +1 -0
  83. package/dist/server/pipeline/passthrough.js +392 -0
  84. package/dist/server/pipeline/passthrough.js.map +1 -0
  85. package/dist/server/pipeline/preflight.js +66 -0
  86. package/dist/server/pipeline/preflight.js.map +1 -0
  87. package/dist/server/pipeline/record.js +49 -0
  88. package/dist/server/pipeline/record.js.map +1 -0
  89. package/dist/server/pipeline/substitute.js +287 -0
  90. package/dist/server/pipeline/substitute.js.map +1 -0
  91. package/dist/server/routes/resolve.js +176 -0
  92. package/dist/server/routes/resolve.js.map +1 -0
  93. package/dist/server/routes/table.js +247 -0
  94. package/dist/server/routes/table.js.map +1 -0
  95. package/dist/server/routes/watch.js +101 -0
  96. package/dist/server/routes/watch.js.map +1 -0
  97. package/dist/server/secret/fingerprint.js +107 -0
  98. package/dist/server/secret/fingerprint.js.map +1 -0
  99. package/dist/server/secret/non-persistable.js +69 -0
  100. package/dist/server/secret/non-persistable.js.map +1 -0
  101. package/dist/server/store/audit.js +53 -0
  102. package/dist/server/store/audit.js.map +1 -0
  103. package/dist/server/store/bootstrap.js +53 -0
  104. package/dist/server/store/bootstrap.js.map +1 -0
  105. package/dist/server/store/db.js +157 -0
  106. package/dist/server/store/db.js.map +1 -0
  107. package/dist/server/store/ids.js +14 -0
  108. package/dist/server/store/ids.js.map +1 -0
  109. package/dist/server/store/migrations/001-init.sql +213 -0
  110. package/dist/server/store/migrations/002-feed-and-error-indexes.sql +26 -0
  111. package/dist/server/store/migrations/003-routing.sql +42 -0
  112. package/dist/server/store/migrations/004-admin-auth.sql +72 -0
  113. package/dist/server/store/migrations/005-notional-cost.sql +28 -0
  114. package/dist/server/store/queries.js +904 -0
  115. package/dist/server/store/queries.js.map +1 -0
  116. package/dist/server/store/retention.js +79 -0
  117. package/dist/server/store/retention.js.map +1 -0
  118. package/dist/server/store/seed.js +203 -0
  119. package/dist/server/store/seed.js.map +1 -0
  120. package/dist/server/store/tokens.js +133 -0
  121. package/dist/server/store/tokens.js.map +1 -0
  122. package/dist/server/store/write.js +330 -0
  123. package/dist/server/store/write.js.map +1 -0
  124. package/dist/server/usage/accumulator.js +209 -0
  125. package/dist/server/usage/accumulator.js.map +1 -0
  126. package/dist/server/usage/cost.js +57 -0
  127. package/dist/server/usage/cost.js.map +1 -0
  128. package/dist/server/usage/prices/catalog.js +136 -0
  129. package/dist/server/usage/prices/catalog.js.map +1 -0
  130. package/dist/server/usage/prices/refresh.js +125 -0
  131. package/dist/server/usage/prices/refresh.js.map +1 -0
  132. package/dist/server/usage/prices/snapshot.json.gz +0 -0
  133. package/dist/server/usage/prices/table.js +102 -0
  134. package/dist/server/usage/prices/table.js.map +1 -0
  135. package/dist/server/usage/pricing.js +103 -0
  136. package/dist/server/usage/pricing.js.map +1 -0
  137. package/dist/shared/api.js +19 -0
  138. package/dist/shared/api.js.map +1 -0
  139. package/dist/shared/base-models.js +28 -0
  140. package/dist/shared/base-models.js.map +1 -0
  141. package/dist/shared/demotion-vars.js +17 -0
  142. package/dist/shared/demotion-vars.js.map +1 -0
  143. package/dist/shared/series.js +50 -0
  144. package/dist/shared/series.js.map +1 -0
  145. package/dist/shared/types.js +40 -0
  146. package/dist/shared/types.js.map +1 -0
  147. package/dist/web/dist/assets/index-8HlKsJqt.css +2 -0
  148. package/dist/web/dist/assets/index-DQ7fyPVm.js +56 -0
  149. package/dist/web/dist/assets/index-DQ7fyPVm.js.map +1 -0
  150. package/dist/web/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  151. package/dist/web/dist/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  152. package/dist/web/dist/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  153. package/dist/web/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  154. package/dist/web/dist/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
  155. package/dist/web/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  156. package/dist/web/dist/assets/inter-latin-700-normal-BLAVimhd.woff +0 -0
  157. package/dist/web/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
  158. package/dist/web/dist/index.html +44 -0
  159. package/dist/web/dist/nearform-icon.svg +4 -0
  160. package/package.json +82 -0
  161. package/routes.example.json +22 -0
@@ -0,0 +1,44 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <!-- No external requests: this dashboard renders a team's traffic metadata
7
+ and must be usable on an air-gapped host. Inter is bundled, not fetched. -->
8
+ <meta name="referrer" content="no-referrer" />
9
+ <!-- Every relative URL in the bundle, and every API call in src/lib/base.ts,
10
+ resolves against this. The gateway rewrites the href when it is mounted
11
+ under a path (FEST_BASE_PATH / the path of FEST_PUBLIC_URL), which is
12
+ what lets one build serve from `/` or from `/fest` unchanged. It must
13
+ stay ahead of the first relative URL below to apply to it. -->
14
+ <base href="/" />
15
+ <link rel="icon" href="./nearform-icon.svg" />
16
+ <title>Fest</title>
17
+ <script>
18
+ // Pre-paint, so the dashboard never flashes the wrong theme on reload.
19
+ // Deliberately inline: a fetched file would be a round trip before first
20
+ // paint, which is the thing this exists to avoid. Kept in sync with
21
+ // src/lib/theme.tsx, which owns the same key and class name.
22
+ (function () {
23
+ try {
24
+ var stored = localStorage.getItem("fest-theme");
25
+ var theme =
26
+ stored === "light" || stored === "dark"
27
+ ? stored
28
+ : window.matchMedia("(prefers-color-scheme: light)").matches
29
+ ? "light"
30
+ : "dark";
31
+ document.documentElement.classList.toggle("dark", theme === "dark");
32
+ document.documentElement.style.colorScheme = theme;
33
+ } catch (e) {
34
+ document.documentElement.classList.add("dark");
35
+ }
36
+ })();
37
+ </script>
38
+ <script type="module" crossorigin src="./assets/index-DQ7fyPVm.js"></script>
39
+ <link rel="stylesheet" crossorigin href="./assets/index-8HlKsJqt.css">
40
+ </head>
41
+ <body>
42
+ <div id="root"></div>
43
+ </body>
44
+ </html>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="60.17 60.17 111.65 86.48">
2
+ <path fill="#000e38" d="m60.18,60.18h11.3l36.71,53.4v-53.4h12.17v75.36h-11.3l-36.71-53.4v53.4h-12.17V60.18Z" />
3
+ <path fill="#00e5a4" d="m126.51,135.54h45.29v11.09h-45.29v-11.09Z" />
4
+ </svg>
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "fest-gateway",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Self-hosted Claude Code gateway: per-user subscription pass-through, central token/cost monitoring, model routing.",
6
+ "license": "MIT",
7
+ "author": "Clifton Cunningham",
8
+ "homepage": "https://github.com/cliftonc/fest-gateway#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/cliftonc/fest-gateway.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/cliftonc/fest-gateway/issues"
15
+ },
16
+ "keywords": [
17
+ "claude",
18
+ "claude-code",
19
+ "anthropic",
20
+ "gateway",
21
+ "proxy",
22
+ "llm",
23
+ "observability",
24
+ "self-hosted"
25
+ ],
26
+ "engines": {
27
+ "node": ">=22.18"
28
+ },
29
+ "bin": {
30
+ "fest": "./dist/server/bin/fest.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "routes.example.json",
35
+ "LICENSE",
36
+ "README.md"
37
+ ],
38
+ "dependencies": {
39
+ "arctic": "^3.7.0",
40
+ "open": "^11.0.0"
41
+ },
42
+ "scripts": {
43
+ "dev": "node tools/dev.mjs",
44
+ "start": "node --env-file-if-exists=.env server/bin/fest.ts serve",
45
+ "cli": "node --env-file-if-exists=.env server/bin/fest.ts",
46
+ "build": "vite build",
47
+ "build:package": "node tools/build-package.mjs",
48
+ "prepack": "npm run build && npm run build:package",
49
+ "capture": "node tools/capture-server.ts",
50
+ "canary": "node tools/canary.ts",
51
+ "prices:sync": "node tools/prices-sync.ts",
52
+ "test": "node --test \"test/**/*.test.ts\"",
53
+ "typecheck": "tsc --noEmit && tsc --noEmit -p web/tsconfig.json",
54
+ "seed": "node --env-file-if-exists=.env server/bin/fest.ts seed",
55
+ "demo": "FEST_DB=./data/demo.db FEST_USAGE_LOG=./data/demo.jsonl node --env-file-if-exists=.env server/bin/fest.ts seed --reset && FEST_DB=./data/demo.db FEST_USAGE_LOG=./data/demo.jsonl node tools/dev.mjs",
56
+ "demo:clean": "FEST_DB=./data/demo.db FEST_USAGE_LOG=./data/demo.jsonl node --env-file-if-exists=.env server/bin/fest.ts seed --clear && rm -f ./data/demo.jsonl"
57
+ },
58
+ "devDependencies": {
59
+ "@fontsource/inter": "^5.3.0",
60
+ "@tailwindcss/vite": "^4.3.3",
61
+ "@tanstack/charts": "^0.18.0",
62
+ "@tanstack/react-query": "^5.103.2",
63
+ "@tanstack/react-virtual": "^3.14.13",
64
+ "@types/node": "^22.10.0",
65
+ "@types/react": "^19.3.0",
66
+ "@types/react-dom": "^19.3.0",
67
+ "@vitejs/plugin-react": "^6.1.1",
68
+ "class-variance-authority": "^0.7.1",
69
+ "clsx": "^2.1.1",
70
+ "cn": "^0.3.2",
71
+ "lucide-react": "^1.47.0",
72
+ "radix-ui": "^1.6.7",
73
+ "react": "^19.3.0",
74
+ "react-dom": "^19.3.0",
75
+ "shadcn": "^4.21.0",
76
+ "tailwind-merge": "^3.7.0",
77
+ "tailwindcss": "^4.3.3",
78
+ "tw-animate-css": "^1.4.0",
79
+ "typescript": "^5.8.0",
80
+ "vite": "^8.3.0"
81
+ }
82
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "upstreams": {
3
+ "fireworks": {
4
+ "adapter": "fireworks",
5
+ "baseUrl": "https://api.fireworks.ai/inference",
6
+ "credential": "{env:FIREWORKS_API_KEY}"
7
+ }
8
+ },
9
+ "routes": [
10
+ {
11
+ "id": "keep-opus-on-subscription",
12
+ "match": "claude-opus-5",
13
+ "upstream": null
14
+ },
15
+ {
16
+ "id": "oss-to-fireworks",
17
+ "match": "gpt-oss-*",
18
+ "upstream": "fireworks",
19
+ "model": "accounts/fireworks/models/gpt-oss-120b"
20
+ }
21
+ ]
22
+ }