返回 DeepSeek-Reasonix
CONFIG_PATHS.md
根目录 / docs / CONFIG_PATHS.md
1 # Configuration Paths
2
3 Starting with **Reasonix v1.8.1**, Reasonix uses one user-facing home directory
4 for global configuration and user-owned state. CLI and desktop share this
5 location.
6
7 ## Reasonix Home
8
9 | Platform | Reasonix home |
10 | --- | --- |
11 | macOS | `~/.reasonix` |
12 | Linux | `~/.reasonix` |
13 | Windows | `%APPDATA%\reasonix` |
14
15 Set `REASONIX_HOME` to override Reasonix home for tests, CI, or portable
16 installations. Normal users should not need it.
17
18 When `REASONIX_HOME` is set, the runtime is fully self-contained: all
19 configuration, state, cache, and data live under that directory tree. Legacy
20 migration, OS-home convention directory scanning, and all other fallback paths
21 are skipped so no data leaks in from a system-wide production install.
22
23 Advanced test and portable setups may set `REASONIX_STATE_HOME` to move runtime
24 state such as sessions, archives, and memory. It does not move global config or
25 provider credentials: those remain under `REASONIX_HOME`. If an older build wrote
26 provider keys to `REASONIX_STATE_HOME/.env`, Reasonix imports those keys
27 non-destructively when `<Reasonix home>/.env` is missing them.
28
29 ## What Lives There
30
31 | Data | Path |
32 | --- | --- |
33 | Global config | `<Reasonix home>/config.toml` |
34 | Global provider credentials | `<Reasonix home>/.env` |
35 | In-progress model credential commits | `<Reasonix home>/transactions/model-credentials/` |
36 | Completed model settings receipts | `<Reasonix home>/transactions/model-settings-receipts/` |
37 | Legacy credentials import source | `<Reasonix home>/credentials` |
38 | Global slash commands | `<Reasonix home>/commands/` |
39 | Global skills | `<Reasonix home>/skills/` |
40 | Global hooks | `<Reasonix home>/settings.json` |
41 | Remote-SSH managed known_hosts | `<Reasonix home>/remote/known_hosts` |
42 | Sessions | `<state root>/sessions/` |
43 | Archives | `<state root>/archive/` |
44 | Memory | `<state root>/memory/` and `<state root>/projects/` |
45 | Global Desktop topic metadata | `<state root>/desktop/topic-state-v1.sqlite` |
46 | Project Desktop topic metadata | `<state root>/projects/<workspace slug>/desktop/topic-state-v1.sqlite` |
47 | Disposable session catalog | `<cache root>/session-catalog/v6.sqlite` |
48 | Disposable history search catalog | `<cache root>/history-search/v1.sqlite` |
49 | Disposable usage catalog | `<cache root>/usage-catalog/v1.sqlite` |
50 | Disposable task catalog | `<cache root>/task-catalog/v1.sqlite` |
51
52 `<state root>` defaults to `<Reasonix home>`. It only differs when
53 `REASONIX_STATE_HOME` is set.
54
55 Desktop topic titles, title sources, creation times, and automatic-title state
56 are authoritative in these SQLite files. On first access, Desktop imports the
57 legacy `desktop-topic-*.json` files from a project's `.reasonix/` directory (or
58 the global Reasonix directory). A scope with legacy files continues mirroring
59 them for downgrade compatibility; a fresh scope does not create them. Legacy
60 files are retained, and project-local settings, skills, commands, attachments,
61 and `reasonix.toml` are unaffected.
62
63 The session catalog is a rebuildable query projection, not user data. Session
64 JSONL, event logs, metadata sidecars, and `desktop-projects.json` remain
65 authoritative. See [Session Catalog and Desktop Startup](./SESSION_CATALOG.md).
66 The history projection is documented in
67 [History Search Catalog](./HISTORY_SEARCH_CATALOG.md).
68 The usage rollup projection is documented in [Usage Catalog](./USAGE_CATALOG.md).
69 Task snapshots and event logs likewise remain authoritative; the rebuildable
70 cross-project projection is documented in [Task Catalog](./TASK_CATALOG.md).
71
72 The global user config is named `config.toml`. Project-local config files keep
73 the name `reasonix.toml`. If someone says "global reasonix.toml", they usually
74 mean `<Reasonix home>/config.toml`.
75
76 ## Global `config.toml`
77
78 `<Reasonix home>/config.toml` stores non-secret configuration shared by the CLI
79 and desktop app. It may contain the same provider, plugin, UI, desktop, tool,
80 skill, sandbox, bot, and agent settings that Reasonix renders into user config.
81 Provider entries store the name of the credential variable in `api_key_env`, not
82 the secret value.
83
84 Saved provider and bot credential variables are removed from every
85 model-controlled child-process environment. On macOS and Linux, the global
86 credential `.env` is also hidden from Reasonix's file readers, sandboxed shell
87 commands, and MCP servers; this does not change the visibility of a project's
88 ordinary `.env`. Windows has no OS-level shell sandbox: shell commands and
89 local tools run as the same OS user and can deliberately read user-readable
90 files, including the credential store, so treat restricted permissions there
91 as a tool-layer write boundary rather than a credential vault.
92
93 If a deny entry left behind by the retired Windows sandbox (v1.38.8 to
94 v1.38.10) blocks the credential store, Reasonix removes it automatically when
95 a marker from that sandbox run proves the entry came from Reasonix. Saving a
96 key works even without that proof: the save resets the file's ACL to the
97 current user without reading it, and if that is also denied it moves the
98 locked file aside as `.env.locked-<timestamp>` (a read deny does not block
99 the move) and writes a new store, so re-entering a key always succeeds. Plain reads never rewrite ACLs; they report
100 the original access error together with the repair outcome.
101
102 Example:
103
104 ```toml
105 config_version = 1
106 default_model = "deepseek/deepseek-v4-flash"
107 language = "zh"
108 credentials_store = "auto" # legacy compatibility; provider keys are in .env
109
110 [ui]
111 theme = "auto"
112 cursor_shape = "bar" # CLI/TUI text cursor: underline|block|bar
113 show_turn_usage = false # hide per-request token/cost receipts in the TUI; default true
114
115 [desktop]
116 provider_access = ["deepseek"]
117
118 [[providers]]
119 name = "deepseek"
120 kind = "anthropic"
121 base_url = "https://api.deepseek.com/anthropic"
122 models = ["deepseek-flash", "deepseek-v4-flash", "deepseek-v4-pro", "deepseek-v4-flash-vision-exp"]
123 default = "deepseek-v4-flash"
124 api_key_env = "DEEPSEEK_API_KEY"
125 web_search = true
126
127 [[plugins]]
128 name = "example"
129 command = "example-mcp-server"
130 ```
131
132 Do not put API key values in `config.toml`. This file is regular configuration:
133 it is safe to inspect, edit, migrate, and include in diagnostics after standard
134 redaction. Secrets belong in the global `.env` below.
135
136 `[ui].cursor_shape` affects only the CLI/TUI composer. The default `bar` stays
137 visible without covering double-width CJK characters; use `block` or
138 `underline` if you prefer those cursor shapes.
139
140 `[ui].show_turn_usage = false` hides the token and cost receipt appended to the
141 TUI transcript after each model request. Accounting and live status updates
142 remain active. The default is `true`.
143
144 ### Custom provider `api_key_env` names
145
146 When a provider credential is added, replaced, or explicitly cleared from
147 desktop settings, TUI `/setup`, or `reasonix setup`, Reasonix allocates a fresh
148 `REASONIX_CONNECTION_*_KEY` slot. It writes that slot first and atomically
149 publishes the selected provider's new `api_key_env` reference second. Other
150 providers keep their current references, even when they previously shared a
151 fixed variable. Existing fixed names remain readable and are not migrated at
152 startup.
153
154 Legacy and manually authored provider entries may derive a default from the provider name. Names that normalize to
155 ASCII keep readable env names such as `LOCAL_GATEWAY_API_KEY`; names made
156 entirely of non-ASCII characters get a stable hash suffix such as
157 `CUSTOM_d39b9067_API_KEY` so two Chinese provider names do not share
158 `CUSTOM_API_KEY`. Names beginning with a digit get a `CUSTOM_` prefix so the
159 generated environment variable remains valid; for example, `9router` becomes
160 `CUSTOM_9ROUTER_API_KEY`.
161
162 The CLI custom-provider wizard uses this rule while building its draft. For example
163 `https://token.sensenova.cn/v1` creates provider name
164 `custom-token-sensenova-cn`, whose default key env is
165 `CUSTOM_TOKEN_SENSENOVA_CN_API_KEY`; commit then switches the saved connection
166 to its newly allocated private slot.
167
168 Existing configs are not rewritten on upgrade. If an old custom provider already
169 uses `CUSTOM_API_KEY`, it will keep working with that key. If several old custom
170 providers accidentally share `CUSTOM_API_KEY`, save each provider's API key
171 again to rotate that connection to a private slot.
172
173 ### Custom provider endpoint URLs
174
175 The desktop custom-provider form treats its **API address** as the exact request
176 URL and stores it in `request_url`; Reasonix does not append or rewrite its path.
177 Existing TOML entries are not reinterpreted: legacy `chat_url` keeps its former
178 OpenAI-only behavior, while Anthropic and Responses continue deriving their path
179 from `base_url` until the provider is explicitly saved in the current desktop UI.
180 Saving an OpenAI-compatible provider mirrors the exact address into legacy
181 `chat_url`, so previous releases continue using the same target. Previous
182 releases cannot honor arbitrary Anthropic or Responses request paths.
183 If model discovery needs a separate address, set `models_url`; otherwise Reasonix
184 probes candidates derived from `base_url`.
185
186 If a gateway requires vendor-specific top-level request body fields, set
187 `extra_body`, for example `extra_body = { enable_thinking = true }`. These values
188 are merged into the OpenAI-compatible chat JSON request body without allowing
189 core fields such as `model`, `messages`, `tools`, or `stream` to be overridden.
190
191 ## Global `.env`
192
193 `<Reasonix home>/.env` is the single runtime source for provider API keys saved
194 by Reasonix. The setup wizard, desktop settings, CLI missing-key prompts, and
195 provider-key delete actions all read or write this file through the same
196 credential helpers.
197
198 Structure:
199
200 ```dotenv
201 DEEPSEEK_API_KEY=sk-...
202 GEMINI_API_KEY=...
203 ANTHROPIC_API_KEY=...
204 # reasonix-cleared OLD_API_KEY
205 ```
206
207 Rules:
208
209 - one `KEY=value` assignment per line;
210 - blank lines and `#` comments are ignored;
211 - `export KEY=value` and quoted values are accepted when reading;
212 - multiline values are rejected by Reasonix writes;
213 - keys must use shell-style names such as `DEEPSEEK_API_KEY`;
214 - `# reasonix-cleared KEY` comments are non-secret tombstones written after a key
215 is deleted so legacy stores do not silently re-import it;
216 - Reasonix writes this file with restricted permissions where the OS supports
217 them.
218
219 For provider requests, Reasonix resolves only this global `.env`. Project `.env`
220 files, home `.env` files, inherited shell environment variables, the old
221 `credentials` file, and the OS keyring do not act as runtime provider-key
222 fallbacks. Project `.env`, home `.env`, and inherited shell environment values
223 are not imported into the global credentials file. The old `credentials` file
224 and old keyring entries are read only as non-destructive migration sources when
225 the new global `.env` is missing a key. Project `.env` files are still read as
226 workspace-scoped, non-provider expansion sources for `${VAR}` references in
227 MCP/plugin env, headers, URLs, commands, and args; those values are not written
228 into the process environment, and Reasonix control variables such as
229 `REASONIX_HOME`, `REASONIX_STATE_HOME`, and `XDG_CONFIG_HOME` are ignored there.
230
231 Caches remain in the OS cache directory, for example
232 `~/Library/Caches/reasonix` on macOS, `$XDG_CACHE_HOME/reasonix` or
233 `~/.cache/reasonix` on Linux, and `%LOCALAPPDATA%\reasonix\cache` on Windows.
234 Set `REASONIX_CACHE_HOME` to override the cache root. When `REASONIX_HOME` is
235 set, the cache is placed under `$REASONIX_HOME/cache` (unless
236 `REASONIX_CACHE_HOME` is also set, which takes precedence).
237
238 ## Config Priority
239
240 Runtime configuration is resolved in this order:
241
242 ```text
243 command-line flags
244 > project ./reasonix.toml
245 > global <Reasonix home>/config.toml
246 > compatible legacy global config
247 > built-in defaults
248 ```
249
250 Writes always target the new global path:
251
252 ```text
253 macOS/Linux: ~/.reasonix/config.toml
254 Windows: %APPDATA%\reasonix\config.toml
255 ```
256
257 ## Legacy Migration
258
259 Starting with **v1.8.1**, Reasonix automatically checks legacy locations on
260 startup before the first config load. Migration is synchronous, one-time, and
261 non-destructive: old files are copied or converted to Reasonix home and left
262 untouched.
263
264 Legacy config sources include:
265
266 ```text
267 ~/Library/Application Support/reasonix/config.toml
268 ~/.config/reasonix/config.toml
269 ~/.reasonix/reasonix.toml
270 ~/.reasonix/config.json
271 ```
272
273 Legacy credentials, memory files, and sessions are also imported into Reasonix
274 home when the new destination does not already exist. Legacy provider keys are
275 copied into `<Reasonix home>/.env` only when that file does not already contain
276 the same key. If the new global config already exists, it wins and legacy config
277 files are only kept as compatibility fallbacks.
278
279 Starting in **v1.9.1**, Reasonix also backfills MCP servers from known legacy
280 paths, legacy `config.json`, desktop-registered projects, and restored tab
281 projects into the global `<Reasonix home>/config.toml`. Existing global
282 `[[plugins]]` entries win by name, so project or legacy entries never overwrite a
283 server the user already configured globally. Source files are left untouched, and
284 the backfill writes a one-time marker so a user-deleted global MCP server is not
285 recreated repeatedly from an old project config.
286
287 ## Manual Migration Rescue
288
289 If Reasonix has already created the new home directory but some legacy data was
290 not present yet, or if the desktop app was opened before the old paths were
291 available, run the migration rescue command from either frontend:
292
293 ```text
294 /migrate
295 ```
296
297 In the CLI TUI, type `/migrate` into the chat input. In the desktop app, type the
298 same command into the composer. The command prints progress notices while it:
299
300 1. checks legacy config and credentials,
301 2. scans known legacy memory locations,
302 3. scans known legacy session directories,
303 4. imports memory files and sessions that were not previously imported, and
304 5. prints a final summary.
305
306 If old v0.x sessions live outside the known legacy locations — for example a
307 Windows v0.52 install/data directory chosen during setup — pass that directory
308 explicitly:
309
310 ```text
311 /migrate --from "D:\OldReasonix"
312 ```
313
314 The explicit form imports sessions only. The path may be the old install
315 directory, a `.reasonix`/data directory, or the `sessions` directory itself;
316 Reasonix checks the common layouts below that root and uses a source-specific
317 marker, so a previous plain `/migrate` run does not hide the later import.
318
319 The rescue command is intentionally non-destructive. It does not overwrite an
320 existing `<Reasonix home>/config.toml`; if the new config already exists, copy
321 any missing legacy settings across by hand. It copies legacy memory files only
322 when the destination file is absent. It also respects session import markers, so
323 sessions that were already imported and later deleted by the user will not be
324 restored on a later `/migrate` run.
325
326 Version limits:
327
328 - Automatic migration starts in **v1.8.1**.
329 - `/migrate` is available only in Go-based Reasonix builds that include the
330 command. If Reasonix reports `unknown command`, upgrade first and rerun it.
331 - The command is not available in the legacy `0.x` TypeScript line.
332 - Plain `/migrate` rescans the legacy locations listed above. Use
333 `/migrate --from <path>` only for a known v0.x session source; it is not a
334 backup restore tool or a downgrade importer.
335
335 lines MARKDOWN