RustCode stores its canonical configuration in config.toml. On macOS and
Linux this is ${XDG_CONFIG_HOME:-~/.config}/rustcode/config.toml; on Windows
it is %APPDATA%\rustcode\config.toml. RUSTCODE_CONFIG_DIR overrides the
directory on every platform, which is useful for portable installs and tests.
Older installations using models.json and config.json are still read. On
the next normal save, Rustcode writes the merged configuration to
config.toml and leaves the legacy files intact as a rollback copy. Missing
fields use compiled defaults. Malformed or newer unsupported TOML is preserved
and reported instead of being overwritten.
When a newer RustCode first starts (terminal, --acp for the macOS app, or a
headless prompt), it applies any user-data migrations that release introduced,
whether it was installed with Homebrew, the installer, or by replacing the
binary. Each migration has a stable id and runs once: its id is recorded in
storage/migrations.json in the config directory only after it succeeded.
storage/migrations.lock keeps RustCode processes that start together from
running the same step twice; a process that cannot take the lock within ten
seconds starts normally and leaves the work to the one that holds it.
A step that fails is not recorded. RustCode prints which step failed, carries on starting, and retries the step (and the steps after it) on the next start. Migrations are written to be safe to repeat after an interruption, and they keep the original data until its replacement is in place.
Inspect the state without changing anything:
rustcode storage status # pending and completed migrations
rustcode storage status --json # the same, for scripts and support tools
rustcode storage usage # how much space each store takes
rustcode storage usage --json # the same, with each store's pathsstorage usage reads only. It lists each store of the config directory with
its size, file count, what it holds and how it is bounded today:
| Store | Holds | Bounded by |
|---|---|---|
| threads | each thread's history, logs and artifacts | kept; scratch threads are pruned |
| history archive | history that compaction removed from a thread | kept |
| tool output | full output of commands too long for the conversation | kept; referenced from thread histories |
| attachments | images attached to messages | kept; referenced from thread histories |
| workspaces | isolated subagent workspaces | kept |
| backups | copies of config files taken before a change | kept |
| logs | debug.log and debug.log.1 |
rotation |
| sync history | the Git history of rustcode sync |
kept |
| indexes | the symbol index and saved memory | kept |
| remote | paired devices and the gateway's state | kept |
Everything else (configuration, credentials, models, locks) is listed as
"other". The sessions link left by the threads rename is not counted twice.
No store is cleaned automatically beyond what the table says.
tool output and attachments collect files whose thread was later deleted
or pruned. storage clean finds them:
rustcode storage clean # list them; changes nothing
rustcode storage clean --apply # move them to storage/removed
rustcode storage clean --json # the plan (and result), for scriptsA file is listed only when no file under threads/ or history_archive/
names it and it has not changed for 30 days; folders and links in the stores
are never touched, and no other store is. --apply moves each file to
storage/removed/<date-time>/<store>/: move it back to restore it. A later
--apply deletes a folder there once it is 14 days old. Nothing runs this
automatically.
If migrations.json was written by a newer RustCode (a higher format), this
version runs no migrations and leaves the file alone; upgrade RustCode. If the
file is unreadable, RustCode reports it and runs nothing; move it aside to let
every step run again. The file is machine-local and is never synced.
Registered migrations:
| Id | What it does |
|---|---|
0001-sessions-folder-to-threads |
Renames sessions/ to threads/ and leaves sessions as a link to it, so an older RustCode still finds every thread. If an older version created a new sessions/ after the rename, its threads are moved in; a thread present in both folders is left in sessions/ and reported, and the step runs again on the next start once one copy is moved aside. Until the step has run, RustCode reads the old folder. |
0002-legacy-thread-layout |
Moves threads that early versions kept directly in threads/<id> (or threads/<id>.json) to threads/YYYY/MM/DD/<id>, as rustcode threads migrate does: each is copied, the copy put in place, and only then the original removed. A thread already at its destination is left alone. |
0003-prune-scratch-thread-folders |
Removes the empty folders that title, compaction and recap requests once left in threads/ (#2562, #2571). Only folders named like those requests and holding no history are removed. Before, this ran on every start of the terminal. |
rustcode threads migrate [--dry-run] still runs the thread-layout move by
hand. The legacy configuration conversion above stays where it is: it merges
into the config.toml being saved, and an older RustCode reads the JSON files
until then. So does the old fmr folder rename, which happens before the
config directory exists to hold a checkpoint.
The TOML file contains the default model selection, models array, runtime
preferences, MCP servers, tool protocol, agent mode, verbosity, theme, active
session, and the per-turn max_tool_rounds safety backstop. It defaults to 40
rounds and is only a final limit after semantic loop and failure guards.
Writes use a temporary file and replacement so an interrupted save does not
leave a truncated configuration. On Unix, the file is written with owner-only
permissions because model profiles may contain API keys.
Several workspace-changing tool calls in one response (shell commands that are
not provably read-only, file writes and edits, MCP tools without
readOnlyHint) run one after another in the order given. Each model profile
may set max_mutating_calls_per_response to change how many run per response:
the default is four, zero is normalized to that default and values above the
hard cap are clamped. Calls beyond the limit are held and run automatically in
a later round. Set allow_tool_batching = false to restrict a profile to one
workspace-changing call per response:
[[models]]
name = "trusted-model"
url = "https://example.invalid/v1"
model = "trusted-model"
max_mutating_calls_per_response = 2OpenCode Zen's paid Muse model uses the OpenAI Responses API. RustCode includes
this profile by default; add OPENCODE_API_KEY to the environment and select
opencode-muse-spark-1.3 as the model:
[[models]]
name = "opencode-muse-spark-1.3"
url = "https://opencode.ai/zen/v1/responses"
model = "muse-spark-1.3"
engine = "openai"
env_key = "OPENCODE_API_KEY"
api_protocol = "responses"
tool_protocol = "apinative"env_key is the name of the environment variable that holds the key, never
the key itself. A value that is not a variable name (a pasted omlx-… key, or
one containing -, :, =, . or spaces) is rejected with a warning that
names the profile, so the profile keeps working through api_key or
credential. Setting env_key to the same value as api_key stores the
secret twice: rustcode doctor reports it and loading the configuration warns
about it. Neither message ever includes the value.
OpenCode's temporary free models are restricted by OpenCode's service to the OpenCode client session. RustCode does not bypass that restriction; use a paid Zen model and valid billing/API credentials for this provider profile.
Configured MCP servers are started by Rustcode before ACP prompts are handled; ACP's optional MCP-over-ACP transport is not required.
Add, list, and remove servers from the command line. rustcode mcp add takes
a name followed by a URL for a remote (Streamable HTTP) server, or by a command
to spawn over stdio:
rustcode mcp add --transport http api https://mcp.example.com/mcp \
--header "Authorization: Bearer <token>"
rustcode mcp add --env API_KEY=<key> files -- npx -y @example/files-mcp
rustcode mcp list
rustcode mcp remove api--transport is inferred from an http(s):// target when omitted. Repeat
--header (remote) or --env (stdio) as needed, and put a stdio command after
-- when its arguments start with a dash. --force replaces a server with the
same name. Servers are written to [[mcp_servers]] in the user config.toml
and start with the next session. Header and environment values are stored
there in plain text (the file is created with mode 0600), and mcp list
prints only their names. config.toml is one of the files rustcode sync
pushes, so keep the sync remote private when it holds tokens.
Inside a session the model does the same through the manage_mcp_servers
tool, which applies the validation of rustcode mcp add:
operation |
Effect |
|---|---|
add |
Saves the server to the user config.toml and starts it in the running session, so its tools are callable in the same turn. Takes name, target (one URL, or the command followed by its arguments), and optionally transport, headers (Name: value), env (KEY=value), client_id, always_include, replace (the tool's --force) and start (false to save without starting). |
list |
Prints the mcp list lines for this workspace, each marked [running] or [not running]. |
start |
Starts, or restarts, a configured server by name in the running session. |
remove |
Removes the server from the user config and stops it. |
Every operation asks for approval before it runs, because add and start
launch a command or open a connection the model chose and add and remove
edit your config; Plan mode blocks the tool outright. Approve-all (YOLO)
answers this prompt like any other. The prompt shows the command or URL and the
header and environment names; their values are left out of the prompt, the tool
result and startup errors, as in mcp list. The values the model passes are
still part of its own tool call in the session history, so prefer adding a
server that needs a real secret with rustcode mcp add yourself. A server that
fails to start stays saved, and start retries it. In the app, Settings ›
Capabilities has a Retry action on every server row that reconnects it in place
without rewriting config.toml, so a failed server needs no off-and-on toggle.
When a project
.rustcode/config.toml sets its own mcp_servers, a server added to the user
config is saved but is not active, and not started, in that workspace.
Native API requests expose at most 16 MCP tool schemas at a time. Set
always_include = true on an MCP server's [[mcp_servers]] entry to reserve
slots for its complete toolset, independent of the current prompt:
[[mcp_servers]]
name = "mail"
command = "mail-mcp"
args = []
always_include = trueReservations are applied in configuration order and still obey the schema
byte budget. If a complete server toolset cannot fit either limit, that
reservation is rejected for the request; the rejection and omitted tool names
are recorded in mcp.native_schema_selection.
An MCP request fails when the server sends neither a response nor progress for
30 seconds. A stdio tool call asks for progress (_meta.progressToken), and
each notifications/progress the server sends for it restarts the wait; a
call that keeps reporting progress may run up to 61 timeouts in total (about
30 minutes at the default). Set timeout_secs on a server whose tools run
longer without reporting progress, such as downloads or builds. rustcode mcp add --force keeps a timeout_secs already set on the server it replaces:
[[mcp_servers]]
name = "video"
command = "video-mcp"
timeout_secs = 600Parallel Search MCP provides web search and page fetching over Streamable HTTP. The anonymous endpoint needs no account or API key and uses Fast mode for search, with lower rate limits intended for exploration and light use.
rustcode mcp add --transport http parallel-search https://search.parallel.ai/mcp \
--header "User-Agent: RustCode"
rustcode mcp listStart a new session in a workspace without a project mcp_servers override,
then ask, for example:
Use Parallel to find the current Tokio
JoinSetdocumentation, fetch the relevant page, and explain how to cancel all tasks. Include the source URL.
The server exposes web_search and web_fetch. Search sends the query to
Parallel; fetching sends the requested URLs. To remove the saved server, run
rustcode mcp remove parallel-search.
Sem provides symbol lookup, source search,
structural diffs and impact analysis over stdio MCP. Install Sem using its
upstream instructions and ensure sem --version works in Rustcode's environment.
rustcode mcp add --env SEM_REPO=/absolute/path/to/checkout sem -- sem mcp
rustcode mcp listReplace the path with an existing Git checkout on the machine running Rustcode.
Start a new session without a project mcp_servers override, then ask:
Use Sem to find an existing function by name and show its implementation and callers. Do not edit the code or run validation commands.
sem_find retrieves symbols and context; sem_grep searches source text.
The configured path is fixed, not automatically changed when you switch
workspaces. Remove it with rustcode mcp remove sem before configuring another
checkout. The first lookup may build a local index. The full server also exposes
validation tools that can execute commands: SEM_REPO selects a repository, not
a sandbox. Use trusted checkouts and appropriate process permissions. Source
returned by tools becomes part of the context sent to your configured model.
/remote starts the remote gateway when none is running. Where
that gateway listens comes from the [remote] section:
[remote]
bind = "100.92.13.44" # address to listen on; default 127.0.0.1
port = 17879 # optional; default 17879
advertise = "mac.netbird.cloud" # optional; what devices dial, if not `bind`
prefer_interface = "netbird" # optional; with an auto bind, try this interface firstEverything unset means loopback, which a phone cannot reach; /remote then
explains what to set. The section is read from the user configuration only: a
project file cannot choose the interface your sessions are exposed on. A
gateway you start yourself with rustcode remote serve --bind … takes its
address from the command line and ignores this section.
A paired device can browse folders and start sessions only inside your home
folder. To allow other places, such as a second disk, list them as roots:
[remote]
roots = ["/Volumes/Work", "/opt/projects"] # absolute or ~/…; missing ones are ignoredThe gateway reads roots on every request, so a change needs no restart. Like
the rest of the section it is read from the user configuration only.
A RustCode server that runs as a background service installs the newest stable release by itself once no turn is running, then restarts onto it. It is on by default; turn it off in the user configuration:
[server]
auto_update = falseIt is read from the user configuration only. How it works and what it logs is
in server.md.
Create a project-local override with:
rustcode init
# or: rustcode --initThis creates .rustcode/config.toml from the global model defaults and adds
.rustcode/config.toml to the project .gitignore. It intentionally does not
copy API keys, MCP servers, or session state. Project configuration is loaded
from parent to child directories, so the nearest file wins:
CLI overrides > nearest project config > global config > built-in defaults
Project files are partial overrides; omitted fields continue to come from the lower-precedence layer.
Legacy [laya] config tables are ignored and can be removed from user or
project config files.
Skills are plain Markdown: <root>/<name>/SKILL.md, scanned exactly one level
deep. RustCode reads them from these roots, highest precedence first, and the
first definition of a skill name wins:
extra_skill_dirsfrom the globalconfig.toml(explicit override)RUSTCODE_EXTRA_SKILL_DIRS, using the platform path-list separator<workspace>/.rustcode/skills<workspace>/.agents/skills<workspace>/.claude/skills— Claude Code's project root, read only~/.agents/skills— the universal root, shared with other agents~/.claude/skills— Claude Code's user root, read only<CLAUDE_CONFIG_DIR>/skillsof every named Claude Code login in[[harness_accounts]](read only;~/.claudecollapses into root 7)<config dir>/skills— RustCode's own root (see Configuration files)
So a project can override a user-level skill, and an explicitly configured
root can override both. The harness roots (5, 7 and 8) are read so Settings ›
Skills lists the skills Claude Code has installed, wherever they live, and one
toggle list covers them. RustCode only reads those directories: it never
creates, rewrites, symlinks or deletes anything there, and nothing has to be
moved out of ~/.claude for the list to be complete. A named login keeps its
own skills directory, because Claude Code reads it with CLAUDE_CONFIG_DIR
set to that directory. A harness's project root comes before RustCode's and
the user's other roots, and a project definition wins over the user's, exactly
as it does inside RustCode's own roots.
The built-in harness's own prompt catalog leaves the harness roots out: Claude Code loads them with its own Skill tool, and RustCode's model is not offered another tool's skills. Settings still lists every one of them, so one toggle list covers what Claude Code has and what RustCode offers.
Extra roots are a global-only setting — a checked-out .rustcode/config.toml
cannot widen skill discovery:
extra_skill_dirs = ["~/work/team-skills", "/opt/shared/skills"]Run /skills to list and toggle the discovered skills, the list_skills tool
to see every root that was actually searched, and rustcode doctor to see
which ones exist. rustcode doctor --fix creates only the RustCode-owned root,
never the universal or workspace roots.
The terminal's /skills and /mcp panels and the macOS app's Settings →
Skills and Settings → MCP Servers list the same things and save to the
same place:
-
Skills. Every discovered skill is listed (installed); a skill that is turned off stays installed but is never offered to the model — routing hints,
list_skillsanduse_skillall skip it. Off skills are stored by name indisabled_skillsin the userconfig.toml, so the choice applies to every project. A project.rustcode/config.tomlcannot set it.disabled_skills = ["cloudflare", "wrangler"]
-
MCP servers. Every configured server is listed with whether it is actually connected in the engine (and how many tools it has), not connected, turned off, or failed with its error. A toggle sets the server's
enabledflag in the user config and starts or stops it right away. A server that only a project config file declares is shown but has to be changed in that file. Header and environment values are never shown; credentials in a URL and secret-looking arguments (--token,API_KEY=…) are masked.
Every enabled server is also handed to the external harnesses, so one list
covers a thread on any of them: an ACP harness (Claude Code, Gemini CLI,
OpenCode) gets them in its session/new's mcpServers, and Codex gets them as
mcp_servers.<name> overrides on thread/start. RustCode spawns nothing
itself for those threads; the harness starts the server in its own session, and
the server's name, command and URL are the same as in Settings → MCP Servers.
Skills are shared in the read direction instead. RustCode reads a harness's own
roots as well as its own (steps 5, 7 and 8 above), so the list is complete, and
a thread on an external harness is told where the discovered skills are on disk
and which ones are turned off, so it can read a SKILL.md with its own tools.
The note is computed when RustCode starts (or restarts) that thread's harness
process: a running process keeps the note it was given, so a toggle made later
reaches that thread when its process is started again — after the idle reaper
stopped it, for example — and every new thread immediately (see
docs/harnesses.md).
A toggle applies from the next message of every open session in the process
that made it: the terminal you toggled in, or the macOS app's engine for all of
its chats. A turn already running is not changed. Another RustCode process
reads disabled_skills the next time it scans skills, and brings its MCP
servers in line with the config on its next message: added or turned-on
servers start, removed or turned-off ones stop.
The app's MCP Settings page also adds servers (Add Server) and removes them
(right-click a server). It reads and writes these through the ACP extension
requests _rustcode/capabilities, _rustcode/capabilities/set and
_rustcode/capabilities/mcp/{add,remove} (see
acp.md).
YOLO auto-approves tool calls that would otherwise ask for confirmation. It is
normally per session, turned on with --yolo, /yolo on or the approval
prompt's toggle. Set yolo = true in the user config.toml to start every new
session that way, including sessions an app opens or creates through the
remote gateway:
yolo = trueThe default is off. A session's own setting is recorded with the session
whenever it changes and wins over this default when the session is reopened by
a remote session owner, so /yolo off sticks for that session. Plan mode still
blocks mutating tools, and sandbox_mode is unchanged (YOLO runs commands as
trusted only while it is on). This is a user trust decision, so a project
.rustcode/config.toml cannot set it.
The activity line above the composer animates a highlight sweep while RustCode
is working. Set reduced_motion = true in config.toml to render it as plain
static text instead:
reduced_motion = trueThe default is off, so the sweep is unchanged unless you opt in. This is purely
presentational, so a project .rustcode/config.toml may set it.
Each mouse wheel event scrolls the transcript one row, and the terminal decides
how many events a wheel notch or trackpad gesture sends. When scrolling feels
slow in every TUI, raise it in the terminal: kitty on Wayland reports a mouse
wheel as high-resolution scrolling, so touch_scroll_multiplier in
kitty.conf (default 1) is the setting that applies, not
wheel_scroll_multiplier.
To scroll more rows per event in RustCode alone, run /scroll-speed: a panel
steps the value with ←/→ (or a digit), Enter saves it and Esc cancels.
/scroll-speed 3 sets it directly. Both write scroll_lines (1–20) and apply
at once:
scroll_lines = 3This is purely presentational, so a project .rustcode/config.toml may set it.
The readable transcript lives in the terminal surface RustCode paints, and on
exit that surface is erased, so the conversation does not stay in the
terminal's own scrollback. Set preserve_transcript_scrollback = true in
config.toml to also copy every committed transcript row into native
scrollback as the session runs:
preserve_transcript_scrollback = trueThe default is off. Native scrollback is write-only: rows copied there cannot
be revised, so an expanded tool body stays expanded after you collapse it, and
the rows sit above the exit handoff where no erase can reach them (#1587,
#1593). Turn it on if you rely on the scrollback copy for terminal copy/paste
or shell piping, and accept that it is a copy rather than the live transcript.
Use the mouse wheel, PageUp/PageDown, or Esc to read the transcript while
a response streams; the transcript never leaves the view (#1595).
theme names the active theme for both the terminal UI and the desktop app
(default rustcode for new configs). Themes are TOML files in
<config>/themes/ (or a project's .rustcode/themes/); each has the terminal
keys and an optional [desktop] table of app tokens derived from them when
left out. Manage them with rustcode theme list | show | new | set | validate | path; themes.md has the format, the token table and derivation,
validation, and the ACP methods.
Settings that belong to a machine — default access, resume after a restart,
continuing after a usage limit, auto-compaction, orchestration, the delegate
limits and reading across projects — are kept in
<config dir>/settings.json on that machine, apart from config.toml because
the app, not the engine's model loop, acts on them:
{
"version": 1,
"values": {
"default-permission-mode": "ask",
"resume-after-restart": true,
"auto-compact-threshold": 150000
}
}A client reads and writes them with _rustcode/settings/get and
_rustcode/settings/set (both take and answer { "values": { … } }; get
accepts "keys" and also answers "stored", the keys the file actually
holds). The engine refuses a key outside its registry, so the file
cannot become a general store over ACP. The keys are
default-permission-mode, resume-after-restart, continue-after-limit,
auto-compact-mode, auto-compact-threshold, orchestration,
delegates-total, delegates-per-thread, read-across-projects,
delegate-presets (a list, see orchestrator.md › Delegate
presets), limit-fallback (off by default), limit-fallback-map (a list,
see › Switching a delegate at a limit) and wake-batch-seconds (default 60;
how long an orchestrator waits to merge its delegates' finishes and stalls into
one wake turn, 0 turns it off, see › Waking a parent thread), and the
workflow limits workflow-concurrency (3), workflow-call-budget (40) and
workflow-timeout-minutes (60) (workflows.md). A client
that reads a key the machine never set gets the engine's default. The desktop
app seeds its own values once on first start, but only for the keys stored
does not list, so a value another machine wrote first is kept.
The default harness, model and effort stay in config.toml
([harness_defaults], _rustcode/harnesses/default) and skill/MCP toggles
stay in disabled_skills and each server's enabled flag
(_rustcode/capabilities*). A paired desktop app may reach these methods and
_rustcode/capabilities* on another machine, but never credentials, accounts,
Remote access or the server's own diagnostics (the gateway's desktop ACP
allowlist, rustcode/engine/src/remote_gateway/acp_relay.rs). See
desktop.md › Settings on one machine or all.
A project can override some keys for itself. They live in the same file
under "projects": { "<folder>": { … } }, keyed by the project's folder (a
worktree's repository) without a trailing separator, and resolve default →
machine → project whenever a thread in that project reads them (the engine's
value_for_session, used for a thread's default access). get with
"project": "<folder>" answers the resolved values, "sources" (default,
machine or project per key) and "project": { "path", "overrides", "overridable" }; set with "project" writes overrides, and "clear": [keys]
removes them (without "project" it removes the machine's own values). Only
default-harness (project-only: { "harness", "model"?, "effort"? }),
text-generator (project-only: { "id", "model"? }; "id": null turns the
generator off in that project, a missing id keeps the machine's selection
with the project's model), voice (project-only: { "generator"?, "model"?, "language"?, "cleanup"? } over the app's Voice settings; "generator": null
turns dictation off there),
default-permission-mode, resume-after-restart, continue-after-limit,
auto-compact-mode and auto-compact-threshold may be overridden; any other
key is refused. A file written before projects existed reads unchanged.
settings.json is deliberately not part of rustcode sync: it is one
machine's behaviour, not a shared configuration.
Initialize a config sync repository with a remote Git URL, then choose a direction explicitly or run the default pull-then-pull sync:
rustcode sync init <remote-git-url>
rustcode sync --pull # or: rustcode sync pull
rustcode sync --push # or: rustcode sync push
rustcode sync # pull, then push--pull and --push cannot be used together.
rustcode sync stages only files inside the RustCode config directory:
.gitignore, config.toml, skills/, themes/, and commands/. Skills in
~/.agents/skills, a workspace .rustcode/skills, or any
extra_skill_dirs entry are not synced — the universal root is shared
with other agents, and pushing one agent's skills into it would conflict with
them. Version those skills separately, or point extra_skill_dirs at a
directory you sync yourself.
In the terminal frontend, reusable Markdown templates are loaded with
/prompt <name> [arguments]; /prompts lists their names and source paths. A
loaded template is placed in the composer for editing and review, and is sent
only after you press Enter again. Put user templates in
<config dir>/commands/<name>.md and workspace templates in
<workspace>/.rustcode/commands/<name>.md. Workspace templates override user
templates with the same name. Names use lowercase ASCII letters, numbers,
hyphens, or underscores. Templates can use the literal $ARGUMENTS
placeholder; supplied arguments replace every occurrence, or are appended after
a blank line if there is no placeholder. With no arguments, placeholders are
removed.
For example, create <workspace>/.rustcode/commands/review.md:
Review $ARGUMENTS for correctness and missing tests.Then run /prompt review the current diff, review or edit the staged text, and
press Enter to submit it. Templates are limited to 64 KiB and expanded prompts
to 256 KiB; empty, invalid UTF-8, symlink, and slash-command expansions are
rejected. Listing does not create command directories. User templates are
included in rustcode sync; workspace templates remain with the project.
Settings › Harnesses › Text generation can add an Anthropic, OpenAI,
OpenRouter or custom OpenAI-compatible generator, then select it. Model IDs
are entered explicitly. Custom base URLs include the API prefix (for example,
http://localhost:11434/v1); local services may use an empty key.
Non-secret definitions and the selected ID live in text-generators.json
beside the engine config. Keys live in the provider credential store.
With none selected, existing thread title and git draft behavior is retained.
Requests are tool-free, limited to 24,000 input characters and 45 seconds.
Settings › Agents › Voice is kept by the desktop app on this machine
(rustcode.voice in its storage): generator (a text generator ID with an
openai or custom provider, or null for Off, the default), model
(default gpt-4o-mini-transcribe), language (empty detects it) and mode
(toggle or hold) and cleanup (off by default). The key is that generator's, in the provider credential
store. The engine sends recordings of at most 10 MB and five minutes to
<base URL>/audio/transcriptions and gives up after 60 seconds. With
cleanup on, the transcript then goes through the text generator the project
resolves to (a dictation_cleanup generation: fix punctuation and
capitalisation, drop filler words, keep the words); without one, or when it
fails, the raw transcript is inserted with a short note.