The bundle is your agent project tree — the directory containing
dari.yml at its root, plus everything under it. When you publish, the
dari CLI archives that tree and uploads it. At runtime, the sandbox
receives it as /bundle.
What gets uploaded
The CLI archives the entire repo root. The manifest validator enforces
rules on known paths:
dari.yml at the root
tools/<name>/tool.yml for each custom tool
skills/<name>/SKILL.md for each declared skill
prompts/system.md (or whatever instructions.system points at)
Dockerfile at the root, if runtime.dockerfile is set
Everything else in the tree is passed through as-is. There is no
.dariignore and no implicit filtering.
Whatever sits at your repo root ends up in the bundle. That includes
.git/, node_modules/, local .env files, build artifacts, and
anything else you haven’t cleaned up. Be deliberate about what you
publish from — secrets in the tree get baked into the sandbox template.
Where it lives in the sandbox
During the prepared-runtime build, Dari copies the archive contents to
/bundle inside the sandbox image and sets /bundle as the working
directory.
This holds for both runtime modes:
- Default base image (no
runtime block) — Dari uses
e2bdev/base:latest and layers the bundle copy on top.
- Custom Dockerfile — your image is built first, then Dari copies
the bundle to
/bundle and sets WORKDIR /bundle on top of it.
How the agent sees it
At session time, the harness runs tool calls with cwd = /bundle:
- Built-ins (
bash, read, edit, grep, find, ls, write) resolve
relative paths against /bundle, so the agent sees your project layout
directly.
- Custom tool handlers resolve against
/bundle/tools/<name>/, so helper
modules and data files you ship alongside tool.yml are visible.
- The system prompt is read from whatever
instructions.system points at
inside the bundle.
Dari does not install dependencies for files outside the known paths — if
you ship a package.json or requirements.txt in your project root and
need them installed, do it in a custom Dockerfile.