Configuration

neondeck keeps mutable local state outside the repository. The app resolves runtime home from NEONDECK_HOME, then XDG_CONFIG_HOME/neondeck, then ~/.config/neondeck.

Runtime home

~/.config/neondeck/
  .env
  config.json
  mcp.json
  repos.json
  dashboard.json
  dashboard.schema.json
  SOUL.md
  skills/
    custom-skill/
      SKILL.md
  data/
    backups/
    neondeck.db
    flue.db

data/neondeck.db stores app state: watches, scheduled tasks, notifications, memories, workflow summaries, config history, and execution approvals. data/flue.db stores Flue runtime state. Neondeck app database migrations are shipped with the package and apply automatically before the app opens data/neondeck.db. Pre-migration backups are retained in data/backups/.

Secrets

Packaged and local app secrets live in runtime-home .env. Repo-root .env is supported as a checkout-only fallback when runtime-home .env does not define a value. Process environment variables still take precedence.

KILOCODE_API_KEY=...
KILOCODE_ORGANIZATION_ID=...
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...
GITHUB_TOKEN=...
GITHUB_LOGIN=...

Models and providers

Agent model choices live in config.json. Model strings must be provider-qualified and use allowlisted providers: kilocode, openai, or anthropic.

{
  "version": 1,
  "models": {
    "displayAssistant": "kilocode/kilo-auto/balanced",
    "displayAssistantThinkingLevel": "medium",
    "utility": "kilocode/kilo-auto/fast",
    "utilityThinkingLevel": "low",
    "selfImprovement": "kilocode/kilo-auto/fast",
    "selfImprovementThinkingLevel": "low",
    "subagents": {
      "default": "kilocode/kilo-auto/balanced",
      "defaultThinkingLevel": "medium",
      "repoResearcher": "kilocode/kilo-auto/balanced",
      "repoResearcherThinkingLevel": "medium",
      "ciInvestigator": "kilocode/kilo-auto/balanced",
      "ciInvestigatorThinkingLevel": "medium",
      "releaseReviewer": "kilocode/kilo-auto/balanced",
      "releaseReviewerThinkingLevel": "medium"
    }
  },
  "providers": {
    "kilocode": {
      "enabled": true,
      "apiKeyEnv": "KILOCODE_API_KEY",
      "organizationIdEnv": "KILOCODE_ORGANIZATION_ID"
    },
    "openai": {
      "enabled": true,
      "apiKeyEnv": "OPENAI_API_KEY"
    },
    "anthropic": {
      "enabled": true,
      "apiKeyEnv": "ANTHROPIC_API_KEY"
    }
  }
}

Provider config stores environment variable names, not raw secrets or arbitrary endpoints. thinkingLevel values use Flue's exposed reasoning tiers. The utility model is optional and falls back to the display assistant when omitted, but a low-cost utility model is recommended for titles, labels, notifications, and compact summaries. The self-improvement model is optional and falls back through the utility model and display assistant. It is used for bounded conversation reflection, memory curation, and PR/autopilot retrospective workflows. Supported thinking levels are off, minimal, low, medium, high, or xhigh. Provider registration changes require a server restart.

Learning

Learning config controls memory writes, skill patch policy, PR retrospective thresholds, review policy, and bounded memory curation. Memory uses active user, local, and project scopes; active sessions are marked stale after memory or skill changes rather than being silently rewritten.

{
  "learning": {
    "enabled": true,
    "memoryWriteMode": "auto",
    "skillWriteMode": "auto",
    "memoryCurationEnabled": true,
    "memoryCurationMode": "review",
    "memoryCurationTurnInterval": 200,
    "prRetrospectiveThreshold": 5,
    "maxPrBatchItems": 8,
    "memoryMaxActiveItems": 200
  }
}

Repositories

repos.json maps repo ids to local git checkouts and GitHub repository metadata. A local checkout is required for local git status and repo diagnostics. GitHub API features use GITHUB_TOKEN and do not expose the token to the browser.

Existing-VM exe.dev repo execution uses execution.exeDev.remoteRoot, optional per-repo execution.exeDev.repos, and per-checkout execution.exeDev.checkouts config. Env forwarding is opt-in and can combine repo-relative .env files, config vars, and explicit host env mappings.

Dashboard

dashboard.json selects theme, layout regions, plugin ids, and plugin config. The checked-in dashboard config and schema are copied into new runtime homes as defaults.

{
  "notifications": {
    "toasts": {
      "enabled": true,
      "soundEnabled": true,
      "minimumLevel": "ready",
      "readyDurationMs": 3600000,
      "maxVisible": 3
    }
  }
}

Ready notifications remain visible for one hour by default. Set readyDurationMs to 0 to keep them visible until dismissed, or choose a nonzero duration from 1 second through 24 hours. Attention and urgent notifications do not auto-timeout. Newly created notifications play a brief chime by default when they meet the toast policy. Set soundEnabled to false to mute it. A browser may require one click or keypress before it allows audio.

Schedules and watches

Scheduled tasks, their execution history, and PR watches are persisted in SQLite so they survive restart.

Watched-PR Autopilot reads shared guardrails from config.json plus any repository override in repos.json. Configure repository policy through the typed Autopilot policy action rather than editing metadata in chat. The Autopilot guide includes an exact guardrails.requiredChecks and unattended execution-policy example.

SOUL and skills

SOUL.md defines the agent name, emoji, and vibe. User runtime skills live under skills/, plus any external skill roots listed in config.json. Start a new session or restart the server after changing SOUL, model choices, memory, or skills so prompt context reloads deliberately.