@boringos/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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/dist/admin-routes.d.ts +12 -0
  3. package/dist/admin-routes.d.ts.map +1 -0
  4. package/dist/admin-routes.js +836 -0
  5. package/dist/admin-routes.js.map +1 -0
  6. package/dist/auth-routes.d.ts +9 -0
  7. package/dist/auth-routes.d.ts.map +1 -0
  8. package/dist/auth-routes.js +112 -0
  9. package/dist/auth-routes.js.map +1 -0
  10. package/dist/auth.d.ts +32 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +102 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/boringos.d.ts +52 -0
  15. package/dist/boringos.d.ts.map +1 -0
  16. package/dist/boringos.js +301 -0
  17. package/dist/boringos.js.map +1 -0
  18. package/dist/connector-routes.d.ts +5 -0
  19. package/dist/connector-routes.d.ts.map +1 -0
  20. package/dist/connector-routes.js +77 -0
  21. package/dist/connector-routes.js.map +1 -0
  22. package/dist/device-auth-routes.d.ts +12 -0
  23. package/dist/device-auth-routes.d.ts.map +1 -0
  24. package/dist/device-auth-routes.js +68 -0
  25. package/dist/device-auth-routes.js.map +1 -0
  26. package/dist/index.d.ts +17 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +8 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/notifications.d.ts +30 -0
  31. package/dist/notifications.d.ts.map +1 -0
  32. package/dist/notifications.js +61 -0
  33. package/dist/notifications.js.map +1 -0
  34. package/dist/plugin-routes.d.ts +12 -0
  35. package/dist/plugin-routes.d.ts.map +1 -0
  36. package/dist/plugin-routes.js +70 -0
  37. package/dist/plugin-routes.js.map +1 -0
  38. package/dist/plugin-system.d.ts +57 -0
  39. package/dist/plugin-system.d.ts.map +1 -0
  40. package/dist/plugin-system.js +62 -0
  41. package/dist/plugin-system.js.map +1 -0
  42. package/dist/plugins/github.d.ts +18 -0
  43. package/dist/plugins/github.d.ts.map +1 -0
  44. package/dist/plugins/github.js +97 -0
  45. package/dist/plugins/github.js.map +1 -0
  46. package/dist/realtime.d.ts +15 -0
  47. package/dist/realtime.d.ts.map +1 -0
  48. package/dist/realtime.js +38 -0
  49. package/dist/realtime.js.map +1 -0
  50. package/dist/routes.d.ts +12 -0
  51. package/dist/routes.d.ts.map +1 -0
  52. package/dist/routes.js +151 -0
  53. package/dist/routes.js.map +1 -0
  54. package/dist/scheduler.d.ts +13 -0
  55. package/dist/scheduler.d.ts.map +1 -0
  56. package/dist/scheduler.js +77 -0
  57. package/dist/scheduler.js.map +1 -0
  58. package/dist/sse-routes.d.ts +4 -0
  59. package/dist/sse-routes.d.ts.map +1 -0
  60. package/dist/sse-routes.js +37 -0
  61. package/dist/sse-routes.js.map +1 -0
  62. package/dist/types.d.ts +81 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +2 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +53 -0
