Automations
- Job files hold only the instructions; name, schedule, mode, model, approval
mode and time limit are settings in the database (jobs.settings). Existing
files are adopted on start-up (frontmatter into the database and removed from
the file); plain Markdown files registered later get default settings and stay
switched off until scheduled.
- New automation: name, project and a starting point (blank example structure or
a template) create .codecraft/jobs/<name>.md and open the editor: settings with
a graphical cron builder (next runs in server time via /jobs/schedule), the
instructions in the Markdown editor and an assistant chat
(POST /jobs/{id}/assistant) whose model edits the file; the editor reloads it
after each turn and warns about conflicts with unsaved edits.
- The schedule tool writes prompt-only files with settings.
Chat list
- Folders and projects keep a user-defined order and can be pinned (drag and
drop, or the group's menu), stored per user via /account/sidebar. A new
message moves the chat to the top of its group, no longer the project itself.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Automations: the approval mode is a selection in the list; PATCH /jobs/{id}
writes permission_mode into the job file's frontmatter (rest of the file
unchanged, invalid modes rejected). "Allow everything" lets nightly runs work
without waiting for approvals via Telegram until the timeout.
- Session.telegram_quiet: approvals and questions of a chat (and its subagents)
are not sent to Telegram; the chat open in Telegram always reports. Toggle in
the chat's ⋯ menu when a bot is paired. New chats from the web UI and
automation runs start quiet; chats started from Telegram and existing chats
keep reporting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Images of messages (pasted images, screenshots, generated images) were base64
inside the message JSON, so opening a chat downloaded all of them at once
(66 MB for a chat with 120 screenshots). They now live in a `blobs` table,
addressed by SHA-256; messages keep a reference (blob, size). The UI loads
them from /api/blobs/<hash> lazily with an immutable cache header, the runner
fills the bytes in before model requests, JSON exports stay self-contained.
- Store::add_message moves inline images out; large opaque PNGs become JPEG
(q85) when smaller. Older chats are converted once at start-up in the
background, unused images are removed (also after deleting a chat) and the
database is vacuumed when that frees 32 MB or more.
- Responses are compressed with gzip/brotli (not images, SSE streams or
binary downloads).
Example (copy of production): chat load 66 MB -> 1.5 MB (370 KB brotli),
database 90 MB -> 27 MB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>