Self-build — developing and building eVi with eVi
eVi is meant to maintain itself. It already has everything needed to work on its own source: a coding agent with file/shell/git tools, an isolated permission model, the full test suite, and a one-command desktop build. This guide is the "bootstrap" — how to drive changes, tests, and builds through eVi instead of an external assistant.
The two enabling artifacts:
EVI.mdat the repo root — auto-loaded as project context (evi/project.py) whenever you run eVi fromC:\evi. It tells eVi's agent the repo map, the two-venv rule, the build/test commands, and the conventions.scripts/build-desktop.{ps1,sh}— the single "build the whole app" entrypoint (freeze the sidecar → bundle the Tauri app), which eVi can run with its shell tool.
The development loop
Run eVi from inside the repo so it picks up EVI.md:
cd C:\evi
evi chat --mode code # or: evi run --mode code "…" for one-shot
A typical change, driven by eVi:
- Describe the task ("add an
evi skill renamecommand", "fix X inserver.py"). eVi has the repo map + conventions fromEVI.md. - eVi reads the relevant
docs/features/<area>.mdand module(s), then edits with its file tools. - eVi tests:
pytest -qplus the matching e2e suite (tests/cli_e2efor CLI changes,tests/e2efor UI). Approve the shell calls (or use--mode codewhich pre-approves the dev toolset; or/auto on). - eVi lints:
ruff check evi tests scripts. - eVi updates the feature doc +
examples/if behavior changed, and commits with a Conventional Commit message.
Tips:
- A subagent / workflow (
evi workflow) can split a big change into plan → implement → test stages. - An eval suite (
evi eval) makes a good regression gate for behavior you care about; a routine/scheduler job can re-run it. - Give eVi a strong local coding model (e.g. a
qwen2.5-codervia Ollama/LM Studio); route coding turns to it withevi route(see examples/routes.json).
Building the app
# unit + lint
.venv/Scripts/python.exe -m pytest -q
.venv/Scripts/python.exe -m ruff check evi tests scripts
# desktop app (sidecar + Tauri) — produces the installers
powershell -File scripts\build-desktop.ps1 # Windows
bash scripts/build-desktop.sh # POSIX
build-desktop runs build-sidecar (PyInstaller --onedir freeze of the web server, using .venv-build) then npm run tauri build with the standalone config. Installers land in desktop/src-tauri/target/release/bundle/{msi,nsis}/.
Note: the final Tauri step may exit non-zero on the optional updater-signing step (it needs the CI-only
TAURI_SIGNING_PRIVATE_KEY). The installers are still complete and runnable — the scripts report this rather than treating it as a failure. See desktop-bundling.md.
Shipping a change
- Tests green (
pytest -q+ the relevant e2e),ruffclean. - Conventional Commit on a branch (don't commit on
mainwithout intent). - Docs touched? Mirror the changed
docs/*.mdto the public wiki (evi-assistant/evi-ai.wiki) — see releasing.md. - Releases are currently paused on a GitHub Actions billing block (a human-only fix). Until that clears, keep changes local on
main; don't tag or trigger the release workflows.
Local-model notes (from dogfooding)
Running eVi against its own repo with a local coder model surfaced two things now fixed, which matter for any local-model use:
- Surgical edits. eVi has an
edit_filetool (exactold_string→new_string). A small local model can't reliably regenerate a 300-line file withwrite_file, but it can produce a one-spot edit — so preferedit_filefor changes (it's also far cheaper in tokens). - Text-emitted tool calls. Some local models (e.g. qwen2.5 via Ollama) print a tool call as JSON content instead of using the structured
tool_callsfield — sometimes as a Python/JSON hybrid (single-quoted strings, lowercasefalse). eVi now recovers these (recover_text_tool_callsinevi/llm/agent.py), so the call still runs. Frontier models over real APIs are unaffected (they always return structured calls).
Worked dogfood: with the recommended qwen2.5-coder:14b set as the model, eVi fixed a real bug in its own evi/recommend.py (a string-vs-numeric compute-capability comparison) via a single edit_file call.
Why this works (and its limits)
eVi's agent is model-driven: how well it can self-develop scales with the local model you give it. EVI.md + the test suite + the build script remove the tooling gap — eVi can read, edit, test, and build itself unattended. What remains is model capability and your review. Treat eVi's changes like any PR: read the diff, check the tests, then commit.
See also: TESTING.md (the four test layers), development.md, desktop-bundling.md, releasing.md.