@hachej/boring-core 0.1.48 → 0.1.49
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/dist/{PostgresMeteringStore-DhOVVtau.d.ts → PostgresMeteringStore-qjKGmVFr.d.ts} +1 -1
- package/dist/app/front/chatFirst/chatFirstPublicShell.css +269 -0
- package/dist/app/front/index.js +80 -40
- package/dist/app/front/styles.css +47 -0
- package/dist/app/server/index.d.ts +4 -4
- package/dist/app/server/index.js +4 -3
- package/dist/{authHook-DtzhSmqS.d.ts → authHook-BbgCBHjP.d.ts} +3 -3
- package/dist/{chunk-FZC3VL5D.js → chunk-BVZ2YT3M.js} +1 -1
- package/dist/chunk-I4PGL4ZD.js +17 -0
- package/dist/{chunk-VYXEXOCO.js → chunk-P4RF2D7H.js} +80 -32
- package/dist/{chunk-LIBHVT7V.js → chunk-QZGYKLXB.js} +1 -0
- package/dist/{chunk-6GAQRQKO.js → chunk-ZMS6O4CY.js} +26 -11
- package/dist/{connection-C5SiqoNc.d.ts → connection-B1iC6B-w.d.ts} +3 -2
- package/dist/front/index.d.ts +3 -2
- package/dist/front/index.js +3 -2
- package/dist/server/db/index.d.ts +4 -4
- package/dist/server/db/index.js +2 -2
- package/dist/server/index.d.ts +53 -48
- package/dist/server/index.js +8 -6
- package/dist/shared/index.d.ts +7 -13
- package/dist/shared/index.js +9 -1
- package/dist/telemetry-DR18MeI0.d.ts +13 -0
- package/dist/{types-CWtJ4kgd.d.ts → types-Bb7I-83I.d.ts} +3 -1
- package/package.json +6 -5
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Default styling for the chat-first public (no-auth) shell rendered by
|
|
3
|
+
* `ChatFirstPublicShell`. Brand-agnostic and token-driven (`--accent`,
|
|
4
|
+
* `--foreground`, `--muted-foreground`) so every consumer — full-app and child
|
|
5
|
+
* apps alike — inherits a polished landing. Apps customize via design tokens +
|
|
6
|
+
* the `chatFirstPublicShell` props (copy, `models`, suggestions), not by
|
|
7
|
+
* re-implementing this sheet. Imported via the package's `styles.css` entry.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* Subtle warm glow behind the hero so the flat background reads with depth.
|
|
11
|
+
Layers as a background-image over the shell's bg-background color. */
|
|
12
|
+
.public-chat-first-shell {
|
|
13
|
+
background-image: radial-gradient(
|
|
14
|
+
70% 52% at 30% 22%,
|
|
15
|
+
color-mix(in oklch, var(--accent) 11%, transparent),
|
|
16
|
+
transparent 68%
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* --- Hand-drawn teaching annotations (public no-auth shell) --- */
|
|
21
|
+
.public-arrow {
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
position: fixed;
|
|
24
|
+
z-index: 20;
|
|
25
|
+
display: flex;
|
|
26
|
+
color: color-mix(in oklch, var(--foreground) 55%, transparent);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.public-arrow-svg {
|
|
30
|
+
overflow: visible;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.public-arrow .paw-stroke {
|
|
34
|
+
fill: none;
|
|
35
|
+
stroke: currentColor;
|
|
36
|
+
stroke-width: 3.5;
|
|
37
|
+
stroke-linecap: round;
|
|
38
|
+
stroke-linejoin: round;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.public-arrow-label {
|
|
42
|
+
font-family: "Caveat", ui-rounded, "Segoe Print", cursive;
|
|
43
|
+
font-weight: 700;
|
|
44
|
+
font-size: 26px;
|
|
45
|
+
line-height: 1;
|
|
46
|
+
color: color-mix(in oklch, var(--foreground) 78%, transparent);
|
|
47
|
+
white-space: nowrap;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Right: points to the workspace surface button on the right edge. */
|
|
51
|
+
.public-arrow-computer {
|
|
52
|
+
right: 12px;
|
|
53
|
+
bottom: 374px;
|
|
54
|
+
align-items: flex-end;
|
|
55
|
+
gap: 4px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.public-arrow-computer .public-arrow-label {
|
|
59
|
+
margin-bottom: 6px;
|
|
60
|
+
transform: rotate(-5deg);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.public-arrow-computer .public-arrow-svg {
|
|
64
|
+
width: 178px;
|
|
65
|
+
height: 134px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Bottom: points up to the composer (the agent input). */
|
|
69
|
+
.public-arrow-agent {
|
|
70
|
+
left: 50%;
|
|
71
|
+
bottom: 78px;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
align-items: center;
|
|
74
|
+
transform: translateX(-50%);
|
|
75
|
+
gap: 2px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.public-arrow-agent .public-arrow-svg {
|
|
79
|
+
width: 96px;
|
|
80
|
+
height: 92px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.public-arrow-agent .public-arrow-label {
|
|
84
|
+
transform: rotate(-4deg);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Teaching arrows + bottom-left sign-in card are edge decorations that need
|
|
88
|
+
horizontal room — keep them on normal screens, hide only when genuinely
|
|
89
|
+
narrow (where they'd collide with the centered hero/composer). */
|
|
90
|
+
@media (max-width: 1100px) {
|
|
91
|
+
.public-arrow,
|
|
92
|
+
.public-chat-first-shell > aside {
|
|
93
|
+
display: none;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* The composer's model/thinking picker menu expands upward over the hero. It
|
|
98
|
+
lives deep in the chat content (a non-positioned ancestor), so a z-index
|
|
99
|
+
can't lift it above the fixed teaching arrow / sign-in card. Instead, while a
|
|
100
|
+
picker menu is open, hide the bottom "Ask your AI here" arrow and the sign-in
|
|
101
|
+
card so the menu reads cleanly; they return as soon as it closes. */
|
|
102
|
+
.public-chat-first-shell:has([data-boring-agent-part="model-picker-menu"], [data-boring-agent-part="thinking-picker-menu"]) .public-arrow-agent,
|
|
103
|
+
.public-chat-first-shell:has([data-boring-agent-part="model-picker-menu"], [data-boring-agent-part="thinking-picker-menu"]) > aside {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Hide the chat-pane header strip ("New session") in the no-auth shell — there's
|
|
108
|
+
only ever a single pane here, so its title/drag/close bar is pure noise. */
|
|
109
|
+
.public-chat-first-shell .dv-chat-stage .dv-tabs-and-actions-container {
|
|
110
|
+
display: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* Keep opened workspace panes above the teaching arrows. */
|
|
114
|
+
.public-chat-first-shell [data-boring-workspace-part="workbench"] {
|
|
115
|
+
z-index: 30;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* --- Prominent hero (public no-auth empty state only) --- */
|
|
119
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] {
|
|
120
|
+
max-width: min(1120px, 92vw);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] > div:first-child {
|
|
124
|
+
font-size: 12px;
|
|
125
|
+
letter-spacing: 0.18em;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] h3 {
|
|
129
|
+
margin-top: 22px;
|
|
130
|
+
font-size: clamp(30px, 4.4vw, 60px);
|
|
131
|
+
font-weight: 600;
|
|
132
|
+
line-height: 1;
|
|
133
|
+
letter-spacing: -0.04em;
|
|
134
|
+
white-space: nowrap;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Editorial accent on the closing period (the title string omits its own). */
|
|
138
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] h3::after {
|
|
139
|
+
content: ".";
|
|
140
|
+
color: var(--accent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] > p {
|
|
144
|
+
display: block;
|
|
145
|
+
/* Let the subhead breathe: more space from the title and looser leading
|
|
146
|
+
between the two lines. */
|
|
147
|
+
margin-top: 18px;
|
|
148
|
+
max-width: 58ch;
|
|
149
|
+
font-size: 17px;
|
|
150
|
+
line-height: 1.85;
|
|
151
|
+
/* Honor the explicit \n after "Choose the AI you trust." in the subhead. */
|
|
152
|
+
white-space: pre-line;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@media (max-width: 560px) {
|
|
156
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] h3 {
|
|
157
|
+
white-space: normal;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Top-bias the hero + composer group instead of vertically centering it, so it
|
|
162
|
+
doesn't float to mid-screen (with a large empty band on top) on tall windows. */
|
|
163
|
+
.public-chat-first-shell [class*="justify-center"]:has([data-boring-agent-part="empty-state"]) {
|
|
164
|
+
justify-content: flex-start;
|
|
165
|
+
padding-top: clamp(28px, 9vh, 132px);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Move the /command cards to the bottom of the hero block (after the footer),
|
|
169
|
+
so they sit directly above the composer. The empty-state is a flex column,
|
|
170
|
+
so `order` reorders without touching the React tree. */
|
|
171
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] .public-hero-foot {
|
|
172
|
+
order: 10;
|
|
173
|
+
}
|
|
174
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] [data-boring-agent-part="suggestion-grid"] {
|
|
175
|
+
order: 20;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Command launcher cards — make the slash commands read as runnable. */
|
|
179
|
+
.public-chat-first-shell [data-boring-agent-part="suggestion-grid"] {
|
|
180
|
+
margin-top: 28px;
|
|
181
|
+
max-width: 560px;
|
|
182
|
+
margin-left: auto;
|
|
183
|
+
margin-right: auto;
|
|
184
|
+
/* Match the composer's rounding + 1px outline so cards + input read as one
|
|
185
|
+
design system (composer rail is rounded-[28px] with a border/0.7 outline). */
|
|
186
|
+
border-radius: 20px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* Accent send button — make the composer's primary action carry the accent so
|
|
190
|
+
the orange reads as intentional, not just decoration on the slash cards.
|
|
191
|
+
Scoped to the public hero; the shared composer elsewhere stays neutral. */
|
|
192
|
+
.public-chat-first-shell [data-boring-agent-part="composer-submit"] {
|
|
193
|
+
background-color: var(--accent);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.public-chat-first-shell [data-boring-agent-part="composer-submit"]:hover {
|
|
197
|
+
background-color: color-mix(in oklch, var(--accent) 90%, var(--foreground));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.public-chat-first-shell [data-boring-agent-part="suggestion-card"] {
|
|
201
|
+
padding-top: 15px;
|
|
202
|
+
padding-bottom: 15px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.public-chat-first-shell [data-boring-agent-part="suggestion-card"] > span > span:first-child {
|
|
206
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
207
|
+
font-size: 13.5px;
|
|
208
|
+
font-weight: 600;
|
|
209
|
+
letter-spacing: -0.01em;
|
|
210
|
+
color: var(--accent);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.public-chat-first-shell [data-boring-agent-part="suggestion-card"] > span > span:nth-child(2) {
|
|
214
|
+
margin-top: 2px;
|
|
215
|
+
font-size: 12.5px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Single compact footer line: "providers … · Open source [logo]". */
|
|
219
|
+
.public-chat-first-shell .public-hero-foot {
|
|
220
|
+
display: flex;
|
|
221
|
+
flex-direction: row;
|
|
222
|
+
flex-wrap: wrap;
|
|
223
|
+
align-items: center;
|
|
224
|
+
justify-content: center;
|
|
225
|
+
gap: 8px;
|
|
226
|
+
margin-top: 30px;
|
|
227
|
+
font-size: 12.5px;
|
|
228
|
+
line-height: 1.4;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.public-chat-first-shell .public-hero-foot span {
|
|
232
|
+
color: var(--muted-foreground);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.public-chat-first-shell .public-hero-foot .public-hero-providers {
|
|
236
|
+
color: color-mix(in oklch, var(--foreground) 60%, transparent);
|
|
237
|
+
letter-spacing: 0.01em;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.public-chat-first-shell .public-hero-foot .public-hero-dot {
|
|
241
|
+
color: var(--muted-foreground);
|
|
242
|
+
opacity: 0.5;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.public-chat-first-shell .public-hero-foot .public-hero-github {
|
|
246
|
+
display: inline-flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
gap: 5px;
|
|
249
|
+
color: var(--foreground);
|
|
250
|
+
font-weight: 500;
|
|
251
|
+
text-decoration: none;
|
|
252
|
+
transition: color 0.15s ease;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.public-chat-first-shell .public-hero-foot .public-hero-github svg {
|
|
256
|
+
width: 15px;
|
|
257
|
+
height: 15px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.public-chat-first-shell .public-hero-foot .public-hero-github:hover {
|
|
261
|
+
color: var(--accent);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Emphasize the trusted choice in the subhead without it reading as a link. */
|
|
265
|
+
.public-chat-first-shell [data-boring-agent-part="empty-state"] > p .public-hero-trust {
|
|
266
|
+
font-style: normal;
|
|
267
|
+
font-weight: 600;
|
|
268
|
+
color: color-mix(in oklch, var(--foreground) 88%, transparent);
|
|
269
|
+
}
|
package/dist/app/front/index.js
CHANGED
|
@@ -3,14 +3,18 @@ import {
|
|
|
3
3
|
UserMenu,
|
|
4
4
|
WorkspaceSwitcher,
|
|
5
5
|
routes,
|
|
6
|
+
useConfig,
|
|
6
7
|
useCurrentWorkspace,
|
|
7
8
|
useSession,
|
|
8
9
|
useSignIn,
|
|
9
10
|
useSignUp,
|
|
10
11
|
useWorkspaceRouteStatus
|
|
11
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-P4RF2D7H.js";
|
|
12
13
|
import "../../chunk-HYNKZSTF.js";
|
|
13
|
-
import
|
|
14
|
+
import {
|
|
15
|
+
isRuntimeEmailVerificationEnabled
|
|
16
|
+
} from "../../chunk-I4PGL4ZD.js";
|
|
17
|
+
import "../../chunk-QZGYKLXB.js";
|
|
14
18
|
import "../../chunk-MLKGABMK.js";
|
|
15
19
|
|
|
16
20
|
// src/app/front/CoreWorkspaceAgentFront.tsx
|
|
@@ -108,6 +112,7 @@ function AuthCard({
|
|
|
108
112
|
onClose
|
|
109
113
|
}) {
|
|
110
114
|
const navigate = useNavigate();
|
|
115
|
+
const config = useConfig();
|
|
111
116
|
const signIn = useSignIn();
|
|
112
117
|
const signUp = useSignUp();
|
|
113
118
|
const [mode, setMode] = useState("signin");
|
|
@@ -127,6 +132,10 @@ function AuthCard({
|
|
|
127
132
|
return;
|
|
128
133
|
}
|
|
129
134
|
onClose?.();
|
|
135
|
+
if (mode === "signup" && isRuntimeEmailVerificationEnabled(config)) {
|
|
136
|
+
navigate(routes.verifyEmail, { replace: true });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
130
139
|
navigate(returnTo, { replace: true });
|
|
131
140
|
} catch (err) {
|
|
132
141
|
setError(err instanceof Error ? err.message : `${mode === "signin" ? "Sign in" : "Sign up"} failed`);
|
|
@@ -521,10 +530,29 @@ function HomeRedirect({
|
|
|
521
530
|
workspaceHref,
|
|
522
531
|
chatEntryMode,
|
|
523
532
|
appTitle,
|
|
533
|
+
topBarLeft,
|
|
534
|
+
topBarRight,
|
|
524
535
|
workspaceProps,
|
|
525
536
|
chatFirstPublicShell,
|
|
526
537
|
chatFirstPublicWorkspaceProps
|
|
527
538
|
}) {
|
|
539
|
+
const config = useConfig();
|
|
540
|
+
const resolvedAppTitle = appTitle ?? config.appName;
|
|
541
|
+
const resolvedTopBarLeft = topBarLeft === void 0 ? /* @__PURE__ */ jsx5(WorkspaceSwitcher, { appTitle: resolvedAppTitle }) : topBarLeft;
|
|
542
|
+
const resolvedLoadingFallback = loadingFallback ?? /* @__PURE__ */ jsx5(
|
|
543
|
+
WorkspaceLoadingPage,
|
|
544
|
+
{
|
|
545
|
+
appTitle: resolvedAppTitle,
|
|
546
|
+
topBarLeft: resolvedTopBarLeft,
|
|
547
|
+
topBarRight
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
const resolvedWorkspaceProps = {
|
|
551
|
+
...workspaceProps,
|
|
552
|
+
appTitle: resolvedAppTitle,
|
|
553
|
+
topBarLeft: resolvedTopBarLeft,
|
|
554
|
+
topBarRight
|
|
555
|
+
};
|
|
528
556
|
const location = useLocation2();
|
|
529
557
|
const session = useSession();
|
|
530
558
|
const workspace = useCurrentWorkspace();
|
|
@@ -539,9 +567,9 @@ function HomeRedirect({
|
|
|
539
567
|
return /* @__PURE__ */ jsx5(
|
|
540
568
|
ChatFirstPublicShell,
|
|
541
569
|
{
|
|
542
|
-
appTitle,
|
|
570
|
+
appTitle: resolvedAppTitle,
|
|
543
571
|
publicShell: chatFirstPublicShell,
|
|
544
|
-
workspaceProps: mergePublicWorkspaceProps(
|
|
572
|
+
workspaceProps: mergePublicWorkspaceProps(resolvedWorkspaceProps, chatFirstPublicWorkspaceProps)
|
|
545
573
|
}
|
|
546
574
|
);
|
|
547
575
|
}
|
|
@@ -549,14 +577,14 @@ function HomeRedirect({
|
|
|
549
577
|
return /* @__PURE__ */ jsx5(
|
|
550
578
|
ChatFirstAuthenticatedShell,
|
|
551
579
|
{
|
|
552
|
-
appTitle,
|
|
580
|
+
appTitle: resolvedAppTitle,
|
|
553
581
|
workspaceId: pendingChatEntry?.intendedWorkspaceId ?? DEFAULT_CHAT_FIRST_PENDING_WORKSPACE_ID,
|
|
554
582
|
initialDraft: pendingChatEntry?.draft,
|
|
555
|
-
workspaceProps
|
|
583
|
+
workspaceProps: resolvedWorkspaceProps
|
|
556
584
|
}
|
|
557
585
|
);
|
|
558
586
|
}
|
|
559
|
-
if (!workspace) return /* @__PURE__ */ jsx5(Fragment3, { children:
|
|
587
|
+
if (!workspace) return /* @__PURE__ */ jsx5(Fragment3, { children: resolvedLoadingFallback });
|
|
560
588
|
return /* @__PURE__ */ jsx5(Navigate, { to: workspaceHref(workspace.id), replace: true });
|
|
561
589
|
}
|
|
562
590
|
function WorkspaceRouteErrorPage({ status, message }) {
|
|
@@ -573,10 +601,29 @@ function WorkspaceRoute({
|
|
|
573
601
|
workspaceProps,
|
|
574
602
|
chatEntryMode,
|
|
575
603
|
appTitle,
|
|
604
|
+
topBarLeft,
|
|
605
|
+
topBarRight,
|
|
576
606
|
workspaceRoute,
|
|
577
607
|
chatFirstPublicShell,
|
|
578
608
|
chatFirstPublicWorkspaceProps
|
|
579
609
|
}) {
|
|
610
|
+
const config = useConfig();
|
|
611
|
+
const resolvedAppTitle = appTitle ?? config.appName;
|
|
612
|
+
const resolvedTopBarLeft = topBarLeft === void 0 ? /* @__PURE__ */ jsx5(WorkspaceSwitcher, { appTitle: resolvedAppTitle }) : topBarLeft;
|
|
613
|
+
const resolvedLoadingFallback = loadingFallback ?? /* @__PURE__ */ jsx5(
|
|
614
|
+
WorkspaceLoadingPage,
|
|
615
|
+
{
|
|
616
|
+
appTitle: resolvedAppTitle,
|
|
617
|
+
topBarLeft: resolvedTopBarLeft,
|
|
618
|
+
topBarRight
|
|
619
|
+
}
|
|
620
|
+
);
|
|
621
|
+
const resolvedWorkspaceProps = {
|
|
622
|
+
...workspaceProps,
|
|
623
|
+
appTitle: resolvedAppTitle,
|
|
624
|
+
topBarLeft: resolvedTopBarLeft,
|
|
625
|
+
topBarRight
|
|
626
|
+
};
|
|
580
627
|
const params = useParams();
|
|
581
628
|
const location = useLocation2();
|
|
582
629
|
const session = useSession();
|
|
@@ -592,22 +639,22 @@ function WorkspaceRoute({
|
|
|
592
639
|
location.hash
|
|
593
640
|
) || pendingChatEntry?.returnTo === "/" && currentWorkspace?.id === workspaceId);
|
|
594
641
|
const requestHeaders = useMemo(
|
|
595
|
-
() => ({ ...
|
|
596
|
-
[workspaceId,
|
|
642
|
+
() => ({ ...resolvedWorkspaceProps.requestHeaders, "x-boring-workspace-id": workspaceId }),
|
|
643
|
+
[workspaceId, resolvedWorkspaceProps.requestHeaders]
|
|
597
644
|
);
|
|
598
645
|
const authHeaders = useMemo(
|
|
599
|
-
() => ({ ...
|
|
600
|
-
[workspaceId,
|
|
646
|
+
() => ({ ...resolvedWorkspaceProps.authHeaders, "x-boring-workspace-id": workspaceId }),
|
|
647
|
+
[workspaceId, resolvedWorkspaceProps.authHeaders]
|
|
601
648
|
);
|
|
602
|
-
if (!workspaceId) return /* @__PURE__ */ jsx5(Fragment3, { children:
|
|
649
|
+
if (!workspaceId) return /* @__PURE__ */ jsx5(Fragment3, { children: resolvedLoadingFallback });
|
|
603
650
|
if (!session.data?.user && chatEntryMode === "chat-first") {
|
|
604
651
|
return /* @__PURE__ */ jsx5(
|
|
605
652
|
ChatFirstPublicShell,
|
|
606
653
|
{
|
|
607
|
-
appTitle,
|
|
654
|
+
appTitle: resolvedAppTitle,
|
|
608
655
|
intendedWorkspaceId: workspaceId,
|
|
609
656
|
publicShell: chatFirstPublicShell,
|
|
610
|
-
workspaceProps: mergePublicWorkspaceProps(
|
|
657
|
+
workspaceProps: mergePublicWorkspaceProps(resolvedWorkspaceProps, chatFirstPublicWorkspaceProps)
|
|
611
658
|
}
|
|
612
659
|
);
|
|
613
660
|
}
|
|
@@ -618,21 +665,21 @@ function WorkspaceRoute({
|
|
|
618
665
|
return /* @__PURE__ */ jsx5(
|
|
619
666
|
ChatFirstAuthenticatedShell,
|
|
620
667
|
{
|
|
621
|
-
appTitle,
|
|
668
|
+
appTitle: resolvedAppTitle,
|
|
622
669
|
workspaceId,
|
|
623
670
|
initialDraft: pendingChatEntry?.draft,
|
|
624
|
-
workspaceProps
|
|
671
|
+
workspaceProps: resolvedWorkspaceProps
|
|
625
672
|
}
|
|
626
673
|
);
|
|
627
674
|
}
|
|
628
|
-
if (routeStatus.status !== "matched" || currentWorkspace?.id !== workspaceId) return /* @__PURE__ */ jsx5(Fragment3, { children:
|
|
675
|
+
if (routeStatus.status !== "matched" || currentWorkspace?.id !== workspaceId) return /* @__PURE__ */ jsx5(Fragment3, { children: resolvedLoadingFallback });
|
|
629
676
|
const shouldRestorePendingDraft = restorePendingDraft && Boolean(pendingChatEntry?.draft);
|
|
630
677
|
const chatParams = {
|
|
631
|
-
...
|
|
678
|
+
...resolvedWorkspaceProps.chatParams,
|
|
632
679
|
...shouldRestorePendingDraft ? { initialDraft: pendingChatEntry?.draft } : {},
|
|
633
680
|
...shouldRestorePendingDraft ? { autoSubmitInitialDraft: true } : {},
|
|
634
681
|
onBeforeSubmit: async (draft, ctx) => {
|
|
635
|
-
const existing =
|
|
682
|
+
const existing = resolvedWorkspaceProps.chatParams?.onBeforeSubmit;
|
|
636
683
|
const result = await existing?.(draft, ctx);
|
|
637
684
|
if (result !== false) clearPendingChatEntry();
|
|
638
685
|
return result;
|
|
@@ -641,9 +688,9 @@ function WorkspaceRoute({
|
|
|
641
688
|
return /* @__PURE__ */ jsx5(
|
|
642
689
|
WorkspaceAgentFront2,
|
|
643
690
|
{
|
|
644
|
-
...
|
|
691
|
+
...resolvedWorkspaceProps,
|
|
645
692
|
workspaceId,
|
|
646
|
-
workspaceLabel:
|
|
693
|
+
workspaceLabel: resolvedWorkspaceProps.workspaceLabel ?? currentWorkspace.name,
|
|
647
694
|
requestHeaders,
|
|
648
695
|
authHeaders,
|
|
649
696
|
chatParams,
|
|
@@ -667,9 +714,9 @@ function CoreWorkspaceAgentFront({
|
|
|
667
714
|
workspaceHref = (workspaceId) => `/workspace/${workspaceId}`,
|
|
668
715
|
loadingFallback,
|
|
669
716
|
bootPreloadPaths,
|
|
670
|
-
topBarLeft
|
|
717
|
+
topBarLeft,
|
|
671
718
|
topBarRight = /* @__PURE__ */ jsx5(DefaultTopBarRight, {}),
|
|
672
|
-
appTitle
|
|
719
|
+
appTitle,
|
|
673
720
|
bridgeEndpoint = "/api/v1/ui",
|
|
674
721
|
hotReload = false,
|
|
675
722
|
chatEntryMode = "auth-first",
|
|
@@ -683,19 +730,8 @@ function CoreWorkspaceAgentFront({
|
|
|
683
730
|
"CoreWorkspaceAgentFront does not support hotReload yet; use static plugin consumption or WorkspaceAgentFront for standalone hot reload."
|
|
684
731
|
);
|
|
685
732
|
}
|
|
686
|
-
const
|
|
687
|
-
WorkspaceLoadingPage,
|
|
688
|
-
{
|
|
689
|
-
appTitle,
|
|
690
|
-
topBarLeft,
|
|
691
|
-
topBarRight
|
|
692
|
-
}
|
|
693
|
-
);
|
|
694
|
-
const resolvedWorkspaceProps = {
|
|
733
|
+
const routedWorkspaceProps = {
|
|
695
734
|
...workspaceProps,
|
|
696
|
-
appTitle,
|
|
697
|
-
topBarLeft,
|
|
698
|
-
topBarRight,
|
|
699
735
|
bridgeEndpoint
|
|
700
736
|
};
|
|
701
737
|
return /* @__PURE__ */ jsxs4(
|
|
@@ -714,11 +750,13 @@ function CoreWorkspaceAgentFront({
|
|
|
714
750
|
element: /* @__PURE__ */ jsx5(
|
|
715
751
|
HomeRedirect,
|
|
716
752
|
{
|
|
717
|
-
loadingFallback
|
|
753
|
+
loadingFallback,
|
|
718
754
|
workspaceHref,
|
|
719
755
|
chatEntryMode,
|
|
720
756
|
appTitle,
|
|
721
|
-
|
|
757
|
+
topBarLeft,
|
|
758
|
+
topBarRight,
|
|
759
|
+
workspaceProps: routedWorkspaceProps,
|
|
722
760
|
chatFirstPublicShell,
|
|
723
761
|
chatFirstPublicWorkspaceProps
|
|
724
762
|
}
|
|
@@ -733,11 +771,13 @@ function CoreWorkspaceAgentFront({
|
|
|
733
771
|
WorkspaceRoute,
|
|
734
772
|
{
|
|
735
773
|
workspaceIdParam,
|
|
736
|
-
loadingFallback
|
|
774
|
+
loadingFallback,
|
|
737
775
|
bootPreloadPaths,
|
|
738
|
-
workspaceProps:
|
|
776
|
+
workspaceProps: routedWorkspaceProps,
|
|
739
777
|
chatEntryMode,
|
|
740
778
|
appTitle,
|
|
779
|
+
topBarLeft,
|
|
780
|
+
topBarRight,
|
|
741
781
|
workspaceRoute,
|
|
742
782
|
chatFirstPublicShell,
|
|
743
783
|
chatFirstPublicWorkspaceProps
|
|
@@ -1351,7 +1391,7 @@ function BuyCreditsNoticeAction({ apiBaseUrl = "", label = "Buy credits" }) {
|
|
|
1351
1391
|
size: "sm",
|
|
1352
1392
|
onClick: () => void onBuy(),
|
|
1353
1393
|
disabled: buying,
|
|
1354
|
-
className: "
|
|
1394
|
+
className: "boring-buy-credits-notice-button",
|
|
1355
1395
|
children: buying ? "Opening\u2026" : label
|
|
1356
1396
|
}
|
|
1357
1397
|
),
|
|
@@ -4,3 +4,50 @@
|
|
|
4
4
|
@import "../../front/theme.css";
|
|
5
5
|
@import "@hachej/boring-workspace/globals.css";
|
|
6
6
|
@import "@hachej/boring-agent/front/styles.css";
|
|
7
|
+
|
|
8
|
+
/* Default styling for the chat-first public (no-auth) shell. Imported last so
|
|
9
|
+
its plain rules sit after Tailwind's utilities in the cascade. */
|
|
10
|
+
@import "./chatFirst/chatFirstPublicShell.css";
|
|
11
|
+
|
|
12
|
+
/* Credit notice CTA renders inside the agent subtree. Keep this selector after
|
|
13
|
+
Tailwind + agent globals so it beats both the Button variant colors and
|
|
14
|
+
[data-boring-agent] button color reset. */
|
|
15
|
+
[data-boring-agent] .boring-buy-credits-notice-button,
|
|
16
|
+
.boring-buy-credits-notice-button {
|
|
17
|
+
border: 1px solid color-mix(in oklab, var(--foreground) 18%, transparent);
|
|
18
|
+
background: var(--foreground);
|
|
19
|
+
color: var(--background);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
[data-boring-agent] .boring-buy-credits-notice-button:hover,
|
|
23
|
+
.boring-buy-credits-notice-button:hover {
|
|
24
|
+
background: color-mix(in oklab, var(--foreground) 90%, transparent);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
html[data-theme="dark"] [data-boring-agent] .boring-buy-credits-notice-button,
|
|
28
|
+
html[data-theme="dark"] .boring-buy-credits-notice-button {
|
|
29
|
+
border-color: oklch(1 0 0 / 0.2);
|
|
30
|
+
background: oklch(0.985 0 0);
|
|
31
|
+
color: oklch(0.145 0.004 285.823);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
html[data-theme="dark"] [data-boring-agent] .boring-buy-credits-notice-button:hover,
|
|
35
|
+
html[data-theme="dark"] .boring-buy-credits-notice-button:hover {
|
|
36
|
+
background: oklch(0.9 0 0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* The public-shell chat composer submit button sits on a brand/accent foreground.
|
|
40
|
+
The generic inverse text is too low-contrast on that amber CTA, so pin the public
|
|
41
|
+
shell icon to dark ink while leaving authenticated workspace composers alone. */
|
|
42
|
+
.public-chat-first-shell [data-boring-agent] [data-boring-agent-part="composer-submit"] {
|
|
43
|
+
color: oklch(0.145 0.004 285.823) !important;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
html[data-theme="dark"] .public-chat-first-shell [data-boring-agent] [data-boring-agent-part="composer-submit"] {
|
|
47
|
+
background: oklch(0.985 0 0) !important;
|
|
48
|
+
color: oklch(0.145 0.004 285.823) !important;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
html[data-theme="dark"] .public-chat-first-shell [data-boring-agent] [data-boring-agent-part="composer-submit"]:hover {
|
|
52
|
+
background: oklch(0.9 0 0) !important;
|
|
53
|
+
}
|
|
@@ -2,10 +2,10 @@ import { RuntimeProvisioningContribution, RegisterAgentRoutesOptions } from '@ha
|
|
|
2
2
|
import { DirPluginEntry, CreateWorkspaceAgentServerOptions } from '@hachej/boring-workspace/app/server';
|
|
3
3
|
import { WorkspaceServerPlugin } from '@hachej/boring-workspace/server';
|
|
4
4
|
import { FastifyInstance } from 'fastify';
|
|
5
|
-
import { C as CoreConfig } from '../../types-
|
|
6
|
-
import { TelemetrySink } from '../../
|
|
7
|
-
import { B as BetterAuthInstance, L as LoadConfigOptions } from '../../authHook-
|
|
8
|
-
import { D as Database, U as UserStore, W as WorkspaceStore } from '../../connection-
|
|
5
|
+
import { C as CoreConfig } from '../../types-Bb7I-83I.js';
|
|
6
|
+
import { T as TelemetrySink } from '../../telemetry-DR18MeI0.js';
|
|
7
|
+
import { B as BetterAuthInstance, L as LoadConfigOptions } from '../../authHook-BbgCBHjP.js';
|
|
8
|
+
import { D as Database, U as UserStore, W as WorkspaceStore } from '../../connection-B1iC6B-w.js';
|
|
9
9
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
10
10
|
import 'better-auth';
|
|
11
11
|
import 'drizzle-orm/postgres-js';
|
package/dist/app/server/index.js
CHANGED
|
@@ -9,20 +9,21 @@ import {
|
|
|
9
9
|
registerRoutes,
|
|
10
10
|
registerSettingsRoutes,
|
|
11
11
|
registerWorkspaceRoutes
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-ZMS6O4CY.js";
|
|
13
13
|
import {
|
|
14
14
|
PostgresUserStore,
|
|
15
15
|
PostgresWorkspaceStore,
|
|
16
16
|
createDatabase,
|
|
17
17
|
telemetryEvents
|
|
18
|
-
} from "../../chunk-
|
|
18
|
+
} from "../../chunk-BVZ2YT3M.js";
|
|
19
19
|
import {
|
|
20
20
|
noopTelemetry,
|
|
21
21
|
safeCapture
|
|
22
22
|
} from "../../chunk-AQBXNPMD.js";
|
|
23
|
+
import "../../chunk-I4PGL4ZD.js";
|
|
23
24
|
import {
|
|
24
25
|
ERROR_CODES
|
|
25
|
-
} from "../../chunk-
|
|
26
|
+
} from "../../chunk-QZGYKLXB.js";
|
|
26
27
|
import "../../chunk-MLKGABMK.js";
|
|
27
28
|
|
|
28
29
|
// src/app/server/createCoreWorkspaceAgentServer.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { C as CoreConfig, R as RuntimeConfig } from './types-
|
|
1
|
+
import { C as CoreConfig, R as RuntimeConfig } from './types-Bb7I-83I.js';
|
|
2
2
|
import { FastifyPluginAsync } from 'fastify';
|
|
3
3
|
import { Auth } from 'better-auth';
|
|
4
|
-
import { W as WorkspaceStore, D as Database } from './connection-
|
|
5
|
-
import { TelemetrySink } from './
|
|
4
|
+
import { W as WorkspaceStore, D as Database } from './connection-B1iC6B-w.js';
|
|
5
|
+
import { T as TelemetrySink } from './telemetry-DR18MeI0.js';
|
|
6
6
|
|
|
7
7
|
interface LoadConfigOptions {
|
|
8
8
|
tomlPath?: string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/shared/authPolicy.ts
|
|
2
|
+
function isCoreEmailVerificationEnabled(config) {
|
|
3
|
+
return Boolean(config.auth.mail);
|
|
4
|
+
}
|
|
5
|
+
function isRuntimeEmailVerificationEnabled(config) {
|
|
6
|
+
return config?.features.emailVerification === true;
|
|
7
|
+
}
|
|
8
|
+
function canUseProtectedApi(user, requireEmailVerification) {
|
|
9
|
+
if (!user) return false;
|
|
10
|
+
return !requireEmailVerification || user.emailVerified === true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
isCoreEmailVerificationEnabled,
|
|
15
|
+
isRuntimeEmailVerificationEnabled,
|
|
16
|
+
canUseProtectedApi
|
|
17
|
+
};
|