HDiQ|=h%LrMQ
z1~_3iCb&FZmfLl#rQ%i^pPVhOR=Rqn!F|>X`mDh%K}f}`eJ$)=u@IV%pb^V`-lNYhq}pZA&1r-3ux0%~};yIl*?~)yg4%bQ~8KIzzlKra!5mctTV}
zytH*7^S5~`vc5%=hoBkg_}vlZEJ8STtbv26*lHznTEOLt2DW?IP!~tCRE|sncec2F
z<%SLVT%Ee$RS?sP`LG<%AKjk$KWZR~#8Bhud6sUPxqjv)u=6k~XQTb6~BEXph|Vl??f<+`W`{b96~8G?Y(!
zp}nNw0cm)0snn!)h((BZcH}2GNY6w+(*tEt+D}jW->N->`Rr&B1fR;+&7|QOhjyQU
zCkZlR1yGCT%DNHbv}Qg%p@V#r;BdWi-EYY3`&5r1QZViN&ZQJxLo!xuv9AR5g-5N2
z${bR67@{90e=X!U0T+da8*a6I8`aC^xG`qcWzVjk;pubAfn6cCb@bYcCuKwlq@g#q^^=35M*OrVe
zFInHHUHwVkrai3C-zN6Kd~@n35_YvdoJMm{gLvMQ?gCRZ$K`>d41;hg;?Pg>(w^br
zRY+y`ct>96fSQ@=O5T;JUHr~f6WjUsiVtddU#H(^Kvg
zZN30WF8Fo14A|@Dq=HMB;VFWOh
Dd#fOY
diff --git a/mkdocs/docs/assets/craftbot_logo_text_no_border_light.png b/mkdocs/docs/assets/craftbot_logo_text_no_border_light.png
deleted file mode 100644
index 4874b22e365417a069dccebc12487d88ad91d555..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 15557
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
diff --git a/mkdocs/docs/assets/logo.png b/mkdocs/docs/assets/logo.png
deleted file mode 100644
index b7cf181a2e07ad9c453802dacd4409b83558afa5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1273
zcmVPx(vq?ljR9HuymurX>Wf;eQ&zyDbCL-w0Y?x6bWMLO0Ga}bZWu)hv48sc;MM^~m
zVnu6Lp;)ZE1T9u-^dXFF!F6UMCCUp(W#twWrTIYu)0yKU3t5)#nI~t??z!#EnR7ZH
z&pgln{k`*CN2v3s_qAS0%Ab!g8LOg
zWgWg}@Qqug=fvT_wgiy1g7_>*5cnN*1I;70NZ0YR6#z46Vzjjscm}wxrjBv|$88hv
zLx8ZEsWp_s~zQ)QrSj$_$&-UQ2@wVLEPuW2rIs>
zk{<7^sOJh2Rp**97a{T?&=gZiKVo}RMAPO~7;-e0R<%_YvptAukcOHH(SVKBT~@?OM%j(
zkWY)#cObrW4jY-4WS{OMgUF&W9kG@e4|BrPV^<&HvnMvgN#lR9DJ@A
zYDu@3OR{eS;2V(Jk^~2z=dj(@pwlJUi_UGGM9N<~ED1$=vE4O8an$?Gm8fh?5)7X!
zo#MEq-jT6ZAUZq3cdcmUCR0@ix=eO@?}wTXj=z|51BWgQqDcu5IZ^{R$&S90h3aXU
z1IDh%HZSx_xXX#W8Y6lH)154vIUkD6HLqp_yHS}KW1kBqi`d@5vJ%{j&=zg4?}?_Z
z>oNE#b`U8qi{lmnH8XY;(iC*hpcPLD{S*(Oi}U#o`RtTiEZwyAFa{sQzcK&b!C_<`
z0J$T^FpscAc9xci;sJ9W8gYG|0SJ%8|TBjo#y!uOGbdS;OPAmY-Gt;CbXvr}@
z9YE!IM!FlMi+oZdYPw}9hVgEV!-Ea&NwIUA3IJidG`~P(R)YBV;CIlRbE-i?jkGzF
z6z!og1yB(b)OlUrY{7yoG%_6OYx5!+8=0EaR1%cc9&fvC&W97ehZ
zgG1&*gy#^su_#aL3Ayc$xd00000NkvXXu0mjfU#U}5
diff --git a/mkdocs/docs/core/commands/builtin.md b/mkdocs/docs/core/commands/builtin.md
deleted file mode 100644
index c9fa7e01..00000000
--- a/mkdocs/docs/core/commands/builtin.md
+++ /dev/null
@@ -1,187 +0,0 @@
-# Built-in commands
-
-Every slash command shipped with CraftBot, with its aliases, subcommands, and behavior. All of them work in both [interfaces](../interfaces/index.md). The two marked otherwise say so.
-
-At a glance:
-
-| Command | Aliases | What it does |
-|---|---|---|
-| [`/help [command]`](#help) | `/h`, `/?` | List commands, or detail one |
-| [`/clear`](#clear) | `/cls` | Clear the chat and action log |
-| [`/clear-tasks`](#clear-tasks) | `/cleartasks` | Remove finished tasks from the task panel |
-| [`/reset`](#reset) | (none) | Reset agent state and clear history |
-| [`/exit`](#exit) | `/quit`, `/q` | Shut down CraftBot |
-| [`/menu`](#menu) | (none) | Open the settings menu (browser only) |
-| [`/provider [name] [key]`](#provider) | (none) | View or change the LLM provider |
-| [`/mcp `](#mcp) | (none) | Manage MCP servers |
-| [`/skill `](#skill) | (none) | Manage skills |
-| [`/cred `](#cred) | (none) | Credentials and integration status |
-| [`/update [--check]`](#update) | `/upgrade` | Check for and install updates |
-| [`/tokens`](#tokens) | (none) | Show this session's token usage |
-
-Beyond these, the registry also holds [integration commands](#integration-commands) (`/gmail`, `/slack`, ...) and [skill commands](#skill-commands) (`/pdf`, `/docx`, ...), covered at the end.
-
-## /help
-
-```
-/help # list all commands with descriptions and aliases
-/help mcp # usage, subcommands, and examples for one command
-```
-
-The leading slash on the argument is optional (`/help mcp` and `/help /mcp` both work). Skill shortcuts are hidden from the main list to keep it short. `/skill list` shows them.
-
-## /clear
-
-Clears the chat transcript and the action log in the current interface, and also drops the agent's persisted conversation memory, so a restart won't resurrect the cleared chat. Task history and dashboard data are unaffected. Use it when the conversation is cluttered. Use [`/reset`](#reset) when the *agent* needs a fresh start.
-
-## /clear-tasks
-
-Removes tasks whose status is completed, failed, or cancelled from the task panel, along with their child actions. Running and waiting tasks are preserved, and dashboard usage data and task history are untouched. Requires an action panel, so it's effectively a browser command. In the CLI it reports that no action panel is available.
-
-## /reset
-
-Resets the agent to its initial state: clears the current task, action history, and conversation context, and wipes the chat view. Saved settings and credentials are **not** affected. Feedback arrives as system messages while the reset runs in the background.
-
-## /exit
-
-Stops the agent cleanly and ends the session. In [service mode](../../start/service-mode.md) the service manager may restart it. Use `python craftbot.py stop` to keep it down.
-
-## /menu
-
-Opens the settings menu. Browser only. In the CLI it points you to `/help` instead. (In practice you'll click **Settings** in the sidebar; the command exists mainly for keyboard-first use.)
-
-## /provider
-
-View or switch the LLM provider without opening settings.
-
-```
-/provider # show current provider and masked API key
-/provider anthropic # switch provider (keeps any stored key)
-/provider anthropic sk-ant-... # switch and set the key in one line
-```
-
-Accepted names:
-
-| Name | Provider | Key |
-|---|---|---|
-| `openai` | OpenAI | `OPENAI_API_KEY` |
-| `gemini` | Google Gemini | `GOOGLE_API_KEY` |
-| `anthropic` | Anthropic | `ANTHROPIC_API_KEY` |
-| `byteplus` | BytePlus | `BYTEPLUS_API_KEY` |
-| `deepseek` | DeepSeek | `DEEPSEEK_API_KEY` |
-| `grok` | Grok (xAI) | `XAI_API_KEY` |
-| `glm` | Z.ai (GLM) | `ZAI_API_KEY` |
-| `fugu` | Sakana (Fugu) | `SAKANA_API_KEY` |
-| `openrouter` | OpenRouter | `OPENROUTER_API_KEY` |
-| `remote` | Ollama (local) | none |
-
-The change is saved to `settings.json` and the LLM reinitializes immediately, with no restart. Model selection, base URLs, and subscription login live in **Settings → Model**; see [LLM providers](../providers/llm.md).
-
-## /mcp
-
-Manage [MCP servers](../../integrations/mcp.md). `/mcp` with no arguments prints usage.
-
-| Subcommand | Does |
-|---|---|
-| `list [--all]` | List enabled servers; `--all` includes disabled ones |
-| `add --transport stdio -- ` | Add a stdio server (everything after `--` is the launch command) |
-| `add --transport http ` | Add an HTTP server |
-| `add-json ''` | Add a server from a JSON config block |
-| `remove ` | Remove a server |
-| `enable ` / `disable ` | Toggle a server without removing it |
-| `env ` | Set an environment variable for a server |
-
-```
-/mcp add myserver --transport stdio -- python server.py
-/mcp add remote-tools --transport http https://example.com/mcp
-/mcp env myserver API_KEY my-secret-key
-/mcp list --all
-```
-
-The browser's **Settings → MCPs** page edits the same configuration.
-
-## /skill
-
-Manage [skills](../concepts/skills.md). `/skill` with no arguments prints usage.
-
-| Subcommand | Does |
-|---|---|
-| `list [--all]` | List enabled skills; `--all` includes disabled ones |
-| `info ` | Description, version, author, path, and the skill's actions |
-| `enable ` / `disable ` | Toggle a skill; this also registers/unregisters its slash command |
-| `install ` | Install from a local directory |
-| `install ` | Install from a GitHub/GitLab URL |
-| `create [description]` | Scaffold a new skill |
-| `remove ` | Remove a skill |
-| `reload` | Re-scan skills from disk |
-| `dirs` | Show the directories scanned for skills |
-
-```
-/skill info pdf
-/skill enable cli-anything
-/skill install https://github.com/user/skill.git
-/skill create my_skill "My custom skill"
-```
-
-## /cred
-
-Read-only overview of credentials and integrations. Connecting happens with the [per-integration commands](#integration-commands) or **Settings → Integrations**.
-
-| Subcommand | Does |
-|---|---|
-| `list` | Every integration with connected / not connected |
-| `status` | Same, with account names for connected integrations and a connected count |
-| `integrations` | Every available integration with its `/command` and description |
-
-## /update
-
-```
-/update # check GitHub for a newer version and install it
-/update --check # check only, don't install
-```
-
-An update pulls the latest code, installs dependencies, and restarts CraftBot automatically, streaming progress as system messages. If you're already current, it says so.
-
-## /tokens
-
-Prints the cumulative token usage of the chat it's typed in, as a system message:
-
-```
-Session token usage
- Input: 79,022
- Cached: 312,455
- Output: 5,770
- Total: 84,792
-```
-
-**Input** is genuinely new prompt tokens (cache reads excluded), **Cached** is prompt tokens served from the provider's cache, and **Total** is Input + Output. Totals accumulate across every run in the session and survive restarts and [`/clear`](#clear) (clearing wipes the conversation, not the session's lifetime counters). A brand-new chat that hasn't sent a message yet reports zeros. Sessions created before this command existed start counting from their next run.
-
-## Integration commands
-
-Every available [integration](../../integrations/index.md) registers its own command named after itself: `/gmail`, `/slack`, `/discord`, `/telegram_bot`, `/notion`, and so on (run `/cred integrations` for the live list). Each supports:
-
-```
-/ # help, including integration-specific subcommands
-/ connect # start the connect flow (token, OAuth, or interactive/QR)
-/ disconnect
-/ status # connection state and accounts
-```
-
-Token-based integrations take their credentials as arguments, like `/telegram_bot connect ` (running `connect` bare tells you which fields it needs). OAuth ones open the provider's flow. Interactive ones (like WhatsApp Web) walk you through it. Some handlers add extra subcommands (QR login, invites), listed in that integration's help. Details per service are on the [integration pages](../../integrations/index.md).
-
-## Skill commands
-
-Every **enabled** skill is also a slash command: `/pdf`, `/docx`, `/xlsx`, and whatever else you've enabled. These don't run UI code. They hand your text to the agent with that skill pre-selected:
-
-```
-/pdf merge report-a.pdf and report-b.pdf into final.pdf
-```
-
-Arguments flow into the skill's instructions through `$ARGUMENTS` substitution (skills can also grab positional pieces with `$ARGUMENTS[0]`, `$1`, ...). Invoked bare, the agent asks what you need. Enabling or disabling a skill registers or removes its command immediately, and a skill whose name collides with an existing command is skipped. They're hidden from `/help`. See them with `/skill list` or the browser's `/` autocomplete.
-
-## Related
-
-- [Commands overview](index.md): how dispatch works
-- [CLI-anything](cli-anything.md): the desktop-app automation skill
-- [UI layer](../interfaces/ui-layer.md): the registry these commands live in
-- [Credentials](../../integrations/credentials.md): where connected secrets are stored
diff --git a/mkdocs/docs/core/commands/cli-anything.md b/mkdocs/docs/core/commands/cli-anything.md
deleted file mode 100644
index e381992f..00000000
--- a/mkdocs/docs/core/commands/cli-anything.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# CLI-anything
-
-CLI-anything is a bundled [skill](../concepts/skills.md) that lets the agent drive real desktop applications (GIMP, Blender, LibreOffice, Audacity, and two dozen others) from the command line, on Windows, macOS, and Linux. You describe the task ("convert report.docx to PDF", "resize photo.jpg to 1920×1080"). The agent picks the right app, installs it if it's missing, runs it, and reports the result. You never name the app, and you never run a command yourself.
-
-!!! note "Disabled by default"
- CLI-anything ships in the `disabled_skills` list of `app/config/skills_config.json`. Turn it on with `/skill enable cli-anything` or in **Settings → Skills**. Once enabled, it activates automatically whenever a task matches a supported app. Like any enabled skill, it also gets a `/cli-anything` slash command.
-
-## What it can automate
-
-Each app is driven through a cross-platform harness command, `cli-anything-`, so the agent never touches platform-specific binaries or paths:
-
-| Task | App | Harness |
-|---|---|---|
-| Resize / crop / filter / convert images | GIMP | `cli-anything-gimp` |
-| SVG and vector graphics, logo export | Inkscape | `cli-anything-inkscape` |
-| Digital painting, `.kra` export | Krita | `cli-anything-krita` |
-| DOCX / XLSX / PPTX → PDF, office macros | LibreOffice | `cli-anything-libreoffice` |
-| Trim / convert / export audio | Audacity | `cli-anything-audacity` |
-| Render and edit video | Kdenlive, Shotcut | `cli-anything-kdenlive`, `cli-anything-shotcut` |
-| Screen recording and streaming | OBS Studio | `cli-anything-obs` |
-| 3D modeling and rendering, `.blend` files | Blender | `cli-anything-blender` |
-| Diagrams (`.drawio`) | Draw.io | `cli-anything-draw-io` |
-| Render Mermaid diagram code | Mermaid | `cli-anything-mermaid` |
-| AI image generation | Stable Diffusion, ComfyUI | `cli-anything-stable-diffusion`, `cli-anything-comfyui` |
-| Run a local LLM | Ollama | `cli-anything-ollama` |
-| AI content generation | AnyGen | `cli-anything-anygen` |
-| AI research / PDF summarization | NotebookLM | `cli-anything-notebooklm` |
-| Execute Jupyter notebooks | JupyterLab | `cli-anything-jupyterlab` |
-| CAD, `.fcstd` → STL/STEP | FreeCAD | `cli-anything-freecad` |
-| GIS maps, `.qgz` export | QGIS | `cli-anything-qgis` |
-| Monitoring dashboards | Grafana | `cli-anything-grafana` |
-| Git hosting, repo creation | Gitea, GitLab | `cli-anything-gitea` |
-| CI/CD pipelines | Jenkins | `cli-anything-jenkins` |
-| Cloud file sync | NextCloud | `cli-anything-nextcloud` |
-| Network-wide ad blocking | AdGuard Home | `cli-anything-adguard-home` |
-| Video conferencing | Zoom | `cli-anything-zoom` |
-| Knowledge outlines | Mubu | `cli-anything-mubu` |
-
-Ask the agent "what can cli-anything do" and it replies with this catalogue directly, without running anything.
-
-## How routing works
-
-The skill's instructions (`skills/cli-anything/SKILL.md`) contain a routing table mapping task descriptions to apps. When the skill is enabled and your request matches ("convert this DOCX", "render this .blend file") the agent selects the app and follows a fixed execution flow:
-
-1. **Detect the OS** (Windows / macOS / Linux).
-2. **Check the app is installed** (`gimp --version` and equivalents).
-3. **Install it if missing**, one attempt only, via the platform's package manager: `winget` on Windows, `brew` on macOS, `apt-get` on Linux. A few apps use their own path instead (ComfyUI and Stable Diffusion via `git clone`, Mermaid via npm, JupyterLab via pip, Ollama on Linux via its install script; web apps like Mubu and NotebookLM need no install and are driven through the browser-automation skill).
-4. **Check the harness** (`cli-anything- --version`); if missing, install `cli-anything-hub` via pip and pull the harness with `cli-hub install `. If the hub fails, the agent generates a minimal harness itself.
-5. **Run the task** using only harness commands, for example:
-
- ```
- cli-anything-gimp image resize input.jpg output.jpg 1920 1080
- cli-anything-libreoffice convert doc.docx output.pdf
- cli-anything-blender render scene.blend --output frames/ --format PNG
- ```
-
-6. **Report** in a sentence or two: what was produced and where.
-
-Every step runs as a shell action, so you can watch the whole flow (version checks, installs, the task command) in the [task panel](../interfaces/browser.md#tasks), and it all lands in [logs](../concepts/logs.md).
-
-The skill hard-bans the failure modes of driving desktop apps directly: no `.exe` suffixes, no hardcoded `C:\Program Files\...` paths, no `&&` command chaining, no raw `soffice`/`gimp`/`blender` invocations. The harness resolves app locations and flags per platform, which is what makes the same task work on all three OSes.
-
-## Python fallback
-
-CLI-anything is the first choice, not the only one. If a harness command fails after one retry, the agent falls back to a pure-Python route (PIL for images, python-docx for documents, pydub for audio, moviepy for video), completes the task anyway, and tells you what it actually used (with a note that installing the app gives better results next time). Installs are never retried, timeouts are never looped on, and after repeated failures on one step the agent stops and reports rather than spinning.
-
-## Requirements
-
-- **Enable the skill** (see the note above). It does nothing while disabled.
-- **Action sets:** the skill declares `shell` and `file_operations`. It works through ordinary shell actions, no extra plumbing.
-- **A package manager** for auto-install: `winget` (Windows), Homebrew (macOS), or `apt` (Linux, where installs run under `sudo`). `pip` is needed for the harness hub.
-- **Internet access** the first time any given app or harness is installed.
-- **File paths:** give the agent full paths to input files (`C:\Users\you\Desktop\photo.jpg`, `/home/user/photo.jpg`) for the smoothest run.
-
-!!! warning "It installs software"
- By design, this skill can install real applications on your machine (silently, with license agreements auto-accepted) and run them with your privileges. Each install is a visible shell action in the task panel, and installs are attempted at most once. If you don't want the agent installing anything, keep the skill disabled or preinstall the apps you care about.
-
-## Related
-
-- [Skills](../concepts/skills.md): how skills are enabled, discovered, and invoked
-- [Built-in commands](builtin.md#skill): `/skill enable cli-anything` and friends
-- [Actions and action sets](../concepts/actions-and-action-sets.md): the shell actions underneath
-- [Living UI](../../living-ui/index.md): a different kind of "agent builds it for you"
diff --git a/mkdocs/docs/core/commands/index.md b/mkdocs/docs/core/commands/index.md
deleted file mode 100644
index 2bb4a143..00000000
--- a/mkdocs/docs/core/commands/index.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Commands
-
-Commands are slash-prefixed inputs (`/help`, `/provider anthropic sk-...`, `/skill enable pdf`) that the [UI layer](../interfaces/ui-layer.md) intercepts before anything reaches the agent. They're how you configure providers, integrations, skills, and MCP servers (instantly, without spending tokens or starting a task) and they work identically in the [browser](../interfaces/browser.md) and the [CLI](../interfaces/cli.md).
-
-
-
-- :material-book-alphabet:{ .lg .middle } __[Built-in commands](builtin.md)__
-
- ---
-
- The complete reference: every command, alias, and subcommand.
-
-- :material-console-line:{ .lg .middle } __[CLI-anything](cli-anything.md)__
-
- ---
-
- The bundled skill that automates desktop apps (GIMP, Blender, LibreOffice, ...) through cross-platform command-line harnesses.
-
-
-
-## How dispatch works
-
-When you submit input, the UI controller offers it to the command executor first. Input starting with `/` is split into a name and arguments, resolved against the command registry (aliases included, case-insensitive), and executed; the result comes back as a system message. Anything not starting with `/` goes to the agent as a normal chat message.
-
-An unknown command like `/frobnicate` returns `Unknown command`. It is **not** forwarded to the agent. Commands and conversation are handled separately.
-
-In the browser, typing `/` opens an autocomplete listing everything registered, so you rarely need to memorize names. In the CLI, `/help` prints the same list.
-
-## Four kinds of commands
-
-The registry is populated from four sources at startup:
-
-| Kind | Examples | Where they come from |
-|---|---|---|
-| **Built-in** | `/help`, `/provider`, `/mcp`, `/skill`, `/cred`, `/update` | Shipped in `app/ui_layer/commands/builtin/`; always present |
-| **Integration** | `/gmail`, `/slack`, `/telegram_bot`, `/notion` | One per available [integration](../../integrations/index.md), each with `connect` / `disconnect` / `status` plus integration-specific subcommands |
-| **Skill** | `/pdf`, `/docx`, `/pptx` | One per **enabled** [skill](../concepts/skills.md); registered and unregistered live as you toggle skills |
-| **Agent-provided** | varies | Commands the agent runtime registers programmatically, wrapped into the same registry |
-
-Built-in and integration commands run immediately in the UI layer. Skill commands are different: `/pdf merge these three files` doesn't run UI code. It routes your text to the agent with that skill pre-selected, and the argument text is substituted into the skill's instructions via `$ARGUMENTS`. It's a shortcut for "do this task, using this skill."
-
-## The commands you'll actually use
-
-```
-/help # list every command; /help mcp for details on one
-/provider [name] [key] # view or switch the LLM provider
-/mcp list # manage MCP servers
-/skill list # manage skills
-/cred status # see which integrations are connected
-/update --check # check for a new CraftBot version
-/clear # clear the chat /reset # reset agent state
-/exit # shut down
-```
-
-The full catalogue with every subcommand is in [Built-in commands](builtin.md).
-
-## Related
-
-- [Interfaces](../interfaces/index.md): where you type commands
-- [UI layer](../interfaces/ui-layer.md): the registry and executor behind dispatch
-- [Skills](../concepts/skills.md): the packages behind skill slash commands
-- [MCP](../../integrations/mcp.md): what `/mcp` manages
diff --git a/mkdocs/docs/core/concepts/actions-and-action-sets.md b/mkdocs/docs/core/concepts/actions-and-action-sets.md
deleted file mode 100644
index 948e84a6..00000000
--- a/mkdocs/docs/core/concepts/actions-and-action-sets.md
+++ /dev/null
@@ -1,103 +0,0 @@
-# Actions and action sets
-
-An **action** is one concrete thing the agent can do: write a file, search the web, send a Slack message, run a shell command. The action registry is the agent's entire vocabulary: if no action exists for something, the agent cannot do it. Action **sets** group related actions so each task carries only the vocabulary it needs.
-
-## Overview
-Three layers, each answering a different question:
-
-| Layer | Question it answers | When it's decided |
-|---|---|---|
-| **Registry** | What can this agent do at all? | At startup (import time), plus whenever MCP servers connect |
-| **Action sets** | What can *this task* do? | Once, at task creation (adjustable mid-task) |
-| **Router** | What happens *this turn*? | Every iteration of the [agent loop](agent-loop.md) |
-
-CraftBot ships 1,176 actions: 56 core actions (task management, files, web, documents, media, shell, scheduling, memory, messaging) and 1,120 integration actions under `app/data/action/integrations//`. The full catalogue is in the [actions reference](default-actions.md).
-
-## Anatomy of an action
-
-An action is a Python function with an `@action` decorator that registers it at import time. The metadata (not the implementation) is what the selection LLM sees, so the `description` field does most of the work:
-
-| Field | What it does |
-|---|---|
-| `name` | Unique identifier, e.g. `web_search` |
-| `description` | What the LLM reads to decide when to pick this action |
-| `input_schema` / `output_schema` | Parameter and result contracts, shown to the LLM |
-| `action_sets` | Which sets contain this action (an action can be in several) |
-| `mode` | Interface visibility (which interface contexts offer the action); `"ALL"` means everywhere |
-| `execution_mode` | `"internal"` (in-process) or `"sandboxed"` (isolated venv) |
-| `platforms` | `windows` / `linux` / `darwin` / `all`; see platform dispatch below |
-| `requirement` | pip packages the action needs; installed automatically before it runs |
-| `parallelizable` | Whether it may run alongside other actions in one turn (`False` for writes, state changes, `send_message`) |
-| `irreversible` | Marks side effects that can't be undone once they reach the outside world (send email, post publicly) |
-| `default`, `test_payload` | Always-available flag (legacy; prefer `action_sets`), and data for simulated test runs |
-
-**Irreversible actions get a crash guard.** Before an `irreversible=True` action executes, its intent is durably recorded in an activity ledger. After execution the outcome is recorded too. If CraftBot crashes between the send and the record, the guard refuses a blind re-execution and surfaces a warning instead. The agent verifies or asks you rather than sending your email twice.
-
-**Platform dispatch.** The registry stores implementations per platform. One logical name like `run_shell` can have Windows, macOS, and Linux variants. Lookup picks the current platform's implementation and falls back to the generic `all` one.
-
-## Action sets
-
-Sets are labels declared in each action's metadata. The registry discovers them dynamically by scanning, so a custom action declaring `action_sets=["my_tools"]` creates the `my_tools` set with no other registration step. The built-in sets:
-
-| Set | Contains |
-|---|---|
-| `core` | 35 always-included actions: messaging, task control, file operations, search, web research, shell and HTTP, clipboard, scheduling, integration management, skill and set management, memory search, and sub-agent spawning |
-| `document_processing` | PDF reading, editing, and conversion, markdown conversion, OCR, image description, video understanding |
-| `image` | `describe_image`, `generate_image`, `perform_ocr`, `understand_video` |
-| `video` | `generate_video`, `perform_ocr`, `understand_video` |
-| `content_creation` | `generate_image`, `generate_video` |
-| `scheduler` | Schedule management actions (also present in `core`) |
-| `proactive` | Recurring-task management for `PROACTIVE.md` plus schedule management |
-| `living_ui` | The 7 Living UI lifecycle actions (scaffold, launch, restart, import, data access) |
-
-Connected integrations contribute their own sets, and each connected [MCP server](../../integrations/mcp.md) becomes a set named `mcp_` (see below).
-
-## How a task gets its actions
-
-When a task starts, one LLM call selects both the [skills](skills.md) and the action sets for it, based on the task description: a report-writing task gets `document_processing`, a Living UI build gets `living_ui`. Sets recommended by the selected skill are merged in automatically, `core` is always included, and the union is compiled into a static action list that the task carries for its lifetime.
-
-This compile-once design is deliberate: during execution there is no retrieval step and no searching for tools. The task's vocabulary is a fixed list the router reads directly.
-
-The list can still change, though. Mid-task, the agent can call `list_action_sets`, `add_action_sets`, and `remove_action_sets` (all in `core`, so always available) to expand or trim its own vocabulary when it discovers it needs something. These calls appear in the action panel when a task discovers mid-way that it needs another capability.
-
-## Per-turn selection
-
-Every iteration of the [agent loop](agent-loop.md), the router makes **one LLM call** that returns reasoning plus a list of one *or more* actions:
-
-```json
-{"reasoning": "...", "actions": [{"action_name": "web_search", "parameters": {...}},
- {"action_name": "task_update_todos", "parameters": {...}}]}
-```
-
-Rules applied to that list before execution:
-
-- **Parallel execution.** Multiple actions in one decision run concurrently, up to 10 per batch.
-- **Non-parallelizable wins alone.** If any selected action has `parallelizable=False`, it runs by itself and the rest are dropped with an error the agent sees next turn.
-- **Format errors retry, then abort.** Malformed LLM output gets up to 3 retries with the parse error fed back. After that the task aborts rather than wasting tokens.
-- **Conversation mode is narrow.** Outside a task, the candidates are only `send_message`, `task_start`, `ignore`, plus messaging actions for connected platforms. Real work requires a task.
-
-Each execution logs `action_start` / `action_end` events to the task's [event stream](event-stream.md), which is what the action panel in the browser renders live.
-
-## Internal vs sandboxed execution
-
-`execution_mode` decides where the function body runs:
-
-- **`internal`** runs in the CraftBot process. Used by actions that touch agent state (task management, messaging, memory) and by MCP tools. Declared `requirement` packages are pip-installed into the main environment before the first run.
-- **`sandboxed`** runs in a separate process using a persistent virtual environment (`~/.craftbot/sandbox_venv`, created lazily on first use and reused). Requirements install into the sandbox venv once and persist across calls. A timeout kills runaway executions.
-
-Either way, the action returns a dict that flows back into the event stream as the observation for the next turn.
-
-## MCP tools join the same registry
-
-Servers configured in `app/config/mcp_config.json` (or managed via the `/mcp` command and **Settings**) expose tools that are converted into ordinary actions at connect time: each tool becomes an action named `mcp__`, its JSON Schema becomes the `input_schema`, and all of a server's tools land in an action set named `mcp_` (configurable per server). From that point nothing downstream knows the difference: MCP sets appear in task-creation selection, MCP actions appear in the router's candidates, and disabling a server unregisters its actions. Details and server setup: [MCP](../../integrations/mcp.md).
-
-!!! note "Implementation files"
- Registry and decorator: `agent_core/core/action_framework/registry.py`. Set compilation: `app/action/action_set.py`. Set/skill selection at task creation: `app/internal_action_interface.py`. Per-turn routing: `agent_core/core/impl/action/router.py`. Execution: `agent_core/core/impl/action/manager.py` and `executor.py`. MCP conversion: `agent_core/core/impl/mcp/adapter.py`.
-
-## Next
-
-- [Actions reference](default-actions.md): the full catalogue, action by action
-- [Write a custom action](../../develop/custom-action.md): one file, one decorator
-- [Skills](skills.md): strategy injected on top of the action vocabulary
-- [Agent loop](agent-loop.md): where selection and execution sit in the cycle
-- [MCP](../../integrations/mcp.md): connecting external tool servers
diff --git a/mkdocs/docs/core/concepts/agent-bundles.md b/mkdocs/docs/core/concepts/agent-bundles.md
deleted file mode 100644
index c8a61e84..00000000
--- a/mkdocs/docs/core/concepts/agent-bundles.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# Agent bundles and profiles
-
-An agent profile is the portable part of a CraftBot agent: its personality files, enabled skills, enabled MCP servers, and Living UI apps, packaged into a single `.craftbot` file. Exporting a profile lets you move your configured agent to another machine or share it. Importing a profile turns a stock CraftBot into a configured specialist in one step.
-
-An **agent bundle** is a pre-built profile authored for a specific role (CEO agent, senior Python engineer, finance agent, and others). CraftOS publishes 42 of them in the [CraftBot Agent Bundles repository](https://github.com/CraftOS-dev/craftbot-agent-bundles), free to download and import.
-
-## Example bundles
-
-The 42 bundles are grouped by domain. Each one wires the agent with the skills, MCP servers, and operating rules a senior practitioner of that role uses, so the agent executes the work rather than only describing it. A sample:
-
-| Bundle | Domain | What it does |
-|---|---|---|
-| `ceo-agent` | Executive | Drafts strategy documents, board packs, and investor updates, and tracks OKRs. |
-| `finance-agent` | Finance | Builds FP&A models, runs capital-allocation analysis, and drafts term sheets. |
-| `project-manager` | Operations | Writes charters, work-breakdown structures, Gantt schedules, and status reports. |
-| `senior-python-engineer` | Engineering | Reviews Python code, debugs failures, and proposes optimizations. |
-| `devops-engineer` | Engineering | Works with containers, Kubernetes, infrastructure-as-code, and GitOps pipelines. |
-| `marketing-agent` | Marketing | Plans campaigns and produces content across channels. |
-| `seo-specialist` | Marketing | Audits sites, researches keywords, and drafts on-page and technical SEO fixes. |
-| `sales-agent` | Sales | Researches prospects, drafts outreach, and maintains pipeline records. |
-| `data-analyst` | Research | Queries data, runs analysis, and turns results into reports and charts. |
-| `legal-counsel` | Legal | Reviews contracts, flags risk, and drafts standard clauses. |
-| `recruiter` | People | Writes job descriptions, sources candidates, and screens applicants. |
-| `personal-assistant` | Personal | Manages your inbox, calendar, and day-to-day tasks. |
-
-The repository lists all 42 with a description of each, spanning executive and strategy, engineering, marketing and growth, sales and customer, content and documentation, research and analytics, legal and compliance, and people and product roles.
-
-## What a profile contains
-
-A `.craftbot` file is a ZIP archive. It carries the parts of an agent that are portable between installs:
-
-| Included | Notes |
-|---|---|
-| Personality files | `SOUL.md`, `USER.md`, and the other `agent_file_system` markdown that defines behavior. See [Agent file system](agent-file-system.md). |
-| Enabled skills | The skill folders you have enabled. Skills already present on the target install are not re-shipped. See [Skills](skills.md). |
-| Enabled MCP servers | Server definitions from `mcp_config.json`, with secret environment values stripped out. See [MCP servers](../../integrations/mcp.md). |
-| Living UI apps | Any apps you built. See [Living UI](../../living-ui/index.md). |
-| `manifest.json` and `README.md` | Bundle metadata and a human-readable summary of the contents. |
-
-Four things are deliberately **never** included, so a bundle is safe to share:
-
-- API keys and provider credentials.
-- OAuth tokens and integration secrets.
-- Personal memory (`MEMORY.md` and the memory index).
-- Conversation history.
-
-## Importing a profile
-
-You import a profile from the browser interface.
-
-1. Open **Settings → General** and choose **Import Agent Profile**.
-2. Select or drag in a `.craftbot` file. To use a pre-built bundle, download one from the [agent bundles repository](https://github.com/CraftOS-dev/craftbot-agent-bundles) first (see [Using a pre-built bundle](#using-a-pre-built-bundle) below).
-3. CraftBot inspects the bundle and shows a preview: which skills and MCP servers it contains, which of those you already have installed, and which MCP servers need environment values (API keys) that were stripped on export.
-4. Choose an import mode:
-
-| Mode | Effect on existing personality files |
-|---|---|
-| **Merge and Replace** | Applies the bundle's skills, MCP servers, and apps, and replaces the personality files the bundle provides. Files the bundle does not include are left alone. |
-| **Overwrite** | Replaces the personality files with the bundle's versions. |
-
-5. Confirm. CraftBot installs the bundle's skills into your `skills/` directory and enables them, adds its MCP servers (disabled until you supply the missing keys), applies the personality files, and registers any Living UI apps.
-
-### What import does not change
-
-- **Your model and provider stay the same.** A bundle's `agent.yaml` names a recommended model, but importing never switches your configured provider or API key. Set the model yourself from **Settings → Model** if you want the recommended one. See [LLM providers](../providers/llm.md).
-- **Your existing credentials stay.** The importer only adds skills, servers, personality files, and apps. It does not touch your keys or connected integrations.
-- **Skills are added, not deleted.** If a skill folder already exists, the importer keeps it and reports it as skipped rather than overwriting your version.
-
-After import, the agent typically asks a few questions about your routines and proposes recurring tasks for `PROACTIVE.md`. See [Proactive mode](../modes/proactive.md).
-
-### Using a pre-built bundle
-
-1. Open the [CraftBot Agent Bundles repository](https://github.com/CraftOS-dev/craftbot-agent-bundles).
-2. Open the `bundles/` folder and download the file for the role you want. Files are named `-.craftbot`, for example `ceo-agent-20260611.craftbot`. The most recent date is the current version.
-3. Import it with the steps above.
-4. Fill in API keys for the MCP servers you actually plan to use. The preview lists exactly which servers need keys. You do not need to configure servers for tools you will not use.
-
-The repository lists all 42 bundles grouped by domain (executive, engineering, marketing, sales, research, legal, and others), each with a description of what it does.
-
-## Exporting your own profile
-
-Once you have configured an agent you like, you can export it.
-
-1. Open **Settings → General** and choose **Export Agent Profile**.
-2. Optionally add a description. CraftBot writes a `.craftbot` file named `craftbot--.craftbot`.
-
-The export includes only enabled skills and enabled MCP servers, so the file stays small and does not carry the roughly 157 disabled default servers or machine-specific command paths. Secrets are stripped, so the recipient supplies their own keys.
-
-Use export to move your agent to another machine, back up a configuration before experimenting, or share a persona you built. To publish a polished persona to the public repository, follow the authoring and submission process in [Create an agent bundle](../../develop/custom-agent.md).
-
-## Next
-
-- [Create an agent bundle](../../develop/custom-agent.md): author your own persona and publish it to the repository
-- [Agent bundle config](../configuration/agent-config-yaml.md): the `agent.yaml` manifest fields
-- [Skills](skills.md) and [MCP servers](../../integrations/mcp.md): the two capability layers a bundle carries
diff --git a/mkdocs/docs/core/concepts/agent-file-system.md b/mkdocs/docs/core/concepts/agent-file-system.md
deleted file mode 100644
index ba12fb12..00000000
--- a/mkdocs/docs/core/concepts/agent-file-system.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Agent file system
-
-`agent_file_system/` at the project root is the agent's home directory: a dozen markdown files that hold its identity, its knowledge of you, and its memory of everything that's happened, plus a `workspace/` where task outputs land. Understanding who writes each file, and which ones you're meant to edit, is the single highest-leverage way to tune your agent.
-
-## Overview
-The files fall into three categories. Some are **yours to write**: the personality brief, your profile, the style guide. Some are **the agent's working notes**: the ops manual it consults and the task list it maintains. The rest are **records**: event logs, task history, and distilled memory, maintained by harness subsystems rather than by you or the agent.
-
-The agent reads and writes these files with ordinary file actions, and a few (SOUL.md, AGENT.md pointers, USER.md) feed directly into every LLM call. Edit one and behavior changes on the next turn, with no restart.
-
-The directory is seeded from templates in `app/data/agent_file_system_template/` on first run, and the `/reset` command restores the markdown files from those templates.
-
-## The files
-
-| File | Who writes it | May I edit it? | What it does |
-|---|---|---|---|
-| `SOUL.md` | You (agent only on your explicit request) | **Yes, the main personality knob** | Personality, tone, behavior. Injected into the system prompt every turn |
-| `USER.md` | Onboarding wizard; agent, after confirming with you | **Yes** | Your profile: identity, timezone, communication preferences, life goals |
-| `FORMAT.md` | You | **Yes** | Formatting standards the agent reads before generating any document |
-| `GLOBAL_LIVING_UI.md` | You | **Yes** | Global design preferences for every [Living UI](../../living-ui/index.md) project: colors, theme, enforced rules |
-| `AGENT.md` | Ships with CraftBot; agent appends learned operational fixes | Yes, carefully | The agent's versioned operations manual: runtime, errors, integrations, conventions. The agent greps it by `## ` |
-| `PROACTIVE.md` | `recurring_*` actions and the planners | Prefer the actions; preserve the `` markers | Recurring proactive tasks plus the planner's Goals / Plan / Status; see [Proactive mode](../modes/proactive.md) |
-| `MEMORY.md` | Memory processor only (nightly job) | **No** | Distilled long-term memory, one timestamped fact per line; see [Memory](memory.md) |
-| `EVENT.md` | Event stream manager | **No** | Append-only chronological log of every event (actions, messages, errors) |
-| `EVENT_UNPROCESSED.md` | Event stream manager | **No** | Staging buffer of events awaiting the nightly memory run; cleared after each run |
-| `TASK_HISTORY.md` | Appended on every `task_end` | **No** | One summary section per finished task: status, timestamps, outcome, skills used |
-| `CONVERSATION_HISTORY.md` | Event stream manager | **No** | Rolling transcript of every user ↔ agent exchange, never auto-cleared |
-| `MISSION_INDEX_TEMPLATE.md` | Static template | **No** | Copied into `workspace/missions//INDEX.md` when a mission starts |
-
-The "No" files are harness-managed. Hand-editing them creates inconsistencies the agent can't recover from: the memory pipeline expects `MEMORY.md` in its exact line format, and the event logs are the ground truth other subsystems replay. Read them freely, but never write to them.
-
-## Files you should edit
-
-Three files do most of the customization work:
-
-**SOUL.md** shapes *how* the agent behaves. It's injected into the system prompt on every single turn, so edits take effect immediately and affect every interaction. Want it more terse, more playful, stricter about asking before acting? Say so here, or just tell the agent to update its soul, and it will ask for confirmation before saving.
-
-**USER.md** shapes *who it's working for*. Onboarding fills the skeleton (identity, timezone, communication preferences, goals). Keep it current as things change. The agent reads it at the start of user-facing tasks and only writes durable, confirmed facts back. One-off requests don't land here.
-
-**FORMAT.md** shapes *what it produces*. The agent consults it before generating any file. A `## global` section sets universal rules (colors, typography, writing style), and per-filetype sections (`## pptx`, `## docx`, `## xlsx`, `## pdf`) override it for that format. If every deck the agent makes has the wrong brand color, fix it once here and every future document follows.
-
-`GLOBAL_LIVING_UI.md` plays the same role for generated apps: design preferences and enforced rules applied to every Living UI project, with per-project answers overriding when they conflict.
-
-A useful side-effect to know: `AGENT.md`, `PROACTIVE.md`, `MEMORY.md`, `USER.md`, and `EVENT_UNPROCESSED.md` are indexed for the agent's semantic memory search, and a file watcher re-indexes them the moment they change, so edits to these files become retrievable knowledge, not just prompt text.
-
-## workspace/
-
-Everything a task produces lands under `agent_file_system/workspace/`. Four zones with different lifecycles:
-
-```text
-workspace/
-├── Persistent task outputs: reports, exports,
-│ anything you asked for. Never auto-cleaned.
-├── tmp// Per-task scratch: drafts, downloads,
-│ intermediate state. Auto-created when the task
-│ starts; auto-deleted on task end AND at startup.
-├── missions// Multi-session initiatives. INDEX.md (from the
-│ template) records goal, findings, next steps;
-│ it's what a future task reads to restore context.
-│ Never auto-cleaned.
-└── living_ui/_/ Living UI projects: self-contained apps managed
- by their own lifecycle actions. Don't rename or
- delete these by hand.
-```
-
-The practical rules:
-
-- **Deliverables go in the workspace root.** That's where "save it as frameworks.md" ends up, and where you go looking for outputs.
-- **Anything in `tmp/` is disposable by design.** If a task saved something there that you want, move it out before the task ends.
-- **Missions are for work bigger than one task** (a job hunt, a research program). The mission's `INDEX.md` is the durable state. Individual tasks come and go.
-
-## Configuration and limits
-
-- **Location:** `agent_file_system/` in the project root. The template lives at `app/data/agent_file_system_template/`.
-- **Edits apply on the next trigger**, with no restart. `SOUL.md` in particular takes effect on the very next turn.
-- **Reset:** `/reset` deletes the markdown files and re-copies the templates. Workspace contents are handled separately, and Living UI projects are preserved by the generic reset (they have their own teardown).
-- **Growth:** `EVENT.md` auto-rotates on size. `CONVERSATION_HISTORY.md` and `TASK_HISTORY.md` grow indefinitely, and `EVENT_UNPROCESSED.md` is cleared by each successful memory run.
-- **Not for secrets:** API keys and credentials live in `app/config/settings.json` and `.credentials/`, not in these markdown files.
-
-## Next
-
-- [Memory](memory.md): how events become `MEMORY.md` facts, and how the agent retrieves them
-- [Proactive mode](../modes/proactive.md): the system that reads and maintains `PROACTIVE.md`
-- [Living UI](../../living-ui/index.md): the projects living under `workspace/living_ui/`
diff --git a/mkdocs/docs/core/concepts/agent-loop.md b/mkdocs/docs/core/concepts/agent-loop.md
deleted file mode 100644
index a4ff63db..00000000
--- a/mkdocs/docs/core/concepts/agent-loop.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Agent loop
-
-The agent loop is the cycle CraftBot runs every time something wakes it up: claim a [trigger](triggers.md), route it to a workflow, let the LLM pick actions, execute them, and queue the follow-up. This cycle explains why tasks tick forward one step at a time, why the agent can wait hours for your reply without burning tokens, and why a restart doesn't lose work in flight.
-
-## Overview
-CraftBot does not run continuously. The agent sleeps until a trigger fires (your message, a schedule, a task's own "continue" note) then runs **exactly one turn** and goes back to sleep. The design has three properties:
-
-1. **One trigger, one turn.** A turn is a single pass through the loop: the LLM picks one or more [actions](actions-and-action-sets.md), CraftBot executes them, and the results land on the [event stream](event-stream.md).
-2. **Continuation is a new trigger, not a loop.** A ten-step task is not a `while` loop held in memory. Each turn ends by enqueuing a fresh continuation trigger for the same session. The next turn picks it up. Waiting is just a trigger with a `fire_at` timestamp in the future.
-3. **State lives outside the process.** Progress is recorded in the task's todos, its event stream, and the durable trigger queue, so a crash or restart between turns re-delivers the pending trigger and the task resumes where it left off.
-
-This is also why several tasks can run "at once": their triggers interleave through the same loop, each turn scoped to its own [session](task-sessions.md).
-
-## The outer loop
-
-A single consumer drives everything:
-
-| Step | What happens |
-|---|---|
-| 1. Claim | `trigger_service.next()` waits for the next due trigger and marks its durable record as claimed |
-| 2. React | `agent.react(trigger)` runs one full turn (everything below) |
-| 3. Settle | On success the trigger is `ack()`ed (done); on an exception it is `nack()`ed, which retries it with backoff |
-
-A crash between claim and settle leaves the trigger claimed. The next boot re-delivers it. The guarantee is *at-least-once*, never silently lost. The details are on the [Triggers](triggers.md) page.
-
-!!! note "Implementation files"
- The consumer is `_consume_triggers()` in `app/ui_layer/controller/ui_controller.py`. The turn itself is `AgentBase.react()` in `app/agent_base.py`. Claim/ack/nack live in `app/triggers/service.py`.
-
-## Inside a turn: routing
-
-`react()` checks the trigger, then the session's state, in a fixed order. First match wins:
-
-| Order | Condition | What runs |
-|---|---|---|
-| 1 | Trigger is a restart notice | Posts the prebuilt "I was restarted" message to chat and returns; no LLM call |
-| 2 | Trigger source is `memory` | Memory workflow: spawns a task that distills recent events into long-term [memory](memory.md) |
-| 3 | Trigger source is `proactive_heartbeat` / `proactive_planner` | [Proactive](../modes/proactive.md) workflow: collects due recurring tasks or runs a planner |
-| 4 | Task waiting for your reply, and this trigger carries no message | Re-schedules the wait for another 3 hours and returns; the task keeps sleeping |
-| 5 | Session has a running **complex** task | Complex-task workflow: todo-driven, approval-gated |
-| 6 | Session has a running **simple** task | Simple-task workflow: linear, auto-completing |
-| 7 | Anything else | Conversation workflow: no task exists yet |
-
-Before steps 4–7, the turn initializes the session and, if the trigger carries a user message routed in mid-task, records it onto the event stream so the LLM sees it.
-
-The three main workflows (5–7) differ in prompt shape, todo handling, and caching (compared side by side in [Task modes](../modes/index.md)) but they all execute the same four-phase pipeline.
-
-## The turn pipeline
-
-Every conversation, simple-task, and complex-task turn runs the same four phases:
-
-1. **Select.** One LLM call chooses one or more actions and their inputs, based on the task instruction, todos, and the event stream. In conversation mode the menu is deliberately tiny: reply, start a task (several in parallel is allowed), or deliberately ignore a message that needs no reaction.
-2. **Prepare.** Each selected action is resolved by name from the task's action sets and its inputs are bound.
-3. **Execute.** The actions run, in parallel when more than one was selected. Every action logs `action_start` / `action_end` events, which is what the action panel in the browser renders live.
-4. **Finalize.** The action output is inspected: did it create a task? ask for a delay (`wait`)? flag `waiting_for_user_reply`? Then a **new continuation trigger** is enqueued for the session (or for each task that a parallel `task_start` created) and the turn ends.
-
-The finalize phase drives multi-step work. A complex task making twenty tool calls is roughly twenty turns, each handed to the next by a `task_continuation` trigger. Between turns the agent is idle, free to run a different task's turn or to sleep.
-
-## What happens when you send a message
-
-Putting it together, end to end:
-
-1. Your message is durably recorded, then [session routing](task-sessions.md) decides whether it continues an existing task or opens a fresh session.
-2. A `user_message` trigger fires. The consumer claims it and calls `react()`.
-3. No task is running for the fresh session, so the conversation workflow runs: the LLM either answers directly (`send_message`) or calls `task_start`.
-4. If a task started, finalize queues a continuation trigger. Each subsequent turn works a todo, until the agent sends you a result and (for complex tasks) waits for your approval before `task_end`.
-5. If the agent asked you something mid-task, the task flips to waiting-for-reply and its trigger sleeps. Your answer routes back and wakes it immediately.
-
-## Watch it run
-
-- **In the browser.** The task card, todo list, and action panel are a live rendering of the loop: each visible action is one entry in a turn's execute phase.
-- **In the logs.** Every run writes to `logs/` ([Logs](logs.md)). Grep for the loop's own tags:
-
-```bash
-grep -E "\[REACT\]|\[WORKFLOW|\[ACTION\]|\[TRIGGER" logs/