Rework the README with current screenshots
The README was a bare file list. It now opens with the horizontal lockup, a theme-aware hero and a workspace dashboard, both taken from the running app, so GitHub's preview shows the product instead of describing it. AGENTS.md records that the design handoff is outdated: its screens and briefs are history, while its brand assets (stones, coordinator, app icon, wordmark) and their copies in src/data are still the foundation.
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
# Agent Instructions
|
# Agent Instructions
|
||||||
|
|
||||||
This is **Cobble** (`cobble.moduletrace.org`): an open-source crew of small AI worker bots. The design handoff in `assets/handoff/` (gitignored locally: `PRODUCT.md`, `IMPLEMENTATION.md`, `tokens/`) is the starting point for the core concepts and visual language, not the end product. The app is expected to move away from it; when it and the current code or the user disagree, the code and the user win. Unit noun is **bot**, never "agent" or "expert".
|
This is **Cobble** (`cobble.moduletrace.org`): an open-source crew of small AI worker bots. Unit noun is **bot**, never "agent" or "expert".
|
||||||
|
|
||||||
|
**The handoff is outdated.** `assets/handoff/` (gitignored locally: `PRODUCT.md`, `IMPLEMENTATION.md`, `tokens/`, `assets/`) is the *foundation*, not the design: it is what the project started from, and the app has moved well past it. Its layouts, screens (`assets/screens/*.png`), right-hand "working on" panel, and PRODUCT/IMPLEMENTATION briefs describe an early single-chat prototype and must not be used as reference for the current UI or copied into docs, screenshots or marketing. What is still authoritative in it:
|
||||||
|
|
||||||
|
- **Brand assets:** the stone icons (`public/brand/icons/*.svg`, mirrored into `src/data/stone-geometry.ts`), the coordinator (`public/brand/coordinator/`), the app icon (`public/brand/app-icon/`), and the wordmark (`public/brand/wordmark/`, mirrored into `src/data/wordmark-paths.ts`). These are the identity and do not change; the mark is a stone with exactly one flat cut, hue is a bot's identity (never status), the coordinator is hue-less.
|
||||||
|
- **Tokens:** `tokens/tokens.css` was the origin of the `:root` / `.dark` block in `src/styles/main.css`. From here on `src/styles/main.css` is the source of truth; treat the handoff CSS as historical.
|
||||||
|
|
||||||
|
For the current UI, read the code: `src/layouts/bots/` (rail, workspace rail, user popover), `src/pages/admin/bots/[bot_id]/` (conversation header, thread, composer, modals) and `src/pages/admin/workspaces/` (dashboard). When the handoff and the current code or the user disagree, the code and the user win, always.
|
||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
@@ -238,7 +245,7 @@ Server functions use `index.server.ts` alongside `index.tsx` (e.g. `single-docum
|
|||||||
- **UNCHANGEABLE RULE - twui components always win over raw JSX elements.** Use twui components (`H1`-`H5`, `P`, `Span`, `List`, `Img`, `Row`, `Stack`, `Container`, `Section`, `Card`, `Button`, `Tag`, `Link`, etc.) before basic JSX elements (`<h1>`-`<h6>`, `<p>`, `<span>`, `<ul>`, `<li>`, `<img>`, `<a>`, `<button>`, `<div>`-as-card, etc.). Never introduce or reintroduce a raw JSX element where a twui equivalent exists. Override twui defaults via `className` rather than reaching for the raw element.
|
- **UNCHANGEABLE RULE - twui components always win over raw JSX elements.** Use twui components (`H1`-`H5`, `P`, `Span`, `List`, `Img`, `Row`, `Stack`, `Container`, `Section`, `Card`, `Button`, `Tag`, `Link`, etc.) before basic JSX elements (`<h1>`-`<h6>`, `<p>`, `<span>`, `<ul>`, `<li>`, `<img>`, `<a>`, `<button>`, `<div>`-as-card, etc.). Never introduce or reintroduce a raw JSX element where a twui equivalent exists. Override twui defaults via `className` rather than reaching for the raw element.
|
||||||
- **Never create new CSS classes, CSS files, or inline `style={{...}}` hacks.** Style exclusively by composing existing component props/classNames, existing twui classNames (`twui-*`), semantic theme-token utilities (`bg-dark`, `bg-light`, `text-dark`, `text-primary`, `bg-primary`, `text-accent`, `bg-accent`, `text-secondary`, `border-slate-200`, etc.), and utility classes already used elsewhere in this codebase. Build up from what exists; extend component code only when the existing API cannot express the need.
|
- **Never create new CSS classes, CSS files, or inline `style={{...}}` hacks.** Style exclusively by composing existing component props/classNames, existing twui classNames (`twui-*`), semantic theme-token utilities (`bg-dark`, `bg-light`, `text-dark`, `text-primary`, `bg-primary`, `text-accent`, `bg-accent`, `text-secondary`, `border-slate-200`, etc.), and utility classes already used elsewhere in this codebase. Build up from what exists; extend component code only when the existing API cannot express the need.
|
||||||
- **Theming:** colors, radii, and fonts change only in `src/styles/main.css`: Cobble tokens as CSS vars on `:root` (light) and `.dark`, exposed in the `@theme inline` block as `paper`, `surface`, `sunken`, `ink`, `ink-secondary`, `ink-disabled`, `hairline`, `hairline-strong`, `on-ink`, `hue-<name>`, plus `shadow-popover` and `--m-fast/base/slow` motion vars (zeroed under reduced motion). Font is Lato (stand-in). Never hardcode hex colors, radii, or font stacks inside components. Hues are bot identity only, never state; use `src/dict/bot-hue-classes-dict.ts` for hue classes.
|
- **Theming:** colors, radii, and fonts change only in `src/styles/main.css`: Cobble tokens as CSS vars on `:root` (light) and `.dark`, exposed in the `@theme inline` block as `paper`, `surface`, `sunken`, `ink`, `ink-secondary`, `ink-disabled`, `hairline`, `hairline-strong`, `on-ink`, `hue-<name>`, plus `shadow-popover` and `--m-fast/base/slow` motion vars (zeroed under reduced motion). Font is Lato (stand-in). Never hardcode hex colors, radii, or font stacks inside components. Hues are bot identity only, never state; use `src/dict/bot-hue-classes-dict.ts` for hue classes.
|
||||||
- **Branding:** `public/logos/logo.svg` is the single source of truth for the logo mark; `logo-icon.tsx` renders it inline (via `BotStone`) and `logo.tsx` renders the stone beside the vector `Wordmark`. Whenever the logo changes, run `bun run gen:favicon` to regenerate `public/favicon.ico`, `public/favicon.png`, `public/apple-touch-icon.png`, and `public/logos/logo.png` (the last is used in emails). Font + favicon links live in `__root.tsx` `Head()`.
|
- **Branding:** `docs/readme/hero-light.png`, `hero-dark.png`, `workspace-light.png` and `workspace-dark.png` are screenshots of the current app (chat and workspace dashboard, 1440px at 2x, downscaled to 1600px wide), committed and picked per theme by GitHub's `#gh-light-mode-only` / `#gh-dark-mode-only` fragment. They are not generated: when the UI changes, retake them from a seeded dev instance (`bun run seed`, `bun run seed:bots`) and keep the same names, so the README never shows an older dashboard. Never use `assets/handoff/assets/screens/*.png` for anything: that design is outdated. `public/logos/logo.svg` is the single source of truth for the logo mark; `logo-icon.tsx` renders it inline (via `BotStone`) and `logo.tsx` renders the stone beside the vector `Wordmark`. Whenever the logo changes, run `bun run gen:favicon` to regenerate `public/favicon.ico`, `public/favicon.png`, `public/apple-touch-icon.png`, and `public/logos/logo.png` (the last is used in emails). Font + favicon links live in `__root.tsx` `Head()`.
|
||||||
- **Site name:** brand literals live only in `src/data/site-data.ts`. Page meta titles, emails, and UI copy must interpolate `SiteData["SiteName"]` - never hardcode a brand name in page files.
|
- **Site name:** brand literals live only in `src/data/site-data.ts`. Page meta titles, emails, and UI copy must interpolate `SiteData["SiteName"]` - never hardcode a brand name in page files.
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|||||||
@@ -1,21 +1,72 @@
|
|||||||
# Cobble
|
<div align="center">
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
<img src="docs/readme/lockup-light.svg#gh-light-mode-only" alt="Cobble" height="56">
|
||||||
|
<img src="docs/readme/lockup-dark.svg#gh-dark-mode-only" alt="Cobble" height="56">
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
A crew of small AI worker bots you host yourself.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
[](https://github.com/Moduletrace/cobble/actions/workflows/ci.yml)
|
[](https://github.com/Moduletrace/cobble/actions/workflows/ci.yml)
|
||||||
|
[](LICENSE)
|
||||||
|
[](https://cobble.moduletrace.org)
|
||||||
|
[](https://bun.sh)
|
||||||
|
|
||||||
A self-hosted crew of small AI worker bots.
|
[Website](https://cobble.moduletrace.org) · [Install](#install) · [Features](#features) · [Development](#development) · [Architecture](AGENTS.md)
|
||||||
|
|
||||||
Cobble gives you a coordinator bot and a crew of workers, each with its own
|
</div>
|
||||||
job, models, memory and workspace. The crew talks to you in a chat, shares
|
|
||||||
workspaces, runs routines on a schedule, and drives its own computers:
|
Cobble is a self-hosted crew of small AI worker bots. You get a coordinator
|
||||||
Docker sandboxes with a browser, terminal, code editor and desktop that a
|
and a set of workers, each with its own job, models, memory and workspace.
|
||||||
bot can use and hand back to you when it needs help.
|
They talk to you in one chat, share workspaces, run routines on a schedule,
|
||||||
|
and drive their own computers: Docker sandboxes with a browser, a terminal,
|
||||||
|
a code editor and a desktop that a bot can use and hand back to you when it
|
||||||
|
needs help.
|
||||||
|
|
||||||
It is an install, not a SaaS. One SQLite database, one Docker container, and
|
It is an install, not a SaaS. One SQLite database, one Docker container, and
|
||||||
your data on your own machine.
|
your data on your own machine.
|
||||||
|
|
||||||
- Website: [cobble.moduletrace.org](https://cobble.moduletrace.org)
|
**Why small workers instead of one big assistant**
|
||||||
- Source: [GitHub](https://github.com/Moduletrace/cobble) and [Gitea](https://git.tben.me/Moduletrace/cobble)
|
|
||||||
- License: MIT
|
- **A crew, not a chat.** Each worker has one job and only loads the context
|
||||||
|
for it. A five-bot crew does five things in parallel, and each one stays
|
||||||
|
cheap and focused.
|
||||||
|
- **Bots you can see through.** The face on each stone is the status: idle,
|
||||||
|
working, done, asleep, needs you. You read the whole crew at a glance
|
||||||
|
instead of asking each one what it is doing.
|
||||||
|
- **Real computers.** Workers run on your own sandboxed machines, with
|
||||||
|
browser, terminal, files and desktop, not just a tool loop.
|
||||||
|
- **Yours.** Self-hosted, MIT, one SQLite file to back up, no account and no
|
||||||
|
per-seat billing.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
| Area | What you get |
|
||||||
|
| --- | --- |
|
||||||
|
| Crew | One coordinator and as many workers as you need, each with a name, a role, a hue and its own core instructions |
|
||||||
|
| Rail | The coordinator, your recent workers and their latest sessions, then your workspaces, each row carrying its status line |
|
||||||
|
| Chat | Markdown with @-mentions for bots and #-mentions for workspaces, replies and quotes, reactions, attachments, older messages on scroll, drafts kept locally |
|
||||||
|
| Header | The bot's model, provider and computer at a glance, one click from either, and its picture, instructions and settings on the avatar |
|
||||||
|
| Workspaces | A shared home for a group of bots: shared context, per-workspace instructions and memory, a default computer, and a dashboard |
|
||||||
|
| Memory | Each bot keeps core memory, memory about you, and workspace memory, and rewrites it as it works |
|
||||||
|
| Routines | Cron schedules per bot, written in chat, that queue a task on its own |
|
||||||
|
| Computers | Docker sandboxes with browser, terminal, code editor and desktop, opened from the chat and handed back to you mid-task |
|
||||||
|
| Files | Bots keep files on your data volume, search them by meaning, and attach the ones they make to a reply |
|
||||||
|
| Models | OpenRouter, OpenAI, Anthropic, Gemini, DeepSeek, Groq, Mistral, xAI, Ollama or any OpenAI-compatible server, per bot and per harness |
|
||||||
|
| Voice | Dictate into the composer, play any bot reply, with speech-to-text and text-to-speech models of your choice |
|
||||||
|
| Tools | Install your own MCP servers and custom HTTP, script or prompt tools, and give them to bots or workspaces |
|
||||||
|
| App | Installable PWA with Web Push, dark mode, and a rail built for a phone |
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
A workspace dashboard: what it is, its latest activity, the bots in it with
|
||||||
|
their instructions there, and its computers.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@@ -106,6 +157,35 @@ curl -fsSL https://url.moduletrace.com/cobble | sudo bash -s -- --uninstall --pu
|
|||||||
| `--uninstall` | Stop and remove the app container |
|
| `--uninstall` | Stop and remove the app container |
|
||||||
| `--purge` | With `--uninstall`, also delete the data directory |
|
| `--purge` | With `--uninstall`, also delete the data directory |
|
||||||
|
|
||||||
|
## How it fits together
|
||||||
|
|
||||||
|
```
|
||||||
|
You ── chat ── Coordinator ── delegates ── Workers
|
||||||
|
│ │
|
||||||
|
├── Workspaces ────────────┤
|
||||||
|
│ context, memory, bots │
|
||||||
|
├── Routines ──────────────┤
|
||||||
|
│ cron schedules │
|
||||||
|
└── Computers ─────────────┘
|
||||||
|
docker sandboxes:
|
||||||
|
browser, terminal, code, desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Coordinator** is yours alone. It plans, delegates to workers, and keeps
|
||||||
|
the crew in order. It is the only bot that reaches every worker.
|
||||||
|
- **Workers** are the crew. Each has a job, its own instructions and memory,
|
||||||
|
and its own models if you want to tune cost per bot.
|
||||||
|
- **Workspaces** group bots around a subject. Models, instructions, memory
|
||||||
|
and the default computer resolve per workspace before per bot.
|
||||||
|
- **Routines** are cron schedules that queue a task without you asking.
|
||||||
|
- **Computers** are per-install Docker containers. Bots use them through the
|
||||||
|
sandbox's tools, and you can open the same machine in the browser and take
|
||||||
|
over.
|
||||||
|
|
||||||
|
Each conversation is split into sessions, so a long-running bot does not grow
|
||||||
|
one endless thread: the bot names a session, summarizes it, and carries the
|
||||||
|
summary into the next one.
|
||||||
|
|
||||||
## Data and settings
|
## Data and settings
|
||||||
|
|
||||||
Everything that must survive an update lives under the install directory:
|
Everything that must survive an update lives under the install directory:
|
||||||
@@ -120,6 +200,8 @@ Everything that must survive an update lives under the install directory:
|
|||||||
db/.backups/
|
db/.backups/
|
||||||
media/
|
media/
|
||||||
computers/<id>/ # each computer's home directory
|
computers/<id>/ # each computer's home directory
|
||||||
|
bots/<id>/ # each bot's files
|
||||||
|
workspaces/<id>/ # files shared in a workspace
|
||||||
```
|
```
|
||||||
|
|
||||||
`.env` holds the port and the encryption keys. The keys encrypt sessions and
|
`.env` holds the port and the encryption keys. The keys encrypt sessions and
|
||||||
@@ -169,27 +251,38 @@ the app from a phone, run a proxy or tunnel in front of it (see
|
|||||||
[HTTPS](#https)); the installed app, Web Push and voice need that secure
|
[HTTPS](#https)); the installed app, Web Push and voice need that secure
|
||||||
context.
|
context.
|
||||||
|
|
||||||
| Command | Purpose |
|
| Command | Purpose |
|
||||||
| -------------------- | ------------------------------------ |
|
| --------------------- | ------------------------------------ |
|
||||||
| `bun run dev` | Development server |
|
| `bun run dev` | Development server |
|
||||||
| `bun run start` | Production server on the host |
|
| `bun run start` | Production server on the host |
|
||||||
| `bun run typecheck` | Type-check |
|
| `bun run typecheck` | Type-check |
|
||||||
| `bun run test` | Run the test suite |
|
| `bun run test` | Run the test suite |
|
||||||
| `bun run seed` | Create the super admin from the CLI |
|
| `bun run check:bundle`| Bundle budget after a build |
|
||||||
| `bun run seed:bots` | Add a sample crew |
|
| `bun run seed` | Create the super admin from the CLI |
|
||||||
| `bun run db:schema` | Sync the schema and types |
|
| `bun run seed:bots` | Add a sample crew |
|
||||||
| `bun run gen:favicon` | Regenerate favicons and PWA assets |
|
| `bun run db:schema` | Sync the schema and types |
|
||||||
|
| `bun run gen:favicon` | Regenerate favicons and PWA assets |
|
||||||
|
|
||||||
The app is Bun, [`@moduletrace/bunext`](https://github.com/Moduletrace/bunext),
|
Plain Node does not work: the app runs on Bun. The stack is Bun,
|
||||||
SQLite via [`@moduletrace/bun-sqlite`](https://github.com/Moduletrace/bun-sqlite),
|
[`@moduletrace/bunext`](https://github.com/Moduletrace/bunext) for
|
||||||
Tailwind CSS and the `@moduletrace/twui` component library. See
|
filesystem routing, SQLite via
|
||||||
[AGENTS.md](AGENTS.md) for the full architecture, routes, queue, harness and
|
[`@moduletrace/bun-sqlite`](https://github.com/Moduletrace/bun-sqlite),
|
||||||
data model.
|
Tailwind CSS and the `@moduletrace/twui` component library. The model layer is
|
||||||
|
one adapter over OpenAI-compatible APIs, so any compatible provider works.
|
||||||
|
|
||||||
CI runs type-check and tests on every push and pull request. Releases are
|
See [AGENTS.md](AGENTS.md) for the full architecture, routes, queue, harness
|
||||||
built by GitHub Actions and pushed to both registries. See
|
and data model. CI runs type-check and tests on every push and pull request;
|
||||||
|
releases are built by GitHub Actions and pushed to both registries. See
|
||||||
[RELEASING.md](RELEASING.md) for the release and launch checklist.
|
[RELEASING.md](RELEASING.md) for the release and launch checklist.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Issues and pull requests are welcome, in English, on either
|
||||||
|
[GitHub](https://github.com/Moduletrace/cobble) or
|
||||||
|
[Gitea](https://git.tben.me/Moduletrace/cobble). Run `bun run typecheck` and
|
||||||
|
`bun run test` before opening a pull request, and read
|
||||||
|
[AGENTS.md](AGENTS.md) first: it documents the conventions the code follows.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT. See [LICENSE](LICENSE).
|
MIT. See [LICENSE](LICENSE).
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 190 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 190 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
Reference in New Issue
Block a user