Users, file manager, image generation, budgets and agent workflow

- User management: local accounts (Argon2) and OpenID Connect, admin/user
  roles, per-user folders plus admin-shared folders, read-only session
  sharing, event filtering per user
- File manager with CodeMirror editor and git client (status, diff,
  stage, commit, branches, fetch/pull/push, log, clone/init)
- Image generation via fal.ai: generate_image tool and image page
- Budgets: monthly limits per provider, provider balances/costs
  (OpenRouter, Anthropic admin cost report, fal.ai), price discovery
- Subagents on other models, background tasks, concurrency limits per
  host/model/subagent
- MCP tools loaded on demand (mcp_search/mcp_call), read-only hints
- Permission mode "auto", safe read-only commands always allowed
- Persistent message queue with attachments, deletable
- Live reasoning incl. <think> tags, activity animations, CSS themes,
  mobile layout, statistics per user, upload size handling
- Docker: named volume for state, localhost-bound port

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-08 16:54:08 +01:00
1 parent f3a2fe3816
commit 49262c612c
70 files changed
+8495 -714

No files matched your search

+99 -11
View File
@@ -24,10 +24,6 @@ workspace = "/workspace"
# Where sessions (SQLite) and runtime state are stored.
data_dir = "/data"
# Access token for the web UI and API. Leave empty to disable auth (only do
# this on localhost!). Recommended: auth_token = "${CODECRAFT_TOKEN}"
auth_token = "${CODECRAFT_TOKEN}"
# Default model for new sessions, as "<provider>/<model>".
default_model = "anthropic/claude-sonnet-5-5"
@@ -37,6 +33,14 @@ small_model = "anthropic/claude-haiku-5-5"
# Compact the conversation automatically when the context is this full (0.0–1.0).
auto_compact_threshold = 0.85
# Max. subagents running at the same time (all sessions). Additionally, each
# subagent can be limited with max_parallel, and each provider/model with
# max_concurrency (see below).
max_parallel_subagents = 4
# MCP servers with more tools than this are loaded on demand (see [mcp.*] load).
mcp_direct_limit = 15
# Currency label for the cost statistics (prices below are in this currency).
currency = "USD"
@@ -57,6 +61,13 @@ currency = "USD"
# Cache prices default to input_price when omitted. Costs are stored per request,
# so changing a price only affects future requests.
#
# Concurrency: max_concurrency limits simultaneous requests – on the provider
# (= the host) and/or per model. Requests beyond the limit wait in a queue,
# e.g. for self-hosted models that can only process one request at a time.
#
# options: extra request body fields sent as-is, e.g.
# options = { temperature = 0.5, reasoning_budget_tokens = 5000 }
#
# Authentication: by default "Authorization: Bearer <api_key>" (openai) or
# "x-api-key: <api_key>" (anthropic). Override with auth_header / auth_prefix.
# Extra static headers: headers = { "X-Foo" = "bar" }
@@ -112,6 +123,7 @@ enabled = false
kind = "openai"
base_url = "http://host.docker.internal:11434/v1"
api_key = ""
max_concurrency = 1 # one request at a time on this host
models = []
enabled = false
@@ -122,6 +134,10 @@ enabled = false
# type = "stdio" → command + args (+ env), started as a child process
# type = "http" → Streamable HTTP endpoint (url + optional headers)
# Tools appear to the model as mcp__<server>__<tool>.
# load = "auto" (default) | "always" | "on_demand": servers with many tools
# (more than server.mcp_direct_limit) are not sent with every request; the
# model finds them with mcp_search and calls them with mcp_call. This keeps
# requests small – important for self-hosted models.
# MCP servers may ask you questions (elicitation); they show up in the UI.
# -----------------------------------------------------------------------------
@@ -163,6 +179,7 @@ bash = "ask"
web_fetch = "ask"
browser_snapshot = "allow"
image_compare = "allow"
generate_image = "ask" # costs money per image
"mcp__*" = "ask"
# Shell command patterns (glob, matched against the full command). First match wins.
@@ -185,14 +202,85 @@ image_compare = "allow"
# mode switcher, mode = "subagent" is only available through the task tool.
# -----------------------------------------------------------------------------
# [agents.reviewer]
# Subagents can run on a different model (and host) than the chat, and in the
# background: the main agent calls task(background = true), keeps working and
# receives the result as a message when the subagent is done.
# [agents.writer]
# mode = "subagent"
# description = "Reviews code changes for bugs and style issues."
# model = "anthropic/claude-opus-5-5" # optional, otherwise session model
# tools = ["read", "glob", "grep", "bash"] # optional, default: all tools
# prompt = """
# You are a meticulous code reviewer. ...
# """
# description = "Writes documentation, summaries, guides and translations."
# model = "local/qwen3-4b" # optional, otherwise the session model
# tools = ["read", "glob", "grep"] # optional, default: all tools
# max_parallel = 1 # optional, instances at the same time
# prompt = '''
# You are a technical writer. Write clear, well-structured text.
# '''
# -----------------------------------------------------------------------------
# Image generation (fal.ai)
# -----------------------------------------------------------------------------
# Agents get the tool generate_image; the "Images" page creates images manually.
# Images are saved in the project (output_dir) and listed in a gallery.
# Model ids: https://fal.ai/models – price is per image (for the statistics).
# size_param: "image_size" (FLUX-style presets, default) or "aspect_ratio" ("16:9").
# -----------------------------------------------------------------------------
[images]
enabled = false
base_url = "https://fal.run"
api_key = "${FAL_KEY}"
default_model = "fal-ai/flux/schnell"
output_dir = "generated"
models = [
{ id = "fal-ai/flux/schnell", name = "FLUX.1 schnell – fast", price = 0.003 },
{ id = "fal-ai/flux-2-pro", name = "FLUX.2 pro" },
{ id = "fal-ai/ideogram/v3", name = "Ideogram 3 – text in images", size_param = "aspect_ratio" },
{ id = "fal-ai/recraft/v4/pro/text-to-image", name = "Recraft V4 pro – design" },
]
# -----------------------------------------------------------------------------
# Users & sign-in
# -----------------------------------------------------------------------------
# Users are managed in the web UI (Settings → Users). On first start without
# users, the server prints a one-time setup code to its log; use it in the UI
# to create the first admin – or set CODECRAFT_ADMIN_USER and
# CODECRAFT_ADMIN_PASSWORD in the environment.
#
# Every user works in their own directory <workspace>/<username>; admins can
# use the whole workspace. Note: file tools are confined to that directory,
# but shell commands run in the shared container and are not sandboxed.
# -----------------------------------------------------------------------------
[auth]
# Lifetime of a login in days.
session_days = 30
# External URL of this server – required for single sign-on (OIDC redirects).
public_url = ""
# Secure cookies: "auto" (when served via https), "true" or "false".
cookie_secure = "auto"
# Single sign-on via OpenID Connect (Authentik, Authelia, Keycloak, ...).
# Redirect URI to register at the IdP: <public_url>/api/auth/oidc/callback
[auth.oidc]
enabled = false
issuer = "https://auth.example.org/application/o/codecraft/"
client_id = "codecraft"
client_secret = "${OIDC_CLIENT_SECRET}"
scopes = ["openid", "profile", "email", "groups"]
username_claim = "preferred_username"
groups_claim = "groups"
# Members of this group are admins; empty = manage roles in CodeCraft.
admin_group = ""
# Only members of this group may sign in; empty = no restriction.
allowed_group = ""
# Create users automatically on their first sign-in.
auto_create = true
# Link a sign-in to an existing local user with the same username.
# Only enable this if you trust the usernames of your IdP.
link_by_username = false
button_label = "Single sign-on"
# -----------------------------------------------------------------------------