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
+3 -3
View File
@@ -3,12 +3,12 @@ import adminCrudHandler from "../functions/frontend/admin-crud-handler";
import _ from "lodash";
import { AppData } from "../data/app-data";
import useStatus from "@moduletrace/twui/hooks/useStatus";
import type { BUN_SQLITE_BSQLITE_ALL_TYPEDEFS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_ALL_TYPEDEFS } from "@/db/types/db";
import type { ApiReqParams, ClientAdminCrudParams, TableType } from "../types";
import type { ServerQueryParam } from "@moduletrace/bun-sqlite";
import EJSON from "../utils/ejson";
type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = Pick<
type Params<T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS> = Pick<
ClientAdminCrudParams,
"id" | "count"
> & {
@@ -22,7 +22,7 @@ type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = Pick<
request_query?: ApiReqParams<T>;
};
export function useAdminCrudGet<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS>({
export function useAdminCrudGet<T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS>({
table,
sql_query,
count: add_count_param,
+3 -3
View File
@@ -3,11 +3,11 @@ import _ from "lodash";
import { AppData } from "../data/app-data";
import useStatus from "@moduletrace/twui/hooks/useStatus";
import adminFetchHandler from "../functions/frontend/admin-fetch-handler";
import type { BUN_SQLITE_BSQLITE_ALL_TYPEDEFS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_ALL_TYPEDEFS } from "@/db/types/db";
import type { AdminFetchParams, ApiReqParams } from "../types";
import EJSON from "../utils/ejson";
type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = Omit<
type Params<T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS> = Omit<
AdminFetchParams<T>,
"method" | "body"
> & {
@@ -16,7 +16,7 @@ type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = Omit<
count?: boolean;
};
export function useFetchGet<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS>({
export function useFetchGet<T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS>({
url,
debug,
initial_res,
+3 -3
View File
@@ -1,4 +1,4 @@
import type { BUN_SQLITE_BSQLITE_ALL_TYPEDEFS } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_ALL_TYPEDEFS } from "@/db/types/db";
import useStatus from "@moduletrace/twui/hooks/useStatus";
import {
useCallback,
@@ -15,7 +15,7 @@ import twuiSlugify from "@moduletrace/twui/utils/slugify";
import _ from "lodash";
import type { AppContextObject } from "../types";
type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = {
type Params<T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS> = {
/**
* Existing record for update. All unneccasary fields
* like join fields should be excluded.
@@ -48,7 +48,7 @@ type Params<T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS> = {
};
export default function useFormInit<
T extends {} = BUN_SQLITE_BSQLITE_ALL_TYPEDEFS,
T extends {} = BUN_SQLITE_COBBLE_ALL_TYPEDEFS,
>(params?: Params<T>) {
const appContext = useContext(AppContext);
+3 -3
View File
@@ -1,13 +1,13 @@
import type { User } from "../types";
import { useEffect, useState } from "react";
import fetchApi from "@moduletrace/twui/utils/fetch/fetchApi";
import type { BUN_SQLITE_BSQLITE_USER_TYPES } from "@/db/types/db";
import type { BUN_SQLITE_COBBLE_USER_TYPES } from "@/db/types/db";
import type { APIResponseObject } from "@moduletrace/bunext/types";
export function useLocalUser() {
const [user, setUser] = useState<User>();
const [userTypes, setUserTypes] =
useState<BUN_SQLITE_BSQLITE_USER_TYPES[]>();
useState<BUN_SQLITE_COBBLE_USER_TYPES[]>();
useEffect(() => {
fetchApi<any, APIResponseObject>(`/api/admin/user-auth`).then((res) => {
@@ -15,7 +15,7 @@ export function useLocalUser() {
setUser(res.singleRes as User);
}
if (res.payload) {
setUserTypes(res.payload as BUN_SQLITE_BSQLITE_USER_TYPES[]);
setUserTypes(res.payload as BUN_SQLITE_COBBLE_USER_TYPES[]);
}
});
}, []);
+4 -4
View File
@@ -2,7 +2,7 @@ import _ from "lodash";
import useStatus from "@moduletrace/twui/hooks/useStatus";
import adminFetchHandler from "../functions/frontend/admin-fetch-handler";
import type { ApiReqParams } from "../types";
import type { BUN_SQLITE_BSQLITE_USERS_JOIN } from "../types/sql-joins";
import type { BUN_SQLITE_COBBLE_USERS_JOIN } from "../types/sql-joins";
import { useEffect, useRef, useState } from "react";
import EJSON from "../utils/ejson";
@@ -10,7 +10,7 @@ type Params = {
query?: ApiReqParams;
debug?: boolean;
page?: number;
initial_users?: BUN_SQLITE_BSQLITE_USERS_JOIN[];
initial_users?: BUN_SQLITE_COBBLE_USERS_JOIN[];
};
export function useUsersGet({
@@ -20,7 +20,7 @@ export function useUsersGet({
initial_users,
}: Params) {
const [users, setUsers] = useState<
BUN_SQLITE_BSQLITE_USERS_JOIN[] | undefined
BUN_SQLITE_COBBLE_USERS_JOIN[] | undefined
>(initial_users);
const [count, setCount] = useState<number | undefined>();
const [page, setPage] = useState<number>(initial_page || 1);
@@ -49,7 +49,7 @@ export function useUsersGet({
console.log("final_query", final_query);
}
adminFetchHandler<BUN_SQLITE_BSQLITE_USERS_JOIN>({
adminFetchHandler<BUN_SQLITE_COBBLE_USERS_JOIN>({
url: `/api/admin/grab-users`,
query: final_query,
})