Configuration Reference
Data directory
Data is split across four roots with different semantics (XDG-style on all platforms):
| Root | Holds | Deleting it |
|---|---|---|
config |
your hand-written config files | resets to defaults |
data |
object store, attachments, per-workspace history, installed runtimes, skills and plugins | ⚠️ do not delete — wipes all local data (conversation content, history, attachments, installed software) |
state |
state.db (sessions, entries, usage), locks, logs, daemon device store |
⚠️ do not delete — removing state.db empties the entire session store |
cache |
regenerable data | nothing happens — safe to wipe |
data and state are the only places your local data lives; deleting them is
unrecoverable (the object store and state.db also reference each other —
losing state.db orphans the objects). Only cache is safe to clear.
Defaults (all platforms use the same XDG-style layout):
~/.config/zlogic/ # config
├── config.yaml # global behavior: default model, context, tools, roles, ...
├── models.yaml # your providers/models + auto_detect_env
├── env.yaml # optional: KEY: value secrets — loaded as environment variables at startup
├── policy.yaml # global security policy + cost budget
├── mcp.json # global MCP servers (optional)
└── desktop.yaml # desktop UI prefs + the daemon backend block (Settings → Run engine)
~/.local/share/zlogic/ # data
├── objects/ # object store (large tool results, attachments)
├── workspaces/ # per-workspace private data
├── extensions/ # plugins/, mcp/, runtimes/ — installed from the Marketplace
└── skills/ # installed skills
~/.local/state/zlogic/ # state
├── state.db # SQLite — sessions, entries, usage
├── security/ # keyring fallback (encrypted key blob)
├── daemon/ # daemon devices.json, listen.json, tls/, uploads/
└── logs/
~/.cache/zlogic/ # cache — safe to delete at any time
Per project, the workspace-private directory .zlogic/ inside the project root
may hold a project-level policy.yaml; MCP servers for a workspace are declared
in the project's .mcp.json, and repository skills/plugins live in
.zlogic/skills + .zlogic/extensions/plugins.
Environment variables
Priority: ZLOGIC_HOME (collapse everything under one root) >
XDG_*_HOME (fine-grained per root) > platform defaults above.
| Variable | Effect |
|---|---|
ZLOGIC_HOME |
Put everything under this one root (portable installs, containers) |
XDG_CONFIG_HOME |
config root (default ~/.config) → zlogic config in ~/.config/zlogic |
XDG_DATA_HOME |
data root (default ~/.local/share) → ~/.local/share/zlogic |
XDG_STATE_HOME |
state root (default ~/.local/state) → ~/.local/state/zlogic |
XDG_CACHE_HOME |
cache root (default ~/.cache) → ~/.cache/zlogic |
config.yaml
Global behavior settings:
default_model: deepseek:deepseek-chat # default model, written as provider:model
providers: # optional: override individual provider fields
deepseek: # (merged over models.yaml / built-ins)
models:
deepseek-chat:
context_window: 64000
llm_roles: # role-based model chains — see Providers & Models
title:
models: [gpt-4o-mini]
thinking: off
session:
auto_title: # session title generation
enabled: true
max_chars: 30
source_chars: 600
context:
compact_ratio: 0.8 # compact when last round used this share of the window
tail_turns: 1 # keep the last N turns structured through compaction (1 = the running turn)
overflow_retries: 1 # retries after a context overflow before failing
tools:
default_shell: auto # shell backend for the shell tool (auto / git_bash / pwsh / cmd / bash)
max_result_chars: 30000 # oversized tool results go to the object store
timeout_secs: 0 # tool execution timeout, 0 = unlimited
web_search:
provider: exa # exa / parallel — whichever has a key
timeout_secs: 25
# `web_search` keys do not go here: the free tier is the default, and a key is entered under
# Settings → Tools → Web search, or with `zlogic key set exa`. It lands in the keychain as
# `web_search:exa` / `web_search:parallel`.
checkpoint: # local history — see the Local history section
enabled: true
max_file_size_mb: 20
budget_gb: 2
exclude: []
exclude_dirs: []
build_dirs: []
max_build_dir_files: 2000
retention_days: 30
worktree:
dir: "../{workspace}-worktrees" # where sub-agent worktrees are checked out
cost: # which currency the books are kept in
display_currency: USD
rates: [] # e.g. {from: USD, to: CNY, rate: 7.2}
limits: # anti-hang guardrails, not a budget
max_rounds: 150 # max LLM rounds per turn
max_depth: 2 # max sub-agent nesting depth
log:
level: info # error / warn / info / debug / trace
to_file: true # write to state/logs/ (the terminal UI swallows stderr)
network: # outbound proxy (see "Proxy" below)
proxy: null # http://127.0.0.1:7890 — also socks5://; empty = follow the env vars
no_proxy: [] # hosts reached directly, e.g. [localhost, 127.0.0.1]
marketplace: # optional download mirrors (when GitHub is unreachable)
github_release_mirror: null # GitHub release mirror, e.g. https://registry.npmmirror.com/-/binary/python-build-standalone
node_dist_mirror: null # node dist mirror, e.g. https://registry.npmmirror.com/-/binary/node
pypi_index: null # Python package index (PyPI mirror), e.g. https://pypi.tuna.tsinghua.edu.cn/simple
Proxy
How outbound HTTP(S) leaves the machine — model calls, the price list, the catalog:
network:
proxy: http://127.0.0.1:7890
no_proxy: [localhost, 127.0.0.1]
- Omitting
networkmeans: followHTTPS_PROXY/HTTP_PROXY/ALL_PROXYand the system proxy (Windows / macOS settings included). A desktop app launched from an icon does not inherit what you exported in a shell, so on that path it is easier to write the proxy here or in Settings → Advanced → Network. http://,https://andsocks5://all work — Clash's http port (7890) and socks port (7891) are both fine. The scheme is required; a bare127.0.0.1:7890is rejected rather than guessed at.- An explicit proxy wins: setting one disables reqwest's automatic system-proxy lookup, so "configured A but traffic went through B" cannot happen silently.
- Scope: this covers the engine's own outbound requests. Marketplace downloads, MCP servers,
web_searchand the desktop's connection to a remote daemon have their own clients and follow the environment variables / system proxy.web_fetchdeliberately does not use a proxy at all — it fetches URLs you name, and routing those through your proxy would widen that tool's reach rather than narrow it.
models.yaml
Your providers and models — the full shape is in Providers & Models:
auto_detect_env: true # default true — read API keys from environment variables
providers:
my-provider:
sdk: openai_chat # openai_chat / openai_responses / deepseek / glm / dashscope /
# qwen_local / openrouter / fireworks / anthropic / gemini /
# bedrock / openai_generic
base_url: https://api.openai.com/v1
models:
gpt-4o: {}
models.yaml only accepts provider/model settings — deny_unknown_fields
rejects misplaced keys like context: or session:. Put those in
config.yaml. API keys are not written here (there is no api_key field) —
they come from the environment or the OS keyring, see
Key Management.
policy.yaml — approvals & budget
Both the security policy and the cost budget live in policy.yaml (global at the
config root, project-level at .zlogic/policy.yaml in the project root). Project
policy tightens the global one, never loosens it.
policy: # approval rules — see Security & Approvals
version: 1
default: ask # ask / allow / deny — fail-closed
commands: [] # simple-command rules (POSIX)
exec: [] # exec rules
paths: [] # path rules (sensitive paths)
scripts: [] # script rules
protected_delete: [] # paths that must survive any deletion
protected_write: [] # paths whose writes can never be auto-approved
budget: # demand-side cost limits
per_turn: 0.5 # max spend per turn (includes sub-agents)
per_session: 5 # max spend per conversation
per_task: 1 # max spend per background task (defaults to per_turn)
window: # rolling time window total
hours: 24
amount: 10
action: ask # what happens when a limit is hit (ask / stop)
A broken budget: section only disables the budget (with a visible warning); the
policy: half is parsed separately and still applies.
Global & per-workspace MCP servers
Workspace servers are declared in the project root .mcp.json; global servers
live in ~/.config/zlogic/mcp.json (both are also managed in the desktop
Marketplace):
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"],
"env": { "MY_VAR": "value" }
}
}
}
Plugins and skills installed from the Marketplace land under the data root
(skills/, extensions/plugins/) — see
Plugins & Skills.
Local history (checkpoints)
Snapshots are taken around every file-changing tool call. "What did this turn change", rollback and diff undo all rely on them.
- Snapshots live in a shadow object store under the local data directory —
they never touch your git history or
.gitignore. - The workspace opening snapshot has a size budget: if it would exceed the budget, local history stays disabled and reports the large directories instead of deciding what to exclude for you.
node_modules,.venvand similar tool caches are always excluded; build-output directories are skipped only once they hold more thanmax_build_dir_filesfiles.- Turning local history off means not a single byte is written: no snapshots, and undo / rollback are unavailable.
Memory
The agent can persist durable facts across conversations (Preferences, Goals, Corrections, References). Project instructions always take precedence over memory.
- Scopes: global (all workspaces) and workspace (current project).
- Manage entries in desktop Settings → Memory, or from the CLI:
zlogic memory(list),zlogic memory remove <id>,zlogic memory undo [global|workspace].