@hachej/boring-core 0.1.24 → 0.1.27
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.
|
@@ -2,12 +2,24 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { C as CoreFrontAuthPagesOverride } from '../../CoreFront-N0QJSYaM.js';
|
|
4
4
|
import { WorkspaceAgentSession, WorkspaceAgentFrontProps } from '@hachej/boring-workspace/app/front';
|
|
5
|
+
import { ChatSuggestion } from '@hachej/boring-agent/front';
|
|
6
|
+
|
|
7
|
+
interface ChatFirstPublicShellOptions {
|
|
8
|
+
composerPlaceholder?: string;
|
|
9
|
+
emptyState?: {
|
|
10
|
+
eyebrow?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
};
|
|
14
|
+
suggestions?: ChatSuggestion[];
|
|
15
|
+
}
|
|
5
16
|
|
|
6
17
|
type ChatEntryMode = 'auth-first' | 'chat-first';
|
|
7
18
|
interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession = WorkspaceAgentSession> extends Omit<WorkspaceAgentFrontProps<TSession>, 'workspaceId' | 'frontPluginHotReload' | 'hotReloadEnabled'> {
|
|
8
19
|
/** Core consumes plugins statically for now; app-level hot reload is explicitly unsupported. */
|
|
9
20
|
hotReload?: false;
|
|
10
21
|
chatEntryMode?: ChatEntryMode;
|
|
22
|
+
chatFirstPublicShell?: ChatFirstPublicShellOptions;
|
|
11
23
|
authPages?: CoreFrontAuthPagesOverride;
|
|
12
24
|
cspNonce?: string;
|
|
13
25
|
children?: ReactNode;
|
|
@@ -17,6 +29,6 @@ interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession =
|
|
|
17
29
|
loadingFallback?: ReactNode;
|
|
18
30
|
bootPreloadPaths?: string[];
|
|
19
31
|
}
|
|
20
|
-
declare function CoreWorkspaceAgentFront<TSession extends WorkspaceAgentSession = WorkspaceAgentSession>({ authPages, cspNonce, children, workspaceRoute, workspaceIdParam, workspaceHref, loadingFallback, bootPreloadPaths, topBarLeft, topBarRight, appTitle, bridgeEndpoint, hotReload, chatEntryMode, ...workspaceProps }: CoreWorkspaceAgentFrontProps<TSession>): react_jsx_runtime.JSX.Element;
|
|
32
|
+
declare function CoreWorkspaceAgentFront<TSession extends WorkspaceAgentSession = WorkspaceAgentSession>({ authPages, cspNonce, children, workspaceRoute, workspaceIdParam, workspaceHref, loadingFallback, bootPreloadPaths, topBarLeft, topBarRight, appTitle, bridgeEndpoint, hotReload, chatEntryMode, chatFirstPublicShell, ...workspaceProps }: CoreWorkspaceAgentFrontProps<TSession>): react_jsx_runtime.JSX.Element;
|
|
21
33
|
|
|
22
|
-
export { CoreWorkspaceAgentFront, type CoreWorkspaceAgentFrontProps };
|
|
34
|
+
export { type ChatFirstPublicShellOptions, CoreWorkspaceAgentFront, type CoreWorkspaceAgentFrontProps };
|
package/dist/app/front/index.js
CHANGED
|
@@ -234,6 +234,17 @@ function workspaceIdFromPath(pathname, workspaceRoute, workspaceIdParam) {
|
|
|
234
234
|
|
|
235
235
|
// src/app/front/chatFirst/ChatFirstPublicShell.tsx
|
|
236
236
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
237
|
+
var defaultPublicEmptyState = {
|
|
238
|
+
eyebrow: "Start here",
|
|
239
|
+
title: "What do you want to build?",
|
|
240
|
+
description: "Type a prompt or pick an example. Sign in on send to unlock your private workspace."
|
|
241
|
+
};
|
|
242
|
+
var defaultPublicSuggestions = [
|
|
243
|
+
{ label: "Build an app from scratch", hint: "Creates files, installs deps, opens a preview", prompt: "Build a full-stack app with auth, a dashboard, and sample data." },
|
|
244
|
+
{ label: "Understand a codebase", hint: "Maps the repo and explains where to start", prompt: "Explain this codebase, map the architecture, and suggest first improvements." },
|
|
245
|
+
{ label: "Fix a bug safely", hint: "Finds the cause, edits files, runs tests", prompt: "Trace a bug, edit the right files, update tests, and summarize the diff." },
|
|
246
|
+
{ label: "Prototype an interface", hint: "Turns an idea into an interactive UI", prompt: "Build an interactive prototype and open it in the workspace." }
|
|
247
|
+
];
|
|
237
248
|
function readComposerDraftFromDom() {
|
|
238
249
|
if (typeof document === "undefined") return "";
|
|
239
250
|
const input = document.querySelector('[data-boring-agent-part="composer-input"]');
|
|
@@ -242,6 +253,7 @@ function readComposerDraftFromDom() {
|
|
|
242
253
|
function ChatFirstPublicShell({
|
|
243
254
|
appTitle,
|
|
244
255
|
intendedWorkspaceId,
|
|
256
|
+
publicShell,
|
|
245
257
|
workspaceProps
|
|
246
258
|
}) {
|
|
247
259
|
const location = useLocation();
|
|
@@ -267,18 +279,12 @@ function ChatFirstPublicShell({
|
|
|
267
279
|
chatParams: {
|
|
268
280
|
...workspaceProps.chatParams,
|
|
269
281
|
emptyPlacement: "hero",
|
|
270
|
-
composerPlaceholder: "Describe the app, bug, or repo task you want help with\u2026",
|
|
282
|
+
composerPlaceholder: publicShell?.composerPlaceholder ?? "Describe the app, bug, or repo task you want help with\u2026",
|
|
271
283
|
emptyState: {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
description: "Type a prompt or pick an example. Sign in on send to unlock your private workspace."
|
|
284
|
+
...defaultPublicEmptyState,
|
|
285
|
+
...publicShell?.emptyState
|
|
275
286
|
},
|
|
276
|
-
suggestions:
|
|
277
|
-
{ label: "Build an app from scratch", hint: "Creates files, installs deps, opens a preview", prompt: "Build a full-stack app with auth, a dashboard, and sample data." },
|
|
278
|
-
{ label: "Understand a codebase", hint: "Maps the repo and explains where to start", prompt: "Explain this codebase, map the architecture, and suggest first improvements." },
|
|
279
|
-
{ label: "Fix a bug safely", hint: "Finds the cause, edits files, runs tests", prompt: "Trace a bug, edit the right files, update tests, and summarize the diff." },
|
|
280
|
-
{ label: "Prototype an interface", hint: "Turns an idea into an interactive UI", prompt: "Build an interactive prototype and open it in the workspace." }
|
|
281
|
-
],
|
|
287
|
+
suggestions: publicShell?.suggestions ?? defaultPublicSuggestions,
|
|
282
288
|
onBeforeSubmit: (draft) => {
|
|
283
289
|
openAuth(draft);
|
|
284
290
|
return false;
|
|
@@ -347,7 +353,8 @@ function HomeRedirect({
|
|
|
347
353
|
workspaceHref,
|
|
348
354
|
chatEntryMode,
|
|
349
355
|
appTitle,
|
|
350
|
-
workspaceProps
|
|
356
|
+
workspaceProps,
|
|
357
|
+
chatFirstPublicShell
|
|
351
358
|
}) {
|
|
352
359
|
const location = useLocation2();
|
|
353
360
|
const session = useSession();
|
|
@@ -359,7 +366,7 @@ function HomeRedirect({
|
|
|
359
366
|
location.search,
|
|
360
367
|
location.hash
|
|
361
368
|
);
|
|
362
|
-
if (!session.data?.user && chatEntryMode === "chat-first") return /* @__PURE__ */ jsx5(ChatFirstPublicShell, { appTitle, workspaceProps });
|
|
369
|
+
if (!session.data?.user && chatEntryMode === "chat-first") return /* @__PURE__ */ jsx5(ChatFirstPublicShell, { appTitle, publicShell: chatFirstPublicShell, workspaceProps });
|
|
363
370
|
if (!workspace && chatEntryMode === "chat-first" && session.data?.user && restorePendingDraft) {
|
|
364
371
|
return /* @__PURE__ */ jsx5(
|
|
365
372
|
ChatFirstAuthenticatedShell,
|
|
@@ -388,7 +395,8 @@ function WorkspaceRoute({
|
|
|
388
395
|
workspaceProps,
|
|
389
396
|
chatEntryMode,
|
|
390
397
|
appTitle,
|
|
391
|
-
workspaceRoute
|
|
398
|
+
workspaceRoute,
|
|
399
|
+
chatFirstPublicShell
|
|
392
400
|
}) {
|
|
393
401
|
const params = useParams();
|
|
394
402
|
const location = useLocation2();
|
|
@@ -414,7 +422,7 @@ function WorkspaceRoute({
|
|
|
414
422
|
);
|
|
415
423
|
if (!workspaceId) return /* @__PURE__ */ jsx5(Fragment2, { children: loadingFallback });
|
|
416
424
|
if (!session.data?.user && chatEntryMode === "chat-first") {
|
|
417
|
-
return /* @__PURE__ */ jsx5(ChatFirstPublicShell, { appTitle, intendedWorkspaceId: workspaceId, workspaceProps });
|
|
425
|
+
return /* @__PURE__ */ jsx5(ChatFirstPublicShell, { appTitle, intendedWorkspaceId: workspaceId, publicShell: chatFirstPublicShell, workspaceProps });
|
|
418
426
|
}
|
|
419
427
|
if (routeStatus.status === "not-found" || routeStatus.status === "forbidden" || routeStatus.status === "switch-failed") {
|
|
420
428
|
return /* @__PURE__ */ jsx5(WorkspaceRouteErrorPage, { status: routeStatus.status, message: routeStatus.message });
|
|
@@ -476,6 +484,7 @@ function CoreWorkspaceAgentFront({
|
|
|
476
484
|
bridgeEndpoint = "/api/v1/ui",
|
|
477
485
|
hotReload = false,
|
|
478
486
|
chatEntryMode = "auth-first",
|
|
487
|
+
chatFirstPublicShell,
|
|
479
488
|
...workspaceProps
|
|
480
489
|
}) {
|
|
481
490
|
if (hotReload !== false) {
|
|
@@ -518,7 +527,8 @@ function CoreWorkspaceAgentFront({
|
|
|
518
527
|
workspaceHref,
|
|
519
528
|
chatEntryMode,
|
|
520
529
|
appTitle,
|
|
521
|
-
workspaceProps: resolvedWorkspaceProps
|
|
530
|
+
workspaceProps: resolvedWorkspaceProps,
|
|
531
|
+
chatFirstPublicShell
|
|
522
532
|
}
|
|
523
533
|
)
|
|
524
534
|
}
|
|
@@ -536,7 +546,8 @@ function CoreWorkspaceAgentFront({
|
|
|
536
546
|
workspaceProps: resolvedWorkspaceProps,
|
|
537
547
|
chatEntryMode,
|
|
538
548
|
appTitle,
|
|
539
|
-
workspaceRoute
|
|
549
|
+
workspaceRoute,
|
|
550
|
+
chatFirstPublicShell
|
|
540
551
|
}
|
|
541
552
|
)
|
|
542
553
|
}
|
package/dist/app/server/index.js
CHANGED
|
@@ -1955,6 +1955,7 @@ var DEFAULT_WORKSPACE_NAME = "My Workspace";
|
|
|
1955
1955
|
var workspaceRoutesPlugin = async (app) => {
|
|
1956
1956
|
const store = app.workspaceStore;
|
|
1957
1957
|
const provisioner = app.provisioner;
|
|
1958
|
+
const defaultWorkspaceCreates = /* @__PURE__ */ new Map();
|
|
1958
1959
|
async function provisionWorkspace(workspace, ownerId, request) {
|
|
1959
1960
|
if (!provisioner) return;
|
|
1960
1961
|
await store.putWorkspaceRuntime(workspace.id, { state: "pending" });
|
|
@@ -2002,8 +2003,26 @@ var workspaceRoutesPlugin = async (app) => {
|
|
|
2002
2003
|
await Promise.all(existing.map((workspace) => ensureDefaultWorkspaceProvisioned(workspace, request)));
|
|
2003
2004
|
return existing;
|
|
2004
2005
|
}
|
|
2005
|
-
const
|
|
2006
|
-
|
|
2006
|
+
const createKey = `${app.config.appId}:${userId}`;
|
|
2007
|
+
const inFlight = defaultWorkspaceCreates.get(createKey);
|
|
2008
|
+
if (inFlight) return await inFlight;
|
|
2009
|
+
const createPromise = (async () => {
|
|
2010
|
+
try {
|
|
2011
|
+
const created = await createWorkspaceForUser(userId, DEFAULT_WORKSPACE_NAME, true, request);
|
|
2012
|
+
return [created];
|
|
2013
|
+
} catch (error) {
|
|
2014
|
+
if (error instanceof HttpError) throw error;
|
|
2015
|
+
const racedExisting = await store.list(userId, app.config.appId);
|
|
2016
|
+
if (racedExisting.length > 0) return racedExisting;
|
|
2017
|
+
throw error;
|
|
2018
|
+
}
|
|
2019
|
+
})();
|
|
2020
|
+
defaultWorkspaceCreates.set(createKey, createPromise);
|
|
2021
|
+
try {
|
|
2022
|
+
return await createPromise;
|
|
2023
|
+
} finally {
|
|
2024
|
+
if (defaultWorkspaceCreates.get(createKey) === createPromise) defaultWorkspaceCreates.delete(createKey);
|
|
2025
|
+
}
|
|
2007
2026
|
}
|
|
2008
2027
|
app.post("/api/v1/workspaces", async (request, reply) => {
|
|
2009
2028
|
const parsed = createWorkspaceBody.safeParse(request.body);
|
package/dist/server/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hachej/boring-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
"react-router-dom": "^7.14.2",
|
|
80
80
|
"smol-toml": "^1.6.1",
|
|
81
81
|
"zod": "^3.25.76",
|
|
82
|
-
"@hachej/boring-agent": "0.1.
|
|
83
|
-
"@hachej/boring-
|
|
84
|
-
"@hachej/boring-
|
|
82
|
+
"@hachej/boring-agent": "0.1.27",
|
|
83
|
+
"@hachej/boring-ui-kit": "0.1.27",
|
|
84
|
+
"@hachej/boring-workspace": "0.1.27"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
87
|
"@testing-library/jest-dom": "^6.9.1",
|