@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
@@ -0,0 +1,507 @@
1
+ import {
2
+ WorkspaceRuntimeSandboxHandleStore,
3
+ authHook,
4
+ createAuth,
5
+ createCoreApp,
6
+ loadConfig,
7
+ registerInviteRoutes,
8
+ registerMemberRoutes,
9
+ registerRoutes,
10
+ registerSettingsRoutes,
11
+ registerWorkspaceRoutes
12
+ } from "../../chunk-CZ4HIXII.js";
13
+ import {
14
+ PostgresUserStore,
15
+ PostgresWorkspaceStore,
16
+ createDatabase
17
+ } from "../../chunk-HSRBZLKT.js";
18
+ import "../../chunk-H5KU6R6Y.js";
19
+ import "../../chunk-MLKGABMK.js";
20
+
21
+ // src/app/server/createCoreWorkspaceAgentServer.ts
22
+ import { access, mkdir, readFile, stat } from "fs/promises";
23
+ import { createReadStream } from "fs";
24
+ import path from "path";
25
+ import {
26
+ registerAgentRoutes
27
+ } from "@hachej/boring-agent/server";
28
+ import {
29
+ collectWorkspaceAgentServerPlugins,
30
+ provisionWorkspaceAgentServer
31
+ } from "@hachej/boring-workspace/app/server";
32
+ import {
33
+ createInMemoryBridge,
34
+ createWorkspaceUiTools,
35
+ uiRoutes
36
+ } from "@hachej/boring-workspace/server";
37
+ var MIME_TYPES = {
38
+ ".css": "text/css; charset=utf-8",
39
+ ".html": "text/html; charset=utf-8",
40
+ ".ico": "image/x-icon",
41
+ ".jpg": "image/jpeg",
42
+ ".js": "text/javascript; charset=utf-8",
43
+ ".json": "application/json; charset=utf-8",
44
+ ".map": "application/json; charset=utf-8",
45
+ ".png": "image/png",
46
+ ".svg": "image/svg+xml",
47
+ ".webp": "image/webp"
48
+ };
49
+ var AUTH_PROXY_BLOCKED_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
50
+ "connection",
51
+ "content-encoding",
52
+ "content-length",
53
+ "keep-alive",
54
+ "transfer-encoding"
55
+ ]);
56
+ var FRONTEND_AUTH_PAGES = /* @__PURE__ */ new Set([
57
+ "/auth/signin",
58
+ "/auth/signup",
59
+ "/auth/forgot-password",
60
+ "/auth/reset-password",
61
+ "/auth/verify-email",
62
+ "/auth/callback/github"
63
+ ]);
64
+ function contentType(filePath) {
65
+ const ext = path.extname(filePath).toLowerCase();
66
+ return MIME_TYPES[ext] ?? "application/octet-stream";
67
+ }
68
+ function injectCspNonceIntoHtml(html, nonce) {
69
+ if (!nonce) return html;
70
+ const metaTag = `<meta name="boring-csp-nonce" content="${nonce}" />`;
71
+ const withMeta = html.includes("</head>") ? html.replace("</head>", ` ${metaTag}
72
+ </head>`) : `${metaTag}
73
+ ${html}`;
74
+ return withMeta.replace(/<script(?![^>]*\bnonce=)/g, `<script nonce="${nonce}"`).replace(/<style(?![^>]*\bnonce=)/g, `<style nonce="${nonce}"`);
75
+ }
76
+ async function pathExists(filePath) {
77
+ try {
78
+ await access(filePath);
79
+ return true;
80
+ } catch {
81
+ return false;
82
+ }
83
+ }
84
+ async function pathIsFile(filePath) {
85
+ try {
86
+ const info = await stat(filePath);
87
+ return info.isFile();
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ function toHeaders(source) {
93
+ const headers = new Headers();
94
+ for (const [key, value] of Object.entries(source)) {
95
+ if (!value) continue;
96
+ headers.set(key, Array.isArray(value) ? value[0] : value);
97
+ }
98
+ return headers;
99
+ }
100
+ function extractSetCookies(headers) {
101
+ const withGetSetCookie = headers;
102
+ if (typeof withGetSetCookie.getSetCookie === "function") {
103
+ return withGetSetCookie.getSetCookie();
104
+ }
105
+ const value = headers.get("set-cookie");
106
+ return value ? [value] : [];
107
+ }
108
+ function encodeAuthRequestBody(request) {
109
+ const isBodyless = request.method === "GET" || request.method === "HEAD";
110
+ if (isBodyless) return void 0;
111
+ const bodyValue = request.body;
112
+ if (bodyValue == null) return void 0;
113
+ if (typeof bodyValue === "string") return bodyValue;
114
+ if (bodyValue instanceof Uint8Array) return bodyValue;
115
+ if (bodyValue instanceof URLSearchParams) return bodyValue;
116
+ const requestContentType = String(request.headers?.["content-type"] ?? "").toLowerCase();
117
+ if (requestContentType.includes("application/x-www-form-urlencoded")) {
118
+ const params = new URLSearchParams();
119
+ for (const [key, value] of Object.entries(bodyValue)) {
120
+ if (value == null) continue;
121
+ params.append(key, String(value));
122
+ }
123
+ return params;
124
+ }
125
+ return JSON.stringify(bodyValue);
126
+ }
127
+ function httpError(message, statusCode) {
128
+ const error = new Error(message);
129
+ error.statusCode = statusCode;
130
+ return error;
131
+ }
132
+ function validateWorkspaceIdSegment(value) {
133
+ const workspaceId = value.trim();
134
+ if (!workspaceId) throw httpError("workspace id is required", 400);
135
+ if (workspaceId.includes("\0") || workspaceId.includes("/") || workspaceId.includes("\\") || workspaceId.includes("..") || path.isAbsolute(workspaceId)) {
136
+ throw httpError("invalid workspace id", 400);
137
+ }
138
+ return workspaceId;
139
+ }
140
+ async function resolveAuthorizedWorkspaceId(request, workspaceStore) {
141
+ const headerValue = request.headers?.["x-boring-workspace-id"];
142
+ const query = request.query;
143
+ const queryValue = query?.workspaceId;
144
+ const workspaceId = typeof headerValue === "string" ? headerValue : typeof queryValue === "string" ? queryValue : "";
145
+ const normalizedWorkspaceId = validateWorkspaceIdSegment(workspaceId);
146
+ const user = request.user;
147
+ if (!user?.id) throw httpError("authentication required", 401);
148
+ let member = false;
149
+ try {
150
+ member = await workspaceStore.isMember(normalizedWorkspaceId, user.id);
151
+ } catch (error) {
152
+ request.log?.error({ err: error, workspaceId: normalizedWorkspaceId }, "workspace access check failed");
153
+ throw httpError("workspace access check failed", 500);
154
+ }
155
+ if (!member) throw httpError("workspace access denied", 403);
156
+ return normalizedWorkspaceId;
157
+ }
158
+ async function resolveWorkspaceRoot(baseRoot, workspaceId) {
159
+ const base = path.resolve(baseRoot);
160
+ const scopedRoot = path.resolve(base, workspaceId);
161
+ if (scopedRoot === base || !scopedRoot.startsWith(`${base}${path.sep}`)) {
162
+ throw httpError("invalid workspace id", 400);
163
+ }
164
+ await mkdir(scopedRoot, { recursive: true });
165
+ return scopedRoot;
166
+ }
167
+ function shouldServeFrontend(pathname) {
168
+ if (pathname === "/health") return false;
169
+ if (pathname.startsWith("/api/")) return false;
170
+ if (FRONTEND_AUTH_PAGES.has(pathname)) return true;
171
+ if (pathname === "/auth") return false;
172
+ if (pathname.startsWith("/auth/")) return false;
173
+ return true;
174
+ }
175
+ async function registerAuthProxy(app) {
176
+ app.all("/auth/*", async (request, reply) => {
177
+ const accept = String(request.headers?.accept ?? "");
178
+ if (request.method === "GET" && accept.includes("text/html")) {
179
+ return reply.callNotFound();
180
+ }
181
+ const body = encodeAuthRequestBody(request);
182
+ const targetUrl = new URL(request.url, app.config.auth.url).toString();
183
+ const response = await app.auth.handler(
184
+ new Request(targetUrl, {
185
+ method: request.method,
186
+ headers: toHeaders(request.headers),
187
+ body
188
+ })
189
+ );
190
+ for (const [key, value] of response.headers.entries()) {
191
+ const lowered = key.toLowerCase();
192
+ if (lowered === "set-cookie") continue;
193
+ if (AUTH_PROXY_BLOCKED_RESPONSE_HEADERS.has(lowered)) continue;
194
+ reply.header(key, value);
195
+ }
196
+ const setCookies = extractSetCookies(response.headers);
197
+ if (setCookies.length > 0) {
198
+ reply.header("set-cookie", setCookies.length === 1 ? setCookies[0] : setCookies);
199
+ }
200
+ reply.status(response.status);
201
+ const responseBody = Buffer.from(await response.arrayBuffer());
202
+ return reply.send(responseBody);
203
+ });
204
+ }
205
+ async function registerFrontendAuthPages(app, appRoot) {
206
+ const frontDistDir = path.resolve(appRoot, "dist/front");
207
+ const indexPath = path.resolve(frontDistDir, "index.html");
208
+ for (const pagePath of FRONTEND_AUTH_PAGES) {
209
+ app.get(pagePath, async (request, reply) => {
210
+ if (!await pathExists(indexPath)) {
211
+ reply.status(503);
212
+ return {
213
+ error: "frontend_not_built",
214
+ message: "Build the frontend before starting in production mode."
215
+ };
216
+ }
217
+ const html = await readFile(indexPath, "utf-8");
218
+ reply.type("text/html; charset=utf-8");
219
+ return reply.send(injectCspNonceIntoHtml(html, request.cspNonce));
220
+ });
221
+ }
222
+ }
223
+ async function registerFrontendFallback(app, appRoot) {
224
+ const frontDistDir = path.resolve(appRoot, "dist/front");
225
+ const indexPath = path.resolve(frontDistDir, "index.html");
226
+ app.get("/", async (request, reply) => {
227
+ if (!await pathExists(indexPath)) {
228
+ reply.status(503);
229
+ return {
230
+ error: "frontend_not_built",
231
+ message: "Build the frontend before starting in production mode."
232
+ };
233
+ }
234
+ const html = await readFile(indexPath, "utf-8");
235
+ reply.type("text/html; charset=utf-8");
236
+ return reply.send(injectCspNonceIntoHtml(html, request.cspNonce));
237
+ });
238
+ app.get("/*", async (request, reply) => {
239
+ const pathname = request.url.split("?")[0] ?? "/";
240
+ if (!shouldServeFrontend(pathname)) return reply.callNotFound();
241
+ const candidate = path.resolve(frontDistDir, `.${pathname}`);
242
+ const withinDist = candidate === frontDistDir || candidate.startsWith(`${frontDistDir}${path.sep}`);
243
+ if (!withinDist) {
244
+ reply.status(400);
245
+ return { error: "invalid_path" };
246
+ }
247
+ if (await pathIsFile(candidate)) {
248
+ reply.type(contentType(candidate));
249
+ return reply.send(createReadStream(candidate));
250
+ }
251
+ if (!await pathExists(indexPath)) {
252
+ reply.status(503);
253
+ return {
254
+ error: "frontend_not_built",
255
+ message: "Build the frontend before starting in production mode."
256
+ };
257
+ }
258
+ const html = await readFile(indexPath, "utf-8");
259
+ reply.type("text/html; charset=utf-8");
260
+ return reply.send(injectCspNonceIntoHtml(html, request.cspNonce));
261
+ });
262
+ }
263
+ async function createCoreRuntime(config) {
264
+ if (config.stores !== "postgres") {
265
+ throw new Error("createCoreWorkspaceAgentServer currently supports only CORE_STORES=postgres");
266
+ }
267
+ const { db, sql } = createDatabase(config);
268
+ const storeDb = db;
269
+ const userStore = new PostgresUserStore(storeDb);
270
+ const workspaceStore = new PostgresWorkspaceStore(
271
+ storeDb,
272
+ config.encryption.workspaceSettingsKey
273
+ );
274
+ const app = await createCoreApp(config);
275
+ const auth = createAuth(config, db, {
276
+ workspaceStore,
277
+ logger: app.log
278
+ });
279
+ app.decorate("db", db);
280
+ app.decorate("auth", auth);
281
+ app.decorate("userStore", userStore);
282
+ app.decorate("workspaceStore", workspaceStore);
283
+ app.addHook("onClose", async () => {
284
+ await sql.end();
285
+ });
286
+ return { app, sql, db, userStore, workspaceStore };
287
+ }
288
+ async function registerCoreRoutes({
289
+ app,
290
+ sql,
291
+ db,
292
+ userStore,
293
+ workspaceStore
294
+ }) {
295
+ await app.register(authHook);
296
+ await app.register(registerRoutes, {
297
+ sql,
298
+ db,
299
+ userStore,
300
+ workspaceStore
301
+ });
302
+ await app.register(registerWorkspaceRoutes);
303
+ await app.register(registerMemberRoutes);
304
+ await app.register(registerSettingsRoutes);
305
+ await app.register(registerInviteRoutes);
306
+ }
307
+ async function createCoreWorkspaceAgentServer(options = {}) {
308
+ const config = options.config ?? await loadConfig({
309
+ allowMissingSecrets: process.env.NODE_ENV !== "production",
310
+ ...options.loadConfigOptions
311
+ });
312
+ const { app, sql, db, userStore, workspaceStore } = await createCoreRuntime(config);
313
+ const appRoot = options.appRoot;
314
+ const serveFrontend = options.serveFrontend ?? (process.env.NODE_ENV !== "development" && Boolean(appRoot));
315
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
316
+ await registerCoreRoutes({ app, sql, db, userStore, workspaceStore });
317
+ if (serveFrontend && appRoot) {
318
+ await registerFrontendAuthPages(app, appRoot);
319
+ }
320
+ await registerAuthProxy(app);
321
+ const pluginCollection = collectWorkspaceAgentServerPlugins({
322
+ workspaceRoot,
323
+ systemPromptAppend: options.systemPromptAppend,
324
+ resourceLoaderOptions: options.resourceLoaderOptions,
325
+ plugins: options.plugins,
326
+ excludeDefaults: options.excludeDefaults
327
+ });
328
+ await provisionWorkspaceAgentServer({
329
+ workspaceRoot,
330
+ provisioningContributions: pluginCollection.provisioningContributions,
331
+ force: options.forceProvisioning
332
+ });
333
+ const bridges = /* @__PURE__ */ new Map();
334
+ const getUiBridge = (workspaceId) => {
335
+ let bridge = bridges.get(workspaceId);
336
+ if (!bridge) {
337
+ bridge = createInMemoryBridge();
338
+ bridges.set(workspaceId, bridge);
339
+ }
340
+ return bridge;
341
+ };
342
+ const resolveWorkspaceId = async (request) => options.getWorkspaceId ? await options.getWorkspaceId(request) : await resolveAuthorizedWorkspaceId(request, workspaceStore);
343
+ const resolveRoot = async (workspaceId, request) => options.getWorkspaceRoot ? await options.getWorkspaceRoot(workspaceId, request) : await resolveWorkspaceRoot(workspaceRoot, workspaceId);
344
+ await app.register(registerAgentRoutes, {
345
+ workspaceRoot,
346
+ sessionId: options.sessionId,
347
+ templatePath: options.templatePath,
348
+ mode: options.mode,
349
+ version: options.version,
350
+ extraTools: [
351
+ ...options.extraTools ?? [],
352
+ ...pluginCollection.agentOptions.extraTools ?? []
353
+ ],
354
+ systemPromptAppend: pluginCollection.agentOptions.systemPromptAppend,
355
+ resourceLoaderOptions: pluginCollection.agentOptions.resourceLoaderOptions,
356
+ getExtraTools: async (ctx) => {
357
+ const callerTools = options.getExtraTools ? await options.getExtraTools(ctx) : [];
358
+ return [
359
+ ...callerTools,
360
+ ...createWorkspaceUiTools(getUiBridge(ctx.workspaceId), { workspaceRoot: ctx.workspaceRoot })
361
+ ];
362
+ },
363
+ sandboxHandleStore: options.sandboxHandleStore ?? new WorkspaceRuntimeSandboxHandleStore(workspaceStore),
364
+ getWorkspaceId: resolveWorkspaceId,
365
+ getWorkspaceRoot: resolveRoot,
366
+ registerHealthRoute: options.registerHealthRoute ?? false
367
+ });
368
+ await app.register(uiRoutes, {
369
+ getBridge: async (request) => getUiBridge(await resolveWorkspaceId(request))
370
+ });
371
+ for (const { routes } of pluginCollection.routeContributions) {
372
+ await app.register(routes);
373
+ }
374
+ if (serveFrontend && appRoot) {
375
+ await registerFrontendFallback(app, appRoot);
376
+ }
377
+ return app;
378
+ }
379
+
380
+ // src/app/server/devServer.ts
381
+ import { createRequire } from "module";
382
+ import path3 from "path";
383
+ import { pathToFileURL } from "url";
384
+
385
+ // src/app/server/appRootFromImportMeta.ts
386
+ import path2 from "path";
387
+ import { fileURLToPath } from "url";
388
+ function appRootFromImportMeta(importMetaUrl, levelsUp = 2) {
389
+ return path2.resolve(path2.dirname(fileURLToPath(importMetaUrl)), "../".repeat(levelsUp));
390
+ }
391
+
392
+ // src/app/server/devServer.ts
393
+ var DEFAULT_FRONTEND_PORT = 5173;
394
+ async function startCoreWorkspaceAgentDevServer({
395
+ appRoot,
396
+ buildServer,
397
+ frontendPort = DEFAULT_FRONTEND_PORT,
398
+ eventPrefix = "core-workspace-agent"
399
+ }) {
400
+ const app = await buildServer({ appRoot, serveFrontend: false });
401
+ const address = await app.listen({
402
+ host: app.config.host,
403
+ port: app.config.port
404
+ });
405
+ app.log.info({ event: `${eventPrefix}.server.ready`, address }, `${eventPrefix}.server.ready`);
406
+ const apiPort = Number(new URL(address).port);
407
+ const apiTarget = `http://127.0.0.1:${apiPort}`;
408
+ const requireFromApp = createRequire(path3.join(appRoot, "package.json"));
409
+ const viteEntry = requireFromApp.resolve("vite");
410
+ const viteModule = await import(pathToFileURL(viteEntry).href);
411
+ const vite = await viteModule.createServer({
412
+ root: appRoot,
413
+ server: {
414
+ port: frontendPort,
415
+ strictPort: false,
416
+ host: true,
417
+ proxy: {
418
+ "/api": apiTarget,
419
+ "/health": apiTarget,
420
+ "/auth": {
421
+ target: apiTarget,
422
+ changeOrigin: true,
423
+ bypass(req) {
424
+ const accept = req.headers.accept ?? "";
425
+ if (req.method === "GET" && accept.includes("text/html")) {
426
+ return req.url;
427
+ }
428
+ return void 0;
429
+ }
430
+ }
431
+ }
432
+ }
433
+ });
434
+ await vite.listen();
435
+ vite.printUrls();
436
+ app.log.info(
437
+ {
438
+ event: `${eventPrefix}.vite.ready`,
439
+ frontendPort,
440
+ apiTarget
441
+ },
442
+ `${eventPrefix}.vite.ready`
443
+ );
444
+ return { app, address, apiTarget };
445
+ }
446
+ async function startCoreWorkspaceAgentDevServerFromMeta(importMetaUrl, opts = {}) {
447
+ const appRoot = appRootFromImportMeta(importMetaUrl, opts.levelsUp ?? 2);
448
+ return startCoreWorkspaceAgentDevServer({
449
+ appRoot,
450
+ buildServer: (options) => createCoreWorkspaceAgentServer(options),
451
+ frontendPort: opts.frontendPort,
452
+ eventPrefix: opts.eventPrefix
453
+ });
454
+ }
455
+
456
+ // src/app/server/vercelFastifyHandler.ts
457
+ function createVercelFastifyHandler({
458
+ createServer
459
+ }) {
460
+ let serverPromise;
461
+ async function getServer() {
462
+ serverPromise ??= Promise.resolve(createServer()).then(async (server) => {
463
+ await server.ready();
464
+ return server;
465
+ }).catch((error) => {
466
+ serverPromise = void 0;
467
+ throw error;
468
+ });
469
+ return serverPromise;
470
+ }
471
+ return async function vercelFastifyHandler(req, res) {
472
+ const server = await getServer();
473
+ server.server.emit("request", req, res);
474
+ };
475
+ }
476
+
477
+ // src/app/server/runServer.ts
478
+ async function runCoreWorkspaceAgentServer(importMetaUrl, opts = {}) {
479
+ const appRoot = appRootFromImportMeta(importMetaUrl, opts.levelsUp ?? 2);
480
+ const app = await createCoreWorkspaceAgentServer({
481
+ appRoot,
482
+ workspaceRoot: opts.workspaceRoot,
483
+ serveFrontend: true
484
+ });
485
+ const address = await app.listen({ host: app.config.host, port: app.config.port });
486
+ app.log.info({ event: "core.server.ready", address }, "core.server.ready");
487
+ }
488
+
489
+ // src/app/server/vercelEntry.ts
490
+ function createCoreVercelEntry(_importMetaUrl, opts = {}) {
491
+ process.env.BORING_AGENT_MODE ??= "vercel-sandbox";
492
+ process.env.BORING_AGENT_WORKSPACE_ROOT ??= opts.workspaceRoot ?? "/tmp/boring-workspaces";
493
+ const appRoot = process.cwd();
494
+ const workspaceRoot = process.env.BORING_AGENT_WORKSPACE_ROOT;
495
+ return createVercelFastifyHandler({
496
+ createServer: () => createCoreWorkspaceAgentServer({ appRoot, workspaceRoot, serveFrontend: true })
497
+ });
498
+ }
499
+ export {
500
+ appRootFromImportMeta,
501
+ createCoreVercelEntry,
502
+ createCoreWorkspaceAgentServer,
503
+ createVercelFastifyHandler,
504
+ runCoreWorkspaceAgentServer,
505
+ startCoreWorkspaceAgentDevServer,
506
+ startCoreWorkspaceAgentDevServerFromMeta
507
+ };
@@ -0,0 +1,10 @@
1
+ type BoringViteAlias = {
2
+ find: string | RegExp;
3
+ replacement: string;
4
+ };
5
+ interface CreateBoringAppViteAliasesOptions {
6
+ repoRoot: string;
7
+ }
8
+ declare function createBoringAppViteAliases({ repoRoot, }: CreateBoringAppViteAliasesOptions): BoringViteAlias[];
9
+
10
+ export { type BoringViteAlias, type CreateBoringAppViteAliasesOptions, createBoringAppViteAliases };
@@ -0,0 +1,33 @@
1
+ import "../../chunk-MLKGABMK.js";
2
+
3
+ // src/app/vite/index.ts
4
+ import path from "path";
5
+ function createBoringAppViteAliases({
6
+ repoRoot
7
+ }) {
8
+ const coreSrc = path.resolve(repoRoot, "packages/core/src");
9
+ const agentSrc = path.resolve(repoRoot, "packages/agent/src");
10
+ const workspaceSrc = path.resolve(repoRoot, "packages/workspace/src");
11
+ return [
12
+ { find: "@hachej/boring-core/front/top-bar-slot", replacement: path.resolve(coreSrc, "front/components/TopBarSlot.tsx") },
13
+ { find: "@hachej/boring-core/app/front/styles.css", replacement: path.resolve(coreSrc, "app/front/styles.css") },
14
+ { find: /^@hachej\/boring-core\/app\/front$/, replacement: path.resolve(coreSrc, "app/front/index.ts") },
15
+ { find: /^@hachej\/boring-core\/front$/, replacement: path.resolve(coreSrc, "front/index.ts") },
16
+ { find: "@hachej/boring-core/theme.css", replacement: path.resolve(coreSrc, "front/theme.css") },
17
+ { find: "@hachej/boring-agent/front/styles.css", replacement: path.resolve(agentSrc, "front/styles/globals.css") },
18
+ { find: /^@hachej\/boring-agent\/front$/, replacement: path.resolve(agentSrc, "front/index.ts") },
19
+ { find: /^@hachej\/boring-agent$/, replacement: path.resolve(agentSrc, "front/index.ts") },
20
+ { find: "@hachej/boring-workspace/globals.css", replacement: path.resolve(workspaceSrc, "globals.css") },
21
+ { find: /^@hachej\/boring-workspace\/shared$/, replacement: path.resolve(workspaceSrc, "shared/index.ts") },
22
+ { find: /^@hachej\/boring-workspace\/app\/front$/, replacement: path.resolve(workspaceSrc, "app/front/index.ts") },
23
+ { find: /^@hachej\/boring-workspace\/testing$/, replacement: path.resolve(workspaceSrc, "front/testing/index.ts") },
24
+ { find: /^@hachej\/boring-workspace$/, replacement: path.resolve(workspaceSrc, "index.ts") },
25
+ { find: "@/front/lib/", replacement: `${workspaceSrc}/front/lib/` },
26
+ { find: "@/front/", replacement: `${agentSrc}/front/` },
27
+ { find: "@/components/", replacement: `${workspaceSrc}/front/components/` },
28
+ { find: "@/lib/", replacement: `${workspaceSrc}/front/lib/` }
29
+ ];
30
+ }
31
+ export {
32
+ createBoringAppViteAliases
33
+ };
@@ -0,0 +1,38 @@
1
+ import { C as CoreConfig, R as RuntimeConfig } from './index-COZa03RP.js';
2
+ import { FastifyPluginAsync } from 'fastify';
3
+ import { Auth } from 'better-auth';
4
+ import { W as WorkspaceStore, D as Database } from './connection-CE7z-wBp.js';
5
+
6
+ interface LoadConfigOptions {
7
+ tomlPath?: string;
8
+ env?: Record<string, string | undefined>;
9
+ allowMissingSecrets?: boolean;
10
+ }
11
+ declare function loadConfig(options?: LoadConfigOptions): Promise<CoreConfig>;
12
+ declare function validateConfig(raw: unknown): CoreConfig;
13
+ declare function buildRuntimeConfigPayload(config: CoreConfig): RuntimeConfig;
14
+
15
+ declare function validatePasswordStrength(password: string): {
16
+ valid: boolean;
17
+ message?: string;
18
+ };
19
+ interface CreateAuthOptions {
20
+ workspaceStore?: WorkspaceStore;
21
+ logger?: {
22
+ warn: (obj: Record<string, unknown>, msg: string) => void;
23
+ };
24
+ }
25
+ declare function createAuth(config: CoreConfig, db: Database, opts?: CreateAuthOptions): Auth<any>;
26
+ type BetterAuthInstance = Auth<any>;
27
+
28
+ interface AuthHookOptions {
29
+ public?: RegExp[];
30
+ }
31
+ declare module 'fastify' {
32
+ interface FastifyInstance {
33
+ auth: BetterAuthInstance;
34
+ }
35
+ }
36
+ declare const authHook: FastifyPluginAsync<AuthHookOptions>;
37
+
38
+ export { type AuthHookOptions as A, type BetterAuthInstance as B, type CreateAuthOptions as C, type LoadConfigOptions as L, authHook as a, buildRuntimeConfigPayload as b, createAuth as c, validatePasswordStrength as d, loadConfig as l, validateConfig as v };