@@ -0,0 +1,301 @@
1
+ import { generateId } from "@boringos/shared";
2
+ import { Hono } from "hono";
3
+ import { serve } from "@hono/node-server";
4
+ import { nullMemory } from "@boringos/memory";
5
+ import { createRuntimeRegistry, claudeRuntime, chatgptRuntime, geminiRuntime, ollamaRuntime, commandRuntime, webhookRuntime, } from "@boringos/runtime";
6
+ import { createLocalStorage } from "@boringos/drive";
7
+ import { createDatabase, createMigrationManager } from "@boringos/db";
8
+ import { createAgentEngine, ContextPipeline } from "@boringos/agent";
9
+ import { createWorkflowEngine, createWorkflowStore, createHandlerRegistry, triggerHandler, conditionHandler, delayHandler, transformHandler, } from "@boringos/workflow";
10
+ import { createConnectorRegistry, createEventBus, createActionRunner, } from "@boringos/connector";
11
+ import { createCallbackRoutes } from "./routes.js";
12
+ import { createConnectorRoutes } from "./connector-routes.js";
13
+ import { createAdminRoutes } from "./admin-routes.js";
14
+ import { createRealtimeBus } from "./realtime.js";
15
+ import { createSSERoutes } from "./sse-routes.js";
16
+ import { bootstrapAuthTables } from "./auth.js";
17
+ import { createAuthRoutes } from "./auth-routes.js";
18
+ import { createDeviceAuthRoutes } from "./device-auth-routes.js";
19
+ import { createRoutineScheduler } from "./scheduler.js";
20
+ import { createPluginRegistry } from "./plugin-system.js";
21
+ import { createPluginWebhookRoutes, createPluginAdminRoutes } from "./plugin-routes.js";
22
+ import { githubPlugin } from "./plugins/github.js";
23
+ export class BoringOS {
24
+ config;
25
+ memoryProvider = nullMemory;
26
+ extraRuntimes = [];
27
+ contextProviders = [];
28
+ personas = new Map();
29
+ plugins = [];
30
+ pluginDefs = [];
31
+ connectorDefs = [];
32
+ beforeStartHooks = [];
33
+ afterStartHooks = [];
34
+ beforeShutdownHooks = [];
35
+ extraRoutes = [];
36
+ blockHandlers = [];
37
+ queueAdapter;
38
+ userSchemaStatements = [];
39
+ inboxRoutes = [];
40
+ constructor(config = {}) {
41
+ this.config = config;
42
+ }
43
+ memory(provider) {
44
+ this.memoryProvider = provider;
45
+ return this;
46
+ }
47
+ runtime(module) {
48
+ this.extraRuntimes.push(module);
49
+ return this;
50
+ }
51
+ contextProvider(provider) {
52
+ this.contextProviders.push(provider);
53
+ return this;
54
+ }
55
+ persona(role, bundle) {
56
+ this.personas.set(role, bundle);
57
+ return this;
58
+ }
59
+ connector(definition) {
60
+ this.connectorDefs.push(definition);
61
+ return this;
62
+ }
63
+ plugin(manifest) {
64
+ if ("jobs" in manifest || "webhooks" in manifest) {
65
+ this.pluginDefs.push(manifest);
66
+ }
67
+ else {
68
+ this.plugins.push(manifest);
69
+ }
70
+ return this;
71
+ }
72
+ queue(adapter) {
73
+ this.queueAdapter = adapter;
74
+ return this;
75
+ }
76
+ schema(ddlStatements) {
77
+ const stmts = Array.isArray(ddlStatements) ? ddlStatements : [ddlStatements];
78
+ this.userSchemaStatements.push(...stmts);
79
+ return this;
80
+ }
81
+ routeToInbox(config) {
82
+ this.inboxRoutes.push(config);
83
+ return this;
84
+ }
85
+ blockHandler(handler) {
86
+ this.blockHandlers.push(handler);
87
+ return this;
88
+ }
89
+ beforeStart(fn) {
90
+ this.beforeStartHooks.push(fn);
91
+ return this;
92
+ }
93
+ afterStart(fn) {
94
+ this.afterStartHooks.push(fn);
95
+ return this;
96
+ }
97
+ beforeShutdown(fn) {
98
+ this.beforeShutdownHooks.push(fn);
99
+ return this;
100
+ }
101
+ route(path, app) {
102
+ this.extraRoutes.push({ path, app });
103
+ return this;
104
+ }
105
+ async listen(port) {
106
+ const listenPort = port ?? 3000;
107
+ // 1. Boot database
108
+ const dbConfig = this.config.database ?? { embedded: true };
109
+ const dbConn = await createDatabase(dbConfig);
110
+ // 2. Run migrations
111
+ const migrator = createMigrationManager(dbConn.db);
112
+ await migrator.apply();
113
+ // 2b. Bootstrap auth tables
114
+ await bootstrapAuthTables(dbConn.db);
115
+ // 2c. Apply user schema DDL
116
+ if (this.userSchemaStatements.length > 0) {
117
+ const { sql: rawSql } = await import("drizzle-orm");
118
+ for (const stmt of this.userSchemaStatements) {
119
+ await dbConn.db.execute(rawSql.raw(stmt));
120
+ }
121
+ }
122
+ // 3. Initialize drive
123
+ const driveRoot = this.config.drive?.root ?? "./.data/drive";
124
+ const drive = this.config.drive?.backend ?? createLocalStorage({ root: driveRoot });
125
+ // 4. Build runtime registry
126
+ const runtimes = createRuntimeRegistry();
127
+ for (const rt of [claudeRuntime, chatgptRuntime, geminiRuntime, ollamaRuntime, commandRuntime, webhookRuntime]) {
128
+ runtimes.register(rt);
129
+ }
130
+ for (const rt of this.extraRuntimes) {
131
+ runtimes.register(rt);
132
+ }
133
+ // 5. Build context pipeline
134
+ const pipeline = new ContextPipeline();
135
+ for (const provider of this.contextProviders) {
136
+ pipeline.add(provider);
137
+ }
138
+ // 6. Create agent engine
139
+ const jwtSecret = this.config.auth?.secret ?? "boringos-dev-secret";
140
+ const callbackUrl = `http://localhost:${listenPort}`;
141
+ const agentEngine = createAgentEngine({
142
+ db: dbConn.db,
143
+ runtimes,
144
+ memory: this.memoryProvider,
145
+ drive,
146
+ pipeline,
147
+ callbackUrl,
148
+ jwtSecret,
149
+ queue: this.queueAdapter,
150
+ });
151
+ // 7. Build workflow engine
152
+ const handlerRegistry = createHandlerRegistry();
153
+ handlerRegistry.register(triggerHandler);
154
+ handlerRegistry.register(conditionHandler);
155
+ handlerRegistry.register(delayHandler);
156
+ handlerRegistry.register(transformHandler);
157
+ for (const handler of this.blockHandlers) {
158
+ handlerRegistry.register(handler);
159
+ }
160
+ const workflowStore = createWorkflowStore(dbConn.db);
161
+ const memoryRef = this.memoryProvider;
162
+ const workflowEngine = createWorkflowEngine({
163
+ store: workflowStore,
164
+ handlers: handlerRegistry,
165
+ services: {
166
+ get(key) {
167
+ const map = { db: dbConn.db, memory: memoryRef, drive, agentEngine };
168
+ return map[key];
169
+ },
170
+ has(key) {
171
+ return ["db", "memory", "drive", "agentEngine"].includes(key);
172
+ },
173
+ },
174
+ });
175
+ // 8. Build app context
176
+ const context = {
177
+ config: this.config,
178
+ db: dbConn.db,
179
+ memory: this.memoryProvider,
180
+ drive,
181
+ runtimes,
182
+ agentEngine,
183
+ workflowEngine,
184
+ };
185
+ // 8. Run beforeStart hooks
186
+ for (const hook of this.beforeStartHooks) {
187
+ await hook(context);
188
+ }
189
+ // 9. Setup plugins
190
+ for (const plugin of this.plugins) {
191
+ await plugin.setup(context);
192
+ }
193
+ // 9b. Setup plugin system
194
+ const pluginRegistry = createPluginRegistry();
195
+ pluginRegistry.register(githubPlugin); // built-in
196
+ for (const def of this.pluginDefs) {
197
+ pluginRegistry.register(def);
198
+ }
199
+ // 10. Setup connectors
200
+ const connectorRegistry = createConnectorRegistry();
201
+ const eventBus = createEventBus();
202
+ for (const def of this.connectorDefs) {
203
+ connectorRegistry.register(def);
204
+ }
205
+ const actionRunner = createActionRunner(connectorRegistry);
206
+ // Wire connector events to agent wakeups + inbox routing
207
+ eventBus.onAny(async (event) => {
208
+ // Route events to inbox based on configured routes
209
+ for (const route of this.inboxRoutes) {
210
+ if (route.filter(event)) {
211
+ const item = route.transform(event);
212
+ const { inboxItems } = await import("@boringos/db");
213
+ await dbConn.db.insert(inboxItems).values({
214
+ id: generateId(),
215
+ tenantId: event.tenantId,
216
+ source: item.source,
217
+ subject: item.subject,
218
+ body: item.body ?? null,
219
+ from: item.from ?? null,
220
+ }).catch(() => { });
221
+ }
222
+ }
223
+ });
224
+ // 11. Build Hono app
225
+ const app = new Hono();
226
+ // Health endpoint
227
+ app.get("/health", (c) => c.json({ status: "ok", timestamp: new Date().toISOString() }));
228
+ // Auth routes (login, signup, session)
229
+ const authApp = createAuthRoutes(dbConn.db, jwtSecret);
230
+ app.route("/api/auth", authApp);
231
+ // Device auth routes (CLI login)
232
+ const deviceAuthApp = createDeviceAuthRoutes(dbConn.db);
233
+ app.route("/api/auth/device", deviceAuthApp);
234
+ // Agent callback API
235
+ const callbackApp = createCallbackRoutes(dbConn.db, agentEngine, jwtSecret);
236
+ app.route("/api/agent", callbackApp);
237
+ // Connector routes
238
+ const connectorApp = createConnectorRoutes(dbConn.db, connectorRegistry, eventBus, actionRunner, jwtSecret);
239
+ app.route("/api/connectors", connectorApp);
240
+ // Admin API (for human management of the platform)
241
+ const adminKeyValue = this.config.auth?.adminKey ?? jwtSecret;
242
+ // Realtime SSE
243
+ const realtimeBus = createRealtimeBus();
244
+ const adminApp = createAdminRoutes(dbConn.db, agentEngine, adminKeyValue, realtimeBus);
245
+ app.route("/api/admin", adminApp);
246
+ const sseApp = createSSERoutes(realtimeBus, adminKeyValue);
247
+ app.route("/api", sseApp);
248
+ // Wire engine events to realtime bus
249
+ agentEngine.beforeRun.use((event) => {
250
+ realtimeBus.publish({
251
+ type: "run:started",
252
+ tenantId: event.tenantId,
253
+ data: { runId: event.runId, agentId: event.agentId, taskId: event.taskId },
254
+ timestamp: new Date().toISOString(),
255
+ });
256
+ });
257
+ agentEngine.afterRun.use((event) => {
258
+ const status = event.result.exitCode === 0 ? "run:completed" : "run:failed";
259
+ realtimeBus.publish({
260
+ type: status,
261
+ tenantId: event.tenantId,
262
+ data: { runId: event.runId, agentId: event.agentId, exitCode: event.result.exitCode },
263
+ timestamp: new Date().toISOString(),
264
+ });
265
+ });
266
+ // Plugin webhook routes
267
+ const pluginWebhookApp = createPluginWebhookRoutes(dbConn.db, pluginRegistry);
268
+ app.route("/webhooks/plugins", pluginWebhookApp);
269
+ // Plugin admin routes (under admin API auth)
270
+ const pluginAdminApp = createPluginAdminRoutes(dbConn.db, pluginRegistry);
271
+ app.route("/api/admin/plugins", pluginAdminApp);
272
+ // Extra routes
273
+ for (const { path, app: routeApp } of this.extraRoutes) {
274
+ app.route(path, routeApp);
275
+ }
276
+ // 11. Start HTTP server
277
+ const server = serve({ fetch: app.fetch, port: listenPort });
278
+ // Get the actual port (important when listenPort is 0)
279
+ const address = server.address();
280
+ const actualPort = typeof address === "object" && address ? address.port : listenPort;
281
+ // 12. Start routine scheduler
282
+ const scheduler = createRoutineScheduler(dbConn.db, agentEngine);
283
+ scheduler.start();
284
+ // 13. Run afterStart hooks
285
+ for (const hook of this.afterStartHooks) {
286
+ await hook(context);
287
+ }
288
+ const url = `http://localhost:${actualPort}`;
289
+ return {
290
+ url,
291
+ port: actualPort,
292
+ context,
293
+ async close() {
294
+ scheduler.stop();
295
+ server.close();
296
+ await dbConn.close();
297
+ },
298
+ };
299
+ }
300
+ }
301
+ //# sourceMappingURL=boringos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boringos.js","sourceRoot":"","sources":["../src/boringos.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Hono } from "hono";
2
+ import type { Db } from "@boringos/db";
3
+ import type { ConnectorRegistry, EventBus, ActionRunner } from "@boringos/connector";
4
+ export declare function createConnectorRoutes(db: Db, registry: ConnectorRegistry, eventBus: EventBus, actionRunner: ActionRunner, jwtSecret: string): Hono;
5
+ //# sourceMappingURL=connector-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector-routes.d.ts","sourceRoot":"","sources":["../src/connector-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAwB,MAAM,qBAAqB,CAAC;AAG3G,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,GAChB,IAAI,CAqFN"}
@@ -0,0 +1,77 @@
1
+ import { Hono } from "hono";
2
+ import { eq, and } from "drizzle-orm";
3
+ import { connectors } from "@boringos/db";
4
+ import { verifyCallbackToken } from "@boringos/agent";
5
+ export function createConnectorRoutes(db, registry, eventBus, actionRunner, jwtSecret) {
6
+ const app = new Hono();
7
+ // POST /webhooks/:kind — incoming webhook from external service
8
+ app.post("/webhooks/:kind", async (c) => {
9
+ const kind = c.req.param("kind");
10
+ const connector = registry.get(kind);
11
+ if (!connector)
12
+ return c.json({ error: `Unknown connector: ${kind}` }, 404);
13
+ if (!connector.handleWebhook)
14
+ return c.json({ error: "Connector does not support webhooks" }, 400);
15
+ const headers = {};
16
+ c.req.raw.headers.forEach((v, k) => { headers[k] = v; });
17
+ const body = await c.req.json().catch(() => ({}));
18
+ // Determine tenantId from query param or header
19
+ const tenantId = c.req.query("tenantId") ?? c.req.header("X-Tenant-Id") ?? "";
20
+ const response = await connector.handleWebhook({
21
+ method: "POST",
22
+ headers,
23
+ body,
24
+ tenantId,
25
+ });
26
+ // Emit events
27
+ if (response.events) {
28
+ for (const event of response.events) {
29
+ await eventBus.emit(event);
30
+ }
31
+ }
32
+ return c.json(response.body ?? { ok: true }, response.status);
33
+ });
34
+ // POST /actions/:kind/:action — agent invokes a connector action (JWT authenticated)
35
+ app.post("/actions/:kind/:action", async (c) => {
36
+ const authHeader = c.req.header("Authorization");
37
+ if (!authHeader?.startsWith("Bearer ")) {
38
+ return c.json({ error: "Missing Authorization header" }, 401);
39
+ }
40
+ const claims = verifyCallbackToken(authHeader.slice(7), jwtSecret);
41
+ if (!claims)
42
+ return c.json({ error: "Invalid or expired token" }, 401);
43
+ const kind = c.req.param("kind");
44
+ const action = c.req.param("action");
45
+ const body = await c.req.json();
46
+ // Fetch connector credentials from DB
47
+ const rows = await db
48
+ .select()
49
+ .from(connectors)
50
+ .where(and(eq(connectors.tenantId, claims.tenant_id), eq(connectors.kind, kind)))
51
+ .limit(1);
52
+ const connectorRow = rows[0];
53
+ if (!connectorRow)
54
+ return c.json({ error: `Connector ${kind} not configured for this tenant` }, 404);
55
+ const credentials = {
56
+ accessToken: connectorRow.credentials?.accessToken ?? "",
57
+ refreshToken: connectorRow.credentials?.refreshToken,
58
+ config: connectorRow.config,
59
+ };
60
+ const result = await actionRunner.execute({ connectorKind: kind, action, tenantId: claims.tenant_id, agentId: claims.agent_id, inputs: body }, credentials);
61
+ return c.json(result, result.success ? 200 : 400);
62
+ });
63
+ // GET /connectors — list available connectors and their capabilities
64
+ app.get("/connectors", (c) => {
65
+ const list = registry.list().map((conn) => ({
66
+ kind: conn.kind,
67
+ name: conn.name,
68
+ description: conn.description,
69
+ events: conn.events,
70
+ actions: conn.actions,
71
+ hasOAuth: !!conn.oauth,
72
+ }));
73
+ return c.json({ connectors: list });
74
+ });
75
+ return app;
76
+ }
77
+ //# sourceMappingURL=connector-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector-routes.js","sourceRoot":"","sources":["../src/connector-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Hono } from "hono";
2
+ import type { Db } from "@boringos/db";
3
+ /**
4
+ * Device auth routes — CLI login flow (like `gh auth login`).
5
+ *
6
+ * Flow:
7
+ * 1. CLI calls POST /api/auth/device/code → gets deviceCode + userCode
8
+ * 2. User opens verification URL in browser, approves
9
+ * 3. CLI polls POST /api/auth/device/poll with deviceCode → gets session token
10
+ */
11
+ export declare function createDeviceAuthRoutes(db: Db): Hono;
12
+ //# sourceMappingURL=device-auth-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-auth-routes.d.ts","sourceRoot":"","sources":["../src/device-auth-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAGvC;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAkEnD"}
@@ -0,0 +1,68 @@
1
+ import { Hono } from "hono";
2
+ import { randomBytes, randomUUID } from "node:crypto";
3
+ import { sql, eq, and } from "drizzle-orm";
4
+ import { cliAuthChallenges } from "@boringos/db";
5
+ /**
6
+ * Device auth routes — CLI login flow (like `gh auth login`).
7
+ *
8
+ * Flow:
9
+ * 1. CLI calls POST /api/auth/device/code → gets deviceCode + userCode
10
+ * 2. User opens verification URL in browser, approves
11
+ * 3. CLI polls POST /api/auth/device/poll with deviceCode → gets session token
12
+ */
13
+ export function createDeviceAuthRoutes(db) {
14
+ const app = new Hono();
15
+ // POST /code — generate device + user codes
16
+ app.post("/code", async (c) => {
17
+ const deviceCode = randomUUID();
18
+ const userCode = randomBytes(4).toString("hex").toUpperCase(); // 8-char code like "A1B2C3D4"
19
+ const expiresAt = new Date(Date.now() + 15 * 60 * 1000); // 15 min
20
+ await db.execute(sql `
21
+ INSERT INTO cli_auth_challenges (id, device_code, user_code, status, expires_at)
22
+ VALUES (${randomUUID()}, ${deviceCode}, ${userCode}, 'pending', ${expiresAt.toISOString()})
23
+ `);
24
+ return c.json({
25
+ deviceCode,
26
+ userCode,
27
+ verificationUrl: "/api/auth/device/verify",
28
+ expiresAt: expiresAt.toISOString(),
29
+ interval: 5,
30
+ });
31
+ });
32
+ // POST /verify — browser approves the device (called by logged-in user)
33
+ app.post("/verify", async (c) => {
34
+ const body = await c.req.json();
35
+ await db.update(cliAuthChallenges).set({
36
+ status: "approved",
37
+ sessionToken: body.sessionToken,
38
+ userId: body.userId,
39
+ tenantId: body.tenantId,
40
+ }).where(and(eq(cliAuthChallenges.userCode, body.userCode), eq(cliAuthChallenges.status, "pending")));
41
+ return c.json({ ok: true });
42
+ });
43
+ // POST /poll — CLI polls for approval
44
+ app.post("/poll", async (c) => {
45
+ const body = await c.req.json();
46
+ const rows = await db.select().from(cliAuthChallenges)
47
+ .where(eq(cliAuthChallenges.deviceCode, body.deviceCode))
48
+ .limit(1);
49
+ if (!rows[0])
50
+ return c.json({ error: "not_found" }, 404);
51
+ if (new Date(rows[0].expiresAt) < new Date())
52
+ return c.json({ error: "expired" }, 410);
53
+ if (rows[0].status === "pending") {
54
+ return c.json({ status: "pending" }, 202);
55
+ }
56
+ if (rows[0].status === "approved" && rows[0].sessionToken) {
57
+ return c.json({
58
+ status: "approved",
59
+ token: rows[0].sessionToken,
60
+ userId: rows[0].userId,
61
+ tenantId: rows[0].tenantId,
62
+ });
63
+ }
64
+ return c.json({ status: rows[0].status }, 400);
65
+ });
66
+ return app;
67
+ }
68
+ //# sourceMappingURL=device-auth-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-auth-routes.js","sourceRoot":"","sources":["../src/device-auth-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type { BoringOSConfig, AuthConfig, DriveAppConfig, LogConfig, AppContext, ConnectorDefinition, SkillDefinition, SkillSource, PersonaBundle, PluginManifest, LifecycleHook, StartedServer, TestInstance, } from "./types.js";
2
+ export { BoringOS } from "./boringos.js";
3
+ export type { MemoryProvider } from "@boringos/memory";
4
+ export type { RuntimeModule, RuntimeRegistry } from "@boringos/runtime";
5
+ export type { StorageBackend } from "@boringos/drive";
6
+ export type { AgentEngine, ContextProvider } from "@boringos/agent";
7
+ export type { WorkflowEngine, BlockHandler } from "@boringos/workflow";
8
+ export { createRealtimeBus } from "./realtime.js";
9
+ export type { RealtimeBus, RealtimeEvent, EventType } from "./realtime.js";
10
+ export { createNotificationService } from "./notifications.js";
11
+ export { createPluginRegistry, createPluginStateStore } from "./plugin-system.js";
12
+ export type { PluginDefinition, PluginJob, PluginWebhook, PluginJobContext, PluginStateStore, PluginRegistry } from "./plugin-system.js";
13
+ export { githubPlugin } from "./plugins/github.js";
14
+ export type { NotificationService, NotificationConfig } from "./notifications.js";
15
+ export { nullMemory } from "@boringos/memory";
16
+ export { createHebbsMemory } from "@boringos/memory";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAClF,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzI,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { BoringOS } from "./boringos.js";
2
+ export { createRealtimeBus } from "./realtime.js";
3
+ export { createNotificationService } from "./notifications.js";
4
+ export { createPluginRegistry, createPluginStateStore } from "./plugin-system.js";
5
+ export { githubPlugin } from "./plugins/github.js";
6
+ export { nullMemory } from "@boringos/memory";
7
+ export { createHebbsMemory } from "@boringos/memory";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AASzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Notification system — sends emails on key events.
3
+ * Uses Resend API. Silently disabled if RESEND_API_KEY is not set.
4
+ */
5
+ export interface NotificationConfig {
6
+ resendApiKey?: string;
7
+ fromEmail?: string;
8
+ }
9
+ export interface NotificationService {
10
+ notify(to: string, subject: string, body: string): Promise<void>;
11
+ isEnabled(): boolean;
12
+ }
13
+ export declare function createNotificationService(config: NotificationConfig): NotificationService;
14
+ export declare function taskCompletedEmail(taskTitle: string, agentName: string): {
15
+ subject: string;
16
+ body: string;
17
+ };
18
+ export declare function runFailedEmail(agentName: string, error: string): {
19
+ subject: string;
20
+ body: string;
21
+ };
22
+ export declare function approvalNeededEmail(agentName: string, approvalType: string): {
23
+ subject: string;
24
+ body: string;
25
+ };
26
+ export declare function budgetWarningEmail(scope: string, spentCents: number, limitCents: number): {
27
+ subject: string;
28
+ body: string;
29
+ };
30
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,IAAI,OAAO,CAAC;CACtB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,kBAAkB,GAAG,mBAAmB,CA+BzF;AAID,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK1G;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAKlG;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK9G;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAK3H"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Notification system — sends emails on key events.
3
+ * Uses Resend API. Silently disabled if RESEND_API_KEY is not set.
4
+ */
5
+ export function createNotificationService(config) {
6
+ const apiKey = config.resendApiKey ?? process.env.RESEND_API_KEY;
7
+ const from = config.fromEmail ?? process.env.NOTIFICATION_FROM_EMAIL ?? "noreply@boringos.dev";
8
+ return {
9
+ isEnabled() {
10
+ return !!apiKey;
11
+ },
12
+ async notify(to, subject, body) {
13
+ if (!apiKey)
14
+ return; // Silently disabled
15
+ try {
16
+ await fetch("https://api.resend.com/emails", {
17
+ method: "POST",
18
+ headers: {
19
+ "Content-Type": "application/json",
20
+ Authorization: `Bearer ${apiKey}`,
21
+ },
22
+ body: JSON.stringify({
23
+ from,
24
+ to,
25
+ subject,
26
+ text: body,
27
+ }),
28
+ });
29
+ }
30
+ catch {
31
+ // Notification failure should never block the main flow
32
+ }
33
+ },
34
+ };
35
+ }
36
+ // ── Pre-built notification templates ─────────────────────────────────────────
37
+ export function taskCompletedEmail(taskTitle, agentName) {
38
+ return {
39
+ subject: `Task completed: ${taskTitle}`,
40
+ body: `Agent "${agentName}" has completed the task "${taskTitle}".`,
41
+ };
42
+ }
43
+ export function runFailedEmail(agentName, error) {
44
+ return {
45
+ subject: `Agent run failed: ${agentName}`,
46
+ body: `Agent "${agentName}" run failed with error:\n\n${error}`,
47
+ };
48
+ }
49
+ export function approvalNeededEmail(agentName, approvalType) {
50
+ return {
51
+ subject: `Approval needed: ${approvalType}`,
52
+ body: `Agent "${agentName}" is requesting approval for: ${approvalType}.\n\nPlease review and approve/reject in the dashboard.`,
53
+ };
54
+ }
55
+ export function budgetWarningEmail(scope, spentCents, limitCents) {
56
+ return {
57
+ subject: `Budget warning: ${scope}`,
58
+ body: `Budget warning for ${scope}: $${(spentCents / 100).toFixed(2)} spent of $${(limitCents / 100).toFixed(2)} limit.`,
59
+ };
60
+ }
61
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,MAAM,UAAU,yBAAyB,CAAC,MAA0B;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACjE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,sBAAsB,CAAC;IAE/F,OAAO;QACL,SAAS;YACP,OAAO,CAAC,CAAC,MAAM,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,OAAe,EAAE,IAAY;YACpD,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,oBAAoB;YAEzC,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,+BAA+B,EAAE;oBAC3C,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,aAAa,EAAE,UAAU,MAAM,EAAE;qBAClC;oBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,IAAI;wBACJ,EAAE;wBACF,OAAO;wBACP,IAAI,EAAE,IAAI;qBACX,CAAC;iBACH,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,wDAAwD;YAC1D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,SAAiB;IACrE,OAAO;QACL,OAAO,EAAE,mBAAmB,SAAS,EAAE;QACvC,IAAI,EAAE,UAAU,SAAS,6BAA6B,SAAS,IAAI;KACpE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,KAAa;IAC7D,OAAO;QACL,OAAO,EAAE,qBAAqB,SAAS,EAAE;QACzC,IAAI,EAAE,UAAU,SAAS,+BAA+B,KAAK,EAAE;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,YAAoB;IACzE,OAAO;QACL,OAAO,EAAE,oBAAoB,YAAY,EAAE;QAC3C,IAAI,EAAE,UAAU,SAAS,iCAAiC,YAAY,yDAAyD;KAChI,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,UAAkB,EAAE,UAAkB;IACtF,OAAO;QACL,OAAO,EAAE,mBAAmB,KAAK,EAAE;QACnC,IAAI,EAAE,sBAAsB,KAAK,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;KACzH,CAAC;AACJ,CAAC"}