Add workspaces, computers, bot memory and the bots queue

- Schema: workspaces (+ workspace_bots, workspace_computers), containers,
  computers, bot_computers, bots.memory, workspaces.system_prompt, and
  bots_queue as a bun-sqlite isQueue table
- Main computer (and its container record) ensured with the coordinator on
  signup, seed and /admin/bots; the coordinator's access to it is locked
- Effective computer access: direct grants plus workspace computers
- Full bot prompt: core instructions, workspace prompts, then memory;
  bots can rewrite their memory and system prompt
- Queue helpers on the native BunSQLite.queue API, plus a handler that
  heartbeats, serializes per computer, recovers after restarts, reports
  lost jobs, supports cancelling and pushes outcomes over the WebSocket
- Enable SQLite foreign keys at startup so schema cascades fire
- Prune finished jobs daily

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-18 18:33:54 +01:00
co-authored by Claude Opus 5.5
parent 694c83346f
commit d49f524fe8
72 changed files with 2961 additions and 31 deletions
+14 -9
View File
@@ -3,6 +3,7 @@ import setUserPassword from "@/src/functions/backend/auth/set-user-password";
import grabHasUsers from "@/src/functions/backend/auth/grab-has-users";
import loginUser from "@/src/functions/backend/auth/login-user";
import ensureCoordinatorBot from "@/src/functions/backend/db/bots/ensure-coordinator-bot";
import ensureMainComputer from "@/src/functions/backend/db/computers/ensure-main-computer";
import validatePassword from "@/src/utils/validate-password";
import logEvent, { grabRequestIP, logError } from "@/src/functions/backend/logger";
import { AppData } from "@/src/data/app-data";
@@ -74,16 +75,20 @@ export const handler: BunextAPIRouteHandler<APIResponseObject> = async ({
/**
* The account exists now, so a failure here mustn't fail signup
* (which is one-shot). `/admin/bots` creates it on the next visit.
* (which is one-shot). `/admin/bots` creates both on the next visit.
*/
await ensureCoordinatorBot({ user_id: new_user_id }).catch((error) =>
logError({
title: "Coordinator bot not created at signup",
error,
user_id: new_user_id,
ip_address: grabRequestIP(req),
}).catch(() => {}),
);
await ensureCoordinatorBot({ user_id: new_user_id })
.then((coordinator_id) =>
ensureMainComputer({ user_id: new_user_id, coordinator_id }),
)
.catch((error) =>
logError({
title: "Coordinator or main computer not created at signup",
error,
user_id: new_user_id,
ip_address: grabRequestIP(req),
}).catch(() => {}),
);
await logEvent({
title: "Super admin created",