Settings
GraphoOS is configured in settings.toml (open it with Open Settings File, or use the
settings page: Open Settings, which has a search box). Every key below lives under its
[section]; the value shown is the default. TOML, not JSON: comments are #, strings
are quoted, and a missing key is the default.
Where settings live
- Yours, in the configuration directory: Open Settings File. That is the file to
edit for this machine. Next to it live
keymaps.toml(Open Keyboard Shortcuts),snippets/(Open User Snippets), colour themes you import, and afonts/folder for faces this editor should load without installing them in the system. - This workspace's, in
.graphoos/settings.toml: Open Workspace Settings File, which creates the file if it is not there. They win over yours while the folder is open, they are meant to be committed, and editing the file applies them at once — no reopening the window.
The palette always opens the right file. If you need the path (* is the release
channel of this build):
- macOS:
~/Library/Application Support/dev.graphoos.GraphoOS*/settings.toml - Linux:
~/.config/graphoos*/settings.toml - Windows:
%APPDATA%\graphoos\GraphoOS*\settings.toml GRAPHOOS_DATA_DIRmoves the whole profile (settings, plugins, caches, logs) to that folder.
The default file starts with #:schema ../extra/schemas/settings.json. That JSON Schema
is generated with this page. Point the same directive at a copy of the schema so the
editor that opens settings.toml can check keys as you type.
A working example
A workspace file only needs the keys this project disagrees with the defaults on. Leave API keys out of anything you commit: use the environment or the keychain (see Keys).
#:schema extra/schemas/settings.json
[editor]
font-size = 13
tab-width = 4
format-on-save = true
rulers = [100]
files-exclude = "**/{.git,node_modules,target,dist,.venv}"
[editor.formatters]
rust = "rustfmt --edition 2024"
python = "black -q -"
javascript = "prettier --stdin-filepath {file}"
[terminal]
font-size = 13
[terminal.env]
EDITOR = "graphoos --wait"
[ui]
language = "en"
density = "Compact"
[ai]
offline = false
chat-provider = "local"
inline-completion-provider = "local"
Coming from VS Code
Import Settings from VS Code reads your settings.json and this workspace's
.vscode/settings.json (comments and trailing commas included) and writes the keys that
mean the same thing here: font, tab width, rulers, wrapping, format on save, breadcrumbs,
indent guides, sticky scroll, inlay hints, autosave and the terminal font. Everything
else is listed by name instead of being guessed at, so nothing arrives translated into
something it is not. What was already in your settings file is kept.
The keyboard from VS Code
Import Keyboard Shortcuts from VS Code reads its keybindings.json and appends the
shortcuts whose commands exist here to your keymap file, keeping what is already in it:
cmd becomes meta, chords stay chords (cmd+k cmd+s), the when of each binding is
kept, and every command with no equivalent here is named in the message rather than
dropped in silence — a shortcut that quietly does nothing is worse than one that is
missing.
A theme from VS Code
Import a Colour Theme from VS Code takes the theme's .json open in the editor —
one from an extension, or the file VS Code writes with Generate Color Theme From
Current Settings — and writes it as a theme of ours in the themes directory, mapping
the colors and the TextMate scopes of tokenColors onto the keys used here. It then
appears in Change Color Theme. What has no equivalent is counted, not guessed at.
Generated by scripts/gen_docs.py from the editor's sources; edit those, not this file.
[core] — Core
Modal editing, themes and the window.
| Key | Default | What it does |
|---|---|---|
modal |
false |
Enable modal editing (Vim like) |
color-theme |
"GraphoOS Dark" |
Set the color theme of GraphoOS |
color-theme-follow-system |
false |
Follow the system's light or dark appearance, with the two themes below |
color-theme-dark |
"GraphoOS Dark" |
The color theme while the system is dark, when following it |
color-theme-light |
"GraphoOS Light" |
The color theme while the system is light, when following it |
icon-theme |
"GraphoOS Colors" |
Set the icon theme of GraphoOS |
custom-titlebar |
true |
Enable customised titlebar and disable OS native one (Linux, BSD, Windows) |
file-explorer-double-click |
false |
Only allow double-click to open files in the file explorer |
auto-reload-plugin |
false |
Enable auto-reload for the plugin when its configuration changes. |
welcome-at-start |
true |
Show the welcome screen when a window opens with nothing in it |
projects-folder |
"~/Projects" |
Where «New Project…» makes a project when only a name is typed |
share-anonymous-usage |
false |
Share anonymous usage numbers: once a week, one counter of the week, system and version goes up by one. Nothing that identifies you or this machine. Off unless you turn it on. |
[editor] — Editor
Fonts, wrapping, completion, formatting, blame and more.
| Key | Default | What it does |
|---|---|---|
font-family |
"JetBrains Mono NL, monospace" |
Set the editor font family |
font-size |
13 |
Set the editor font size |
code-glance-font-size |
2 |
Height in pixels of each line in the minimap (the map of the file on the right) |
minimap |
true |
Show the minimap: the whole file drawn small down the right-hand side, with the git changes and the matches of the find bar, to click or drag |
minimap-width |
90 |
Width of the minimap, in pixels |
auto-closing-tags |
true |
In HTML, XML, JSX and the like, write the closing tag when one is opened, and finish </ with the tag that is open |
color-swatches |
true |
Draw a bar in its own colour under every colour written in the file (#1e1e2e, rgb(…)) |
line-height |
1.5 |
Set the editor line height. If less than 5.0, line height will be a multiple of the font size. |
smart-tab |
true |
If enabled, when you input a tab character, it will insert indent that's detected based on your files. |
tab-width |
4 |
Set the tab width |
show-tab |
true |
If opened editors are shown in a tab |
show-bread-crumbs |
true |
If navigation breadcrumbs are shown for the file |
scroll-beyond-last-line |
true |
If the editor can scroll beyond the last line |
cursor-surrounding-lines |
1 |
Set the minimum number of visible lines above and below the cursor |
wrap-style |
"editor-width" |
The kind of wrapping to perform |
column-selection |
false |
Dragging the mouse selects a column (a box), as Shift+Alt+drag does |
wrap-column |
80 |
The number of columns to wrap at |
wrap-width |
600 |
The number of pixels to wrap at |
sticky-header |
true |
Show code context like functions and classes at the top of editor when scroll |
completion-width |
600 |
The number of pixels to show completion |
completion-show-documentation |
true |
If the editor should show the documentation of the current completion item |
completion-item-show-detail |
false |
Should the completion item use the detail field to replace the label field? |
show-signature |
true |
If the editor should show the signature of the function as the parameters are being typed |
signature-label-code-block |
true |
If the signature view should put the codeblock into a label. This might not work nicely for LSPs which provide invalid code for their labels. |
auto-closing-matching-pairs |
true |
Whether the editor should enable automatic closing of matching pairs |
auto-surround |
true |
Whether the editor should automatically surround selected text when typing quotes or brackets |
hover-delay |
300 |
How long (in ms) it should take before the hover information appears |
modal-mode-relative-line-numbers |
true |
If modal mode should have relative line numbers (though, not in insert mode) |
format-on-save |
false |
Whether it should format the document on save (if there is an available formatter) |
normalize-line-endings |
true |
Whether newlines should be automatically converted to the current line ending |
formatters |
External formatters by LSP language id (rust, javascript, python...). The command runs in the workspace with the document on stdin and must print the formatted document on stdout; {file} is replaced by the file path. When a language has one, it is used instead of the language server for Format Document and format on save. |
|
highlight-matching-brackets |
true |
If matching brackets are highlighted |
highlight-selection-occurrences |
true |
If the other places the selected text appears are highlighted |
occurrences-highlight |
true |
If the other places the symbol under the cursor appears are highlighted, as the language server finds them |
linked-editing |
false |
Rename the other half of a pair as one half is typed (an HTML tag's closing tag), where the language server knows the pairs |
highlight-scope-lines |
false |
If scope lines are highlighted |
enable-inlay-hints |
true |
If inlay hints should be displayed |
inlay-hint-font-family |
"" |
Set the inlay hint font family. If empty, it uses the editor font family. |
inlay-hint-font-size |
0 |
Set the inlay hint font size. If less than 5 or greater than editor font size, it uses the editor font size. |
enable-error-lens |
true |
If diagnostics should be displayed inline |
enable-git-blame |
true |
Show who last changed the current line, when, and the commit summary, inline at the end of the line (git blame) |
local-history |
true |
Local history: keep a copy of every file each time it is saved, to see and restore earlier versions (Local History in the palette) |
only-render-error-styling |
true |
Only render the styling without displaying messages, provided that Enable ErrorLens is enabled |
error-lens-end-of-line |
true |
Whether error lens should go to the end of view line, or only to the end of the diagnostic |
error-lens-multiline |
false |
Whether error lens should extend over multiple lines. If false, it will have newlines stripped. |
error-lens-font-family |
"" |
Set error lens font family. If empty, it uses the inlay hint font family. |
error-lens-font-size |
0 |
Set the error lens font size. If 0 it uses the inlay hint font size. |
enable-completion-lens |
false |
If the editor should display the completion item as phantom text |
enable-inline-completion |
true |
If the editor should display inline completions |
completion-lens-font-family |
"" |
Set completion lens font family. If empty, it uses the inlay hint font family. |
completion-lens-font-size |
0 |
Set the completion lens font size. If 0 it uses the inlay hint font size. |
blink-interval |
500 |
Set the cursor blink interval (in milliseconds). Set to 0 to completely disable. |
smooth-caret |
true |
The cursor glides to where it goes instead of jumping (not with the system's «reduce motion») |
smooth-scrolling |
true |
Jumps in the file (to a line, a page) scroll there instead of cutting (not with the system's «reduce motion») |
multicursor-case-sensitive |
true |
Whether the multiple cursor selection is case sensitive. |
multicursor-whole-words |
true |
Whether the multiple cursor selection only selects whole words. |
render-whitespace |
"none" |
How the editor should render whitespace characters.\nOptions: none, all, boundary, trailing. |
show-indent-guide |
true |
Whether the editor show indent guide. |
rulers |
[] |
Columns to draw a vertical guide at, e.g. [80, 100]; empty = none |
scroll-speed-modifier |
1.0 |
How much a turn of the mouse wheel scrolls, as a multiplier |
autosave-interval |
0 |
Set the auto save delay (in milliseconds), Set to 0 to completely disable |
format-on-autosave |
true |
Whether the document should be formatted when an autosave is triggered (required Format on Save) |
atomic-soft-tabs |
false |
If enabled the cursor treats leading soft tabs as if they are hard tabs. |
double-click |
"single" |
Use a double click to interact with the file explorer.\nOptions: single (default), file or all. |
move-focus-while-search |
true |
Move the focus as you type in the global search box |
diff-context-lines |
3 |
Set the default number of visible lines above and below the diff block (-1 for infinite) |
bracket-pair-colorization |
false |
Whether the editor colorizes brackets |
bracket-colorization-limit |
30000 |
Bracket colorization Limit |
files-exclude |
"**/{.git,.svn,.hg,CVS,.DS_Store,Thumbs.db}" |
Glob patterns for excluding files and folders (in file explorer) |
[terminal] — Terminal
The integrated terminal and its profiles.
| Key | Default | What it does |
|---|---|---|
font-family |
"" |
Set the terminal font family. If empty, it uses editor font family. |
font-size |
0 |
Set the terminal font size, If 0, it uses editor font size. |
line-height |
0 |
Set the terminal line height, If 0, it uses editor line height |
scrollback |
10000 |
Lines kept above the screen, to scroll back to (at most 100000) |
shell-integration |
true |
Let the shell tell the editor about its commands (where each starts, how it ended, the folder it is in), without touching your shell's files |
copy-on-selection |
false |
Copy what is selected in the terminal as soon as it is selected |
sticky-scroll |
true |
Keep the command whose output is on screen in the terminal's first line when its prompt has scrolled out of sight |
restore-sessions |
true |
Open the terminals of the last session again, each in its folder, with its name, colour and icon and its last lines |
suggestions |
true |
Suggest, in grey after the cursor, the rest of a command run before that starts as what is typed; → takes it |
letter-spacing |
0 |
Pixels added between the letters of the terminal (may be negative) |
cursor-blinking |
false |
Make the terminal's cursor blink while it has the focus, at the editor's blink interval |
font-ligatures |
false |
Let the font join letters into ligatures in the terminal (=>, !=, ->), for fonts that have them |
[ui] — UI
Fonts and sizes of the interface, panels and tabs.
| Key | Default | What it does |
|---|---|---|
scale |
+1.0 |
Set the UI scale. Defaults to 1.0 |
font-family |
"" |
Set the UI font family. If empty, it uses system default. |
font-size |
13 |
Set the UI base font size |
icon-size |
0 |
Set the icon size in the UI |
header-height |
36 |
Set the header height for panel header and editor tab header |
status-height |
25 |
Set the height for status line |
tab-min-width |
100 |
Set the minimum width for editor tab |
tab-separator-height |
"Content" |
Set whether the editor tab separator should be full height or the height of the content |
scroll-width |
10 |
Set the width for scroll bar |
drop-shadow-width |
0 |
Controls the width of drop shadow in the UI |
palette-width |
500 |
Controls the width of the command palette |
hover-font-family |
"" |
Set the hover font family. If empty, it uses the UI font family |
hover-font-size |
0 |
Set the hover font size. If 0, uses the UI font size |
trim-search-results-whitespace |
true |
Trim whitespace from search results |
list-line-height |
25 |
Set the line height for list items |
tab-close-button |
"Right" |
Set position of the close button in editor tabs |
open-editors-visible |
true |
Display the Open Editors section in the explorer |
density |
"Comfortable" |
How much room the interface leaves: Comfortable, or Compact for more on screen |
explorer-auto-reveal |
true |
Select the active file in the explorer when switching tabs, opening the folders it is in |
explorer-indent-guides |
true |
Draw a guide line per level in the explorer's tree |
explorer-compact-folders |
true |
Show folders that hold only one folder as one row in the explorer (src/main/java) |
language |
"system" |
The language of the interface: system, en or es |
[ai] — AI
AiloOS providers, the assistant, the agent and ghost text.
| Key | Default | What it does |
|---|---|---|
ailoos-endpoint |
"https://api.ailoos.com/api/andromeda/v1" |
AiloOS cloud endpoint: the base of its OpenAI-compatible API (AndromedaLM lives at https://api.ailoos.com/api/andromeda/v1) |
ailoos-api-key |
"" |
AiloOS API key sent as a Bearer token. Leave empty to use the AILOOS_API_KEY environment variable, or when the endpoint needs none. |
local-endpoint |
"http://127.0.0.1:8080/v1" |
Local endpoint: the base of an OpenAI-compatible API on this machine, such as ailoos serve running EmpoorioLM (http://127.0.0.1:8080/v1) |
ailoos-model |
"andromedaLM-1b-v1" |
Model used by default with the AiloOS cloud provider |
local-model |
"" |
Model used by default with the local provider (empty: the first one the server lists) |
max-tokens |
1024 |
Maximum tokens the assistant may generate per answer |
temperature |
0.7 |
Sampling temperature (0 = deterministic, 1 = creative) |
context-chars |
12000 |
Characters of the current file sent as context with each message (0 disables file context) |
rules-chars |
16000 |
Characters of project rules (AGENTS.md, .graphoos/rules.md, .graphoos/rules/*.md) and workspace memory (.graphoos/memory.md) sent with each message (0 disables them) |
offline |
false |
Offline: never contact AiloOS in the cloud. Only the local server answers (chat, model list and agent). |
session-token-limit |
0 |
Tokens (prompt + answer, all providers) the assistant may use in one editor session; 0 = no limit. When reached, new requests are refused until the counter in the panel is clicked to reset it. |
ailoos-usd-per-million-input |
0.0 |
USD per million prompt tokens billed by AiloOS, to show the cost of the session (0 while the API is free) |
ailoos-usd-per-million-output |
0.0 |
USD per million answer tokens billed by AiloOS, to show the cost of the session (0 while the API is free) |
inline-completion |
true |
Ghost text: propose code at the cursor from the AI when no language server offers an inline completion (Tab accepts) |
inline-completion-provider |
"ailoos" |
Provider of the ghost text: local (EmpoorioLM through ailoos serve, native continuation), ailoos (AndromedaLM in the cloud, through the chat API) or custom (the extra provider) |
inline-completion-model |
"" |
Model for the ghost text; empty = the provider's default model |
inline-completion-delay-ms |
400 |
Milliseconds to wait after the last keystroke before asking for ghost text |
inline-completion-max-tokens |
48 |
Maximum tokens of one ghost text proposal |
inline-completion-context-chars |
3000 |
Characters before the cursor sent with a ghost text request (a third as many after it) |
custom-name |
"Custom" |
An extra OpenAI-compatible provider for development (DeepSeek, OpenRouter, Groq, …): its name in the provider menu |
custom-endpoint |
"" |
Base URL of the extra provider, ending in /v1 (e.g. https://api.deepseek.com/v1); empty = no extra provider |
custom-api-key |
"" |
API key of the extra provider (or the GRAPHOOS_AI_API_KEY environment variable) |
custom-model |
"" |
Default model of the extra provider |
agent-backend |
"graphoos" |
Who acts in Agent mode: graphoos (the agent that comes with the editor, with the chosen model), claude, codex or gemini (the one installed on this machine, with its own account) or andromeda (the Ailoos CLI); the same cards and diffs for all |
auto-context |
true |
Automatic context: attach the places of the workspace the index finds for each message (no @ needed) |
auto-context-chunks |
3 |
How many places the index attaches per message |
index-embeddings |
true |
Embed the workspace index with the local EmpoorioLM (ailoos serve, /v1/embeddings); off = lexical search only |
providers |
More OpenAI-compatible providers, by name, as [ai.providers. |
|
agent-provider |
"" |
Provider of the agent: empty = the one the chat uses; ailoos, local, custom or the name of one of [ai.providers] |
chat-provider |
"" |
Provider the chat starts on in every window: empty or ailoos = AiloOS, local, or the name of one of [ai.providers] (set by «Choose Your Assistant») |
agent-model |
"" |
Model of the agent; empty = its provider's default model |
[editor.formatters]
External formatters by language id: a command that reads the file on stdin and writes the
formatted text on stdout ({file} in the command is replaced by the path). Used by
Format Document and by format-on-save when the language server has no formatter.
When a language has an entry here, it is used instead of the language server.
[editor.formatters]
rust = "rustfmt --edition 2024"
python = "black -q -"
go = "gofmt"
javascript = "prettier --stdin-filepath {file}"
[terminal.profiles] and [terminal.env]
Named shells for the terminal panel. [terminal.default-profile] picks one per OS
(macos, linux, windows). Each profile may set command, arguments,
environment and workdir.
[terminal.default-profile]
macos = "default"
linux = "default"
windows = "default"
[terminal.profiles]
default = {}
[terminal.profiles.cargo]
command = "cargo"
arguments = ["run"]
workdir = "/home/user"
environment = { KEY = "VALUE" }
[terminal.env] is added to every terminal. [terminal.env-macos],
[terminal.env-linux] and [terminal.env-windows] win on that system, the same way
VS Code's terminal.integrated.env.* does. Full behaviour of the panel is in
Terminal.
Plugin settings
Each plugin adds its own section named after it (for example [graphoos-c]), with the keys
its volt.toml declares; the plugin's page in the Plugins panel edits them. How to write
one: Writing a plugin.
The rest of the workspace
settings.toml is only the editor. Developers also keep these files next to the
project. Deep behaviour lives on the pages linked; this table is the map.
| File | What it is |
|---|---|
.graphoos/settings.toml |
Workspace settings; win over yours while the folder is open |
keymaps.toml (config dir) |
Bindings on this machine. Same [[keymaps]] shape as the defaults. Keyboard shortcuts |
.graphoos/snippets/<lang>.toml, global.toml |
Workspace snippets. User copies live in the config dir's snippets/ |
.graphoos/run.toml |
Run and debug configurations ([[configs]]). Run and debug |
.vscode/launch.json |
Read as it is, next to run.toml; compounds included |
AGENTS.md, .graphoos/rules.md, .graphoos/rules/*.md |
Project rules sent with the assistant |
.graphoos/memory.md |
Workspace memory; /remember appends a dated note |
.graphoos/agent.toml |
Agent permissions (read / write / delete / run / network / mcp = allow | ask | deny) and allow-commands |
.graphoos/mcp.toml |
MCP servers for this workspace. User-wide: ~/.ailoos/mcp.toml |
.graphoos/mcp-server.toml |
Which of the editor's own MCP tools a client may call |
.graphoos/tasks.toml |
Scheduled agent work ([[tasks]] with name, prompt, schedule) |
.graphoos/skills/ |
Markdown skills with name / description / triggers frontmatter. User-wide: ~/.ailoos/skills/ |
.graphoos/spec.md |
Spec the agent can open as /spec |
.graphoos/first-prompt.md |
First prompt when New Project… opens the folder |
Assistant, agent, index and MCP: Assistant and AI.
Markdown you can copy
Paste these as they are. The assistant reads them as instructions (not as attached data). Each block is one file.
AGENTS.md — workspace root. Travels with every message, before .graphoos/rules.
# Agent
- Prefer this workspace's own tools (`cargo`, `npm`, `make`).
- Do not commit secrets, API keys or `.env`.
- After a code change, run the project's check (`cargo test`, `npm test`, …) before calling the task done.
.graphoos/rules.md — extra rules for this editor. .graphoos/rules/*.md are concatenated after it.
Answer in the language of the request.
Keep diffs small. Do not refactor files you were not asked to touch.
.graphoos/memory.md — /remember <note> appends a dated line. Edit freely.
# Memory
<!-- `/remember` appends here. The assistant reads this file with the project rules. -->
.graphoos/spec.md — /spec creates this template (the editor writes it in Spanish) and opens it. The agent reads it before each task.
# Especificación — {project}
<!-- El agente lee este fichero antes de tocar código y pregunta si falta algo. -->
## Objetivo
<!-- Qué problema resuelve el cambio y para quién, en dos frases. -->
## Invariantes
<!-- Lo que NUNCA puede romperse. Una línea por invariante, comprobable. -->
-
## Criterios de aceptación
<!-- Cómo se sabe que está hecho. Cada uno debería poder ser un test. -->
- [ ]
## Fuera de alcance
<!-- Lo que el agente no debe tocar aunque parezca relacionado. -->
-
## Notas
.graphoos/skills/rust-tests.md — a skill. name, description and triggers in the frontmatter; the body is the procedure. User-wide copy: ~/.ailoos/skills/.
---
name: rust-tests
description: Run and write Rust tests in this workspace
triggers: [test, cargo test]
---
1. `cargo test` at the workspace root.
2. If a test fails, read the file and the assertion before changing anything else.
3. Do not ignore a failing test to make the suite green.
.graphoos/first-prompt.md — New Project… → Describe it to the agent writes your description here. The file is the prompt, nothing around it.
Build a CLI that reads a folder and prints a tree of its files. Rust, clap, tests.
Keys, not in the TOML
Do not commit API keys in .graphoos/settings.toml.
ai.ailoos-api-keyempty →AILOOS_API_KEY.ai.custom-api-keyempty →GRAPHOOS_AI_API_KEY.[ai.providers.<name>]withapi-keyempty → the key kept by AI: Keep an API Key in the Keychain… (the system keychain, not the file).ai.offline = truenever contacts AiloOS in the cloud; only the local server (ai.local-endpoint, defaulthttp://127.0.0.1:8080/v1) answers.
The assistant blanks recognisable secrets before text leaves the machine. Put keys in the environment or the keychain, not in a committed file.
See also
Source: docs/settings.md