docs: sync public docs to recent changes

Document Daytona Dockerfile path refs, static template includes, Slack review context, skipped LLM setup, and template validation behavior.
This commit is contained in:
Bryan Helmkamp 2026-05-18 14:23:23 -04:00
parent 7f81beb63c
commit c28a102af8
No known key found for this signature in database
8 changed files with 33 additions and 5 deletions

View file

@ -1 +1 @@
aea71a13e5a9c0c276aff04ccc5e2b71e86ce6d6
6f3275f2be085b1e94f4f82b7cb76f826e9e00e3

View file

@ -66,6 +66,16 @@ Before execution, `{{ goal }}` becomes `Add a /health endpoint to the API server
Undefined prompt variables render as empty text and produce a `template_undefined_variable` diagnostic. `fabro validate` reports that diagnostic as a warning; run-style commands promote it to an error before proceeding. Environment variables are not available in prompt templates.
Prompt and goal templates can use static MiniJinja includes to share partials:
```md title="prompts/plan.md"
{% include "partials/context.md" %}
Write a plan for {{ goal }}.
```
Include names must be literal strings, resolve relative to the file being rendered, and stay under that template root. Dynamic include expressions such as `{% include inputs.partial %}` are rejected during manifest bundling because Fabro must know every template file before a sandbox run starts.
### Fallback to label
If a node has neither a `prompt` attribute nor an empty one, Fabro uses the `label` as the prompt:

View file

@ -148,6 +148,8 @@ cpu = 4
memory = "8GB"
disk = "20GB"
dockerfile = "FROM rust:1.85-slim-bookworm\nRUN apt-get update && apt-get install -y git ripgrep"
# Or reference a Dockerfile beside this TOML file:
# dockerfile = { path = "./Dockerfile" }
```
| Field | Description |
@ -156,7 +158,7 @@ dockerfile = "FROM rust:1.85-slim-bookworm\nRUN apt-get update && apt-get instal
| `cpu` | CPU cores for the snapshot VM. |
| `memory` | Memory in GB. |
| `disk` | Disk in GB. |
| `dockerfile` | Dockerfile content for building the snapshot. Required when creating a new snapshot. |
| `dockerfile` | Dockerfile content or `{ path = "..." }` reference for building the snapshot. Required when creating a new snapshot. Paths resolve relative to the TOML file that declares them. |
If the snapshot already exists and is in `Active` state, Fabro uses it directly. If it's in `Building` or `Pending` state, Fabro polls with exponential backoff until it's ready.

View file

@ -541,7 +541,7 @@ Fabro validates the run config when it loads:
- **`_version` check** — Only `_version = 1` (or missing, which defaults to `1`) is accepted. The legacy top-level `version` key is rejected with a rename hint.
- **Unknown keys** — Any top-level key not in `[project]`, `[workflow]`, `[run]`, `[cli]`, `[server]`, `[features]`, or `_version` is rejected with a targeted rename hint pointing at the v2 replacement path.
- **Variable check** — Any undefined workflow template variable in the Graphviz file produces an error.
- **Variable check** — Undefined workflow or prompt template variables produce diagnostics. `fabro validate` reports them as warnings; run-style commands treat them as errors before creating or starting a run.
Use `fabro preflight` to validate a run config without executing it:

View file

@ -56,6 +56,8 @@ cpu = 4
memory = "8GB"
disk = "20GB"
dockerfile = "FROM rust:1.85-slim-bookworm\nRUN apt-get update && apt-get install -y git ripgrep"
# Or keep the Dockerfile next to this TOML file:
# dockerfile = { path = "./Dockerfile" }
```
See [Server Configuration](/administration/server-configuration) for the full reference on all sandbox fields and server defaults.
@ -93,7 +95,7 @@ disk = 20
dockerfile = "FROM node:20-slim\nRUN apt-get update && apt-get install -y git"
```
When a run starts with a snapshot configured, Fabro looks up the snapshot by name. If it doesn't exist and a `dockerfile` is provided, Fabro creates it automatically and polls until it reaches `Active` state (up to 10 minutes). If the snapshot already exists, it's reused immediately.
When a run starts with a snapshot configured, Fabro looks up the snapshot by name. If it doesn't exist and a `dockerfile` is provided, Fabro creates it automatically and polls until it reaches `Active` state (up to 10 minutes). `dockerfile` can be inline content or `{ path = "..." }`; paths are resolved relative to the TOML file that declares them and are bundled into run manifests. If the snapshot already exists, it's reused immediately.
<Note>
If a snapshot is configured by name but doesn't exist and no `dockerfile` is provided, the run fails immediately. If no snapshot is configured at all, sandboxes are created from the `daytona-medium` snapshot which includes standard dev tools (git, etc.).

View file

@ -26,6 +26,12 @@ Fabro posts a message to your configured Slack channel:
> **Approve Plan**
>
> stage `approve`
>
> Open in Fabro
>
> _(context from the upstream stage, when available)_
>
> `[Approve]` `[Revise]`
A team member clicks a button, the message updates to show the selection, and the workflow resumes on the chosen path.
@ -106,7 +112,7 @@ Or use the `chat:write.public` scope to post to public channels without an invit
Fabro uses the same [web interviewer](/execution/interviews#web) that powers the web UI. When a human gate fires:
1. Fabro builds a [Block Kit](https://api.slack.com/block-kit) message from the question (buttons for choices, a thread prompt for freeform)
1. Fabro builds a [Block Kit](https://api.slack.com/block-kit) message from the question, stage hint, upstream context, optional run link, and answer controls
2. Posts the message to the configured Slack channel
3. The workflow blocks, waiting for an answer

View file

@ -21,6 +21,8 @@ This starts the server on a Unix socket at `~/.fabro/fabro.sock` by default. Use
If `~/.fabro/settings.toml` does not yet exist, `fabro server start` enters **install mode**: it prints an install URL and a one-time install token, attempts to open the URL in your default browser, and serves a web wizard that walks you through configuring your server URL, shared object store, LLM provider, and GitHub integration.
The LLM step can be completed with one or more provider keys, or explicitly skipped so you can finish server setup first and add model credentials later. A skipped LLM step writes no LLM vault credentials; LLM-dependent workflows keep failing with provider-not-configured errors until credentials are added.
When Fabro can construct a direct install URL, the token is embedded in the URL and also printed on its own line for copying. If you open the server root through a reverse proxy or another machine, paste the printed install token when prompted.
The `Object store` step offers two wizard-managed modes:

View file

@ -89,6 +89,12 @@ Fabro renders the graph `goal` first and stores the rendered value back onto the
Fabro renders undefined workflow variables as empty text and records a `template_undefined_variable` diagnostic. `fabro validate` reports that diagnostic as a warning so you can validate workflow structure before all inputs are known. Run-style commands such as `fabro run`, `fabro create`, and preflight promote the same diagnostic to an error before proceeding.
## Template includes
Prompt and goal templates support static MiniJinja loader dependencies such as `{% include "partial.md" %}`. Includes are resolved relative to the template file being rendered and can be nested.
Fabro discovers those static dependencies while building the run manifest so sandbox providers receive every required prompt file. Dynamic loader expressions such as `{% include inputs.partial %}` are rejected; use a literal include path and choose content with normal template conditionals instead.
## Escaping
To emit literal template syntax, use MiniJinja escaping: