antigravity-claude-proxy 2.0.0 → 2.0.1

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 CHANGED
@@ -458,6 +458,63 @@ By using this software, you acknowledge and accept the following:
458
458
 
459
459
  ---
460
460
 
461
+ ## Development
462
+
463
+ ### For Developers & Contributors
464
+
465
+ This project uses a local Tailwind CSS build system. CSS is pre-compiled and included in the repository, so you can run the project immediately after cloning.
466
+
467
+ #### Quick Start
468
+
469
+ ```bash
470
+ git clone https://github.com/badri-s2001/antigravity-claude-proxy.git
471
+ cd antigravity-claude-proxy
472
+ npm install # Automatically builds CSS via prepare hook
473
+ npm start # Start server (no rebuild needed)
474
+ ```
475
+
476
+ #### Frontend Development
477
+
478
+ If you need to modify styles in `public/css/src/input.css`:
479
+
480
+ ```bash
481
+ # Option 1: Build once
482
+ npm run build:css
483
+
484
+ # Option 2: Watch for changes (auto-rebuild)
485
+ npm run watch:css
486
+
487
+ # Option 3: Watch both CSS and server (recommended)
488
+ npm run dev:full
489
+ ```
490
+
491
+ **File Structure:**
492
+ - `public/css/src/input.css` - Source CSS with Tailwind `@apply` directives (edit this)
493
+ - `public/css/style.css` - Compiled & minified CSS (auto-generated, don't edit)
494
+ - `tailwind.config.js` - Tailwind configuration
495
+ - `postcss.config.js` - PostCSS configuration
496
+
497
+ #### Backend-Only Development
498
+
499
+ If you're only working on backend code and don't need frontend dev tools:
500
+
501
+ ```bash
502
+ npm install --production # Skip devDependencies (saves ~20MB)
503
+ npm start
504
+ ```
505
+
506
+ **Note:** Pre-compiled CSS is committed to the repository, so you don't need to rebuild unless modifying styles.
507
+
508
+ #### Project Structure
509
+
510
+ See [CLAUDE.md](./CLAUDE.md) for detailed architecture documentation, including:
511
+ - Request flow and module organization
512
+ - Frontend architecture (Alpine.js + Tailwind)
513
+ - Service layer patterns (`ErrorHandler.withLoading`, `AccountActions`)
514
+ - Dashboard module documentation
515
+
516
+ ---
517
+
461
518
  ## Credits
462
519
 
463
520
  This project is based on insights and code from:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antigravity-claude-proxy",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Proxy server to use Antigravity's Claude models with Claude Code CLI",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -13,8 +13,12 @@
13
13
  "public"
14
14
  ],
15
15
  "scripts": {
16
+ "build:css": "tailwindcss -i ./public/css/src/input.css -o ./public/css/style.css --minify",
17
+ "watch:css": "tailwindcss -i ./public/css/src/input.css -o ./public/css/style.css --watch",
18
+ "prepare": "npm run build:css",
16
19
  "start": "node src/index.js",
17
20
  "dev": "node --watch src/index.js",
21
+ "dev:full": "concurrently \"npm run watch:css\" \"npm run dev\"",
18
22
  "accounts": "node src/cli/accounts.js",
19
23
  "accounts:add": "node src/cli/accounts.js add",
20
24
  "accounts:list": "node src/cli/accounts.js list",
@@ -57,5 +61,13 @@
57
61
  "better-sqlite3": "^12.5.0",
58
62
  "cors": "^2.8.5",
59
63
  "express": "^4.18.2"
64
+ },
65
+ "devDependencies": {
66
+ "@tailwindcss/forms": "^0.5.7",
67
+ "autoprefixer": "^10.4.16",
68
+ "concurrently": "^8.2.2",
69
+ "daisyui": "^4.12.14",
70
+ "postcss": "^8.4.32",
71
+ "tailwindcss": "^3.4.0"
60
72
  }
61
73
  }
