Release 0.1.0: MIT license, changelog, multi-arch Docker image without CLI builds

- LICENSE (MIT), CHANGELOG for 0.1.0, README overhaul
- docker-compose.release.yml pulling the registry image
- Dockerfile cross-compiles the server with cargo-zigbuild for amd64 and arm64;
  the terminal client is no longer built into the image
- Server, install script and settings point to a source install of the
  terminal client when no prebuilt binaries are available (/info: cli_builds)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-09 07:50:57 +01:00
1 parent d14c609576
commit ed9942829a
15 files changed
+384 -109

No files matched your search

+159 -74
View File
@@ -5,35 +5,38 @@
<h1 align="center">CodeCraft</h1>
<p align="center">
<b>A self-hosted coding agent for your browser: any model, your tools, your rules.</b><br>
Run Claude, Gemini, opencode Go, fal.ai or your own models as coding agents with files, shell, MCP and subagents,<br>
approve what they do from any device, and see exactly what every request costs.
<b>A self-hosted coding agent for your browser and terminal: any model, your tools, your rules.</b><br>
Run Claude, Gemini, OpenRouter, opencode or your own models as coding agents with files, shell, MCP and subagents,<br>
approve what they do from any device, automate recurring work, and see exactly what every request costs.
</p>
<p align="center">
<img alt="Version 0.1.0" src="https://img.shields.io/badge/version-0.1.0-d69e2e?style=flat-square">
<img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-689d6a?style=flat-square">
<img alt="Rust backend" src="https://img.shields.io/badge/backend-Rust-b7410e?style=flat-square&logo=rust">
<img alt="React PWA" src="https://img.shields.io/badge/frontend-React%20PWA-2d81ff?style=flat-square&logo=react">
<img alt="Docker" src="https://img.shields.io/badge/deploy-Docker-1d63ed?style=flat-square&logo=docker&logoColor=white">
<img alt="Status: early alpha" src="https://img.shields.io/badge/status-early%20alpha-d69e2e?style=flat-square">
<img alt="Docker: amd64 and arm64" src="https://img.shields.io/badge/docker-amd64%20%7C%20arm64-1d63ed?style=flat-square&logo=docker&logoColor=white">
</p>
<p align="center">
<a href="#install">Install</a> ·
<a href="#how-it-works">How it works</a> ·
<a href="#modes">Modes</a> ·
<a href="#models">Models</a> ·
<a href="#users">Users</a> ·
<a href="#terminal-client">Terminal client</a> ·
<a href="#automations">Automations</a> ·
<a href="#integrations">Integrations</a> ·
<a href="#users-and-security">Users</a> ·
<a href="#statistics">Statistics</a> ·
<a href="#get-started">Get started</a> ·
<a href="#configuration">Configuration</a> ·
<a href="#themes">Themes</a> ·
<a href="#development">Development</a> ·
<a href="#status">Status</a>
<a href="#development">Development</a>
</p>
<br>
<p align="center">
<img src="docs/images/chat.png" alt="A CodeCraft session: the agent edits a file, a permission card shows the diff and asks before running a command, the task list shows what is left" width="100%">
<img src="docs/images/chat.png" alt="A CodeCraft session: the agent edits a file, a permission card shows the command and asks before running it, the task list shows what is left" width="100%">
<br>
<sub>A session: the agent works through its task list, shows diffs, and asks before anything outside the rules.</sub>
</p>
@@ -41,47 +44,84 @@
<table>
<tr>
<td width="25%" valign="top">
<h3>🧠 Any model</h3>
Anthropic natively, plus everything that speaks the OpenAI API: Gemini, opencode Go, fal.ai, OpenRouter, Ollama, vLLM, llama.cpp. Mix them in one chat.
<h3>Any model</h3>
Anthropic natively, plus everything that speaks the OpenAI API: Gemini, OpenRouter, opencode, fal.ai, Ollama, vLLM, llama.cpp. Mix them in one chat, with automatic fallback.
</td>
<td width="25%" valign="top">
<h3>🛠️ Real tools</h3>
Read, write, edit, glob, grep, shell, web fetch, task lists, subagents, skills – and every tool of your MCP servers.
<h3>Real tools</h3>
Files, shell, web, an interactive browser, LSP diagnostics, task lists, subagents, skills – and every tool of your MCP servers.
</td>
<td width="25%" valign="top">
<h3>🙋 You decide</h3>
Permission requests with diffs, questions from agents and MCP servers, per-tool rules. On your phone, with notifications.
<h3>You decide</h3>
Permission cards with diffs, questions from agents and MCP servers, per-tool rules. On your phone, with push notifications.
</td>
<td width="25%" valign="top">
<h3>📊 Every token counted</h3>
Tokens, cache hits, prefill and output speed, and cost per request – per chat and in a dashboard.
<h3>Every token counted</h3>
Tokens, cache hits, prefill and output speed, and cost per request – per chat, per day and per model.
</td>
</tr>
</table>
<br>
## Install
You need Docker with Compose. The image is published for **amd64 and arm64**.
```sh
mkdir codecraft && cd codecraft
curl -fsSLO https://git.familie-zink.org/zink/codecraft/raw/branch/main/docker-compose.release.yml
curl -fsSL --create-dirs -o docker/seccomp-sandbox.json \
https://git.familie-zink.org/zink/codecraft/raw/branch/main/docker/seccomp-sandbox.json
curl -fsSL -o .env https://git.familie-zink.org/zink/codecraft/raw/branch/main/.env.example
$EDITOR .env # workspace path, provider keys, time zone
docker compose -f docker-compose.release.yml up -d
docker compose -f docker-compose.release.yml logs codecraft # one-time setup code for the first admin
```
Open `http://localhost:8787`, enter the setup code and create the admin account. Then add a
provider under *Settings → Providers & models* – or put the keys into `.env` and reference
them in the config as `${NAME}`.
**Update:** `docker compose -f docker-compose.release.yml pull && docker compose -f docker-compose.release.yml up -d`.
Pin a version with `CODECRAFT_VERSION=0.1.0` in `.env`. Admins see a notice when a new release is out.
**From source:** `git clone https://git.familie-zink.org/zink/codecraft.git && cd codecraft`,
`cp .env.example .env`, then `docker compose up -d --build`.
All state – configuration, database, backups, the agent's home directory – lives in the Docker
volume `codecraft-data`; recreating the container keeps it. Your projects are mounted from
`WORKSPACE`. The port is bound to `127.0.0.1`: put a TLS reverse proxy in front of it (with
WebSocket support) and set `auth.public_url` – installing the app and push notifications
require HTTPS.
## How it works
CodeCraft runs on your server, next to your projects. You talk to it from a browser or the
installed app; the agent keeps working when you close the tab.
CodeCraft runs on your server, next to your projects. You talk to it from a browser, the
installed app or the terminal client; the agent keeps working when you close the tab.
1. **Pick a folder and a mode.** Every user has their own folder; admins can share more.
1. **Pick a folder and a task.** The start screen asks what you want to do – build, plan,
craft something, model a part for 3D printing – and where: a new folder, an existing one
or a git repository.
2. **Say what you want.** The agent plans with a task list, reads the code and makes changes.
3. **Approve or answer.** Anything outside your rules shows up as a card: allow once, allow
for the session, or reject with feedback. Questions from agents and MCP servers too.
4. **Delegate.** The agent hands work to subagents – in parallel or in the background, on
other models and hosts – and continues while they run.
Every change can be reviewed hunk by hunk, rewound to a checkpoint, or isolated in a git
worktree. Sessions can be pinned, archived and filed into folders; <kbd>Ctrl</kbd>+<kbd>K</kbd>
opens the command palette, and prompt templates with placeholders save typing.
<table>
<tr>
<td width="50%" valign="top">
<td width="40%" valign="top">
<img src="docs/images/mobile.png" alt="CodeCraft on a phone: a session with a question card offering three options" width="100%"><br>
<sub><b>Mobile:</b> answer questions and approve changes from your phone.</sub>
<sub><b>Mobile:</b> answer questions and approve changes from your phone. Share links and text from other apps into a chat.</sub>
</td>
<td width="50%" valign="top">
<img src="docs/images/settings.png" alt="Settings: providers with models, context sizes and prices per million tokens" width="100%"><br>
<sub><b>Settings:</b> providers, models, prices, MCP, permissions and users – all in the UI.</sub>
<td width="60%" valign="top">
<img src="docs/images/settings.png" alt="Settings: providers with model counts and their status (reachable, API key rejected)" width="100%"><br>
<sub><b>Settings:</b> providers, models, prices, MCP, permissions, users, templates and backups – all in the UI.</sub>
</td>
</tr>
</table>
@@ -92,11 +132,13 @@ installed app; the agent keeps working when you close the tab.
|---|---|
| **build** | Full access: implement, edit, run. |
| **plan** | Read-only: investigate, ask, and propose a step-by-step plan. One click switches to build. |
| **craft** | Study a target, build your own version, check it visually, refine. Websites are captured at several screen widths in a headless browser and compared with the build (similarity per page and width). *Clean room* uses only what a visitor sees; *deep mode* may read the page source. |
| **craft** | Study a target – a website, app, game or old program – and build your own version, check it visually and refine. Websites are captured at several screen widths in a headless browser and compared with the build. *Clean room* uses only what a visitor sees; *deep mode* may read the source. |
| *custom* | Your own modes and subagents – in the UI, the config file or as Markdown in `.codecraft/agents` / `.claude/agents`. |
Projects keep working the way they do in Claude Code and opencode: `AGENTS.md`, `CLAUDE.md`,
slash commands in `.claude/commands` and skills in `.claude/skills` are picked up automatically.
The agent keeps notes about a project in `.codecraft/memory.md`; your personal memory applies to
every project.
## Models
@@ -105,76 +147,108 @@ output limit, reasoning effort, extra request options and prices per million tok
- **Several models per chat:** switch the model at any time, give modes a fixed model, and
run subagents on other models – e.g. a coding model on one GPU host and a small model that
writes documentation and translations in the background on another.
writes documentation in the background on another.
- **Fallback:** if a host is unreachable or its budget is used up, the request goes to the
model's fallback.
- **Concurrency limits:** `max_concurrency` per host or model queues requests for servers that
can only process one at a time; `max_parallel` limits instances of a subagent. Waiting time
is shown in the chat and never counted as model latency.
- **Background subagents:** the agent starts them with `background = true`, keeps working,
and receives their result as a message when they finish.
process one at a time; waiting time is shown and never counted as model latency.
- **Status:** every five minutes each provider's model list is fetched (no tokens used), so
you see at a glance which hosts answer and which keys are rejected.
## Users
## Terminal client
`codecraft` is a full-screen terminal client in the style of Claude Code and opencode. The agent
loop, the tools and the chat history run **on your machine**, in the current folder. Signed in to
a CodeCraft server, it uses the server's models, keys, budgets, modes, rules, skills, MCP tools and
your theme, and the server counts usage and costs. Without a server, a guided setup connects
Anthropic, OpenAI, Gemini, OpenRouter, opencode or a local model server (Ollama, LM Studio,
llama.cpp, vLLM – detected automatically); both can be mixed.
```sh
cargo install --locked --git https://git.familie-zink.org/zink/codecraft codecraft-cli
codecraft login # server URL, user name, password → creates an API token
codecraft # start in the current folder; /help lists the commands
```
There are no prebuilt binaries yet, so the client is installed from source (needs a Rust
toolchain). A server that has binaries in `CODECRAFT_CLI_DIR` (`codecraft-linux-x86_64`,
`codecraft-linux-aarch64`) also offers `curl -fsSL https://<your-server>/cli/install.sh | sh`
and `codecraft update`.
## Automations
An automation is a Markdown file with a cron schedule in its front matter
(`.codecraft/jobs/<name>.md`). Each run is a normal chat session, so you can read and continue
it; if it needs a permission, you get a push notification. Ask an agent in any chat to set one
up, start from a template (dependency check, security review of recent commits, test suite
health, daily summary, TODO report, documentation freshness) or write the file yourself.
**Webhooks** start an automation from outside, e.g. on every push: the request is checked with a
shared secret or a Gitea/GitHub HMAC signature, and its JSON payload is handed to the agent.
## Integrations
- **API tokens** (*Settings → Account*) with full or read-only scope for scripts and the terminal client.
- **Prometheus:** set `server.metrics_token` and scrape `GET /metrics` with
`Authorization: Bearer <token>` – requests, errors, tokens, cost and time per model, provider
status, sessions, pending permissions.
- **JSON logs:** `CODECRAFT_LOG_FORMAT=json` writes one JSON object per line.
- **Backups:** daily at 03:00 into `/data/backups` (the last 30 are kept), optionally copied to
any S3-compatible bucket (AWS, MinIO, Garage, Backblaze B2, Hetzner). *Settings → Audit*
shows them, creates one on demand and downloads them.
- **Health:** `GET /api/health` for monitoring, with version and commit.
## Users and security
- Local accounts (Argon2 passwords) and single sign-on via OpenID Connect (Authentik, Authelia,
Keycloak, …) with optional admin and access groups.
- **Admins** manage providers, MCP, permissions, users and shared folders and see all statistics.
**Users** see their own sessions and statistics.
- Every user works in `<workspace>/<username>`; admins can share additional folders with
selected users. Sessions are private and can be shared read-only.
> [!NOTE]
> File tools are confined to a user's folders. Shell commands run in the shared container and
> are **not** sandboxed per user – only give accounts to people you trust with that container.
- Every user works in `<workspace>/<username>`; admins can share additional folders. Sessions
are private and can be shared read-only. An audit log records sign-ins, permissions and
configuration changes.
- Shell commands of non-admin users run in a **bubblewrap sandbox**: read-only system, only
their folders writable, own home and processes, no server environment. It needs the security
options in the compose file; without them non-admins cannot run shell commands.
- The browser tool reaches the internet and `localhost`, never addresses in private networks.
## Statistics
<p align="center">
<img src="docs/images/stats.png" alt="The statistics dashboard: cost and token tiles, cost per day stacked by model, tokens per day, and an activity heatmap by weekday and hour" width="100%">
<img src="docs/images/stats.png" alt="The statistics dashboard: cost and token tiles, cost per day stacked by model, tokens per day, and an activity heatmap of the last 14 days" width="100%">
</p>
Every model request is stored with input, output and cache tokens, time to first token,
prefill and output speed, and its cost at the price configured at that moment. The dashboard
shows totals, cost per day by model, tokens per day, a weekday × hour heatmap, and tables per
model, provider, mode, user and session – each chart also as a table.
## Get started
```sh
git clone <this repository> codecraft && cd codecraft
cp .env.example .env # workspace path, provider keys, optional first admin
docker compose up -d --build
docker compose logs codecraft # shows the one-time setup code for the first admin
```
All state – configuration, database, the agent's home directory – lives in the Docker volume
`codecraft-data`; rebuilding or recreating the container keeps it. Your projects are mounted
from `WORKSPACE`.
The port is bound to `127.0.0.1` by default. Put a TLS reverse proxy in front of it (enable
WebSocket support) and set `auth.public_url` – installing the PWA requires HTTPS.
shows totals, cost per day by model, tokens per day, an activity heatmap of the last 14 days,
and tables per model, provider, mode, user and session – each chart also as a table. Turn on
the daily cost summary to get a push notification every evening.
## Configuration
One commented TOML file, `/data/config.toml` in the volume, created from
[`config.example.toml`](config.example.toml) on first start. The settings page edits it in
place and keeps your comments. Secrets belong in the environment and are referenced as
[`config.example.toml`](config.example.toml) on first start. The settings pages edit it in
place and keep your comments. Secrets belong in the environment and are referenced as
`${NAME}`.
| Section | Purpose |
|---|---|
| `[server]` | workspace, default and small model, currency, auto-compaction, subagent limit |
| `[providers.<name>]` | `kind = "anthropic" \| "openai"`, `base_url`, `api_key`, `max_concurrency`, `models` |
| `[server]` | workspace, default and small model, currency, auto-compaction, subagent limit, `metrics_token` |
| `[providers.<name>]` | `kind = "anthropic" \| "openai"`, `base_url`, `api_key`, `max_concurrency`, `models` (with prices and `fallback`) |
| `[mcp.<name>]` | `type = "stdio"` (command, args, env) or `"http"` (url, headers) |
| `[permissions]` | `allow` / `ask` / `deny` per tool (globs like `mcp__*`); `bash_rules` for commands |
| `[agents.<name>]` | modes and subagents: model, tools, `max_parallel`, prompt |
| `[auth]`, `[auth.oidc]` | sign-in, public URL, single sign-on |
| `[sandbox]` | shell sandbox for non-admins (`auto`, `always`, `off`) |
| `[backup]`, `[backup.s3]` | daily backups, retention, S3 target |
| `[craft]` | headless browser, screen widths, clean room |
Compound shell commands (`&&`, `;`, `|`) are only auto-allowed when every part is allowed.
## Themes
Pick a **base theme** in *Settings → Interface* and switch **light / dark / auto** there or with
the ◐ button in the sidebar (auto follows the system preference). Every base theme has a dark and
Pick a **base theme** in *Settings → General* and switch **light / dark / auto** there or with
the theme button in the sidebar (auto follows the system preference). Every base theme has a dark and
a light variant. The palettes come from [zink/trilium-themes](https://git.familie-zink.org/zink/trilium-themes)
(MIT, see [`web/src/themes/LICENSE-trilium-themes`](web/src/themes/LICENSE-trilium-themes)), which
in turn are based on:
@@ -224,33 +298,44 @@ cd server && CODECRAFT_CONFIG=../data/config.toml cargo run
# frontend with hot reload, proxies /api to 127.0.0.1:8787
cd web && npm install && npm run dev
# terminal client
cargo run -p codecraft-cli
```
Tests: `cd server && cargo test` · type check: `cd web && npx tsc --noEmit`.
Tests: `cargo test --workspace` · type check: `cd web && npx tsc --noEmit`.
```
core/ shared crate: types, config, providers, permissions, prompts
server/ Rust (axum, tokio)
runner.rs agent loop: streaming, tools, permissions, subagents, compaction
provider/ Anthropic and OpenAI-compatible streaming clients, concurrency slots
tools/ built-in tools (files, shell, web, agent, craft)
tools/ built-in tools (files, shell, web, browser, agent, craft)
mcp.rs MCP client (stdio, Streamable HTTP, elicitation)
auth.rs users, sessions, OpenID Connect
prompts.rs modes, system prompt, AGENTS.md, commands, skills
jobs.rs automations and webhooks
auth.rs users, sessions, API tokens, OpenID Connect
cli/ terminal client (ratatui)
web/ React + Vite PWA
src/components chat, composer, cards, settings, statistics
src/themes CSS themes
src/i18n English (reference) and German
```
The Docker build cross-compiles the server with
[cargo-zigbuild](https://github.com/rust-cross/cargo-zigbuild), so a multi-arch image builds
quickly on either architecture:
`docker buildx build --platform linux/amd64,linux/arm64 -t <registry>/codecraft:<version> --push .`
Translations: copy `web/src/i18n/en.ts`, translate the values and register the language in
`web/src/i18n/index.ts` – the type checker reports missing keys.
## Status
Early alpha. Planned next:
Early, but in daily use. See the [changelog](CHANGELOG.md). Planned next:
- Per-user sandboxes for shell commands
- File checkpoints and undo, background shells, `@file` mentions
- Prebuilt terminal client binaries (Linux, macOS, Windows)
- MCP OAuth, resources and prompts
- Hooks before/after tool calls
- Image generation tools (fal.ai) and the OpenAI Responses API
- The OpenAI Responses API
## License
[MIT](LICENSE) © Richard Zink. The theme palettes keep the licenses listed under [Themes](#themes).