business-stack 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.
- package/.python-version +1 -0
- package/backend/.env.example +65 -0
- package/backend/alembic/env.py +63 -0
- package/backend/alembic/script.py.mako +26 -0
- package/backend/alembic/versions/2a9c8f1d0e7b_multimodal_kb_schema.py +279 -0
- package/backend/alembic/versions/3c1d2e4f5a6b_sqlite_vec_embeddings.py +58 -0
- package/backend/alembic/versions/4e8b0c2d1a3f_document_links.py +50 -0
- package/backend/alembic/versions/6a0b1c2d3e4f_link_expansion_dedupe_columns.py +49 -0
- package/backend/alembic/versions/7d8e9f0a1b2c_document_chunks.py +70 -0
- package/backend/alembic/versions/8f2a1c0d9e3b_initial_empty_revision.py +22 -0
- package/backend/alembic/versions/9f0a1b2c3d4e_entity_mentions_cooccurrence.py +123 -0
- package/backend/alembic/versions/b1c2d3e4f5a6_pipeline_dedupe_dlq.py +99 -0
- package/backend/alembic/versions/c2d3e4f5061a_chat_sessions_messages.py +59 -0
- package/backend/alembic.ini +42 -0
- package/backend/app/__init__.py +0 -0
- package/backend/app/config.py +337 -0
- package/backend/app/connectors/__init__.py +13 -0
- package/backend/app/connectors/base.py +39 -0
- package/backend/app/connectors/builtins.py +51 -0
- package/backend/app/connectors/playwright_session.py +146 -0
- package/backend/app/connectors/registry.py +68 -0
- package/backend/app/connectors/thread_expansion/__init__.py +33 -0
- package/backend/app/connectors/thread_expansion/fakes.py +154 -0
- package/backend/app/connectors/thread_expansion/models.py +113 -0
- package/backend/app/connectors/thread_expansion/reddit.py +53 -0
- package/backend/app/connectors/thread_expansion/twitter.py +49 -0
- package/backend/app/db.py +5 -0
- package/backend/app/dependencies.py +34 -0
- package/backend/app/logging_config.py +35 -0
- package/backend/app/main.py +97 -0
- package/backend/app/middleware/__init__.py +0 -0
- package/backend/app/middleware/gateway_identity.py +17 -0
- package/backend/app/middleware/openapi_gateway.py +71 -0
- package/backend/app/middleware/request_id.py +23 -0
- package/backend/app/openapi_config.py +126 -0
- package/backend/app/routers/__init__.py +0 -0
- package/backend/app/routers/admin_pipeline.py +123 -0
- package/backend/app/routers/chat.py +206 -0
- package/backend/app/routers/chunks.py +36 -0
- package/backend/app/routers/entity_extract.py +31 -0
- package/backend/app/routers/example.py +8 -0
- package/backend/app/routers/gemini_embed.py +58 -0
- package/backend/app/routers/health.py +28 -0
- package/backend/app/routers/ingestion.py +146 -0
- package/backend/app/routers/link_expansion.py +34 -0
- package/backend/app/routers/pipeline_status.py +304 -0
- package/backend/app/routers/query.py +63 -0
- package/backend/app/routers/vectors.py +63 -0
- package/backend/app/schemas/__init__.py +0 -0
- package/backend/app/schemas/canonical.py +44 -0
- package/backend/app/schemas/chat.py +50 -0
- package/backend/app/schemas/ingest.py +29 -0
- package/backend/app/schemas/query.py +153 -0
- package/backend/app/schemas/vectors.py +56 -0
- package/backend/app/services/__init__.py +0 -0
- package/backend/app/services/chat_store.py +152 -0
- package/backend/app/services/chunking/__init__.py +3 -0
- package/backend/app/services/chunking/llm_boundaries.py +63 -0
- package/backend/app/services/chunking/schemas.py +30 -0
- package/backend/app/services/chunking/semantic_chunk.py +178 -0
- package/backend/app/services/chunking/splitters.py +214 -0
- package/backend/app/services/embeddings/__init__.py +20 -0
- package/backend/app/services/embeddings/build_inputs.py +140 -0
- package/backend/app/services/embeddings/dlq.py +128 -0
- package/backend/app/services/embeddings/gemini_api.py +207 -0
- package/backend/app/services/embeddings/persist.py +74 -0
- package/backend/app/services/embeddings/types.py +32 -0
- package/backend/app/services/embeddings/worker.py +224 -0
- package/backend/app/services/entities/__init__.py +12 -0
- package/backend/app/services/entities/gliner_extract.py +63 -0
- package/backend/app/services/entities/llm_extract.py +94 -0
- package/backend/app/services/entities/pipeline.py +179 -0
- package/backend/app/services/entities/spacy_extract.py +63 -0
- package/backend/app/services/entities/types.py +15 -0
- package/backend/app/services/gemini_chat.py +113 -0
- package/backend/app/services/hooks/__init__.py +3 -0
- package/backend/app/services/hooks/post_ingest.py +186 -0
- package/backend/app/services/ingestion/__init__.py +0 -0
- package/backend/app/services/ingestion/persist.py +188 -0
- package/backend/app/services/integrations_remote.py +91 -0
- package/backend/app/services/link_expansion/__init__.py +3 -0
- package/backend/app/services/link_expansion/canonical_url.py +45 -0
- package/backend/app/services/link_expansion/domain_policy.py +26 -0
- package/backend/app/services/link_expansion/html_extract.py +72 -0
- package/backend/app/services/link_expansion/rate_limit.py +32 -0
- package/backend/app/services/link_expansion/robots.py +46 -0
- package/backend/app/services/link_expansion/schemas.py +67 -0
- package/backend/app/services/link_expansion/worker.py +458 -0
- package/backend/app/services/normalization/__init__.py +7 -0
- package/backend/app/services/normalization/normalizer.py +331 -0
- package/backend/app/services/normalization/persist_normalized.py +67 -0
- package/backend/app/services/playwright_extract/__init__.py +13 -0
- package/backend/app/services/playwright_extract/__main__.py +96 -0
- package/backend/app/services/playwright_extract/extract.py +181 -0
- package/backend/app/services/retrieval_service.py +351 -0
- package/backend/app/sqlite_ext.py +36 -0
- package/backend/app/storage/__init__.py +3 -0
- package/backend/app/storage/blobs.py +30 -0
- package/backend/app/vectorstore/__init__.py +13 -0
- package/backend/app/vectorstore/sqlite_vec_store.py +242 -0
- package/backend/backend.egg-info/PKG-INFO +18 -0
- package/backend/backend.egg-info/SOURCES.txt +93 -0
- package/backend/backend.egg-info/dependency_links.txt +1 -0
- package/backend/backend.egg-info/entry_points.txt +2 -0
- package/backend/backend.egg-info/requires.txt +15 -0
- package/backend/backend.egg-info/top_level.txt +4 -0
- package/backend/package.json +15 -0
- package/backend/pyproject.toml +52 -0
- package/backend/tests/conftest.py +40 -0
- package/backend/tests/test_chat.py +92 -0
- package/backend/tests/test_chunking.py +132 -0
- package/backend/tests/test_entities.py +170 -0
- package/backend/tests/test_gemini_embed.py +224 -0
- package/backend/tests/test_health.py +24 -0
- package/backend/tests/test_ingest_raw.py +123 -0
- package/backend/tests/test_link_expansion.py +241 -0
- package/backend/tests/test_main.py +12 -0
- package/backend/tests/test_normalizer.py +114 -0
- package/backend/tests/test_openapi_gateway.py +40 -0
- package/backend/tests/test_pipeline_hardening.py +285 -0
- package/backend/tests/test_pipeline_status.py +71 -0
- package/backend/tests/test_playwright_extract.py +80 -0
- package/backend/tests/test_post_ingest_hooks.py +162 -0
- package/backend/tests/test_query.py +165 -0
- package/backend/tests/test_thread_expansion.py +72 -0
- package/backend/tests/test_vectors.py +85 -0
- package/backend/uv.lock +1839 -0
- package/bin/business-stack.cjs +412 -0
- package/frontend/web/.env.example +23 -0
- package/frontend/web/AGENTS.md +5 -0
- package/frontend/web/CLAUDE.md +1 -0
- package/frontend/web/README.md +36 -0
- package/frontend/web/components.json +25 -0
- package/frontend/web/next-env.d.ts +6 -0
- package/frontend/web/next.config.ts +30 -0
- package/frontend/web/package.json +65 -0
- package/frontend/web/postcss.config.mjs +7 -0
- package/frontend/web/skills-lock.json +35 -0
- package/frontend/web/src/app/account/[[...path]]/page.tsx +19 -0
- package/frontend/web/src/app/auth/[[...path]]/page.tsx +14 -0
- package/frontend/web/src/app/chat/page.tsx +725 -0
- package/frontend/web/src/app/favicon.ico +0 -0
- package/frontend/web/src/app/globals.css +563 -0
- package/frontend/web/src/app/layout.tsx +50 -0
- package/frontend/web/src/app/page.tsx +96 -0
- package/frontend/web/src/app/settings/integrations/actions.ts +74 -0
- package/frontend/web/src/app/settings/integrations/integrations-settings-form.tsx +330 -0
- package/frontend/web/src/app/settings/integrations/page.tsx +41 -0
- package/frontend/web/src/app/webhooks/alpha-alerts/route.ts +84 -0
- package/frontend/web/src/components/home-auth-panel.tsx +49 -0
- package/frontend/web/src/components/providers.tsx +50 -0
- package/frontend/web/src/lib/alpha-webhook/connectors/registry.ts +35 -0
- package/frontend/web/src/lib/alpha-webhook/connectors/types.ts +8 -0
- package/frontend/web/src/lib/alpha-webhook/connectors/wabridge-delivery.test.ts +40 -0
- package/frontend/web/src/lib/alpha-webhook/connectors/wabridge-delivery.ts +78 -0
- package/frontend/web/src/lib/alpha-webhook/connectors/wabridge.ts +30 -0
- package/frontend/web/src/lib/alpha-webhook/handler.ts +12 -0
- package/frontend/web/src/lib/alpha-webhook/signature.test.ts +33 -0
- package/frontend/web/src/lib/alpha-webhook/signature.ts +21 -0
- package/frontend/web/src/lib/alpha-webhook/types.ts +23 -0
- package/frontend/web/src/lib/auth-client.ts +23 -0
- package/frontend/web/src/lib/integrations-config.ts +125 -0
- package/frontend/web/src/lib/ui-utills.tsx +90 -0
- package/frontend/web/src/lib/utils.ts +6 -0
- package/frontend/web/tsconfig.json +36 -0
- package/frontend/web/tsconfig.tsbuildinfo +1 -0
- package/frontend/web/vitest.config.ts +14 -0
- package/gateway/.env.example +23 -0
- package/gateway/README.md +13 -0
- package/gateway/package.json +24 -0
- package/gateway/src/auth.ts +49 -0
- package/gateway/src/index.ts +141 -0
- package/gateway/src/integrations/admin.ts +19 -0
- package/gateway/src/integrations/crypto.ts +52 -0
- package/gateway/src/integrations/handlers.ts +124 -0
- package/gateway/src/integrations/keys.ts +12 -0
- package/gateway/src/integrations/store.ts +106 -0
- package/gateway/src/stack-secrets.ts +35 -0
- package/gateway/tsconfig.json +13 -0
- package/package.json +33 -0
- package/turbo.json +27 -0
|
Binary file
|
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noDuplicateProperties: Tailwind and UI imports layer duplicate custom properties intentionally */
|
|
2
|
+
@import "tailwindcss";
|
|
3
|
+
|
|
4
|
+
@import "@daveyplate/better-auth-ui/css";
|
|
5
|
+
|
|
6
|
+
@import "tw-animate-css";
|
|
7
|
+
|
|
8
|
+
@import "shadcn/tailwind.css";
|
|
9
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
10
|
+
|
|
11
|
+
@theme inline {
|
|
12
|
+
/* :root tokens are full oklch() colors — do not wrap in hsl(); that yields invalid CSS. */
|
|
13
|
+
--color-background: var(--background);
|
|
14
|
+
--color-foreground: var(--foreground);
|
|
15
|
+
--font-sans: var(--font-geist-sans);
|
|
16
|
+
--font-mono: var(--font-mono);
|
|
17
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
18
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
19
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
20
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
21
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
22
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
23
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
24
|
+
--color-sidebar: var(--sidebar);
|
|
25
|
+
--color-chart-5: var(--chart-5);
|
|
26
|
+
--color-chart-4: var(--chart-4);
|
|
27
|
+
--color-chart-3: var(--chart-3);
|
|
28
|
+
--color-chart-2: var(--chart-2);
|
|
29
|
+
--color-chart-1: var(--chart-1);
|
|
30
|
+
--color-ring: var(--ring);
|
|
31
|
+
--color-input: var(--input);
|
|
32
|
+
--color-border: var(--border);
|
|
33
|
+
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
34
|
+
--color-destructive: var(--destructive);
|
|
35
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
36
|
+
--color-accent: var(--accent);
|
|
37
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
38
|
+
--color-muted: var(--muted);
|
|
39
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
40
|
+
--color-secondary: var(--secondary);
|
|
41
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
42
|
+
--color-primary: var(--primary);
|
|
43
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
44
|
+
--color-popover: var(--popover);
|
|
45
|
+
--color-card-foreground: var(--card-foreground);
|
|
46
|
+
--color-card: var(--card);
|
|
47
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
48
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
49
|
+
--radius-lg: var(--radius);
|
|
50
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
51
|
+
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
52
|
+
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
53
|
+
--animate-marquee: marquee var(--duration) infinite linear;
|
|
54
|
+
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
|
|
55
|
+
--animate-orbit: orbit calc(var(--duration) * 1s) linear infinite;
|
|
56
|
+
--animate-slide-down: slide-down 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
|
57
|
+
--animate-slide-up: slide-up 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
|
58
|
+
--scaleIn: scaleIn 200ms ease;
|
|
59
|
+
--scaleOut: scaleOut 200ms ease;
|
|
60
|
+
--fadeIn: fadeIn 200ms ease;
|
|
61
|
+
--fadeOut: fadeOut 200ms ease;
|
|
62
|
+
--enterFromLeft: enterFromLeft 250ms ease;
|
|
63
|
+
--enterFromRight: enterFromRight 250ms ease;
|
|
64
|
+
--exitToLeft: exitToLeft 250ms ease;
|
|
65
|
+
--exitToRight: exitToRight 250ms ease;
|
|
66
|
+
--animate-elliptical-orbit: elliptical-orbit 20s linear infinite;
|
|
67
|
+
--animate-alert-flash: alert-flash var(--flash-duration, 2s) ease-in-out;
|
|
68
|
+
--animate-reason-flash: reason-flash var(--flash-duration, 2s) ease-in-out;
|
|
69
|
+
--animate-skeleton: skeleton 1.5s ease-in-out infinite;
|
|
70
|
+
@keyframes skeleton {
|
|
71
|
+
0% {
|
|
72
|
+
background-position: 200% 0;
|
|
73
|
+
}
|
|
74
|
+
100% {
|
|
75
|
+
background-position: -200% 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
@keyframes orbit {
|
|
79
|
+
0% {
|
|
80
|
+
transform: rotate(calc(var(--angle) * 1deg))
|
|
81
|
+
translateY(calc(var(--radius) * 1px)) rotate(calc(var(--angle) * -1deg));
|
|
82
|
+
}
|
|
83
|
+
100% {
|
|
84
|
+
transform: rotate(calc(var(--angle) * 1deg + 360deg))
|
|
85
|
+
translateY(calc(var(--radius) * 1px))
|
|
86
|
+
rotate(calc((var(--angle) * -1deg) - 360deg));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@keyframes accordion-down {
|
|
91
|
+
from {
|
|
92
|
+
height: 0;
|
|
93
|
+
}
|
|
94
|
+
to {
|
|
95
|
+
height: var(--radix-accordion-content-height);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@keyframes accordion-up {
|
|
100
|
+
from {
|
|
101
|
+
height: var(--radix-accordion-content-height);
|
|
102
|
+
}
|
|
103
|
+
to {
|
|
104
|
+
height: 0;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@keyframes marquee {
|
|
109
|
+
from {
|
|
110
|
+
transform: translateX(0);
|
|
111
|
+
}
|
|
112
|
+
to {
|
|
113
|
+
transform: translateX(calc(-100% - var(--gap)));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@keyframes marquee-vertical {
|
|
118
|
+
from {
|
|
119
|
+
transform: translateY(0);
|
|
120
|
+
}
|
|
121
|
+
to {
|
|
122
|
+
transform: translateY(calc(-100% - var(--gap)));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
@keyframes slide-down {
|
|
126
|
+
from {
|
|
127
|
+
height: 0px;
|
|
128
|
+
}
|
|
129
|
+
to {
|
|
130
|
+
height: var(--radix-accordion-content-height);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@keyframes slide-up {
|
|
135
|
+
from {
|
|
136
|
+
height: var(--radix-accordion-content-height);
|
|
137
|
+
}
|
|
138
|
+
to {
|
|
139
|
+
height: 0px;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Add this to your globals.css */
|
|
144
|
+
@keyframes enterFromRight {
|
|
145
|
+
from {
|
|
146
|
+
opacity: 0;
|
|
147
|
+
transform: translateX(200px);
|
|
148
|
+
}
|
|
149
|
+
to {
|
|
150
|
+
opacity: 1;
|
|
151
|
+
transform: translateX(0);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@keyframes enterFromLeft {
|
|
156
|
+
from {
|
|
157
|
+
opacity: 0;
|
|
158
|
+
transform: translateX(-200px);
|
|
159
|
+
}
|
|
160
|
+
to {
|
|
161
|
+
opacity: 1;
|
|
162
|
+
transform: translateX(0);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@keyframes exitToRight {
|
|
167
|
+
from {
|
|
168
|
+
opacity: 1;
|
|
169
|
+
transform: translateX(0);
|
|
170
|
+
}
|
|
171
|
+
to {
|
|
172
|
+
opacity: 0;
|
|
173
|
+
transform: translateX(200px);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@keyframes exitToLeft {
|
|
178
|
+
from {
|
|
179
|
+
opacity: 1;
|
|
180
|
+
transform: translateX(0);
|
|
181
|
+
}
|
|
182
|
+
to {
|
|
183
|
+
opacity: 0;
|
|
184
|
+
transform: translateX(-200px);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@keyframes scaleIn {
|
|
189
|
+
from {
|
|
190
|
+
opacity: 0;
|
|
191
|
+
transform: rotateX(-30deg) scale(0.9);
|
|
192
|
+
}
|
|
193
|
+
to {
|
|
194
|
+
opacity: 1;
|
|
195
|
+
transform: rotateX(0deg) scale(1);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@keyframes scaleOut {
|
|
200
|
+
from {
|
|
201
|
+
opacity: 1;
|
|
202
|
+
transform: rotateX(0deg) scale(1);
|
|
203
|
+
}
|
|
204
|
+
to {
|
|
205
|
+
opacity: 0;
|
|
206
|
+
transform: rotateX(-10deg) scale(0.95);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@keyframes fadeIn {
|
|
211
|
+
from {
|
|
212
|
+
opacity: 0;
|
|
213
|
+
}
|
|
214
|
+
to {
|
|
215
|
+
opacity: 1;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@keyframes fadeOut {
|
|
220
|
+
from {
|
|
221
|
+
opacity: 1;
|
|
222
|
+
}
|
|
223
|
+
to {
|
|
224
|
+
opacity: 0;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@keyframes elliptical-orbit {
|
|
229
|
+
from {
|
|
230
|
+
transform: rotate(var(--angle, 0) deg)
|
|
231
|
+
translate(var(--h-radius, 160px), 0)
|
|
232
|
+
rotate(calc(var(--angle, 0) deg * -1));
|
|
233
|
+
}
|
|
234
|
+
to {
|
|
235
|
+
transform: rotate(calc(var(--angle, 0) deg + 360deg))
|
|
236
|
+
translate(var(--h-radius, 160px), 0)
|
|
237
|
+
rotate(calc((var(--angle, 0) deg + 360deg) * -1));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@keyframes alert-flash {
|
|
242
|
+
0% {
|
|
243
|
+
background-color: inherit;
|
|
244
|
+
}
|
|
245
|
+
50% {
|
|
246
|
+
background-color: hsl(var(--flash-color, 142 76% 36% / 0.3));
|
|
247
|
+
}
|
|
248
|
+
100% {
|
|
249
|
+
background-color: inherit;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@keyframes reason-flash {
|
|
254
|
+
0% {
|
|
255
|
+
background-color: inherit;
|
|
256
|
+
}
|
|
257
|
+
50% {
|
|
258
|
+
background-color: hsl(45 93% 47% / 0.4); /* Yellow flash */
|
|
259
|
+
}
|
|
260
|
+
100% {
|
|
261
|
+
background-color: inherit;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
--font-heading: var(--font-mono);
|
|
266
|
+
|
|
267
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
268
|
+
|
|
269
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
270
|
+
|
|
271
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
:root {
|
|
275
|
+
--muted: oklch(0.967 0.001 286.375);
|
|
276
|
+
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
277
|
+
--popover: oklch(1 0 0);
|
|
278
|
+
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
279
|
+
--card: oklch(1 0 0);
|
|
280
|
+
--card-foreground: oklch(0.141 0.005 285.823);
|
|
281
|
+
--border: oklch(0.92 0.004 286.32);
|
|
282
|
+
--input: oklch(0.92 0.004 286.32);
|
|
283
|
+
--primary: oklch(0.5 0.134 242.749);
|
|
284
|
+
--primary-foreground: oklch(0.977 0.013 236.62);
|
|
285
|
+
--secondary: oklch(0.967 0.001 286.375);
|
|
286
|
+
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
287
|
+
--accent: oklch(0.967 0.001 286.375);
|
|
288
|
+
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
289
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
290
|
+
--destructive-foreground: 0 0% 100%;
|
|
291
|
+
--ring: oklch(0.705 0.015 286.067);
|
|
292
|
+
--chart-1: oklch(0.905 0.182 98.111);
|
|
293
|
+
--chart-2: oklch(0.795 0.184 86.047);
|
|
294
|
+
--chart-3: oklch(0.681 0.162 75.834);
|
|
295
|
+
--chart-4: oklch(0.554 0.135 66.442);
|
|
296
|
+
--chart-5: oklch(0.476 0.114 61.907);
|
|
297
|
+
--radius: 0;
|
|
298
|
+
--sidebar: oklch(0.985 0 0);
|
|
299
|
+
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
|
300
|
+
--sidebar-primary: oklch(0.588 0.158 241.966);
|
|
301
|
+
--sidebar-primary-foreground: oklch(0.977 0.013 236.62);
|
|
302
|
+
--sidebar-accent: oklch(0.967 0.001 286.375);
|
|
303
|
+
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
|
304
|
+
--sidebar-border: oklch(0.92 0.004 286.32);
|
|
305
|
+
--sidebar-ring: oklch(0.705 0.015 286.067);
|
|
306
|
+
--background: oklch(1 0 0);
|
|
307
|
+
--foreground: oklch(0.141 0.005 285.823);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.dark {
|
|
311
|
+
--background: oklch(0.141 0.005 285.823);
|
|
312
|
+
--foreground: oklch(0.985 0 0);
|
|
313
|
+
--muted: oklch(0.274 0.006 286.033);
|
|
314
|
+
--muted-foreground: oklch(0.705 0.015 286.067);
|
|
315
|
+
--popover: oklch(0.21 0.006 285.885);
|
|
316
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
317
|
+
--card: oklch(0.21 0.006 285.885);
|
|
318
|
+
--card-foreground: oklch(0.985 0 0);
|
|
319
|
+
--border: oklch(1 0 0 / 10%);
|
|
320
|
+
--input: oklch(1 0 0 / 15%);
|
|
321
|
+
--primary: oklch(0.443 0.11 240.79);
|
|
322
|
+
--primary-foreground: oklch(0.977 0.013 236.62);
|
|
323
|
+
--secondary: oklch(0.274 0.006 286.033);
|
|
324
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
325
|
+
--accent: oklch(0.274 0.006 286.033);
|
|
326
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
327
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
328
|
+
--destructive-foreground: 0 0% 93.33%;
|
|
329
|
+
--ring: oklch(0.552 0.016 285.938);
|
|
330
|
+
--chart-1: oklch(0.905 0.182 98.111);
|
|
331
|
+
--chart-2: oklch(0.795 0.184 86.047);
|
|
332
|
+
--chart-3: oklch(0.681 0.162 75.834);
|
|
333
|
+
--chart-4: oklch(0.554 0.135 66.442);
|
|
334
|
+
--chart-5: oklch(0.476 0.114 61.907);
|
|
335
|
+
--sidebar: oklch(0.21 0.006 285.885);
|
|
336
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
337
|
+
--sidebar-primary: oklch(0.685 0.169 237.323);
|
|
338
|
+
--sidebar-primary-foreground: oklch(0.293 0.066 243.157);
|
|
339
|
+
--sidebar-accent: oklch(0.274 0.006 286.033);
|
|
340
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
341
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
342
|
+
--sidebar-ring: oklch(0.552 0.016 285.938);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
@layer base {
|
|
346
|
+
* {
|
|
347
|
+
@apply border-border outline-ring/50;
|
|
348
|
+
}
|
|
349
|
+
html {
|
|
350
|
+
scroll-behavior: smooth;
|
|
351
|
+
scrollbar-width: thin; /* Firefox thin scrollbar */
|
|
352
|
+
scrollbar-color: color-mix(in oklch, var(--muted) 40%, transparent)
|
|
353
|
+
transparent; /* Firefox scrollbar colors */
|
|
354
|
+
@apply font-mono;
|
|
355
|
+
}
|
|
356
|
+
body {
|
|
357
|
+
@apply bg-background text-foreground;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
@layer components {
|
|
362
|
+
/* Sonner Toast Styles */
|
|
363
|
+
[data-sonner-toast] {
|
|
364
|
+
background: var(--normal-bg);
|
|
365
|
+
color: var(--normal-text);
|
|
366
|
+
border: 1px solid var(--normal-border);
|
|
367
|
+
border-radius: var(--border-radius);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
[data-sonner-toast][data-styled="true"] {
|
|
371
|
+
background: var(--normal-bg);
|
|
372
|
+
color: var(--normal-text);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* Scrollbar Hide Utility - !important overrides global scrollbar styles */
|
|
376
|
+
.scrollbar-hide {
|
|
377
|
+
-ms-overflow-style: none !important; /* IE 10+ */
|
|
378
|
+
scrollbar-width: none !important; /* Firefox */
|
|
379
|
+
}
|
|
380
|
+
.scrollbar-hide::-webkit-scrollbar {
|
|
381
|
+
display: none !important; /* Chrome, Safari, Edge */
|
|
382
|
+
width: 0 !important;
|
|
383
|
+
height: 0 !important;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/* Subtle scrollbar - thin, minimal, visible on hover (use instead of scrollbar-hide if you prefer styled) */
|
|
387
|
+
.scrollbar-subtle::-webkit-scrollbar {
|
|
388
|
+
width: 6px;
|
|
389
|
+
height: 6px;
|
|
390
|
+
}
|
|
391
|
+
.scrollbar-subtle::-webkit-scrollbar-track {
|
|
392
|
+
background: transparent;
|
|
393
|
+
}
|
|
394
|
+
.scrollbar-subtle::-webkit-scrollbar-thumb {
|
|
395
|
+
background: color-mix(in oklch, var(--muted) 35%, transparent);
|
|
396
|
+
border-radius: 9999px;
|
|
397
|
+
}
|
|
398
|
+
.scrollbar-subtle::-webkit-scrollbar-thumb:hover {
|
|
399
|
+
background: color-mix(in oklch, var(--muted) 60%, transparent);
|
|
400
|
+
}
|
|
401
|
+
.scrollbar-subtle {
|
|
402
|
+
scrollbar-width: thin;
|
|
403
|
+
scrollbar-color: color-mix(in oklch, var(--muted) 35%, transparent)
|
|
404
|
+
transparent;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* Custom Scrollbar Styles - Auto-hide on idle, show on hover */
|
|
408
|
+
::-webkit-scrollbar {
|
|
409
|
+
width: 8px;
|
|
410
|
+
height: 8px;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
::-webkit-scrollbar-track {
|
|
414
|
+
background: transparent;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
::-webkit-scrollbar-thumb {
|
|
418
|
+
background: color-mix(in oklch, var(--muted) 30%, transparent);
|
|
419
|
+
border-radius: var(--radius-sm);
|
|
420
|
+
transition:
|
|
421
|
+
opacity 0.2s ease,
|
|
422
|
+
background-color 0.2s ease;
|
|
423
|
+
opacity: 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
::-webkit-scrollbar-thumb:hover {
|
|
427
|
+
background: color-mix(in oklch, var(--muted) 60%, transparent);
|
|
428
|
+
opacity: 1;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* Show scrollbar on hover over scrollable elements */
|
|
432
|
+
*:hover::-webkit-scrollbar-thumb {
|
|
433
|
+
opacity: 0.4;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
*:hover::-webkit-scrollbar-thumb:hover {
|
|
437
|
+
opacity: 1;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/* Custom Prose Styles for MDX Content */
|
|
441
|
+
.prose {
|
|
442
|
+
@apply text-foreground max-w-none;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.prose h1 {
|
|
446
|
+
@apply text-3xl font-bold tracking-tight mt-8 mb-6 text-foreground;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.prose h2 {
|
|
450
|
+
@apply text-2xl font-bold tracking-tight mt-8 mb-4 text-foreground;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.prose h3 {
|
|
454
|
+
@apply text-xl font-bold tracking-tight mt-6 mb-3 text-foreground;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.prose h4 {
|
|
458
|
+
@apply text-lg font-semibold mt-6 mb-3 text-foreground;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.prose h5 {
|
|
462
|
+
@apply text-base font-semibold mt-4 mb-2 text-foreground;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.prose h6 {
|
|
466
|
+
@apply text-sm font-semibold mt-4 mb-2 text-foreground;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.prose p {
|
|
470
|
+
@apply leading-relaxed mb-4 text-muted-foreground;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.prose strong {
|
|
474
|
+
@apply font-semibold text-foreground;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.prose em {
|
|
478
|
+
@apply italic;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.prose a {
|
|
482
|
+
@apply text-primary no-underline hover:underline;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.prose ul {
|
|
486
|
+
@apply list-disc pl-6 mb-4 text-muted-foreground;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.prose ol {
|
|
490
|
+
@apply list-decimal pl-6 mb-4 text-muted-foreground;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.prose li {
|
|
494
|
+
@apply mb-1 text-muted-foreground;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.prose blockquote {
|
|
498
|
+
@apply border-l-4 border-primary bg-muted/50 py-2 px-4 my-4 italic;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.prose code {
|
|
502
|
+
@apply bg-muted px-1 py-0.5 rounded font-mono text-sm;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.prose pre {
|
|
506
|
+
@apply bg-muted border rounded-lg p-4 overflow-x-auto my-4;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.prose pre code {
|
|
510
|
+
@apply bg-transparent p-0;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.prose img {
|
|
514
|
+
@apply rounded-lg border my-4;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.prose hr {
|
|
518
|
+
@apply border-border my-8;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.prose table {
|
|
522
|
+
@apply border border-border rounded-lg my-4 w-full;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.prose th {
|
|
526
|
+
@apply bg-muted font-semibold p-3 text-left border-b border-border;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.prose td {
|
|
530
|
+
@apply p-3 border-b border-border;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.prose tbody tr:last-child td {
|
|
534
|
+
@apply border-b-0;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
@layer utilities {
|
|
539
|
+
/* Dynamic viewport height for mobile browsers */
|
|
540
|
+
/* Uses 100dvh (dynamic viewport height) which accounts for mobile browser UI */
|
|
541
|
+
/* Falls back to 100vh for older browsers that don't support dvh */
|
|
542
|
+
.h-dvh {
|
|
543
|
+
height: 100vh; /* Fallback for older browsers */
|
|
544
|
+
height: 100dvh; /* Modern browsers - accounts for dynamic mobile browser UI */
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* Dynamic minimum viewport height for mobile browsers */
|
|
548
|
+
.min-h-dvh {
|
|
549
|
+
min-height: 100vh; /* Fallback for older browsers */
|
|
550
|
+
min-height: 100dvh; /* Modern browsers - accounts for dynamic mobile browser UI */
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* Reranking animation for smooth table row transitions */
|
|
554
|
+
.reranking {
|
|
555
|
+
& tr {
|
|
556
|
+
transition: all 0.3s ease-in-out;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
iframe {
|
|
562
|
+
color-scheme: light;
|
|
563
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Geist, Geist_Mono, JetBrains_Mono } from "next/font/google";
|
|
3
|
+
import { Providers } from "@/components/providers";
|
|
4
|
+
import "./globals.css";
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
const jetbrainsMono = JetBrains_Mono({
|
|
8
|
+
subsets: ["latin"],
|
|
9
|
+
variable: "--font-mono",
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const geistSans = Geist({
|
|
13
|
+
variable: "--font-geist-sans",
|
|
14
|
+
subsets: ["latin"],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const geistMono = Geist_Mono({
|
|
18
|
+
variable: "--font-geist-mono",
|
|
19
|
+
subsets: ["latin"],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const metadata: Metadata = {
|
|
23
|
+
title: "Create Next App",
|
|
24
|
+
description: "Generated by create next app",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default function RootLayout({
|
|
28
|
+
children,
|
|
29
|
+
}: Readonly<{
|
|
30
|
+
children: React.ReactNode;
|
|
31
|
+
}>) {
|
|
32
|
+
return (
|
|
33
|
+
<html
|
|
34
|
+
lang="en"
|
|
35
|
+
className={cn(
|
|
36
|
+
"h-full",
|
|
37
|
+
"antialiased",
|
|
38
|
+
geistSans.variable,
|
|
39
|
+
geistMono.variable,
|
|
40
|
+
"font-mono",
|
|
41
|
+
jetbrainsMono.variable,
|
|
42
|
+
)}
|
|
43
|
+
>
|
|
44
|
+
<body className="min-h-full flex flex-col">
|
|
45
|
+
<Providers>{children}</Providers>
|
|
46
|
+
<div className="absolute inset-0 -z-10 h-full w-full bg-background bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:14px_24px]"></div>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import { HomeAuthPanel } from "@/components/home-auth-panel";
|
|
6
|
+
|
|
7
|
+
type BackendRootResponse = { message: string };
|
|
8
|
+
|
|
9
|
+
function parseBackendRoot(json: unknown): BackendRootResponse | null {
|
|
10
|
+
if (
|
|
11
|
+
json !== null &&
|
|
12
|
+
typeof json === "object" &&
|
|
13
|
+
"message" in json &&
|
|
14
|
+
typeof (json as { message: unknown }).message === "string"
|
|
15
|
+
) {
|
|
16
|
+
return { message: (json as { message: string }).message };
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function fetchBackendHelloWorld(): Promise<BackendRootResponse> {
|
|
22
|
+
let res: Response;
|
|
23
|
+
try {
|
|
24
|
+
res = await fetch("/api/backend/hello-world", {
|
|
25
|
+
credentials: "include",
|
|
26
|
+
});
|
|
27
|
+
} catch {
|
|
28
|
+
throw new Error("Network error.");
|
|
29
|
+
}
|
|
30
|
+
const json: unknown = await res.json().catch(() => null);
|
|
31
|
+
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
if (res.status === 401) {
|
|
34
|
+
throw new Error("Sign in to load data from the API.");
|
|
35
|
+
}
|
|
36
|
+
throw new Error(`Request failed (${res.status}).`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const parsed = parseBackendRoot(json);
|
|
40
|
+
if (!parsed) {
|
|
41
|
+
throw new Error("Unexpected response shape from the API.");
|
|
42
|
+
}
|
|
43
|
+
return parsed;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default function Page() {
|
|
47
|
+
const { data, error, isPending } = useQuery({
|
|
48
|
+
queryKey: ["backend", "hello-world"],
|
|
49
|
+
queryFn: fetchBackendHelloWorld,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const errorMessage =
|
|
53
|
+
error instanceof Error
|
|
54
|
+
? error.message
|
|
55
|
+
: error != null
|
|
56
|
+
? "Something went wrong."
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<main className="mx-auto flex w-full max-w-xl flex-1 flex-col gap-6 p-6">
|
|
61
|
+
<h1 className="text-2xl font-semibold tracking-tight">Homed</h1>
|
|
62
|
+
<HomeAuthPanel />
|
|
63
|
+
<p className="text-sm">
|
|
64
|
+
<Link
|
|
65
|
+
href="/chat"
|
|
66
|
+
className="text-neutral-600 underline dark:text-neutral-400"
|
|
67
|
+
>
|
|
68
|
+
Chat & ingest
|
|
69
|
+
</Link>
|
|
70
|
+
{" · "}
|
|
71
|
+
<Link
|
|
72
|
+
href="/settings/integrations"
|
|
73
|
+
className="text-neutral-600 underline dark:text-neutral-400"
|
|
74
|
+
>
|
|
75
|
+
Integration settings
|
|
76
|
+
</Link>
|
|
77
|
+
</p>
|
|
78
|
+
<section className="rounded-lg border border-neutral-200 bg-white/60 p-4 dark:border-neutral-800 dark:bg-neutral-950/40">
|
|
79
|
+
<h2 className="text-sm font-medium text-neutral-500">
|
|
80
|
+
Backend (via gateway)
|
|
81
|
+
</h2>
|
|
82
|
+
{isPending ? (
|
|
83
|
+
<p className="mt-2 text-sm text-neutral-600">Loading…</p>
|
|
84
|
+
) : errorMessage ? (
|
|
85
|
+
<p className="mt-2 text-sm text-amber-800 dark:text-amber-200">
|
|
86
|
+
{errorMessage}
|
|
87
|
+
</p>
|
|
88
|
+
) : data ? (
|
|
89
|
+
<p className="mt-2 text-sm text-neutral-800 dark:text-neutral-100">
|
|
90
|
+
{data.message}
|
|
91
|
+
</p>
|
|
92
|
+
) : null}
|
|
93
|
+
</section>
|
|
94
|
+
</main>
|
|
95
|
+
);
|
|
96
|
+
}
|