@@ -0,0 +1,491 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ /* === Background Layers === */
7
+ --color-space-950: #09090b;
8
+ --color-space-900: #0f0f11;
9
+ --color-space-850: #121214;
10
+ --color-space-800: #18181b;
11
+ --color-space-border: #27272a;
12
+
13
+ /* === Neon Accents (Full Saturation) === */
14
+ --color-neon-purple: #a855f7;
15
+ --color-neon-green: #22c55e;
16
+ --color-neon-cyan: #06b6d4;
17
+ --color-neon-yellow: #eab308;
18
+ --color-neon-red: #ef4444;
19
+
20
+ /* === Soft Neon (Reduced Saturation for Fills) === */
21
+ --color-neon-purple-soft: #9333ea;
22
+ --color-neon-green-soft: #16a34a;
23
+ --color-neon-cyan-soft: #0891b2;
24
+
25
+ /* === Text Hierarchy (WCAG AA Compliant) === */
26
+ --color-text-primary: #ffffff; /* Emphasis: Titles, Key Numbers */
27
+ --color-text-secondary: #d4d4d8; /* Content: Body Text (zinc-300) */
28
+ --color-text-tertiary: #a1a1aa; /* Metadata: Timestamps, Labels (zinc-400) */
29
+ --color-text-quaternary: #71717a; /* Subtle: Decorative (zinc-500) */
30
+
31
+ /* === Legacy Aliases (Backward Compatibility) === */
32
+ --color-text-main: var(--color-text-secondary);
33
+ --color-text-dim: var(--color-text-tertiary);
34
+ --color-text-muted: var(--color-text-tertiary);
35
+ --color-text-bright: var(--color-text-primary);
36
+
37
+ /* Gradient Accents */
38
+ --color-green-400: #4ade80;
39
+ --color-yellow-400: #facc15;
40
+ --color-red-400: #f87171;
41
+
42
+ /* Chart Colors */
43
+ --color-chart-1: #a855f7;
44
+ --color-chart-2: #c084fc;
45
+ --color-chart-3: #e879f9;
46
+ --color-chart-4: #d946ef;
47
+ --color-chart-5: #22c55e;
48
+ --color-chart-6: #4ade80;
49
+ --color-chart-7: #86efac;
50
+ --color-chart-8: #10b981;
51
+ --color-chart-9: #06b6d4;
52
+ --color-chart-10: #f59e0b;
53
+ --color-chart-11: #ef4444;
54
+ --color-chart-12: #ec4899;
55
+ --color-chart-13: #8b5cf6;
56
+ --color-chart-14: #14b8a6;
57
+ --color-chart-15: #f97316;
58
+ --color-chart-16: #6366f1;
59
+ }
60
+
61
+ [x-cloak] {
62
+ display: none !important;
63
+ }
64
+
65
+ /* Custom Scrollbar */
66
+ .custom-scrollbar {
67
+ scrollbar-gutter: stable;
68
+ }
69
+
70
+ ::-webkit-scrollbar {
71
+ width: 8px;
72
+ height: 8px;
73
+ }
74
+
75
+ ::-webkit-scrollbar-track {
76
+ background: rgba(9, 9, 11, 0.3);
77
+ border-radius: 4px;
78
+ }
79
+
80
+ ::-webkit-scrollbar-thumb {
81
+ background: linear-gradient(180deg, #27272a 0%, #18181b 100%);
82
+ border-radius: 4px;
83
+ border: 1px solid rgba(255, 255, 255, 0.05);
84
+ transition: background 0.2s ease;
85
+ }
86
+
87
+ ::-webkit-scrollbar-thumb:hover {
88
+ background: linear-gradient(180deg, #3f3f46 0%, #27272a 100%);
89
+ border-color: rgba(168, 85, 247, 0.3);
90
+ }
91
+
92
+ /* Animations */
93
+ .fade-enter-active,
94
+ .fade-leave-active {
95
+ transition: opacity 0.2s ease;
96
+ }
97
+
98
+ .fade-enter-from,
99
+ .fade-leave-to {
100
+ opacity: 0;
101
+ }
102
+
103
+ @keyframes fadeIn {
104
+ from {
105
+ opacity: 0;
106
+ transform: translateY(5px);
107
+ }
108
+ to {
109
+ opacity: 1;
110
+ transform: translateY(0);
111
+ }
112
+ }
113
+
114
+ .animate-fade-in {
115
+ animation: fadeIn 0.4s ease-out forwards;
116
+ }
117
+
118
+ /* Note: .glass-panel has been deprecated. Use .view-card instead for consistency. */
119
+
120
+ .nav-item.active {
121
+ background: linear-gradient(
122
+ 90deg,
123
+ theme("colors.neon.purple / 15%") 0%,
124
+ transparent 100%
125
+ );
126
+ @apply border-l-4 border-neon-purple text-white;
127
+ }
128
+
129
+ .nav-item {
130
+ @apply border-l-4 border-transparent transition-all duration-200;
131
+ }
132
+
133
+ .progress-gradient-success::-webkit-progress-value {
134
+ background-image: linear-gradient(
135
+ to right,
136
+ var(--color-neon-green),
137
+ var(--color-green-400)
138
+ );
139
+ }
140
+
141
+ .progress-gradient-warning::-webkit-progress-value {
142
+ background-image: linear-gradient(
143
+ to right,
144
+ var(--color-neon-yellow),
145
+ var(--color-yellow-400)
146
+ );
147
+ }
148
+
149
+ .progress-gradient-error::-webkit-progress-value {
150
+ background-image: linear-gradient(
151
+ to right,
152
+ var(--color-neon-red),
153
+ var(--color-red-400)
154
+ );
155
+ }
156
+
157
+ /* Dashboard Grid */
158
+ .stats-grid {
159
+ display: grid;
160
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
161
+ gap: 1.5rem;
162
+ }
163
+
164
+ /* Tooltip Customization */
165
+ .tooltip:before {
166
+ @apply bg-space-800 border border-space-border text-gray-200 font-mono text-xs;
167
+ }
168
+
169
+ .tooltip-left:before {
170
+ margin-right: 0.5rem;
171
+ }
172
+
173
+ /* -------------------------------------------------------------------------- */
174
+ /* Refactored Global Utilities */
175
+ /* -------------------------------------------------------------------------- */
176
+
177
+ /* Standard Layout Constants */
178
+ :root {
179
+ --view-padding: 2rem; /* 32px - Standard Padding */
180
+ --view-gap: 2rem; /* 32px - Standard component gap */
181
+ --card-radius: 0.75rem; /* 12px */
182
+ }
183
+
184
+ @media (max-width: 768px) {
185
+ :root {
186
+ --view-padding: 1rem;
187
+ --view-gap: 1.25rem;
188
+ }
189
+ }
190
+
191
+ /* Base View Container */
192
+ .view-container {
193
+ display: flex;
194
+ flex-direction: column;
195
+ margin-left: auto;
196
+ margin-right: auto;
197
+ width: 100%;
198
+ padding: var(--view-padding);
199
+ gap: var(--view-gap);
200
+ min-height: calc(100vh - 56px); /* Align with navbar height */
201
+ max-width: 1400px;
202
+ scrollbar-gutter: stable;
203
+ }
204
+
205
+ /* Specialized container for data-heavy pages (Logs) */
206
+ .view-container-full {
207
+ @apply w-full animate-fade-in flex flex-col;
208
+ padding: var(--view-padding);
209
+ gap: var(--view-gap);
210
+ min-height: calc(100vh - 56px);
211
+ max-width: 100%;
212
+ }
213
+
214
+ /* Centered container for form-heavy pages (Settings/Accounts) */
215
+ .view-container-centered {
216
+ @apply mx-auto w-full animate-fade-in flex flex-col;
217
+ padding: var(--view-padding);
218
+ gap: var(--view-gap);
219
+ min-height: calc(100vh - 56px);
220
+ max-width: 900px; /* Comfortable reading width for forms */
221
+ }
222
+
223
+ /* Standard Section Header */
224
+ .view-header {
225
+ display: flex;
226
+ flex-direction: column;
227
+ justify-content: space-between;
228
+ margin-bottom: 0.5rem;
229
+ gap: 1rem;
230
+ }
231
+
232
+ @media (min-width: 768px) {
233
+ .view-header {
234
+ flex-direction: row;
235
+ align-items: flex-end;
236
+ }
237
+ }
238
+
239
+ .view-header-title {
240
+ @apply flex flex-col;
241
+ }
242
+
243
+ .view-header-title h2 {
244
+ @apply text-2xl font-bold text-white tracking-tight;
245
+ }
246
+
247
+ .view-header-title p {
248
+ @apply text-sm text-gray-500 mt-1;
249
+ }
250
+
251
+ .view-header-actions {
252
+ @apply flex items-center gap-3;
253
+ }
254
+
255
+ /* Standard Card Panel */
256
+ .view-card {
257
+ position: relative;
258
+ overflow: hidden;
259
+ border-radius: var(--card-radius);
260
+ padding: 1.5rem;
261
+ border: 1px solid rgba(255, 255, 255, 0.08);
262
+ background: linear-gradient(135deg,
263
+ rgba(15, 15, 17, 0.75) 0%,
264
+ rgba(18, 18, 20, 0.70) 100%
265
+ );
266
+ -webkit-backdrop-filter: blur(12px);
267
+ backdrop-filter: blur(12px);
268
+ box-shadow:
269
+ 0 0 0 1px rgba(255, 255, 255, 0.02) inset,
270
+ 0 4px 24px rgba(0, 0, 0, 0.4);
271
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
272
+ }
273
+
274
+ .view-card:hover {
275
+ border-color: rgba(255, 255, 255, 0.12);
276
+ box-shadow:
277
+ 0 0 0 1px rgba(255, 255, 255, 0.04) inset,
278
+ 0 8px 32px rgba(0, 0, 0, 0.5);
279
+ }
280
+
281
+ .view-card-header {
282
+ @apply flex items-center justify-between mb-4 pb-4 border-b border-[rgba(39,39,42,0.3)];
283
+ }
284
+
285
+ /* Component Unification */
286
+ .standard-table {
287
+ @apply table w-full border-separate border-spacing-0;
288
+ }
289
+ .standard-table thead {
290
+ @apply bg-space-900/50 text-gray-500 font-mono text-xs uppercase border-b border-space-border;
291
+ }
292
+ .standard-table tbody tr {
293
+ @apply transition-all duration-200 border-b border-[rgba(39,39,42,0.3)] last:border-0;
294
+ }
295
+
296
+ .standard-table tbody tr:hover {
297
+ background: linear-gradient(
298
+ 90deg,
299
+ rgba(255, 255, 255, 0.03) 0%,
300
+ rgba(255, 255, 255, 0.05) 50%,
301
+ rgba(255, 255, 255, 0.03) 100%
302
+ );
303
+ border-color: rgba(255, 255, 255, 0.08);
304
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
305
+ }
306
+
307
+ /* Custom Range Slider - Simplified */
308
+ .custom-range {
309
+ -webkit-appearance: none;
310
+ appearance: none;
311
+ width: 100%;
312
+ height: 4px;
313
+ background: var(--color-space-800);
314
+ border-radius: 999px;
315
+ outline: none;
316
+ cursor: pointer;
317
+ }
318
+
319
+ .custom-range::-webkit-slider-thumb {
320
+ -webkit-appearance: none;
321
+ appearance: none;
322
+ width: 14px;
323
+ height: 14px;
324
+ border-radius: 50%;
325
+ background: var(--range-color, var(--color-neon-purple));
326
+ cursor: pointer;
327
+ transition: transform 0.1s ease;
328
+ }
329
+
330
+ .custom-range::-webkit-slider-thumb:hover {
331
+ transform: scale(1.15);
332
+ }
333
+
334
+ .custom-range::-moz-range-thumb {
335
+ width: 14px;
336
+ height: 14px;
337
+ border: none;
338
+ border-radius: 50%;
339
+ background: var(--range-color, var(--color-neon-purple));
340
+ cursor: pointer;
341
+ transition: transform 0.1s ease;
342
+ }
343
+
344
+ .custom-range::-moz-range-thumb:hover {
345
+ transform: scale(1.15);
346
+ }
347
+
348
+ /* Color Variants */
349
+ .custom-range-purple {
350
+ --range-color: var(--color-neon-purple);
351
+ }
352
+ .custom-range-green {
353
+ --range-color: var(--color-neon-green);
354
+ }
355
+ .custom-range-cyan {
356
+ --range-color: var(--color-neon-cyan);
357
+ }
358
+ .custom-range-yellow {
359
+ --range-color: var(--color-neon-yellow);
360
+ }
361
+ .custom-range-accent {
362
+ --range-color: var(--color-neon-cyan);
363
+ }
364
+
365
+ /* -------------------------------------------------------------------------- */
366
+ /* Refactored UI Components (Phase 1.2) */
367
+ /* -------------------------------------------------------------------------- */
368
+
369
+ /* Action Buttons */
370
+ .btn-action-ghost {
371
+ @apply btn btn-xs btn-ghost text-gray-400 hover:text-white transition-colors;
372
+ }
373
+
374
+ .btn-action-ghost-square {
375
+ @apply btn btn-xs btn-ghost btn-square text-gray-400 hover:text-white transition-colors;
376
+ }
377
+
378
+ .btn-action-primary {
379
+ @apply btn bg-gradient-to-r from-neon-purple to-indigo-600
380
+ border-none text-white shadow-lg shadow-neon-purple/20
381
+ hover:shadow-neon-purple/40 transition-all;
382
+ }
383
+
384
+ .btn-action-success {
385
+ @apply btn btn-xs btn-ghost btn-square text-green-500 hover:bg-green-500/20;
386
+ }
387
+
388
+ .btn-action-danger {
389
+ @apply btn btn-xs btn-ghost btn-square text-red-400 hover:bg-red-500/20;
390
+ }
391
+
392
+ .btn-action-neutral {
393
+ @apply btn btn-xs btn-ghost btn-square text-gray-500 hover:bg-gray-500/20;
394
+ }
395
+
396
+ /* Status Pills/Badges */
397
+ .status-pill {
398
+ @apply px-2 py-1 text-[10px] font-mono font-bold uppercase rounded border;
399
+ }
400
+
401
+ .status-pill-purple {
402
+ @apply status-pill bg-neon-purple/10 text-neon-purple border-neon-purple/30;
403
+ }
404
+
405
+ .status-pill-ultra {
406
+ @apply status-pill bg-yellow-500/10 text-yellow-400 border-yellow-500/30;
407
+ }
408
+
409
+ .status-pill-pro {
410
+ @apply status-pill bg-blue-500/10 text-blue-400 border-blue-500/30;
411
+ }
412
+
413
+ .status-pill-free {
414
+ @apply status-pill bg-gray-500/10 text-gray-400 border-gray-500/30;
415
+ }
416
+
417
+ .status-pill-success {
418
+ @apply status-pill bg-neon-green/10 text-neon-green border-neon-green/30;
419
+ }
420
+
421
+ .status-pill-warning {
422
+ @apply status-pill bg-yellow-500/10 text-yellow-400 border-yellow-500/30;
423
+ }
424
+
425
+ .status-pill-error {
426
+ @apply status-pill bg-red-500/10 text-red-400 border-red-500/30;
427
+ }
428
+
429
+ /* Input Components */
430
+ .input-search {
431
+ @apply w-full bg-space-900/50 border border-[rgba(39,39,42,0.5)] text-gray-300
432
+ rounded-lg pl-10 pr-4 py-2
433
+ focus:outline-none focus:bg-space-800 focus:border-neon-purple/50
434
+ hover:border-space-border hover:bg-space-800/80
435
+ transition-all placeholder-gray-600/80;
436
+ }
437
+
438
+ .input-search-sm {
439
+ @apply input-search h-8 text-xs font-normal;
440
+ }
441
+
442
+ /* -------------------------------------------------------------------------- */
443
+ /* Skeleton Loading (Phase 4.1) */
444
+ /* -------------------------------------------------------------------------- */
445
+
446
+ /* Skeleton animation */
447
+ @keyframes skeleton-pulse {
448
+ 0%, 100% {
449
+ opacity: 1;
450
+ }
451
+ 50% {
452
+ opacity: 0.4;
453
+ }
454
+ }
455
+
456
+ /* Base skeleton element */
457
+ .skeleton {
458
+ @apply bg-gradient-to-r from-space-900/60 via-space-800/40 to-space-900/60;
459
+ background-size: 200% 100%;
460
+ animation: skeleton-pulse 1.5s ease-in-out infinite;
461
+ border-radius: 0.375rem;
462
+ }
463
+
464
+ /* Skeleton variants */
465
+ .skeleton-text {
466
+ @apply skeleton h-4 w-full;
467
+ }
468
+
469
+ .skeleton-text-sm {
470
+ @apply skeleton h-3 w-3/4;
471
+ }
472
+
473
+ .skeleton-title {
474
+ @apply skeleton h-6 w-1/2;
475
+ }
476
+
477
+ .skeleton-circle {
478
+ @apply skeleton rounded-full;
479
+ }
480
+
481
+ .skeleton-stat-card {
482
+ @apply skeleton h-32 w-full rounded-xl;
483
+ }
484
+
485
+ .skeleton-chart {
486
+ @apply skeleton h-64 w-full rounded-xl;
487
+ }
488
+
489
+ .skeleton-table-row {
490
+ @apply skeleton h-12 w-full mb-2;
491
+ }