config-format

kode specs/kode/config-format.kmd

Specification body

Kode Config Format

This spec defines the on-disk format and hierarchical resolution of the kode CLI/TUI configuration. It elevates internal/config/ to parity with Claude Code (settings.json) without breaking existing YAML installs.

File location and format

Kode persists config as YAML for backwards compatibility with shipped installs. JSON inputs are also accepted (auto-detected by the leading non-whitespace byte: { or [ → JSON; otherwise YAML). Writes always emit YAML.

Scope Path Auto-created
User defaults ~/.config/kode/config.yaml Yes (on first run)
Workspace overlay <work_dir>/.kode/config.yaml No
CLI flags --once, --json, --model … n/a

Older docs may refer to ~/.kode/kode.json; that path is not the canonical location — the XDG-compliant ~/.config/kode/config.yaml is authoritative. A future major version may switch to JSON; until then the extension is implementation detail.

Resolution order (last wins)

  1. Built-in defaults — see cfg := &Config{...} in internal/config/config.go.
  2. User config (~/.config/kode/config.yaml).
  3. Workspace overlay (<work_dir>/.kode/config.yaml) — merged deeply, last key wins.
  4. Environment variables — KODE_RELAY_URL and similar prefixed KODE_<UPPER_SNAKE> overrides.
  5. CLI flags — --once, --json, --model, etc.

Every key reports its origin via kode --once /config show. Surfaces must not invent additional layers; new sources go into this list with an RFC.

Schema (v1)

# Versioned schema marker (planned for v2 migrations; absent = v1).
kodeVersion: 1

# Relay endpoint. Override via KODE_RELAY_URL.
relay_url: wss://kode.koder.dev/v1/relay/ws

# Default model the agent picks when no /model is set in the session.
default_provider: claude
default_model: claude-opus-4-7

# Working directory for context engines (Chronicle, Watch, etc.).
work_dir: ~/dev

# Custom prompt prepended to every session as system instructions.
custom_instructions: ""

# Tools the agent may call. Permissions (allow/deny per glob) are a
# follow-up — see DKODE-043 §Permissões.
allowed_tools:
  - shell
  - read_file
  - write_file
  - list_dir
  - install_pkg
  - env_info

# Ambient context engines (DKODE-080 family).
context:
  git_snapshot: true
  shell_history: true
  file_watcher: true
  stderr_buffer: true
  auto_kode_md: true
  chronicle:
    enabled: false
    mode: local           # "local" or "cloud"
    interval_turns: 5

# Auto-execution post-edit (opt-in; off by default in fresh installs).
auto_lint: false
lint_cmd: ""
auto_test: false
test_cmd: ""
auto_commit: false

# Watch mode: monitor work_dir for `// kode:` and `# kode:` comments.
watch_mode: false

# Reasoning controls.
thinking_tokens: 0          # 0 = disabled
reasoning_effort: ""        # "low" | "medium" | "high"

# Other toggles.
cache_prompts: false
dry_run: false
tui_skin: kode              # "kode" | "claude" | "gemini" | "codex"
welcomed_skins: []
output_style: ""            # "" | "concise" | "explanatory" | "markdown"
yolo_mode: false            # auto-approve every tool call (UNSAFE)

Planned schema additions (DKODE-043 §Permissões / §Auth / §Hooks)

These three blocks are documented now so workspace overlays can opt in ahead of full enforcement, but the runtime ignores unknown keys until the follow-up tickets land.

agents (named agent profiles)

agents:
  - name: refactor-bot
    model: claude/claude-opus-4-7
    system_prompt: "Senior Go engineer. Prefer hyperscale-first."
    tools: [shell, read_file, write_file]
    requires:
      - tools.has: shell
      - workspace.has: go.mod

permissions (allow/deny per glob)

permissions:
  allow:
    - "fs:read:~/dev/**"
    - "bash:git status"
  deny:
    - "fs:write:/etc/**"
    - "bash:*"     # default deny — agents must opt-in per workspace

Patterns are matcher-glob with these prefixes: fs:read:, fs:write:, bash:, net:http:, tool:<name>.

Workspace overlays may tighten but never loosen the user-level allow list — same constraint pattern as RFC-003 component policies.

hooks (subprocess callbacks)

See hooks.kmd for the full contract. Schema:

hooks:
  user_prompt_submit:
    - exec: ~/.kode/hooks/redact-secrets.sh
      timeout_ms: 1500
  tool_call_pre:
    - exec: ~/.kode/hooks/log-tools.py
  tool_call_post:
    - exec: ~/.kode/hooks/notify.sh
  session_start:
    - exec: ~/.kode/hooks/welcome.sh

CLI surface

Command Behaviour
kode --once /config show Print effective config + origin per key.
kode --once /config set <key> <value> Edit user-level config; round-trips YAML.
kode --once /config set --workspace <key> <value> Edit workspace overlay; creates <work_dir>/.kode/config.yaml if absent.
kode --once /config validate Lint user + workspace overlay; reports unknown keys, type errors.

Errors emitted by kode config follow errors/user-facing-messages.kmd — human message + KODE-CFG-NNN ID + technical detail on --verbose.

Migration

Until a kodeVersion: 2 schema lands, configs without the version key are treated as v1. The loader is permissive: unknown keys are ignored with a warning to stderr (one-shot mode) or to a log line in the TUI. This keeps pre-spec installs working unchanged.

Out of scope

  • Auth tokens — credentials live in credentials.enc (encrypted via keyring or machine-id derived key); never in config.yaml.
  • Per-session ephemeral state (skin pick, sessionID) — owned by the relay.
  • Secrets (API keys for non-OAuth providers) — same encrypted store.

References

  • internal/config/config.go — current implementation (YAML reader/writer).
  • meta/docs/stack/specs/kode/hooks.kmd — hooks contract.
  • meta/docs/stack/policies/document-format.kmd.kmd over .md.
  • products/dev/kode/backlog/done/043-kode-config-hierarquico.md — origin ticket.