@hachej/boring-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/CoreFront-CDeLdfb0.d.ts +19 -0
  4. package/dist/app/front/index.d.ts +18 -0
  5. package/dist/app/front/index.js +162 -0
  6. package/dist/app/front/styles.css +6 -0
  7. package/dist/app/server/index.d.ts +96 -0
  8. package/dist/app/server/index.js +507 -0
  9. package/dist/app/vite/index.d.ts +10 -0
  10. package/dist/app/vite/index.js +33 -0
  11. package/dist/authHook-vsRhOvnh.d.ts +38 -0
  12. package/dist/chunk-CZ4HIXII.js +2869 -0
  13. package/dist/chunk-H5KU6R6Y.js +68 -0
  14. package/dist/chunk-HSRBZLKT.js +1684 -0
  15. package/dist/chunk-HYNKZSTF.js +18 -0
  16. package/dist/chunk-MLKGABMK.js +9 -0
  17. package/dist/chunk-VTOS4C7B.js +3443 -0
  18. package/dist/connection-CE7z-wBp.d.ts +145 -0
  19. package/dist/front/index.d.ts +458 -0
  20. package/dist/front/index.js +126 -0
  21. package/dist/front/theme.css +168 -0
  22. package/dist/front/top-bar-slot.d.ts +10 -0
  23. package/dist/front/top-bar-slot.js +9 -0
  24. package/dist/index-COZa03RP.d.ts +266 -0
  25. package/dist/migrate-D49JsATX.d.ts +8 -0
  26. package/dist/server/db/index.d.ts +209 -0
  27. package/dist/server/db/index.js +18 -0
  28. package/dist/server/index.d.ts +395 -0
  29. package/dist/server/index.js +136 -0
  30. package/dist/shared/index.d.ts +1 -0
  31. package/dist/shared/index.js +13 -0
  32. package/drizzle/.gitkeep +0 -0
  33. package/drizzle/0000_easy_meggan.sql +53 -0
  34. package/drizzle/0001_groovy_smiling_tiger.sql +14 -0
  35. package/drizzle/0002_busy_iron_man.sql +16 -0
  36. package/drizzle/0003_aspiring_richard_fisk.sql +12 -0
  37. package/drizzle/0004_heavy_lenny_balinger.sql +9 -0
  38. package/drizzle/0005_flimsy_mastermind.sql +17 -0
  39. package/drizzle/0006_happy_callisto.sql +13 -0
  40. package/drizzle/0007_v7_substrate.sql +54 -0
  41. package/drizzle/0008_workspace_sandbox_handles.sql +32 -0
  42. package/drizzle/0009_workspace_runtime_resources.sql +39 -0
  43. package/drizzle/meta/0000_snapshot.json +380 -0
  44. package/drizzle/meta/0001_snapshot.json +471 -0
  45. package/drizzle/meta/0002_snapshot.json +599 -0
  46. package/drizzle/meta/0003_snapshot.json +693 -0
  47. package/drizzle/meta/0004_snapshot.json +753 -0
  48. package/drizzle/meta/0005_snapshot.json +886 -0
  49. package/drizzle/meta/0006_snapshot.json +968 -0
  50. package/drizzle/meta/_journal.json +76 -0
  51. package/drizzle/schema.ts +110 -0
  52. package/package.json +127 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 boringdata
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # @boring/core
2
+
3
+ Database, auth, and app factory for boring-ui apps.
4
+
5
+ ```bash
6
+ pnpm add @boring/core
7
+ ```
8
+
9
+ ---
10
+
11
+ ## What it provides
12
+
13
+ - **Database** — Drizzle ORM schema for users, workspaces, sessions, invites
14
+ - **Auth** — better-auth with workspace support, invite flows, email verification
15
+ - **App factory** — Fastify app with auth routes, middleware, and CORS wired in
16
+ - **Frontend shell** — `<BoringApp>` React provider with auth pages and workspace switcher
17
+
18
+ ---
19
+
20
+ ## Quickstart
21
+
22
+ Server:
23
+
24
+ ```ts
25
+ import { createCoreApp, loadConfig } from "@boring/core/server"
26
+
27
+ const config = await loadConfig()
28
+ const app = await createCoreApp(config)
29
+ await app.listen({ port: config.port })
30
+ ```
31
+
32
+ Frontend:
33
+
34
+ ```tsx
35
+ import { BoringApp } from "@boring/core/front"
36
+ import { WorkspaceProvider, IdeLayout } from "@boring/workspace"
37
+
38
+ export function App() {
39
+ return (
40
+ <BoringApp>
41
+ <Route path="/" element={<WorkspaceProvider><IdeLayout /></WorkspaceProvider>} />
42
+ </BoringApp>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Config
50
+
51
+ Minimum `.env` to get started:
52
+
53
+ ```bash
54
+ DATABASE_URL=postgres://postgres:postgres@localhost:5432/boring
55
+ BETTER_AUTH_SECRET=<any 64-char hex string>
56
+ ANTHROPIC_API_KEY=sk-ant-...
57
+ ```
58
+
59
+ Run migrations:
60
+
61
+ ```bash
62
+ pnpm --filter @boring/core drizzle:migrate
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Package surfaces
68
+
69
+ ```ts
70
+ import { ... } from "@boring/core/server" // Fastify app factory, config
71
+ import { ... } from "@boring/core/front" // React shell, auth pages
72
+ import { ... } from "@boring/core/db" // Drizzle schema and client
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Part of [boring-ui](https://github.com/hachej/boring-ui)
78
+
79
+ | Package | Role |
80
+ |---|---|
81
+ | `@boring/core` | DB, auth, app factory |
82
+ | `@boring/workspace` | Plugin system, layouts |
83
+ | `@boring/agent` | Agent runtime + tools |
@@ -0,0 +1,19 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface CoreFrontAuthPagesOverride {
5
+ signIn?: React.FC;
6
+ signUp?: React.FC;
7
+ forgotPassword?: React.FC;
8
+ resetPassword?: React.FC;
9
+ verifyEmail?: React.FC;
10
+ userSettings?: React.FC;
11
+ }
12
+ interface CoreFrontProps {
13
+ children?: ReactNode;
14
+ authPages?: CoreFrontAuthPagesOverride;
15
+ cspNonce?: string;
16
+ }
17
+ declare function CoreFront({ children, authPages, cspNonce }: CoreFrontProps): react_jsx_runtime.JSX.Element;
18
+
19
+ export { type CoreFrontAuthPagesOverride as C, CoreFront as a, type CoreFrontProps as b };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { C as CoreFrontAuthPagesOverride } from '../../CoreFront-CDeLdfb0.js';
4
+ import { WorkspaceAgentSession, WorkspaceAgentFrontProps } from '@hachej/boring-workspace/app/front';
5
+
6
+ interface CoreWorkspaceAgentFrontProps<TSession extends WorkspaceAgentSession = WorkspaceAgentSession> extends Omit<WorkspaceAgentFrontProps<TSession>, 'workspaceId'> {
7
+ authPages?: CoreFrontAuthPagesOverride;
8
+ cspNonce?: string;
9
+ children?: ReactNode;
10
+ workspaceRoute?: string;
11
+ workspaceIdParam?: string;
12
+ workspaceHref?: (workspaceId: string) => string;
13
+ loadingFallback?: ReactNode;
14
+ bootPreloadPaths?: string[];
15
+ }
16
+ declare function CoreWorkspaceAgentFront<TSession extends WorkspaceAgentSession = WorkspaceAgentSession>({ authPages, cspNonce, children, workspaceRoute, workspaceIdParam, workspaceHref, loadingFallback, bootPreloadPaths, topBarLeft, topBarRight, appTitle, bridgeEndpoint, ...workspaceProps }: CoreWorkspaceAgentFrontProps<TSession>): react_jsx_runtime.JSX.Element;
17
+
18
+ export { CoreWorkspaceAgentFront, type CoreWorkspaceAgentFrontProps };
@@ -0,0 +1,162 @@
1
+ import {
2
+ CoreFront,
3
+ UserMenu,
4
+ WorkspaceSwitcher,
5
+ useCurrentWorkspace
6
+ } from "../../chunk-VTOS4C7B.js";
7
+ import "../../chunk-HYNKZSTF.js";
8
+ import "../../chunk-H5KU6R6Y.js";
9
+ import "../../chunk-MLKGABMK.js";
10
+
11
+ // src/app/front/CoreWorkspaceAgentFront.tsx
12
+ import { useMemo } from "react";
13
+ import { Navigate, Route, useParams } from "react-router-dom";
14
+ import {
15
+ WorkspaceAgentFront,
16
+ WorkspaceBootGate
17
+ } from "@hachej/boring-workspace/app/front";
18
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
19
+ var DEFAULT_WORKSPACE_ROUTE = "/workspace/:id";
20
+ var DEFAULT_WORKSPACE_ID_PARAM = "id";
21
+ function DefaultTopBarRight() {
22
+ return /* @__PURE__ */ jsx(UserMenu, {});
23
+ }
24
+ function WorkspaceLoadingPage({
25
+ appTitle,
26
+ topBarLeft,
27
+ topBarRight
28
+ }) {
29
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-screen min-h-0 flex-col bg-background text-foreground", children: [
30
+ /* @__PURE__ */ jsxs("header", { className: "flex h-12 shrink-0 items-center justify-between border-b border-border bg-card px-3", children: [
31
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
32
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold", children: appTitle }),
33
+ topBarLeft
34
+ ] }),
35
+ topBarRight
36
+ ] }),
37
+ /* @__PURE__ */ jsx("main", { className: "flex min-h-0 flex-1 items-center justify-center px-6", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-6 text-center shadow-sm", children: [
38
+ /* @__PURE__ */ jsx(
39
+ "div",
40
+ {
41
+ "aria-hidden": "true",
42
+ className: "mx-auto mb-4 h-8 w-8 rounded-full border-2 border-muted-foreground/20 border-t-foreground animate-spin will-change-transform"
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold", children: "Switching workspace" }),
46
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Restoring files, sessions, and saved layout." }),
47
+ /* @__PURE__ */ jsx("p", { className: "mt-4 text-xs uppercase tracking-[0.18em] text-muted-foreground", children: "Loading workspace" })
48
+ ] }) })
49
+ ] });
50
+ }
51
+ function HomeRedirect({
52
+ loadingFallback,
53
+ workspaceHref
54
+ }) {
55
+ const workspace = useCurrentWorkspace();
56
+ if (!workspace) return /* @__PURE__ */ jsx(Fragment, { children: loadingFallback });
57
+ return /* @__PURE__ */ jsx(Navigate, { to: workspaceHref(workspace.id), replace: true });
58
+ }
59
+ function WorkspaceRoute({
60
+ workspaceIdParam,
61
+ loadingFallback,
62
+ bootPreloadPaths,
63
+ workspaceProps
64
+ }) {
65
+ const params = useParams();
66
+ const currentWorkspace = useCurrentWorkspace();
67
+ const workspaceId = params[workspaceIdParam]?.trim() ?? "";
68
+ const requestHeaders = useMemo(
69
+ () => ({ ...workspaceProps.requestHeaders, "x-boring-workspace-id": workspaceId }),
70
+ [workspaceId, workspaceProps.requestHeaders]
71
+ );
72
+ const authHeaders = useMemo(
73
+ () => ({ ...workspaceProps.authHeaders, "x-boring-workspace-id": workspaceId }),
74
+ [workspaceId, workspaceProps.authHeaders]
75
+ );
76
+ if (!workspaceId) return /* @__PURE__ */ jsx(Fragment, { children: loadingFallback });
77
+ if (currentWorkspace?.id !== workspaceId) return /* @__PURE__ */ jsx(Fragment, { children: loadingFallback });
78
+ return /* @__PURE__ */ jsx(
79
+ WorkspaceBootGate,
80
+ {
81
+ workspaceId,
82
+ requestHeaders,
83
+ apiBaseUrl: workspaceProps.apiBaseUrl,
84
+ preloadPaths: bootPreloadPaths,
85
+ loadingFallback,
86
+ children: /* @__PURE__ */ jsx(
87
+ WorkspaceAgentFront,
88
+ {
89
+ ...workspaceProps,
90
+ workspaceId,
91
+ requestHeaders,
92
+ authHeaders
93
+ }
94
+ )
95
+ }
96
+ );
97
+ }
98
+ function CoreWorkspaceAgentFront({
99
+ authPages,
100
+ cspNonce,
101
+ children,
102
+ workspaceRoute = DEFAULT_WORKSPACE_ROUTE,
103
+ workspaceIdParam = DEFAULT_WORKSPACE_ID_PARAM,
104
+ workspaceHref = (workspaceId) => `/workspace/${workspaceId}`,
105
+ loadingFallback,
106
+ bootPreloadPaths,
107
+ topBarLeft = /* @__PURE__ */ jsx(WorkspaceSwitcher, {}),
108
+ topBarRight = /* @__PURE__ */ jsx(DefaultTopBarRight, {}),
109
+ appTitle = "Boring",
110
+ bridgeEndpoint = "/api/v1/ui",
111
+ ...workspaceProps
112
+ }) {
113
+ const resolvedLoadingFallback = loadingFallback ?? /* @__PURE__ */ jsx(
114
+ WorkspaceLoadingPage,
115
+ {
116
+ appTitle,
117
+ topBarLeft,
118
+ topBarRight
119
+ }
120
+ );
121
+ const resolvedWorkspaceProps = {
122
+ ...workspaceProps,
123
+ appTitle,
124
+ topBarLeft,
125
+ topBarRight,
126
+ bridgeEndpoint
127
+ };
128
+ return /* @__PURE__ */ jsxs(CoreFront, { authPages, cspNonce, children: [
129
+ /* @__PURE__ */ jsx(
130
+ Route,
131
+ {
132
+ path: "/",
133
+ element: /* @__PURE__ */ jsx(
134
+ HomeRedirect,
135
+ {
136
+ loadingFallback: resolvedLoadingFallback,
137
+ workspaceHref
138
+ }
139
+ )
140
+ }
141
+ ),
142
+ /* @__PURE__ */ jsx(
143
+ Route,
144
+ {
145
+ path: workspaceRoute,
146
+ element: /* @__PURE__ */ jsx(
147
+ WorkspaceRoute,
148
+ {
149
+ workspaceIdParam,
150
+ loadingFallback: resolvedLoadingFallback,
151
+ bootPreloadPaths,
152
+ workspaceProps: resolvedWorkspaceProps
153
+ }
154
+ )
155
+ }
156
+ ),
157
+ children
158
+ ] });
159
+ }
160
+ export {
161
+ CoreWorkspaceAgentFront
162
+ };
@@ -0,0 +1,6 @@
1
+ @import "tailwindcss" source(none);
2
+ @source "../..";
3
+
4
+ @import "../../front/theme.css";
5
+ @import "@hachej/boring-workspace/globals.css";
6
+ @import "@hachej/boring-agent/front/styles.css";
@@ -0,0 +1,96 @@
1
+ import { RuntimeProvisioningContribution, RegisterAgentRoutesOptions } from '@hachej/boring-agent/server';
2
+ import { CreateWorkspaceAgentServerOptions } from '@hachej/boring-workspace/app/server';
3
+ import { FastifyInstance } from 'fastify';
4
+ import { C as CoreConfig } from '../../index-COZa03RP.js';
5
+ import { B as BetterAuthInstance, L as LoadConfigOptions } from '../../authHook-vsRhOvnh.js';
6
+ import { D as Database, U as UserStore, W as WorkspaceStore } from '../../connection-CE7z-wBp.js';
7
+ import { IncomingMessage, ServerResponse } from 'node:http';
8
+ import 'better-auth';
9
+ import 'drizzle-orm/postgres-js';
10
+ import 'postgres';
11
+
12
+ type CoreWorkspaceAgentServer = FastifyInstance & {
13
+ auth: BetterAuthInstance;
14
+ db: Database;
15
+ userStore: UserStore;
16
+ workspaceStore: WorkspaceStore;
17
+ };
18
+ type CoreWorkspaceAgentServerPlugin = NonNullable<CreateWorkspaceAgentServerOptions['plugins']>[number] & {
19
+ provisioning?: RuntimeProvisioningContribution;
20
+ };
21
+ interface CreateCoreWorkspaceAgentServerOptions extends Omit<RegisterAgentRoutesOptions, 'extraTools'> {
22
+ appRoot?: string;
23
+ config?: CoreConfig;
24
+ loadConfigOptions?: LoadConfigOptions;
25
+ plugins?: CoreWorkspaceAgentServerPlugin[];
26
+ excludeDefaults?: CreateWorkspaceAgentServerOptions['excludeDefaults'];
27
+ forceProvisioning?: boolean;
28
+ extraTools?: RegisterAgentRoutesOptions['extraTools'];
29
+ systemPromptAppend?: string;
30
+ serveFrontend?: boolean;
31
+ }
32
+ declare function createCoreWorkspaceAgentServer(options?: CreateCoreWorkspaceAgentServerOptions): Promise<CoreWorkspaceAgentServer>;
33
+
34
+ interface StartCoreWorkspaceAgentDevServerOptions {
35
+ appRoot: string;
36
+ buildServer: (options: {
37
+ appRoot: string;
38
+ serveFrontend: false;
39
+ }) => Promise<CoreWorkspaceAgentServer>;
40
+ frontendPort?: number;
41
+ eventPrefix?: string;
42
+ }
43
+ interface CoreWorkspaceAgentDevServerHandle {
44
+ app: CoreWorkspaceAgentServer;
45
+ address: string;
46
+ apiTarget: string;
47
+ }
48
+ declare function startCoreWorkspaceAgentDevServer({ appRoot, buildServer, frontendPort, eventPrefix, }: StartCoreWorkspaceAgentDevServerOptions): Promise<CoreWorkspaceAgentDevServerHandle>;
49
+ interface StartCoreWorkspaceAgentDevServerFromMetaOptions {
50
+ frontendPort?: number;
51
+ eventPrefix?: string;
52
+ levelsUp?: number;
53
+ }
54
+ declare function startCoreWorkspaceAgentDevServerFromMeta(importMetaUrl: string, opts?: StartCoreWorkspaceAgentDevServerFromMetaOptions): Promise<CoreWorkspaceAgentDevServerHandle>;
55
+
56
+ interface VercelFastifyLikeServer {
57
+ ready(): PromiseLike<void> | void;
58
+ server: {
59
+ emit(event: 'request', req: IncomingMessage, res: ServerResponse): boolean;
60
+ };
61
+ }
62
+ type VercelFastifyHandler = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
63
+ interface CreateVercelFastifyHandlerOptions<TServer extends VercelFastifyLikeServer> {
64
+ createServer: () => Promise<TServer> | TServer;
65
+ }
66
+ /**
67
+ * Adapt a Fastify server factory to Vercel's Node function signature.
68
+ *
69
+ * The Fastify instance is created once per warm function process and reused for
70
+ * subsequent invocations. App-specific policy (runtime mode, workspace root,
71
+ * appRoot, etc.) belongs in the caller's `createServer` factory.
72
+ */
73
+ declare function createVercelFastifyHandler<TServer extends VercelFastifyLikeServer>({ createServer, }: CreateVercelFastifyHandlerOptions<TServer>): VercelFastifyHandler;
74
+
75
+ declare function appRootFromImportMeta(importMetaUrl: string, levelsUp?: number): string;
76
+
77
+ interface RunCoreWorkspaceAgentServerOptions {
78
+ workspaceRoot?: string;
79
+ /** How many directory levels up from the entry file is the app root. Default: 2 (src/server → app). */
80
+ levelsUp?: number;
81
+ }
82
+ declare function runCoreWorkspaceAgentServer(importMetaUrl: string, opts?: RunCoreWorkspaceAgentServerOptions): Promise<void>;
83
+
84
+ interface CreateCoreVercelEntryOptions {
85
+ workspaceRoot?: string;
86
+ }
87
+ /**
88
+ * Creates a Vercel Function handler.
89
+ * Sets BORING_AGENT_MODE and BORING_AGENT_WORKSPACE_ROOT defaults for Vercel.
90
+ *
91
+ * Usage in vercel-entry.ts:
92
+ * export default createCoreVercelEntry(import.meta.url)
93
+ */
94
+ declare function createCoreVercelEntry(_importMetaUrl: string, opts?: CreateCoreVercelEntryOptions): VercelFastifyHandler;
95
+
96
+ export { type CoreWorkspaceAgentDevServerHandle, type CoreWorkspaceAgentServer, type CoreWorkspaceAgentServerPlugin, type CreateCoreVercelEntryOptions, type CreateCoreWorkspaceAgentServerOptions, type CreateVercelFastifyHandlerOptions, type RunCoreWorkspaceAgentServerOptions, type StartCoreWorkspaceAgentDevServerFromMetaOptions, type StartCoreWorkspaceAgentDevServerOptions, type VercelFastifyHandler, type VercelFastifyLikeServer, appRootFromImportMeta, createCoreVercelEntry, createCoreWorkspaceAgentServer, createVercelFastifyHandler, runCoreWorkspaceAgentServer, startCoreWorkspaceAgentDevServer, startCoreWorkspaceAgentDevServerFromMeta };