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, and ChatGPT OAuth credentials.
data/flue.db stores Flue runtime state. On POSIX systems, Neondeck
protects the data/ directory and the Neondeck database, including
existing WAL and shared-memory sidecars, before accessing OAuth credentials.
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/; Neondeck retains the latest two recognized
backup sets. Use neondeck db backup to make a snapshot and
neondeck db restore <backup-name> only after stopping
Neondeck.
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=...
Trusted dashboard origins
Neondeck accepts dashboard API traffic from loopback hosts by default.
To run the dashboard behind an authenticated reverse proxy, add each
externally visible browser origin to server.trustedOrigins
in config.json. Merge this block into the existing file;
preserve its generated localApi.token and other settings:
{
"version": 1,
"server": {
"trustedOrigins": ["https://example.exe.xyz"]
}
}
Origins are exact scheme, host, and port matches. Wildcards, credentials, paths, query strings, and fragments are rejected. Non-loopback origins must use HTTPS. Restart Neondeck after changing this startup-time setting.
Models and providers
Agent model choices and provider registration live in
config.json. Model strings must be provider-qualified and
use a built-in or explicitly configured provider:
kilocode, openai,
anthropic, openai-codex, or a validated
OpenAI-compatible provider id.
Choose models
{
"models": {
"displayAssistant": "openai-codex/gpt-5.6-sol",
"displayAssistantThinkingLevel": "medium",
"prReview": "openai/gpt-5.5",
"prReviewThinkingLevel": "medium",
"prReviewTimeoutMs": 1800000,
"subagents": {
"explore": "openai/gpt-5.6-terra",
"exploreThinkingLevel": "medium"
}
}
}
Register providers
{
"providers": {
"openai": {
"enabled": true,
"apiKeyEnv": "OPENAI_API_KEY"
},
"openaiCodex": {
"enabled": true
},
"openaiCompatible": [
{
"id": "openrouter",
"enabled": true,
"baseUrl": "https://openrouter.ai/api/v1",
"apiKeyEnv": "OPENROUTER_API_KEY",
"api": "openai-completions",
"contextWindow": 200000,
"maxTokens": 8192
}
]
}
}
Compatible endpoint rules
-
Credentials: provider config stores environment variable
names, never raw secrets.
apiKeyEnvis optional, so keyless loopback servers work too. -
Limits:
contextWindowandmaxTokensare optional positive integers describing the selected service and model. - URLs: endpoints require HTTPS except for loopback HTTP. URL credentials, query strings, fragments, reserved ids, and duplicate ids are rejected.
- Ownership: endpoint definitions may be changed through setup or the local access-controlled dashboard/API, never through a model-callable config action.
ChatGPT OAuth tokens live in the local app database and are managed
with
neondeck auth ... openai-codex.
Model roles and fallbacks
| Setting | Work it powers | Default behavior |
|---|---|---|
displayAssistant |
Chat and model-backed Autopilot owners | Primary model |
prReview |
Initial and follow-up read-only PR review | Uses displayAssistant |
utility |
Titles, labels, notifications, and compact summaries | Uses displayAssistant |
selfImprovement |
Reflection, memory curation, and retrospectives | Uses utility, then displayAssistant |
subagents.explore |
Focused read-only repository investigation for chat, PR review, and Autopilot | Uses displayAssistant |
Reasoning and runtime behavior
-
thinkingLevelacceptsoff,minimal,low,medium,high, orxhigh. -
prReviewTimeoutMsdefaults to 1,800,000 milliseconds and accepts values from 10,000 through 1,800,000. Initial and follow-up reviewers may delegate focused evidence gathering toexplore; the parent reviewer still owns the final review or response. - Provider registration and standalone CLI ChatGPT login or logout require a server restart.
Explore subagent
explore is a shared Flue subagent available to the display
assistant, initial and follow-up code reviewers, and active Autopilot owners.
It runs in a fresh context and receives only the complete task briefing
written by its parent. Its model and reasoning level are independently configurable
through models.subagents.explore
and models.subagents.exploreThinkingLevel.
When those settings are absent, Explore uses the display-assistant
model and reasoning level. During neondeck init, setup
offers an optional cheaper model for this role and recommends a fast
profile such as OpenAI Luna with high reasoning or OpenAI Terra with
medium reasoning.
Parent agents use one Explore task for narrow or dependent research. When several investigations are independent, they may launch up to three distinct Explore tasks in one tool-call batch; Flue runs that batch concurrently, and the parent reconciles the returned evidence before it acts or answers.
PR reviewer prompts
Human review has two independently configurable full system prompts:
initial-review for each fresh bounded review submission and
follow-up-reviewer for the durable read-only reviewer chat.
Inspect, replace, or reset either prompt in the dashboard's Runtime panel, through typed config tools, or through the local access-controlled
API.
{
"prReview": {
"prompts": {
"initial-review": "Complete replacement prompt…",
"follow-up-reviewer": "{{reviewContextDeliveryGuidance}}\n{{workspaceToolGuidance}}"
}
}
}
Overrides are non-empty strings up to 40,000 characters. The initial
prompt receives PR facts separately as untrusted JSON and has no
template tokens. The follow-up prompt supports {{workspaceToolGuidance}}
and {{reviewContextDeliveryGuidance}}. These expand
to stable policy explaining the workspace tools and per-question
signal delivery; mutable review facts are delivered separately in the review-context signal. Initial changes apply to the next review run; follow-up changes
apply to the next turn, including an existing reviewer conversation. There
is no prompt versioning or stale-session state.
Set a prompt to null through
neondeck_config_update_pr_review_prompt or
POST /api/pr-review/prompts to restore its built-in default.
The override replaces the whole shipped prompt, including its safety and
review guidance. That footgun is intentional. The read-only workspace tools,
structured result schema, and GitHub delivery boundary are still selected
and enforced by the server rather than by prompt text.
Autopilot owner prompts
Full owner system prompts are configurable independently for
prepare-only, autofix-with-approval, and
autofix-push-when-safe. Use the prompt editor in the
dashboard's Runtime panel, ask Neon through the typed config
actions, or use the local access-controlled API. The editor shows the effective
prompt and can reset an override to the built-in default. notify-only has no template because it never starts an owner mutation turn.
{
"autopilot": {
"prompts": {
"prepare-only": "Complete replacement prompt using {{mode}} and {{workspaceInstructions}}",
"autofix-with-approval": "Complete replacement prompt…",
"autofix-push-when-safe": "Complete replacement prompt…"
}
}
}
Overrides are non-empty strings up to 20,000 characters. Supported
substitutions are {{source}},
{{mode}}, {{status}},
{{capabilities}}, and
{{workspaceInstructions}}. Existing owners use a
saved change on their next turn; no prompt versioning or stale-owner
state is created. Set a mode's prompt to null through
neondeck_config_update_autopilot_prompt or
POST /api/autopilot/prompts to restore the default.
The override replaces the entire shipped owner prompt. This is a powerful local footgun by design. Prompt text still cannot expand the tools supplied for the current turn or bypass server-side delivery guards; those capabilities are derived from current watch state and enforced outside the model prompt.
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.
Work in progress: exe.dev settings describe an experimental approved-command backend for an existing VM. They do not select a remote workspace for chat, schedules, reviews, managed worktrees, or Autopilot. Keep local execution as the default unless you are deliberately testing that limited command path.
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 explains the mode-specific
delivery ceiling and semantic autonomous judgment. Effective
guardrails.requiredChecks values are optional hints for the
continuing owner; they are not an autonomous delivery prerequisite. The
same setting remains enforceable in separate `/fix-ci`, Kilo, and prepared-diff
verification flows.
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.