cyberine
Usage

Configuration file

Cyberine supports layered JSON config files as an alternative to .env files. Precedence (highest first):

shell env  >  .cyberine/config.local.json  >  .cyberine/config.json  >  ~/.cyberine/config.json
>  ~/.cyberine/.env  >  <cwd>/.env  >  built-in defaults
LayerPathTrust
global~/.cyberine/config.jsonfully trusted (can hold API keys)
project<cwd>/.cyberine/config.jsonuntrusted: security-sensitive keys (apiKey, baseUrl, token, sandbox, taskTrusted, skipPermissions) are silently dropped
project-local<cwd>/.cyberine/config.local.jsonsame security restrictions as project

Config keys are dotted: <section>.<key>. Every key maps to exactly one env var. Example:

{
  "deepseek": { "apiKey": "sk-...", "model": "deepseek-v4-flash" },
  "loop":     { "maxTokens": 8000 },
  "chat":     { "model": "deepseek-v4-flash" }
}

cyberine config — manage config files

cyberine config path                       # list which config files exist on disk
cyberine config show [--json]              # merged effective config (secrets masked)
cyberine config get deepseek.model         # print one key's value
cyberine config set openai.model gpt-4o    # write to <cwd>/.cyberine/config.json (default)
cyberine config set openai.model gpt-4o --global   # write to ~/.cyberine/config.json
cyberine config set openai.model gpt-4o --local    # write to <cwd>/.cyberine/config.local.json
cyberine config doctor                     # list .env keys with a config.json equivalent

Backward compat: if no config.json exists, behaviour is identical to today — all config reads from env vars and .env files.

cyberine keybindings — find, create and edit the keymap file (ksq3f)

Before this, the keybindings file was described only in a header comment inside the source, so a user who had not read src/tui/keybindings.ts had no way to find it or to learn which action ids were legal.

cyberine keybindings            # create it from the CURRENT defaults if absent, then open $EDITOR
cyberine keybindings --path     # print the path the loader reads, and whether it exists
cyberine keybindings --print    # print the resolved default dump to stdout, write nothing

It writes to the same path the loader reads — $CYBERINE_KEYBINDINGS, else $CYBERINE_HOME/keybindings.json (default ~/.cyberine) — so the file it hands you is the file that actually loads. It never clobbers: an existing file is opened untouched, whatever is in it. After the editor exits, the file is re-loaded and any warning is printed, so a typo surfaces immediately rather than as a key that silently does nothing.

The generated file is the RESOLVED DEFAULT DUMP, not an empty scaffold: every action id Cyberine knows is listed, including the four chat actions that ship with no key, which appear with an empty chord "". An empty chord is a real value meaning "unbound" — it is also how you remove a default you do not want. Both accepted shapes are emitted, the flat fleet.* / chat.* action map and the KEYMAP-V2 bindings array, so the file documents what the loader will take.

Known Limitations and Deferred Work. No $schema URL is published: doing so would commit to hosting it, and this project has no settled public origin yet (T671), so the file carries a $docs pointer to this section instead of an invented domain. Editing is $EDITOR only — an interactive settings SCREEN for bindings is T418's scope and is gated on a real TTY. One behavioural note: a default written back as a chord is slightly STRICTER than the built-in default it came from, because a chord asserts ctrl/meta are not held (q stops also firing on Ctrl+Q). That is the intended chord semantics, but it means dumping the defaults and changing nothing is not a perfect no-op.