Configuration
OpenPocket loads config from JSON, merges with defaults, normalizes legacy keys, and writes a resolved runtime structure.
File Location
Resolution order:
- CLI
--config <path>if provided - default
OPENPOCKET_HOME/config.json - if missing, a default config file is auto-created
OPENPOCKET_HOME defaults to ~/.openpocket.
Load Order
At startup, config handling does the following:
- Parse JSON from config path.
- Convert legacy
snake_casekeys tocamelCasekeys. - Deep-merge with default config object.
- Normalize model profiles and typed fields.
- Resolve paths (
~and relative paths to absolute). - Ensure required directories exist.
- Bootstrap workspace files if missing.
API Keys
For each model profile:
- Use
models.<name>.apiKeyif non-empty. - Else use env var from
models.<name>.apiKeyEnv. - Else treat key as missing and fail task early.
Legacy Keys
The loader accepts old keys and maps them automatically, including:
- top-level:
project_name,workspace_dir,state_dir,default_model,script_executor - top-level (also):
heartbeat_config,cron_config - nested:
avd_name,android_sdk_root,bot_token,max_steps,save_step_screenshots,allowed_commands,base_url,api_key,reasoning_effort, etc.
After onboard (or legacy init), saved config uses camelCase keys.
Validation
Normalization currently enforces:
agent.progressReportInterval >= 1screenshots.maxCount >= 20scriptExecutor.timeoutSec >= 1scriptExecutor.maxOutputChars >= 1000heartbeat.everySec >= 5heartbeat.stuckTaskWarnSec >= 30cron.tickSec >= 2
If defaultModel does not exist in models, startup throws an error.
Defaults
See Config Defaults for the exact default JSON and field-by-field reference.