Build Cobble project structure from the handoff

- Remove the preset document suite (letters, emails, invoices, quotes,
  PDF generation, line items) with its routes, API handlers and tables
- Rebrand to Cobble: site data, Lato, handoff design tokens (light and
  dark) in main.css, brand assets in public/brand, ember stone logo and
  regenerated favicons
- Add bots, bot_messages, bot_tasks and bot_task_steps tables, regenerate
  DB types (BUN_SQLITE_COBBLE_*) and add a sample crew seed (seed:bots)
- Add the chat shell at /admin/bots: rail with pinned coordinator and
  user popover, bottom-anchored conversation with composer, working-on
  panel, and a send-message API scoped to the session user
- Add BotStone and Wordmark components, crew status and relative time
  utils with tests, and update AGENTS.md

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-18 17:10:36 +01:00
co-authored by Claude Opus 5.5
parent 81e4a8aecc
commit 3286b80029
340 changed files with 3161 additions and 12060 deletions
@@ -1,4 +1,4 @@
import type { BUN_SQLITE_BSQLITE_USERS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_USERS } from "@/db/types/db";
import adminCrudHandler from "@/src/functions/frontend/admin-crud-handler";
import clientDeleteMediaHandler from "@/src/functions/frontend/client-delete-media-handler";
import clientUploadMediaHandler from "@/src/functions/frontend/client-upload-media-handler";
@@ -24,7 +24,7 @@ export default async function submitAccountForm({
return;
}
const new_user_data: BUN_SQLITE_BSQLITE_USERS = _.pick<
const new_user_data: BUN_SQLITE_COBBLE_USERS = _.pick<
UserFormObject,
keyof UserFormObject
>(form, ["first_name", "last_name", "email", "username", "bio"]);
@@ -1,9 +1,9 @@
import type { BUN_SQLITE_BSQLITE_USERS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_USERS } from "@/db/types/db";
import Button from "@moduletrace/twui/layout/Button";
import useFormInit from "@/src/hooks/use-form-init";
export default function AccountFormAction(
_params: ReturnType<typeof useFormInit<BUN_SQLITE_BSQLITE_USERS>>,
_params: ReturnType<typeof useFormInit<BUN_SQLITE_COBBLE_USERS>>,
) {
return (
<>
@@ -1,7 +1,7 @@
import Form from "@moduletrace/twui/form/Form";
import LoadingOverlay from "@moduletrace/twui/elements/LoadingOverlay";
import useFormInit from "@/src/hooks/use-form-init";
import type { BUN_SQLITE_BSQLITE_USERS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_USERS } from "@/db/types/db";
import submitAccountForm from "../(functions)/submit-account-form";
import AccountFormAction from "./account-form-action";
import Tag from "@moduletrace/twui/elements/Tag";
@@ -15,7 +15,7 @@ import type { UserFormObject } from "@/src/types";
type Props = {
existing_user?: UserFormObject;
existing_user_full?: BUN_SQLITE_BSQLITE_USERS;
existing_user_full?: BUN_SQLITE_COBBLE_USERS;
};
export default function AccountForm({ existing_user, existing_user_full }: Props) {
@@ -4,7 +4,7 @@ import { useContext } from "react";
import AccountForm from "../(partials)/account-form";
import _ from "lodash";
import type { UserFormObject } from "@/src/types";
import type { BUN_SQLITE_BSQLITE_USERS_JOIN } from "@/src/types/sql-joins";
import type { BUN_SQLITE_COBBLE_USERS_JOIN } from "@/src/types/sql-joins";
export default function AccountFormSection() {
const { pageProps } = useContext(AppContext);
@@ -18,8 +18,8 @@ export default function AccountFormSection() {
<AccountForm
existing_user={
_.pick<
BUN_SQLITE_BSQLITE_USERS_JOIN,
keyof BUN_SQLITE_BSQLITE_USERS_JOIN
BUN_SQLITE_COBBLE_USERS_JOIN,
keyof BUN_SQLITE_COBBLE_USERS_JOIN
>(person, [
"first_name",
"last_name",