guide

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 network means: follow HTTPS_PROXY / HTTP_PROXY / ALL_PROXY and 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:// and socks5:// all work — Clash's http port (7890) and socks port (7891) are both fine. The scheme is required; a bare 127.0.0.1:7890 is 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_search and the desktop's connection to a remote daemon have their own clients and follow the environment variables / system proxy. web_fetch deliberately 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, .venv and similar tool caches are always excluded; build-output directories are skipped only once they hold more than max_build_dir_files files.
  • 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].