@oh-my-pi/pi-coding-agent 13.11.1 → 13.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/package.json +7 -7
  3. package/src/capability/context-file.ts +2 -0
  4. package/src/capability/extension-module.ts +1 -0
  5. package/src/capability/hook.ts +1 -0
  6. package/src/capability/index.ts +21 -10
  7. package/src/capability/instruction.ts +1 -0
  8. package/src/capability/mcp.ts +1 -0
  9. package/src/capability/prompt.ts +1 -0
  10. package/src/capability/rule.ts +5 -0
  11. package/src/capability/skill.ts +1 -0
  12. package/src/capability/slash-command.ts +1 -0
  13. package/src/capability/tool.ts +1 -0
  14. package/src/capability/types.ts +10 -0
  15. package/src/cli/commands/init-xdg.ts +27 -0
  16. package/src/cli/config-cli.ts +8 -3
  17. package/src/cli/shell-cli.ts +1 -1
  18. package/src/commands/config.ts +1 -1
  19. package/src/config/model-registry.ts +63 -10
  20. package/src/config/model-resolver.ts +84 -21
  21. package/src/config/settings-schema.ts +977 -769
  22. package/src/discovery/helpers.ts +8 -2
  23. package/src/exec/bash-executor.ts +62 -25
  24. package/src/extensibility/custom-tools/types.ts +2 -3
  25. package/src/extensibility/extensions/loader.ts +5 -1
  26. package/src/extensibility/extensions/types.ts +2 -0
  27. package/src/extensibility/hooks/types.ts +2 -0
  28. package/src/extensibility/plugins/loader.ts +23 -5
  29. package/src/extensibility/plugins/manager.ts +14 -0
  30. package/src/extensibility/plugins/types.ts +4 -0
  31. package/src/extensibility/skills.ts +7 -1
  32. package/src/index.ts +6 -6
  33. package/src/internal-urls/docs-index.generated.ts +2 -2
  34. package/src/ipy/kernel.ts +4 -5
  35. package/src/memories/index.ts +20 -7
  36. package/src/memories/storage.ts +46 -32
  37. package/src/modes/components/agent-dashboard.ts +23 -35
  38. package/src/modes/components/assistant-message.ts +25 -2
  39. package/src/modes/components/btw-panel.ts +104 -0
  40. package/src/modes/components/diff.ts +2 -7
  41. package/src/modes/components/extensions/state-manager.ts +3 -2
  42. package/src/modes/components/settings-defs.ts +56 -6
  43. package/src/modes/components/settings-selector.ts +11 -6
  44. package/src/modes/controllers/btw-controller.ts +193 -0
  45. package/src/modes/controllers/command-controller.ts +9 -3
  46. package/src/modes/controllers/event-controller.ts +4 -0
  47. package/src/modes/controllers/input-controller.ts +10 -1
  48. package/src/modes/interactive-mode.ts +22 -0
  49. package/src/modes/prompt-action-autocomplete.ts +17 -3
  50. package/src/modes/rpc/rpc-client.ts +30 -19
  51. package/src/modes/theme/theme.ts +28 -36
  52. package/src/modes/types.ts +4 -0
  53. package/src/modes/utils/ui-helpers.ts +3 -0
  54. package/src/patch/diff.ts +9 -1
  55. package/src/patch/index.ts +56 -9
  56. package/src/prompts/system/btw-user.md +8 -0
  57. package/src/prompts/system/custom-system-prompt.md +1 -1
  58. package/src/prompts/system/system-prompt.md +1 -0
  59. package/src/sdk.ts +23 -26
  60. package/src/session/agent-session.ts +65 -37
  61. package/src/session/blob-store.ts +32 -0
  62. package/src/session/compaction/compaction.ts +37 -6
  63. package/src/session/history-storage.ts +2 -2
  64. package/src/session/session-manager.ts +129 -49
  65. package/src/slash-commands/builtin-registry.ts +11 -0
  66. package/src/system-prompt.ts +4 -17
  67. package/src/task/agents.ts +1 -1
  68. package/src/task/index.ts +9 -8
  69. package/src/tools/browser.ts +11 -0
  70. package/src/tools/output-meta.ts +103 -3
  71. package/src/tools/path-utils.ts +11 -0
  72. package/src/utils/title-generator.ts +70 -92
  73. package/src/utils/tools-manager.ts +1 -1
  74. package/src/web/scrapers/index.ts +7 -7
  75. package/src/web/scrapers/utils.ts +1 -0
@@ -17,45 +17,40 @@ import { THINKING_EFFORTS } from "@oh-my-pi/pi-ai";
17
17
  // ═══════════════════════════════════════════════════════════════════════════
18
18
 
19
19
  export type SettingTab =
20
- | "display"
21
- | "agent"
22
- | "input"
20
+ | "appearance"
21
+ | "model"
22
+ | "interaction"
23
+ | "context"
24
+ | "editing"
23
25
  | "tools"
24
- | "config"
25
- | "services"
26
- | "bash"
27
- | "lsp"
28
- | "ttsr"
29
- | "status";
26
+ | "tasks"
27
+ | "providers";
30
28
 
31
29
  /** Tab display metadata - icon is resolved via theme.symbol() */
32
30
  export type TabMetadata = { label: string; icon: `tab.${string}` };
33
31
 
34
- /** Ordered list of tabs for UI rendering (status excluded - custom menu) */
32
+ /** Ordered list of tabs for UI rendering */
35
33
  export const SETTING_TABS: SettingTab[] = [
36
- "display",
37
- "agent",
38
- "input",
34
+ "appearance",
35
+ "model",
36
+ "interaction",
37
+ "context",
38
+ "editing",
39
39
  "tools",
40
- "config",
41
- "services",
42
- "bash",
43
- "lsp",
44
- "ttsr",
40
+ "tasks",
41
+ "providers",
45
42
  ];
46
43
 
47
44
  /** Tab display metadata - icon is a symbol key from theme.ts (tab.*) */
48
45
  export const TAB_METADATA: Record<SettingTab, { label: string; icon: `tab.${string}` }> = {
49
- display: { label: "Display", icon: "tab.display" },
50
- agent: { label: "Agent", icon: "tab.agent" },
51
- input: { label: "Input", icon: "tab.input" },
46
+ appearance: { label: "Appearance", icon: "tab.appearance" },
47
+ model: { label: "Model", icon: "tab.model" },
48
+ interaction: { label: "Interaction", icon: "tab.interaction" },
49
+ context: { label: "Context", icon: "tab.context" },
50
+ editing: { label: "Editing", icon: "tab.editing" },
52
51
  tools: { label: "Tools", icon: "tab.tools" },
53
- config: { label: "Config", icon: "tab.config" },
54
- services: { label: "Services", icon: "tab.services" },
55
- bash: { label: "Bash", icon: "tab.bash" },
56
- lsp: { label: "LSP", icon: "tab.lsp" },
57
- ttsr: { label: "TTSR", icon: "tab.ttsr" },
58
- status: { label: "Status", icon: "tab.status" },
52
+ tasks: { label: "Tasks", icon: "tab.tasks" },
53
+ providers: { label: "Providers", icon: "tab.providers" },
59
54
  };
60
55
 
61
56
  /** Status line segment identifiers */
@@ -140,1134 +135,1345 @@ type SettingDef =
140
135
  // Schema Definition
141
136
  // ═══════════════════════════════════════════════════════════════════════════
142
137
 
138
+ // Typed defaults for array/record settings — named constants avoid `as` casts
139
+ // under `as const` while still letting SettingValue infer the correct element type.
140
+ const EMPTY_STRING_ARRAY: string[] = [];
141
+ const EMPTY_STRING_RECORD: Record<string, string> = {};
142
+
143
143
  export const SETTINGS_SCHEMA = {
144
- // ─────────────────────────────────────────────────────────────────────────
145
- // Top-level settings
146
- // ─────────────────────────────────────────────────────────────────────────
144
+ // ────────────────────────────────────────────────────────────────────────
145
+ // General settings (no UI)
146
+ // ────────────────────────────────────────────────────────────────────────
147
147
  lastChangelogVersion: { type: "string", default: undefined },
148
+
149
+ shellPath: { type: "string", default: undefined },
150
+
151
+ extensions: { type: "array", default: EMPTY_STRING_ARRAY },
152
+
153
+ enabledModels: { type: "array", default: EMPTY_STRING_ARRAY },
154
+
155
+ disabledProviders: { type: "array", default: EMPTY_STRING_ARRAY },
156
+
157
+ disabledExtensions: { type: "array", default: EMPTY_STRING_ARRAY },
158
+
159
+ modelRoles: { type: "record", default: EMPTY_STRING_RECORD },
160
+
161
+ // ────────────────────────────────────────────────────────────────────────
162
+ // Appearance
163
+ // ────────────────────────────────────────────────────────────────────────
164
+
165
+ // Theme
148
166
  "theme.dark": {
149
167
  type: "string",
150
168
  default: "titanium",
151
169
  ui: {
152
- tab: "display",
153
- label: "Dark theme",
170
+ tab: "appearance",
171
+ label: "Dark Theme",
154
172
  description: "Theme used when terminal has dark background",
155
173
  submenu: true,
156
174
  },
157
175
  },
176
+
158
177
  "theme.light": {
159
178
  type: "string",
160
179
  default: "light",
161
180
  ui: {
162
- tab: "display",
163
- label: "Light theme",
181
+ tab: "appearance",
182
+ label: "Light Theme",
164
183
  description: "Theme used when terminal has light background",
165
184
  submenu: true,
166
185
  },
167
186
  },
187
+
168
188
  symbolPreset: {
169
189
  type: "enum",
170
190
  values: ["unicode", "nerd", "ascii"] as const,
171
191
  default: "unicode",
172
- ui: { tab: "display", label: "Symbol preset", description: "Icon/symbol style", submenu: true },
192
+ ui: { tab: "appearance", label: "Symbol Preset", description: "Icon/symbol style", submenu: true },
173
193
  },
194
+
174
195
  colorBlindMode: {
175
196
  type: "boolean",
176
197
  default: false,
177
198
  ui: {
178
- tab: "display",
179
- label: "Color blind mode",
199
+ tab: "appearance",
200
+ label: "Color-Blind Mode",
180
201
  description: "Use blue instead of green for diff additions",
181
202
  },
182
203
  },
183
- "display.tabWidth": {
184
- type: "number",
185
- default: 3,
186
- ui: {
187
- tab: "display",
188
- label: "Tab width",
189
- description: "Default number of spaces used when rendering tab characters",
190
- submenu: true,
191
- },
192
- },
193
- defaultThinkingLevel: {
204
+
205
+ // Status line
206
+ "statusLine.preset": {
194
207
  type: "enum",
195
- values: THINKING_EFFORTS,
196
- default: "high",
208
+ values: ["default", "minimal", "compact", "full", "nerd", "ascii", "custom"] as const,
209
+ default: "default",
197
210
  ui: {
198
- tab: "agent",
199
- label: "Thinking level",
200
- description: "Reasoning depth for thinking-capable models",
211
+ tab: "appearance",
212
+ label: "Status Line Preset",
213
+ description: "Pre-built status line configurations",
201
214
  submenu: true,
202
215
  },
203
216
  },
204
- hideThinkingBlock: {
205
- type: "boolean",
206
- default: false,
207
- ui: { tab: "agent", label: "Hide thinking", description: "Hide thinking blocks in assistant responses" },
208
- },
209
- steeringMode: {
210
- type: "enum",
211
- values: ["all", "one-at-a-time"] as const,
212
- default: "one-at-a-time",
213
- ui: {
214
- tab: "agent",
215
- label: "Steering mode",
216
- description: "How to process queued messages while agent is working",
217
- },
218
- },
219
- followUpMode: {
217
+
218
+ "statusLine.separator": {
220
219
  type: "enum",
221
- values: ["all", "one-at-a-time"] as const,
222
- default: "one-at-a-time",
220
+ values: ["powerline", "powerline-thin", "slash", "pipe", "block", "none", "ascii"] as const,
221
+ default: "powerline-thin",
223
222
  ui: {
224
- tab: "agent",
225
- label: "Follow-up mode",
226
- description: "How to drain follow-up messages after a turn completes",
223
+ tab: "appearance",
224
+ label: "Status Line Separator",
225
+ description: "Style of separators between segments",
226
+ submenu: true,
227
227
  },
228
228
  },
229
- interruptMode: {
230
- type: "enum",
231
- values: ["immediate", "wait"] as const,
232
- default: "immediate",
233
- ui: { tab: "agent", label: "Interrupt mode", description: "When steering messages interrupt tool execution" },
234
- },
235
- doubleEscapeAction: {
236
- type: "enum",
237
- values: ["branch", "tree", "none"] as const,
238
- default: "tree",
229
+ "tools.artifactSpillThreshold": {
230
+ type: "number",
231
+ default: 50,
239
232
  ui: {
240
- tab: "input",
241
- label: "Double-escape action",
242
- description: "Action when pressing Escape twice with empty editor",
233
+ tab: "tools",
234
+ label: "Artifact spill threshold (KB)",
235
+ description: "Tool output above this size is saved as an artifact; tail is kept inline",
236
+ submenu: true,
243
237
  },
244
238
  },
245
- treeFilterMode: {
246
- type: "enum",
247
- values: ["default", "no-tools", "user-only", "labeled-only", "all"] as const,
248
- default: "default",
239
+ "tools.artifactTailBytes": {
240
+ type: "number",
241
+ default: 20,
249
242
  ui: {
250
- tab: "input",
251
- label: "Tree filter mode",
252
- description: "Default filter mode when opening the session tree",
243
+ tab: "tools",
244
+ label: "Artifact tail size (KB)",
245
+ description: "Amount of tail content kept inline when output spills to artifact",
246
+ submenu: true,
253
247
  },
254
248
  },
255
- shellPath: { type: "string", default: undefined },
256
- collapseChangelog: {
257
- type: "boolean",
258
- default: false,
259
- ui: { tab: "input", label: "Collapse changelog", description: "Show condensed changelog after updates" },
260
- },
261
- autocompleteMaxVisible: {
249
+ "tools.artifactTailLines": {
262
250
  type: "number",
263
- default: 5,
251
+ default: 500,
264
252
  ui: {
265
- tab: "input",
266
- label: "Autocomplete max items",
267
- description: "Max visible items in autocomplete dropdown (3-20)",
253
+ tab: "tools",
254
+ label: "Artifact tail lines",
255
+ description: "Maximum lines of tail content kept inline when output spills to artifact",
268
256
  submenu: true,
269
257
  },
270
258
  },
271
- repeatToolDescriptions: {
259
+
260
+ "statusLine.showHookStatus": {
272
261
  type: "boolean",
273
- default: false,
262
+ default: true,
274
263
  ui: {
275
- tab: "agent",
276
- label: "Repeat tool descriptions",
277
- description: "Render full tool descriptions in the system prompt instead of a tool name list",
264
+ tab: "appearance",
265
+ label: "Show Hook Status",
266
+ description: "Display hook status messages below status line",
278
267
  },
279
268
  },
280
- readLineNumbers: {
269
+
270
+ "statusLine.leftSegments": { type: "array", default: [] as StatusLineSegmentId[] },
271
+
272
+ "statusLine.rightSegments": { type: "array", default: [] as StatusLineSegmentId[] },
273
+
274
+ "statusLine.segmentOptions": { type: "record", default: {} as Record<string, unknown> },
275
+
276
+ // Images and terminal
277
+ "terminal.showImages": {
281
278
  type: "boolean",
282
- default: false,
279
+ default: true,
283
280
  ui: {
284
- tab: "config",
285
- label: "Read line numbers",
286
- description: "Prepend line numbers to read tool output by default",
281
+ tab: "appearance",
282
+ label: "Show Inline Images",
283
+ description: "Render images inline in terminal",
284
+ condition: "hasImageProtocol",
287
285
  },
288
286
  },
289
- readHashLines: {
287
+
288
+ "images.autoResize": {
290
289
  type: "boolean",
291
290
  default: true,
292
291
  ui: {
293
- tab: "config",
294
- label: "Read hash lines",
295
- description: "Include line hashes in read output for hashline edit mode (LINE#ID:content)",
292
+ tab: "appearance",
293
+ label: "Auto-Resize Images",
294
+ description: "Resize large images to 2000x2000 max for better model compatibility",
296
295
  },
297
296
  },
298
- "read.defaultLimit": {
297
+
298
+ "images.blockImages": {
299
+ type: "boolean",
300
+ default: false,
301
+ ui: { tab: "appearance", label: "Block Images", description: "Prevent images from being sent to LLM providers" },
302
+ },
303
+
304
+ // Display rendering
305
+ "display.tabWidth": {
299
306
  type: "number",
300
- default: 300,
307
+ default: 3,
301
308
  ui: {
302
- tab: "tools",
303
- label: "Read default limit",
304
- description: "Default number of lines returned when agent calls read without a limit",
309
+ tab: "appearance",
310
+ label: "Tab Width",
311
+ description: "Default number of spaces used when rendering tab characters",
305
312
  submenu: true,
306
313
  },
307
314
  },
315
+
316
+ "display.showTokenUsage": {
317
+ type: "boolean",
318
+ default: false,
319
+ ui: {
320
+ tab: "appearance",
321
+ label: "Show Token Usage",
322
+ description: "Show per-turn token usage on assistant messages",
323
+ },
324
+ },
325
+
308
326
  showHardwareCursor: {
309
327
  type: "boolean",
310
328
  default: true, // will be computed based on platform if undefined
311
- ui: { tab: "display", label: "Hardware cursor", description: "Show terminal cursor for IME support" },
329
+ ui: { tab: "appearance", label: "Show Hardware Cursor", description: "Show terminal cursor for IME support" },
312
330
  },
331
+
313
332
  clearOnShrink: {
314
333
  type: "boolean",
315
334
  default: false,
316
335
  ui: {
317
- tab: "display",
318
- label: "Clear on shrink",
336
+ tab: "appearance",
337
+ label: "Clear on Shrink",
319
338
  description: "Clear empty rows when content shrinks (may cause flicker)",
320
339
  },
321
340
  },
322
- extensions: { type: "array", default: [] as string[] },
323
- enabledModels: { type: "array", default: [] as string[] },
324
- disabledProviders: { type: "array", default: [] as string[] },
325
- disabledExtensions: { type: "array", default: [] as string[] },
326
- modelRoles: { type: "record", default: {} as Record<string, string> },
327
- "contextPromotion.enabled": {
328
- type: "boolean",
329
- default: true,
341
+
342
+ // ────────────────────────────────────────────────────────────────────────
343
+ // Model
344
+ // ────────────────────────────────────────────────────────────────────────
345
+
346
+ // Reasoning and prompts
347
+ defaultThinkingLevel: {
348
+ type: "enum",
349
+ values: THINKING_EFFORTS,
350
+ default: "high",
330
351
  ui: {
331
- tab: "agent",
332
- label: "Auto-promote context",
333
- description: "Promote to a larger-context model on context overflow instead of compacting",
352
+ tab: "model",
353
+ label: "Thinking Level",
354
+ description: "Reasoning depth for thinking-capable models",
355
+ submenu: true,
334
356
  },
335
357
  },
336
358
 
337
- // ─────────────────────────────────────────────────────────────────────────
338
- // Secrets settings
339
- // ─────────────────────────────────────────────────────────────────────────
340
- "secrets.enabled": {
359
+ hideThinkingBlock: {
341
360
  type: "boolean",
342
361
  default: false,
343
- ui: { tab: "config", label: "Hide secrets", description: "Obfuscate secrets before sending to AI providers" },
362
+ ui: { tab: "model", label: "Hide Thinking Blocks", description: "Hide thinking blocks in assistant responses" },
344
363
  },
345
364
 
346
- // ─────────────────────────────────────────────────────────────────────────
347
- // Compaction settings
348
- // ─────────────────────────────────────────────────────────────────────────
349
- "compaction.enabled": {
365
+ repeatToolDescriptions: {
350
366
  type: "boolean",
351
- default: true,
367
+ default: false,
352
368
  ui: {
353
- tab: "agent",
354
- label: "Auto-compact",
355
- description: "Automatically compact context when it gets too large",
369
+ tab: "model",
370
+ label: "Repeat Tool Descriptions",
371
+ description: "Render full tool descriptions in the system prompt instead of a tool name list",
356
372
  },
357
373
  },
358
- "compaction.strategy": {
359
- type: "enum",
360
- values: ["context-full", "handoff", "off"] as const,
361
- default: "context-full",
374
+
375
+ // Sampling
376
+ temperature: {
377
+ type: "number",
378
+ default: -1,
362
379
  ui: {
363
- tab: "agent",
364
- label: "Context-full strategy",
365
- description: "Choose in-place context-full maintenance, auto-handoff, or disable auto maintenance (off)",
380
+ tab: "model",
381
+ label: "Temperature",
382
+ description: "Sampling temperature (0 = deterministic, 1 = creative, -1 = provider default)",
366
383
  submenu: true,
367
384
  },
368
385
  },
369
- "compaction.thresholdPercent": {
386
+
387
+ topP: {
370
388
  type: "number",
371
389
  default: -1,
372
390
  ui: {
373
- tab: "agent",
374
- label: "Context threshold",
375
- description: "Percent threshold for context maintenance; set to Default to use legacy reserve-based behavior",
391
+ tab: "model",
392
+ label: "Top P",
393
+ description: "Nucleus sampling cutoff (0-1, -1 = provider default)",
376
394
  submenu: true,
377
395
  },
378
396
  },
379
- "compaction.handoffSaveToDisk": {
380
- type: "boolean",
381
- default: false,
397
+
398
+ topK: {
399
+ type: "number",
400
+ default: -1,
382
401
  ui: {
383
- tab: "agent",
384
- label: "Save auto-handoff docs",
385
- description: "Save generated handoff documents to markdown files for the auto-handoff flow",
402
+ tab: "model",
403
+ label: "Top K",
404
+ description: "Sample from top-K tokens (-1 = provider default)",
405
+ submenu: true,
386
406
  },
387
407
  },
388
- "compaction.reserveTokens": { type: "number", default: 16384 },
389
- "compaction.keepRecentTokens": { type: "number", default: 20000 },
390
- "compaction.autoContinue": { type: "boolean", default: true },
391
- "compaction.remoteEnabled": {
392
- type: "boolean",
393
- default: true,
408
+
409
+ minP: {
410
+ type: "number",
411
+ default: -1,
394
412
  ui: {
395
- tab: "agent",
396
- label: "Remote compaction",
397
- description: "Use remote compaction endpoints when available instead of local summarization",
413
+ tab: "model",
414
+ label: "Min P",
415
+ description: "Minimum probability threshold (0-1, -1 = provider default)",
416
+ submenu: true,
398
417
  },
399
418
  },
400
- "compaction.remoteEndpoint": { type: "string", default: undefined },
401
419
 
402
- // ─────────────────────────────────────────────────────────────────────────
403
- // Branch summary settings
404
- // ─────────────────────────────────────────────────────────────────────────
405
- "branchSummary.enabled": {
406
- type: "boolean",
407
- default: false,
408
- ui: { tab: "agent", label: "Branch summaries", description: "Prompt to summarize when leaving a branch" },
420
+ presencePenalty: {
421
+ type: "number",
422
+ default: -1,
423
+ ui: {
424
+ tab: "model",
425
+ label: "Presence Penalty",
426
+ description: "Penalty for introducing already-present tokens (-1 = provider default)",
427
+ submenu: true,
428
+ },
409
429
  },
410
- "branchSummary.reserveTokens": { type: "number", default: 16384 },
411
430
 
412
- // ─────────────────────────────────────────────────────────────────────────
413
- // Memories settings
414
- // ─────────────────────────────────────────────────────────────────────────
415
- "memories.enabled": {
416
- type: "boolean",
417
- default: false,
431
+ repetitionPenalty: {
432
+ type: "number",
433
+ default: -1,
418
434
  ui: {
419
- tab: "agent",
420
- label: "Memories",
421
- description: "Enable autonomous memory extraction and consolidation",
435
+ tab: "model",
436
+ label: "Repetition Penalty",
437
+ description: "Penalty for repeated tokens (-1 = provider default)",
438
+ submenu: true,
439
+ },
440
+ },
441
+
442
+ serviceTier: {
443
+ type: "enum",
444
+ values: ["none", "auto", "default", "flex", "scale", "priority"] as const,
445
+ default: "none",
446
+ ui: {
447
+ tab: "model",
448
+ label: "Service Tier",
449
+ description: "OpenAI processing priority (none = omit parameter)",
450
+ submenu: true,
422
451
  },
423
452
  },
424
- "memories.maxRolloutsPerStartup": { type: "number", default: 64 },
425
- "memories.maxRolloutAgeDays": { type: "number", default: 30 },
426
- "memories.minRolloutIdleHours": { type: "number", default: 12 },
427
- "memories.threadScanLimit": { type: "number", default: 300 },
428
- "memories.maxRawMemoriesForGlobal": { type: "number", default: 200 },
429
- "memories.stage1Concurrency": { type: "number", default: 8 },
430
- "memories.stage1LeaseSeconds": { type: "number", default: 120 },
431
- "memories.stage1RetryDelaySeconds": { type: "number", default: 120 },
432
- "memories.phase2LeaseSeconds": { type: "number", default: 180 },
433
- "memories.phase2RetryDelaySeconds": { type: "number", default: 180 },
434
- "memories.phase2HeartbeatSeconds": { type: "number", default: 30 },
435
- "memories.rolloutPayloadPercent": { type: "number", default: 0.7 },
436
- "memories.fallbackTokenLimit": { type: "number", default: 16000 },
437
- "memories.summaryInjectionTokenLimit": { type: "number", default: 5000 },
438
453
 
439
- // ─────────────────────────────────────────────────────────────────────────
440
- // Retry settings
441
- // ─────────────────────────────────────────────────────────────────────────
454
+ // Retries
442
455
  "retry.enabled": { type: "boolean", default: true },
456
+
443
457
  "retry.maxRetries": {
444
458
  type: "number",
445
459
  default: 3,
446
460
  ui: {
447
- tab: "agent",
448
- label: "Retry max attempts",
461
+ tab: "model",
462
+ label: "Retry Attempts",
449
463
  description: "Maximum retry attempts on API errors",
450
464
  submenu: true,
451
465
  },
452
466
  },
467
+
453
468
  "retry.baseDelayMs": { type: "number", default: 2000 },
454
469
 
455
- // ─────────────────────────────────────────────────────────────────────────
456
- // Todo completion settings
457
- // ─────────────────────────────────────────────────────────────────────────
458
- "todo.reminders": {
459
- type: "boolean",
460
- default: true,
461
- ui: { tab: "agent", label: "Todo reminders", description: "Remind agent to complete todos before stopping" },
462
- },
463
- "todo.reminders.max": {
464
- type: "number",
465
- default: 3,
470
+ // ────────────────────────────────────────────────────────────────────────
471
+ // Interaction
472
+ // ────────────────────────────────────────────────────────────────────────
473
+
474
+ // Conversation flow
475
+ steeringMode: {
476
+ type: "enum",
477
+ values: ["all", "one-at-a-time"] as const,
478
+ default: "one-at-a-time",
466
479
  ui: {
467
- tab: "agent",
468
- label: "Todo max reminders",
469
- description: "Maximum reminders to complete todos before giving up",
470
- submenu: true,
480
+ tab: "interaction",
481
+ label: "Steering Mode",
482
+ description: "How to process queued messages while agent is working",
471
483
  },
472
484
  },
473
- "todo.eager": {
474
- type: "boolean",
475
- default: false,
485
+
486
+ followUpMode: {
487
+ type: "enum",
488
+ values: ["all", "one-at-a-time"] as const,
489
+ default: "one-at-a-time",
476
490
  ui: {
477
- tab: "agent",
478
- label: "Eager todos",
479
- description: "Automatically create a comprehensive todo list after the first message",
491
+ tab: "interaction",
492
+ label: "Follow-Up Mode",
493
+ description: "How to drain follow-up messages after a turn completes",
480
494
  },
481
495
  },
482
496
 
483
- // ─────────────────────────────────────────────────────────────────────────
484
- // Optional tools
485
- // ─────────────────────────────────────────────────────────────────────────
486
- "todo.enabled": {
487
- type: "boolean",
488
- default: true,
489
- ui: { tab: "tools", label: "Enable Todos", description: "Enable the todo_write tool for task tracking" },
490
- },
491
- "find.enabled": {
492
- type: "boolean",
493
- default: true,
494
- ui: { tab: "tools", label: "Enable Find", description: "Enable the find tool for file searching" },
495
- },
496
- "grep.enabled": {
497
- type: "boolean",
498
- default: true,
499
- ui: { tab: "tools", label: "Enable Grep", description: "Enable the grep tool for content searching" },
500
- },
501
- "grep.contextBefore": {
502
- type: "number",
503
- default: 0,
497
+ interruptMode: {
498
+ type: "enum",
499
+ values: ["immediate", "wait"] as const,
500
+ default: "immediate",
504
501
  ui: {
505
- tab: "tools",
506
- label: "Grep context before",
507
- description: "Lines of context before each grep match",
508
- submenu: true,
502
+ tab: "interaction",
503
+ label: "Interrupt Mode",
504
+ description: "When steering messages interrupt tool execution",
509
505
  },
510
506
  },
511
- "grep.contextAfter": {
512
- type: "number",
513
- default: 0,
507
+
508
+ // Input and startup
509
+ doubleEscapeAction: {
510
+ type: "enum",
511
+ values: ["branch", "tree", "none"] as const,
512
+ default: "tree",
514
513
  ui: {
515
- tab: "tools",
516
- label: "Grep context after",
517
- description: "Lines of context after each grep match",
518
- submenu: true,
514
+ tab: "interaction",
515
+ label: "Double-Escape Action",
516
+ description: "Action when pressing Escape twice with empty editor",
519
517
  },
520
518
  },
521
- "astGrep.enabled": {
522
- type: "boolean",
523
- default: true,
524
- ui: { tab: "tools", label: "Enable AST Grep", description: "Enable the ast_grep tool for structural AST search" },
525
- },
526
- "astEdit.enabled": {
527
- type: "boolean",
528
- default: true,
519
+
520
+ treeFilterMode: {
521
+ type: "enum",
522
+ values: ["default", "no-tools", "user-only", "labeled-only", "all"] as const,
523
+ default: "default",
529
524
  ui: {
530
- tab: "tools",
531
- label: "Enable AST Edit",
532
- description: "Enable the ast_edit tool for structural AST rewrites",
525
+ tab: "interaction",
526
+ label: "Session Tree Filter",
527
+ description: "Default filter mode when opening the session tree",
533
528
  },
534
529
  },
535
- "renderMermaid.enabled": {
536
- type: "boolean",
537
- default: false,
530
+
531
+ autocompleteMaxVisible: {
532
+ type: "number",
533
+ default: 5,
538
534
  ui: {
539
- tab: "tools",
540
- label: "Enable Render Mermaid",
541
- description: "Enable the render_mermaid tool for Mermaid-to-ASCII rendering",
535
+ tab: "interaction",
536
+ label: "Autocomplete Items",
537
+ description: "Max visible items in autocomplete dropdown (3-20)",
538
+ submenu: true,
542
539
  },
543
540
  },
544
- "notebook.enabled": {
545
- type: "boolean",
546
- default: true,
547
- ui: { tab: "tools", label: "Enable Notebook", description: "Enable the notebook tool for notebook editing" },
548
- },
549
- "inspect_image.enabled": {
541
+
542
+ "startup.quiet": {
550
543
  type: "boolean",
551
544
  default: false,
552
545
  ui: {
553
- tab: "tools",
554
- label: "Enable Inspect Image",
555
- description: "Enable the inspect_image tool, delegating image understanding to a vision-capable model",
546
+ tab: "interaction",
547
+ label: "Quiet Startup",
548
+ description: "Skip welcome screen and startup status messages",
556
549
  },
557
550
  },
558
- "checkpoint.enabled": {
551
+
552
+ collapseChangelog: {
559
553
  type: "boolean",
560
554
  default: false,
561
- ui: {
562
- tab: "tools",
563
- label: "Enable Checkpoint/Rewind",
564
- description: "Enable the checkpoint and rewind tools for context checkpointing",
565
- },
566
- },
567
- "fetch.enabled": {
568
- type: "boolean",
569
- default: true,
570
- ui: { tab: "tools", label: "Enable Fetch", description: "Enable the fetch tool for URL fetching" },
571
- },
572
- "web_search.enabled": {
573
- type: "boolean",
574
- default: true,
575
- ui: { tab: "tools", label: "Enable Web Search", description: "Enable the web_search tool for web searching" },
555
+ ui: { tab: "interaction", label: "Collapse Changelog", description: "Show condensed changelog after updates" },
576
556
  },
577
- "lsp.enabled": {
578
- type: "boolean",
579
- default: true,
580
- ui: { tab: "tools", label: "Enable LSP", description: "Enable the lsp tool for language server protocol" },
557
+
558
+ // Notifications
559
+ "completion.notify": {
560
+ type: "enum",
561
+ values: ["on", "off"] as const,
562
+ default: "on",
563
+ ui: { tab: "interaction", label: "Completion Notification", description: "Notify when the agent completes" },
581
564
  },
582
- "calc.enabled": {
583
- type: "boolean",
584
- default: false,
565
+
566
+ "ask.timeout": {
567
+ type: "number",
568
+ default: 30,
585
569
  ui: {
586
- tab: "tools",
587
- label: "Enable Calculator",
588
- description: "Enable the calculator tool for basic calculations",
570
+ tab: "interaction",
571
+ label: "Ask Timeout",
572
+ description: "Auto-select recommended option after timeout (0 to disable)",
573
+ submenu: true,
589
574
  },
590
575
  },
591
- "browser.enabled": {
592
- type: "boolean",
593
- default: true,
594
- ui: {
595
- tab: "tools",
596
- label: "Enable Browser",
597
- description: "Enable the browser tool (Ulixee Hero)",
598
- },
576
+
577
+ "ask.notify": {
578
+ type: "enum",
579
+ values: ["on", "off"] as const,
580
+ default: "on",
581
+ ui: { tab: "interaction", label: "Ask Notification", description: "Notify when ask tool is waiting for input" },
599
582
  },
600
- "browser.headless": {
583
+
584
+ // Speech-to-text
585
+ "stt.enabled": {
601
586
  type: "boolean",
602
- default: true,
603
- ui: {
604
- tab: "tools",
605
- label: "Browser headless",
606
- description: "Launch browser in headless mode (disable to show browser UI)",
607
- },
587
+ default: false,
588
+ ui: { tab: "interaction", label: "Speech-to-Text", description: "Enable speech-to-text input via microphone" },
608
589
  },
609
- "tools.intentTracing": {
610
- type: "boolean",
611
- default: true,
590
+
591
+ "stt.language": {
592
+ type: "string",
593
+ default: "en",
612
594
  ui: {
613
- tab: "tools",
614
- label: "Intent tracing",
615
- description: "Ask the agent to describe the intent of each tool call before executing it",
595
+ tab: "interaction",
596
+ label: "Speech Language",
597
+ description: "Language code for transcription (e.g., en, es, fr)",
598
+ submenu: true,
616
599
  },
617
600
  },
618
- "tools.maxTimeout": {
619
- type: "number",
620
- default: 0,
601
+
602
+ "stt.modelName": {
603
+ type: "enum",
604
+ values: ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large"] as const,
605
+ default: "base.en",
621
606
  ui: {
622
- tab: "tools",
623
- label: "Max tool timeout",
624
- description: "Maximum timeout in seconds the agent can set for any tool (0 = no limit)",
607
+ tab: "interaction",
608
+ label: "Speech Model",
609
+ description: "Whisper model size (larger = more accurate but slower)",
625
610
  submenu: true,
626
611
  },
627
612
  },
628
- "async.enabled": {
613
+
614
+ // ────────────────────────────────────────────────────────────────────────
615
+ // Context
616
+ // ────────────────────────────────────────────────────────────────────────
617
+
618
+ // Context promotion
619
+ "contextPromotion.enabled": {
629
620
  type: "boolean",
630
- default: false,
621
+ default: true,
631
622
  ui: {
632
- tab: "tools",
633
- label: "Async execution",
634
- description: "Enable async bash commands and background task execution",
623
+ tab: "context",
624
+ label: "Auto-Promote Context",
625
+ description: "Promote to a larger-context model on context overflow instead of compacting",
635
626
  },
636
627
  },
637
- "async.maxJobs": {
638
- type: "number",
639
- default: 100,
628
+
629
+ // Compaction
630
+ "compaction.enabled": {
631
+ type: "boolean",
632
+ default: true,
640
633
  ui: {
641
- tab: "tools",
642
- label: "Async max jobs",
643
- description: "Maximum concurrent background jobs (1-100)",
644
- submenu: true,
634
+ tab: "context",
635
+ label: "Auto-Compact",
636
+ description: "Automatically compact context when it gets too large",
645
637
  },
646
638
  },
647
639
 
648
- // ─────────────────────────────────────────────────────────────────────────
649
- // Task tool settings
650
- // ─────────────────────────────────────────────────────────────────────────
651
- "task.isolation.mode": {
640
+ "compaction.strategy": {
652
641
  type: "enum",
653
- values: ["none", "worktree", "fuse-overlay", "fuse-projfs"] as const,
654
- default: "none",
642
+ values: ["context-full", "handoff", "off"] as const,
643
+ default: "context-full",
655
644
  ui: {
656
- tab: "tools",
657
- label: "Task isolation",
658
- description:
659
- "Isolation mode for subagents (none, git worktree, fuse-overlayfs on Unix, or ProjFS on Windows via fuse-projfs; unsupported modes fall back to worktree)",
645
+ tab: "context",
646
+ label: "Compaction Strategy",
647
+ description: "Choose in-place context-full maintenance, auto-handoff, or disable auto maintenance (off)",
660
648
  submenu: true,
661
649
  },
662
650
  },
663
- "task.isolation.merge": {
664
- type: "enum",
665
- values: ["patch", "branch"] as const,
666
- default: "patch",
651
+
652
+ "compaction.thresholdPercent": {
653
+ type: "number",
654
+ default: -1,
667
655
  ui: {
668
- tab: "tools",
669
- label: "Task isolation merge",
670
- description: "How isolated task changes are integrated (patch apply or branch merge)",
656
+ tab: "context",
657
+ label: "Compaction Threshold",
658
+ description: "Percent threshold for context maintenance; set to Default to use legacy reserve-based behavior",
671
659
  submenu: true,
672
660
  },
673
661
  },
674
- "task.isolation.commits": {
675
- type: "enum",
676
- values: ["generic", "ai"] as const,
677
- default: "generic",
662
+ "compaction.thresholdTokens": {
663
+ type: "number",
664
+ default: -1,
678
665
  ui: {
679
- tab: "tools",
680
- label: "Task isolation commits",
681
- description: "Commit message style for nested repo changes (generic or AI-generated)",
666
+ tab: "context",
667
+ label: "Compaction Token Limit",
668
+ description: "Fixed token limit for context maintenance; overrides percentage if set",
682
669
  submenu: true,
683
670
  },
684
671
  },
685
- "task.eager": {
672
+
673
+ "compaction.handoffSaveToDisk": {
686
674
  type: "boolean",
687
675
  default: false,
688
676
  ui: {
689
- tab: "tools",
690
- label: "Eager task delegation",
691
- description: "Encourage the agent to delegate work to subagents unless changes are trivial",
692
- },
693
- },
694
- "task.maxConcurrency": {
695
- type: "number",
696
- default: 32,
697
- ui: {
698
- tab: "tools",
699
- label: "Task max concurrency",
700
- description: "Concurrent limit for subagents",
701
- submenu: true,
677
+ tab: "context",
678
+ label: "Save Handoff Docs",
679
+ description: "Save generated handoff documents to markdown files for the auto-handoff flow",
702
680
  },
703
681
  },
704
- "task.maxRecursionDepth": {
705
- type: "number",
706
- default: 2,
682
+
683
+ "compaction.remoteEnabled": {
684
+ type: "boolean",
685
+ default: true,
707
686
  ui: {
708
- tab: "tools",
709
- label: "Task max recursion depth",
710
- description: "How many levels deep subagents can spawn their own subagents",
711
- submenu: true,
687
+ tab: "context",
688
+ label: "Remote Compaction",
689
+ description: "Use remote compaction endpoints when available instead of local summarization",
712
690
  },
713
691
  },
714
- "task.disabledAgents": {
715
- type: "array",
716
- default: [] as string[],
717
- },
718
- "task.agentModelOverrides": {
719
- type: "record",
720
- default: {} as Record<string, string>,
721
- },
722
692
 
723
- // ─────────────────────────────────────────────────────────────────────────
724
- // Startup settings
725
- // ─────────────────────────────────────────────────────────────────────────
726
- "startup.quiet": {
693
+ "compaction.reserveTokens": { type: "number", default: 16384 },
694
+
695
+ "compaction.keepRecentTokens": { type: "number", default: 20000 },
696
+
697
+ "compaction.autoContinue": { type: "boolean", default: true },
698
+
699
+ "compaction.remoteEndpoint": { type: "string", default: undefined },
700
+
701
+ // Branch summaries
702
+ "branchSummary.enabled": {
727
703
  type: "boolean",
728
704
  default: false,
729
- ui: { tab: "input", label: "Startup quiet", description: "Skip welcome screen and startup status messages" },
705
+ ui: { tab: "context", label: "Branch Summaries", description: "Prompt to summarize when leaving a branch" },
730
706
  },
731
707
 
732
- // ─────────────────────────────────────────────────────────────────────────
733
- // Notification settings
734
- // ─────────────────────────────────────────────────────────────────────────
735
- "completion.notify": {
736
- type: "enum",
737
- values: ["on", "off"] as const,
738
- default: "on",
739
- ui: { tab: "input", label: "Completion notification", description: "Notify when the agent completes" },
740
- },
708
+ "branchSummary.reserveTokens": { type: "number", default: 16384 },
741
709
 
742
- // ─────────────────────────────────────────────────────────────────────────
743
- // Ask settings
744
- // ─────────────────────────────────────────────────────────────────────────
745
- "ask.timeout": {
746
- type: "number",
747
- default: 30,
710
+ // Memories
711
+ "memories.enabled": {
712
+ type: "boolean",
713
+ default: false,
748
714
  ui: {
749
- tab: "input",
750
- label: "Ask tool timeout",
751
- description: "Auto-select recommended option after timeout (0 to disable)",
752
- submenu: true,
715
+ tab: "context",
716
+ label: "Memories",
717
+ description: "Enable autonomous memory extraction and consolidation",
753
718
  },
754
719
  },
755
- "ask.notify": {
756
- type: "enum",
757
- values: ["on", "off"] as const,
758
- default: "on",
759
- ui: { tab: "input", label: "Ask notification", description: "Notify when ask tool is waiting for input" },
760
- },
761
720
 
762
- // ─────────────────────────────────────────────────────────────────────────
763
- // Terminal settings
764
- // ─────────────────────────────────────────────────────────────────────────
765
- "terminal.showImages": {
721
+ "memories.maxRolloutsPerStartup": { type: "number", default: 64 },
722
+
723
+ "memories.maxRolloutAgeDays": { type: "number", default: 30 },
724
+
725
+ "memories.minRolloutIdleHours": { type: "number", default: 12 },
726
+
727
+ "memories.threadScanLimit": { type: "number", default: 300 },
728
+
729
+ "memories.maxRawMemoriesForGlobal": { type: "number", default: 200 },
730
+
731
+ "memories.stage1Concurrency": { type: "number", default: 8 },
732
+
733
+ "memories.stage1LeaseSeconds": { type: "number", default: 120 },
734
+
735
+ "memories.stage1RetryDelaySeconds": { type: "number", default: 120 },
736
+
737
+ "memories.phase2LeaseSeconds": { type: "number", default: 180 },
738
+
739
+ "memories.phase2RetryDelaySeconds": { type: "number", default: 180 },
740
+
741
+ "memories.phase2HeartbeatSeconds": { type: "number", default: 30 },
742
+
743
+ "memories.rolloutPayloadPercent": { type: "number", default: 0.7 },
744
+
745
+ "memories.fallbackTokenLimit": { type: "number", default: 16000 },
746
+
747
+ "memories.summaryInjectionTokenLimit": { type: "number", default: 5000 },
748
+
749
+ // TTSR
750
+ "ttsr.enabled": {
766
751
  type: "boolean",
767
752
  default: true,
768
753
  ui: {
769
- tab: "display",
770
- label: "Show images",
771
- description: "Render images inline in terminal",
772
- condition: "hasImageProtocol",
754
+ tab: "context",
755
+ label: "TTSR",
756
+ description: "Time Traveling Stream Rules: interrupt agent when output matches patterns",
773
757
  },
774
758
  },
775
759
 
776
- // ─────────────────────────────────────────────────────────────────────────
777
- // Image settings
778
- // ─────────────────────────────────────────────────────────────────────────
779
- "images.autoResize": {
780
- type: "boolean",
781
- default: true,
760
+ "ttsr.contextMode": {
761
+ type: "enum",
762
+ values: ["discard", "keep"] as const,
763
+ default: "discard",
782
764
  ui: {
783
- tab: "display",
784
- label: "Auto-resize images",
785
- description: "Resize large images to 2000x2000 max for better model compatibility",
765
+ tab: "context",
766
+ label: "TTSR Context Mode",
767
+ description: "What to do with partial output when TTSR triggers",
786
768
  },
787
769
  },
788
- "images.blockImages": {
789
- type: "boolean",
790
- default: false,
791
- ui: { tab: "display", label: "Block images", description: "Prevent images from being sent to LLM providers" },
792
- },
793
-
794
- // ─────────────────────────────────────────────────────────────────────────
795
- // Skills settings
796
- // ─────────────────────────────────────────────────────────────────────────
797
- "skills.enabled": { type: "boolean", default: true },
798
- "skills.enableSkillCommands": {
799
- type: "boolean",
800
- default: true,
801
- ui: { tab: "tools", label: "Skill commands", description: "Register skills as /skill:name commands" },
802
- },
803
- "skills.enableCodexUser": { type: "boolean", default: true },
804
- "skills.enableClaudeUser": { type: "boolean", default: true },
805
- "skills.enableClaudeProject": { type: "boolean", default: true },
806
- "skills.enablePiUser": { type: "boolean", default: true },
807
- "skills.enablePiProject": { type: "boolean", default: true },
808
- "skills.customDirectories": { type: "array", default: [] as string[] },
809
- "skills.ignoredSkills": { type: "array", default: [] as string[] },
810
- "skills.includeSkills": { type: "array", default: [] as string[] },
811
-
812
- // ─────────────────────────────────────────────────────────────────────────
813
- // Commands settings
814
- // ─────────────────────────────────────────────────────────────────────────
815
- "commands.enableClaudeUser": {
816
- type: "boolean",
817
- default: true,
818
- ui: { tab: "tools", label: "Claude user commands", description: "Load commands from ~/.claude/commands/" },
819
- },
820
- "commands.enableClaudeProject": {
821
- type: "boolean",
822
- default: true,
823
- ui: { tab: "tools", label: "Claude project commands", description: "Load commands from .claude/commands/" },
824
- },
825
770
 
826
- // ─────────────────────────────────────────────────────────────────────────
827
- // Provider settings
828
- // ─────────────────────────────────────────────────────────────────────────
829
- "providers.webSearch": {
830
- type: "enum",
831
- values: [
832
- "auto",
833
- "exa",
834
- "brave",
835
- "jina",
836
- "kimi",
837
- "zai",
838
- "perplexity",
839
- "anthropic",
840
- "gemini",
841
- "codex",
842
- "tavily",
843
- "kagi",
844
- "synthetic",
845
- "parallel",
846
- ] as const,
847
- default: "auto",
848
- ui: { tab: "services", label: "Web search provider", description: "Provider for web search tool", submenu: true },
849
- },
850
- "providers.codeSearch": {
771
+ "ttsr.interruptMode": {
851
772
  type: "enum",
852
- values: ["grep", "exa"] as const,
853
- default: "grep",
773
+ values: ["never", "prose-only", "tool-only", "always"] as const,
774
+ default: "always",
854
775
  ui: {
855
- tab: "services",
856
- label: "Code search provider",
857
- description: "Provider for code search tool",
776
+ tab: "context",
777
+ label: "TTSR Interrupt Mode",
778
+ description: "When to interrupt mid-stream vs inject warning after completion",
858
779
  submenu: true,
859
780
  },
860
781
  },
861
- "providers.image": {
782
+
783
+ "ttsr.repeatMode": {
862
784
  type: "enum",
863
- values: ["auto", "gemini", "openrouter"] as const,
864
- default: "auto",
785
+ values: ["once", "after-gap"] as const,
786
+ default: "once",
865
787
  ui: {
866
- tab: "services",
867
- label: "Image provider",
868
- description: "Provider for image generation tool",
869
- submenu: true,
788
+ tab: "context",
789
+ label: "TTSR Repeat Mode",
790
+ description: "How rules can repeat: once per session or after a message gap",
870
791
  },
871
792
  },
872
- "providers.kimiApiFormat": {
873
- type: "enum",
874
- values: ["openai", "anthropic"] as const,
875
- default: "anthropic",
793
+
794
+ "ttsr.repeatGap": {
795
+ type: "number",
796
+ default: 10,
876
797
  ui: {
877
- tab: "services",
878
- label: "Kimi API format",
879
- description: "API format for Kimi Code provider",
798
+ tab: "context",
799
+ label: "TTSR Repeat Gap",
800
+ description: "Messages before a rule can trigger again",
880
801
  submenu: true,
881
802
  },
882
803
  },
883
- "providers.openaiWebsockets": {
804
+
805
+ // ────────────────────────────────────────────────────────────────────────
806
+ // Editing
807
+ // ────────────────────────────────────────────────────────────────────────
808
+
809
+ // Edit tool
810
+ "edit.mode": {
884
811
  type: "enum",
885
- values: ["auto", "off", "on"] as const,
886
- default: "auto",
812
+ values: ["replace", "patch", "hashline"] as const,
813
+ default: "hashline",
887
814
  ui: {
888
- tab: "services",
889
- label: "OpenAI websockets",
890
- description: "Websocket policy for OpenAI Codex models (auto uses model defaults, on forces, off disables)",
891
- submenu: true,
815
+ tab: "editing",
816
+ label: "Edit Mode",
817
+ description: "Select the edit tool variant (replace, patch, or hashline)",
892
818
  },
893
819
  },
894
820
 
895
- "providers.parallelFetch": {
821
+ "edit.fuzzyMatch": {
896
822
  type: "boolean",
897
823
  default: true,
898
824
  ui: {
899
- tab: "services",
900
- label: "Parallel fetch",
901
- description: "Use Parallel extract API for URL fetching when credentials are available",
825
+ tab: "editing",
826
+ label: "Fuzzy Match",
827
+ description: "Accept high-confidence fuzzy matches for whitespace differences",
902
828
  },
903
829
  },
904
830
 
905
- // ─────────────────────────────────────────────────────────────────────────
906
- // Exa settings
907
- // ─────────────────────────────────────────────────────────────────────────
908
- "exa.enabled": {
909
- type: "boolean",
910
- default: true,
911
- ui: { tab: "services", label: "Exa enabled", description: "Master toggle for all Exa search tools" },
912
- },
913
- "exa.enableSearch": {
914
- type: "boolean",
915
- default: true,
916
- ui: { tab: "services", label: "Exa search", description: "Basic search, deep search, code search, crawl" },
917
- },
918
- "exa.enableResearcher": {
919
- type: "boolean",
920
- default: false,
921
- ui: { tab: "services", label: "Exa researcher", description: "AI-powered deep research tasks" },
831
+ "edit.fuzzyThreshold": {
832
+ type: "number",
833
+ default: 0.95,
834
+ ui: {
835
+ tab: "editing",
836
+ label: "Fuzzy Match Threshold",
837
+ description: "Similarity threshold for fuzzy matches",
838
+ submenu: true,
839
+ },
922
840
  },
923
- "exa.enableWebsets": {
841
+
842
+ "edit.streamingAbort": {
924
843
  type: "boolean",
925
844
  default: false,
926
- ui: { tab: "services", label: "Exa websets", description: "Webset management and enrichment tools" },
845
+ ui: {
846
+ tab: "editing",
847
+ label: "Abort on Failed Preview",
848
+ description: "Abort streaming edit tool calls when patch preview fails",
849
+ },
927
850
  },
928
851
 
929
- // ─────────────────────────────────────────────────────────────────────────
930
- // Bash interceptor settings
931
- // ─────────────────────────────────────────────────────────────────────────
932
- "bashInterceptor.enabled": {
852
+ // Read tool
853
+ readLineNumbers: {
933
854
  type: "boolean",
934
855
  default: false,
935
- ui: { tab: "bash", label: "Interceptor", description: "Block shell commands that have dedicated tools" },
936
- },
937
- "bashInterceptor.simpleLs": {
938
- type: "boolean",
939
- default: true,
940
856
  ui: {
941
- tab: "bash",
942
- label: "Intercept ls",
943
- description: "Intercept bare ls commands (when interceptor is enabled)",
857
+ tab: "editing",
858
+ label: "Line Numbers",
859
+ description: "Prepend line numbers to read tool output by default",
944
860
  },
945
861
  },
946
- // bashInterceptor.patterns is complex - handle separately
947
862
 
948
- // ─────────────────────────────────────────────────────────────────────────
949
- // MCP settings
950
- // ─────────────────────────────────────────────────────────────────────────
951
- "mcp.enableProjectConfig": {
863
+ readHashLines: {
952
864
  type: "boolean",
953
865
  default: true,
954
- ui: { tab: "tools", label: "MCP project config", description: "Load .mcp.json/mcp.json from project root" },
955
- },
956
- "mcp.notifications": {
957
- type: "boolean",
958
- default: false,
959
866
  ui: {
960
- tab: "tools",
961
- label: "MCP update injection",
962
- description: "Inject MCP resource updates into the agent conversation",
867
+ tab: "editing",
868
+ label: "Hash Lines",
869
+ description: "Include line hashes in read output for hashline edit mode (LINE#ID:content)",
963
870
  },
964
871
  },
965
- "mcp.notificationDebounceMs": {
872
+
873
+ "read.defaultLimit": {
966
874
  type: "number",
967
- default: 500,
875
+ default: 300,
968
876
  ui: {
969
- tab: "tools",
970
- label: "MCP notification debounce (ms)",
971
- description: "Debounce window for MCP resource update notifications before injecting into conversation",
877
+ tab: "editing",
878
+ label: "Default Read Limit",
879
+ description: "Default number of lines returned when agent calls read without a limit",
880
+ submenu: true,
972
881
  },
973
882
  },
974
883
 
975
- // ─────────────────────────────────────────────────────────────────────────
976
- // LSP settings
977
- // ─────────────────────────────────────────────────────────────────────────
884
+ // LSP
885
+ "lsp.enabled": {
886
+ type: "boolean",
887
+ default: true,
888
+ ui: { tab: "editing", label: "LSP", description: "Enable the lsp tool for language server protocol" },
889
+ },
890
+
978
891
  "lsp.formatOnWrite": {
979
892
  type: "boolean",
980
893
  default: false,
981
894
  ui: {
982
- tab: "lsp",
983
- label: "Format on write",
895
+ tab: "editing",
896
+ label: "Format on Write",
984
897
  description: "Automatically format code files using LSP after writing",
985
898
  },
986
899
  },
900
+
987
901
  "lsp.diagnosticsOnWrite": {
988
902
  type: "boolean",
989
903
  default: true,
990
- ui: { tab: "lsp", label: "Diagnostics on write", description: "Return LSP diagnostics after writing code files" },
904
+ ui: {
905
+ tab: "editing",
906
+ label: "Diagnostics on Write",
907
+ description: "Return LSP diagnostics after writing code files",
908
+ },
991
909
  },
910
+
992
911
  "lsp.diagnosticsOnEdit": {
993
912
  type: "boolean",
994
913
  default: false,
995
- ui: { tab: "lsp", label: "Diagnostics on edit", description: "Return LSP diagnostics after editing code files" },
914
+ ui: {
915
+ tab: "editing",
916
+ label: "Diagnostics on Edit",
917
+ description: "Return LSP diagnostics after editing code files",
918
+ },
919
+ },
920
+
921
+ // Bash interceptor
922
+ "bashInterceptor.enabled": {
923
+ type: "boolean",
924
+ default: false,
925
+ ui: { tab: "editing", label: "Bash Interceptor", description: "Block shell commands that have dedicated tools" },
926
+ },
927
+
928
+ "bashInterceptor.simpleLs": {
929
+ type: "boolean",
930
+ default: true,
931
+ ui: {
932
+ tab: "editing",
933
+ label: "Intercept `ls`",
934
+ description: "Intercept bare ls commands (when interceptor is enabled)",
935
+ },
996
936
  },
997
937
 
998
- // ─────────────────────────────────────────────────────────────────────────
999
- // Python settings
1000
- // ─────────────────────────────────────────────────────────────────────────
938
+ // Python
1001
939
  "python.toolMode": {
1002
940
  type: "enum",
1003
941
  values: ["ipy-only", "bash-only", "both"] as const,
1004
942
  default: "both",
1005
- ui: { tab: "config", label: "Python tool mode", description: "How Python code is executed" },
943
+ ui: { tab: "editing", label: "Python Tool Mode", description: "How Python code is executed" },
1006
944
  },
945
+
1007
946
  "python.kernelMode": {
1008
947
  type: "enum",
1009
948
  values: ["session", "per-call"] as const,
1010
949
  default: "session",
1011
950
  ui: {
1012
- tab: "config",
1013
- label: "Python kernel mode",
951
+ tab: "editing",
952
+ label: "Python Kernel Mode",
1014
953
  description: "Whether to keep IPython kernel alive across calls",
1015
954
  },
1016
955
  },
956
+
1017
957
  "python.sharedGateway": {
1018
958
  type: "boolean",
1019
959
  default: true,
1020
960
  ui: {
1021
- tab: "config",
1022
- label: "Python shared gateway",
961
+ tab: "editing",
962
+ label: "Shared Python Gateway",
1023
963
  description: "Share IPython kernel gateway across pi instances",
1024
964
  },
1025
965
  },
1026
966
 
1027
- // ─────────────────────────────────────────────────────────────────────────
1028
- // STT settings
1029
- // ─────────────────────────────────────────────────────────────────────────
1030
- "stt.enabled": {
967
+ // ────────────────────────────────────────────────────────────────────────
968
+ // Tools
969
+ // ────────────────────────────────────────────────────────────────────────
970
+
971
+ // Todo tool
972
+ "todo.enabled": {
1031
973
  type: "boolean",
1032
- default: false,
1033
- ui: { tab: "input", label: "Speech-to-text", description: "Enable speech-to-text input via microphone" },
974
+ default: true,
975
+ ui: { tab: "tools", label: "Todos", description: "Enable the todo_write tool for task tracking" },
1034
976
  },
1035
- "stt.language": {
1036
- type: "string",
1037
- default: "en",
1038
- ui: {
1039
- tab: "input",
1040
- label: "STT language",
1041
- description: "Language code for transcription (e.g., en, es, fr)",
1042
- submenu: true,
1043
- },
977
+
978
+ "todo.reminders": {
979
+ type: "boolean",
980
+ default: true,
981
+ ui: { tab: "tools", label: "Todo Reminders", description: "Remind agent to complete todos before stopping" },
1044
982
  },
1045
- "stt.modelName": {
1046
- type: "enum",
1047
- values: ["tiny", "tiny.en", "base", "base.en", "small", "small.en", "medium", "medium.en", "large"] as const,
1048
- default: "base.en",
983
+
984
+ "todo.reminders.max": {
985
+ type: "number",
986
+ default: 3,
1049
987
  ui: {
1050
- tab: "input",
1051
- label: "STT model",
1052
- description: "Whisper model size (larger = more accurate but slower)",
988
+ tab: "tools",
989
+ label: "Todo Reminder Limit",
990
+ description: "Maximum reminders to complete todos before giving up",
1053
991
  submenu: true,
1054
992
  },
1055
993
  },
1056
994
 
1057
- // ─────────────────────────────────────────────────────────────────────────
1058
- // Edit settings
1059
- // ─────────────────────────────────────────────────────────────────────────
1060
- "edit.fuzzyMatch": {
995
+ "todo.eager": {
1061
996
  type: "boolean",
1062
- default: true,
997
+ default: false,
1063
998
  ui: {
1064
- tab: "config",
1065
- label: "Edit fuzzy match",
1066
- description: "Accept high-confidence fuzzy matches for whitespace differences",
999
+ tab: "tools",
1000
+ label: "Create Todos Automatically",
1001
+ description: "Automatically create a comprehensive todo list after the first message",
1067
1002
  },
1068
1003
  },
1069
- "edit.fuzzyThreshold": {
1004
+
1005
+ // Search and AST tools
1006
+ "find.enabled": {
1007
+ type: "boolean",
1008
+ default: true,
1009
+ ui: { tab: "tools", label: "Find", description: "Enable the find tool for file searching" },
1010
+ },
1011
+
1012
+ "grep.enabled": {
1013
+ type: "boolean",
1014
+ default: true,
1015
+ ui: { tab: "tools", label: "Grep", description: "Enable the grep tool for content searching" },
1016
+ },
1017
+
1018
+ "grep.contextBefore": {
1070
1019
  type: "number",
1071
- default: 0.95,
1020
+ default: 0,
1072
1021
  ui: {
1073
- tab: "config",
1074
- label: "Edit fuzzy threshold",
1075
- description: "Similarity threshold for fuzzy matches",
1022
+ tab: "tools",
1023
+ label: "Grep Context Before",
1024
+ description: "Lines of context before each grep match",
1076
1025
  submenu: true,
1077
1026
  },
1078
1027
  },
1079
- "edit.mode": {
1080
- type: "enum",
1081
- values: ["replace", "patch", "hashline"] as const,
1082
- default: "hashline",
1028
+
1029
+ "grep.contextAfter": {
1030
+ type: "number",
1031
+ default: 0,
1083
1032
  ui: {
1084
- tab: "config",
1085
- label: "Edit mode",
1086
- description: "Select the edit tool variant (replace, patch, or hashline)",
1033
+ tab: "tools",
1034
+ label: "Grep Context After",
1035
+ description: "Lines of context after each grep match",
1036
+ submenu: true,
1087
1037
  },
1088
1038
  },
1089
- "edit.streamingAbort": {
1039
+
1040
+ "astGrep.enabled": {
1041
+ type: "boolean",
1042
+ default: true,
1043
+ ui: {
1044
+ tab: "tools",
1045
+ label: "AST Grep",
1046
+ description: "Enable the ast_grep tool for structural AST search",
1047
+ },
1048
+ },
1049
+
1050
+ "astEdit.enabled": {
1051
+ type: "boolean",
1052
+ default: true,
1053
+ ui: {
1054
+ tab: "tools",
1055
+ label: "AST Edit",
1056
+ description: "Enable the ast_edit tool for structural AST rewrites",
1057
+ },
1058
+ },
1059
+
1060
+ // Optional tools
1061
+ "notebook.enabled": {
1062
+ type: "boolean",
1063
+ default: true,
1064
+ ui: { tab: "tools", label: "Notebook", description: "Enable the notebook tool for notebook editing" },
1065
+ },
1066
+
1067
+ "renderMermaid.enabled": {
1090
1068
  type: "boolean",
1091
1069
  default: false,
1092
1070
  ui: {
1093
- tab: "config",
1094
- label: "Edit streaming abort",
1095
- description: "Abort streaming edit tool calls when patch preview fails",
1071
+ tab: "tools",
1072
+ label: "Render Mermaid",
1073
+ description: "Enable the render_mermaid tool for Mermaid-to-ASCII rendering",
1096
1074
  },
1097
1075
  },
1098
- // edit.modelVariants is complex - handle separately
1099
1076
 
1100
- // ─────────────────────────────────────────────────────────────────────────
1101
- // TTSR settings
1102
- // ─────────────────────────────────────────────────────────────────────────
1103
- "ttsr.enabled": {
1077
+ "calc.enabled": {
1078
+ type: "boolean",
1079
+ default: false,
1080
+ ui: {
1081
+ tab: "tools",
1082
+ label: "Calculator",
1083
+ description: "Enable the calculator tool for basic calculations",
1084
+ },
1085
+ },
1086
+
1087
+ "inspect_image.enabled": {
1088
+ type: "boolean",
1089
+ default: false,
1090
+ ui: {
1091
+ tab: "tools",
1092
+ label: "Inspect Image",
1093
+ description: "Enable the inspect_image tool, delegating image understanding to a vision-capable model",
1094
+ },
1095
+ },
1096
+
1097
+ "checkpoint.enabled": {
1098
+ type: "boolean",
1099
+ default: false,
1100
+ ui: {
1101
+ tab: "tools",
1102
+ label: "Checkpoint/Rewind",
1103
+ description: "Enable the checkpoint and rewind tools for context checkpointing",
1104
+ },
1105
+ },
1106
+
1107
+ // Fetching and browser
1108
+ "fetch.enabled": {
1109
+ type: "boolean",
1110
+ default: true,
1111
+ ui: { tab: "tools", label: "Fetch", description: "Enable the fetch tool for URL fetching" },
1112
+ },
1113
+
1114
+ "web_search.enabled": {
1115
+ type: "boolean",
1116
+ default: true,
1117
+ ui: { tab: "tools", label: "Web Search", description: "Enable the web_search tool for web searching" },
1118
+ },
1119
+
1120
+ "browser.enabled": {
1104
1121
  type: "boolean",
1105
1122
  default: true,
1106
1123
  ui: {
1107
- tab: "ttsr",
1108
- label: "TTSR enabled",
1109
- description: "Time Traveling Stream Rules: interrupt agent when output matches patterns",
1124
+ tab: "tools",
1125
+ label: "Browser",
1126
+ description: "Enable the browser tool (Ulixee Hero)",
1110
1127
  },
1111
1128
  },
1112
- "ttsr.contextMode": {
1113
- type: "enum",
1114
- values: ["discard", "keep"] as const,
1115
- default: "discard",
1116
- ui: { tab: "ttsr", label: "TTSR context mode", description: "What to do with partial output when TTSR triggers" },
1129
+
1130
+ "browser.headless": {
1131
+ type: "boolean",
1132
+ default: true,
1133
+ ui: {
1134
+ tab: "tools",
1135
+ label: "Headless Browser",
1136
+ description: "Launch browser in headless mode (disable to show browser UI)",
1137
+ },
1117
1138
  },
1118
- "ttsr.interruptMode": {
1119
- type: "enum",
1120
- values: ["never", "prose-only", "tool-only", "always"] as const,
1121
- default: "always",
1139
+
1140
+ // Tool execution
1141
+ "tools.intentTracing": {
1142
+ type: "boolean",
1143
+ default: true,
1122
1144
  ui: {
1123
- tab: "ttsr",
1124
- label: "TTSR interrupt mode",
1125
- description: "When to interrupt mid-stream vs inject warning after completion",
1145
+ tab: "tools",
1146
+ label: "Intent Tracing",
1147
+ description: "Ask the agent to describe the intent of each tool call before executing it",
1148
+ },
1149
+ },
1150
+
1151
+ "tools.maxTimeout": {
1152
+ type: "number",
1153
+ default: 0,
1154
+ ui: {
1155
+ tab: "tools",
1156
+ label: "Max Tool Timeout",
1157
+ description: "Maximum timeout in seconds the agent can set for any tool (0 = no limit)",
1126
1158
  submenu: true,
1127
1159
  },
1128
1160
  },
1129
- "ttsr.repeatMode": {
1130
- type: "enum",
1131
- values: ["once", "after-gap"] as const,
1132
- default: "once",
1161
+
1162
+ // Async jobs
1163
+ "async.enabled": {
1164
+ type: "boolean",
1165
+ default: false,
1133
1166
  ui: {
1134
- tab: "ttsr",
1135
- label: "TTSR repeat mode",
1136
- description: "How rules can repeat: once per session or after a message gap",
1167
+ tab: "tools",
1168
+ label: "Async Execution",
1169
+ description: "Enable async bash commands and background task execution",
1137
1170
  },
1138
1171
  },
1139
- "ttsr.repeatGap": {
1172
+
1173
+ "async.maxJobs": {
1140
1174
  type: "number",
1141
- default: 10,
1175
+ default: 100,
1142
1176
  ui: {
1143
- tab: "ttsr",
1144
- label: "TTSR repeat gap",
1145
- description: "Messages before a rule can trigger again",
1177
+ tab: "tools",
1178
+ label: "Max Async Jobs",
1179
+ description: "Maximum concurrent background jobs (1-100)",
1146
1180
  submenu: true,
1147
1181
  },
1148
1182
  },
1149
1183
 
1150
- // ─────────────────────────────────────────────────────────────────────────
1151
- // Commit settings (no UI - advanced)
1152
- // ─────────────────────────────────────────────────────────────────────────
1153
- "commit.mapReduceEnabled": { type: "boolean", default: true },
1154
- "commit.mapReduceMinFiles": { type: "number", default: 4 },
1155
- "commit.mapReduceMaxFileTokens": { type: "number", default: 50000 },
1156
- "commit.mapReduceTimeoutMs": { type: "number", default: 120000 },
1157
- "commit.mapReduceMaxConcurrency": { type: "number", default: 5 },
1158
- "commit.changelogMaxDiffChars": { type: "number", default: 120000 },
1184
+ // MCP
1185
+ "mcp.enableProjectConfig": {
1186
+ type: "boolean",
1187
+ default: true,
1188
+ ui: { tab: "tools", label: "MCP Project Config", description: "Load .mcp.json/mcp.json from project root" },
1189
+ },
1159
1190
 
1160
- // ─────────────────────────────────────────────────────────────────────────
1161
- // Thinking budgets (no UI - advanced)
1162
- // ─────────────────────────────────────────────────────────────────────────
1163
- "thinkingBudgets.minimal": { type: "number", default: 1024 },
1164
- "thinkingBudgets.low": { type: "number", default: 2048 },
1165
- "thinkingBudgets.medium": { type: "number", default: 8192 },
1166
- "thinkingBudgets.high": { type: "number", default: 16384 },
1191
+ "mcp.notifications": {
1192
+ type: "boolean",
1193
+ default: false,
1194
+ ui: {
1195
+ tab: "tools",
1196
+ label: "MCP Update Injection",
1197
+ description: "Inject MCP resource updates into the agent conversation",
1198
+ },
1199
+ },
1167
1200
 
1168
- // ─────────────────────────────────────────────────────────────────────────
1169
- // Status line settings
1170
- // ─────────────────────────────────────────────────────────────────────────
1171
- "statusLine.preset": {
1201
+ "mcp.notificationDebounceMs": {
1202
+ type: "number",
1203
+ default: 500,
1204
+ ui: {
1205
+ tab: "tools",
1206
+ label: "MCP Notification Debounce",
1207
+ description: "Debounce window for MCP resource update notifications before injecting into conversation",
1208
+ },
1209
+ },
1210
+
1211
+ // ────────────────────────────────────────────────────────────────────────
1212
+ // Tasks
1213
+ // ────────────────────────────────────────────────────────────────────────
1214
+
1215
+ // Delegation
1216
+ "task.isolation.mode": {
1172
1217
  type: "enum",
1173
- values: ["default", "minimal", "compact", "full", "nerd", "ascii", "custom"] as const,
1174
- default: "default",
1175
- ui: { tab: "status", label: "Preset", description: "Pre-built status line configurations", submenu: true },
1218
+ values: ["none", "worktree", "fuse-overlay", "fuse-projfs"] as const,
1219
+ default: "none",
1220
+ ui: {
1221
+ tab: "tasks",
1222
+ label: "Isolation Mode",
1223
+ description:
1224
+ "Isolation mode for subagents (none, git worktree, fuse-overlayfs on Unix, or ProjFS on Windows via fuse-projfs; unsupported modes fall back to worktree)",
1225
+ submenu: true,
1226
+ },
1176
1227
  },
1177
- "statusLine.separator": {
1228
+
1229
+ "task.isolation.merge": {
1178
1230
  type: "enum",
1179
- values: ["powerline", "powerline-thin", "slash", "pipe", "block", "none", "ascii"] as const,
1180
- default: "powerline-thin",
1231
+ values: ["patch", "branch"] as const,
1232
+ default: "patch",
1181
1233
  ui: {
1182
- tab: "status",
1183
- label: "Separator style",
1184
- description: "Style of separators between segments",
1234
+ tab: "tasks",
1235
+ label: "Isolation Merge Strategy",
1236
+ description: "How isolated task changes are integrated (patch apply or branch merge)",
1185
1237
  submenu: true,
1186
1238
  },
1187
1239
  },
1188
- "statusLine.showHookStatus": {
1240
+
1241
+ "task.isolation.commits": {
1242
+ type: "enum",
1243
+ values: ["generic", "ai"] as const,
1244
+ default: "generic",
1245
+ ui: {
1246
+ tab: "tasks",
1247
+ label: "Isolation Commit Style",
1248
+ description: "Commit message style for nested repo changes (generic or AI-generated)",
1249
+ submenu: true,
1250
+ },
1251
+ },
1252
+
1253
+ "task.eager": {
1189
1254
  type: "boolean",
1190
- default: true,
1255
+ default: false,
1191
1256
  ui: {
1192
- tab: "status",
1193
- label: "Show extension status",
1194
- description: "Display hook status messages below status line",
1257
+ tab: "tasks",
1258
+ label: "Prefer Task Delegation",
1259
+ description: "Encourage the agent to delegate work to subagents unless changes are trivial",
1195
1260
  },
1196
1261
  },
1197
- "statusLine.leftSegments": { type: "array", default: [] as StatusLineSegmentId[] },
1198
- "statusLine.rightSegments": { type: "array", default: [] as StatusLineSegmentId[] },
1199
- "statusLine.segmentOptions": { type: "record", default: {} as Record<string, unknown> },
1200
- temperature: {
1262
+
1263
+ "task.maxConcurrency": {
1201
1264
  type: "number",
1202
- default: -1,
1265
+ default: 32,
1203
1266
  ui: {
1204
- tab: "agent",
1205
- label: "Temperature",
1206
- description: "Sampling temperature (0 = deterministic, 1 = creative, -1 = provider default)",
1267
+ tab: "tasks",
1268
+ label: "Max Concurrent Tasks",
1269
+ description: "Concurrent limit for subagents",
1207
1270
  submenu: true,
1208
1271
  },
1209
1272
  },
1210
- topP: {
1273
+
1274
+ "task.maxRecursionDepth": {
1211
1275
  type: "number",
1212
- default: -1,
1276
+ default: 2,
1213
1277
  ui: {
1214
- tab: "agent",
1215
- label: "Top P",
1216
- description: "Nucleus sampling cutoff (0-1, -1 = provider default)",
1278
+ tab: "tasks",
1279
+ label: "Max Task Recursion",
1280
+ description: "How many levels deep subagents can spawn their own subagents",
1217
1281
  submenu: true,
1218
1282
  },
1219
1283
  },
1220
- topK: {
1221
- type: "number",
1222
- default: -1,
1284
+
1285
+ "task.disabledAgents": {
1286
+ type: "array",
1287
+ default: [] as string[],
1288
+ },
1289
+
1290
+ "task.agentModelOverrides": {
1291
+ type: "record",
1292
+ default: {} as Record<string, string>,
1293
+ },
1294
+
1295
+ // Skills
1296
+ "skills.enabled": { type: "boolean", default: true },
1297
+
1298
+ "skills.enableSkillCommands": {
1299
+ type: "boolean",
1300
+ default: true,
1301
+ ui: { tab: "tasks", label: "Skill Commands", description: "Register skills as /skill:name commands" },
1302
+ },
1303
+
1304
+ "skills.enableCodexUser": { type: "boolean", default: true },
1305
+
1306
+ "skills.enableClaudeUser": { type: "boolean", default: true },
1307
+
1308
+ "skills.enableClaudeProject": { type: "boolean", default: true },
1309
+
1310
+ "skills.enablePiUser": { type: "boolean", default: true },
1311
+
1312
+ "skills.enablePiProject": { type: "boolean", default: true },
1313
+
1314
+ "skills.customDirectories": { type: "array", default: [] as string[] },
1315
+
1316
+ "skills.ignoredSkills": { type: "array", default: [] as string[] },
1317
+
1318
+ "skills.includeSkills": { type: "array", default: [] as string[] },
1319
+
1320
+ // Commands
1321
+ "commands.enableClaudeUser": {
1322
+ type: "boolean",
1323
+ default: true,
1324
+ ui: { tab: "tasks", label: "Claude User Commands", description: "Load commands from ~/.claude/commands/" },
1325
+ },
1326
+
1327
+ "commands.enableClaudeProject": {
1328
+ type: "boolean",
1329
+ default: true,
1330
+ ui: { tab: "tasks", label: "Claude Project Commands", description: "Load commands from .claude/commands/" },
1331
+ },
1332
+
1333
+ // ────────────────────────────────────────────────────────────────────────
1334
+ // Providers
1335
+ // ────────────────────────────────────────────────────────────────────────
1336
+
1337
+ // Secret handling
1338
+ "secrets.enabled": {
1339
+ type: "boolean",
1340
+ default: false,
1341
+ ui: { tab: "providers", label: "Hide Secrets", description: "Obfuscate secrets before sending to AI providers" },
1342
+ },
1343
+
1344
+ // Provider selection
1345
+ "providers.webSearch": {
1346
+ type: "enum",
1347
+ values: [
1348
+ "auto",
1349
+ "exa",
1350
+ "brave",
1351
+ "jina",
1352
+ "kimi",
1353
+ "zai",
1354
+ "perplexity",
1355
+ "anthropic",
1356
+ "gemini",
1357
+ "codex",
1358
+ "tavily",
1359
+ "kagi",
1360
+ "synthetic",
1361
+ "parallel",
1362
+ ] as const,
1363
+ default: "auto",
1223
1364
  ui: {
1224
- tab: "agent",
1225
- label: "Top K",
1226
- description: "Sample from top-K tokens (-1 = provider default)",
1365
+ tab: "providers",
1366
+ label: "Web Search Provider",
1367
+ description: "Provider for web search tool",
1227
1368
  submenu: true,
1228
1369
  },
1229
1370
  },
1230
- minP: {
1231
- type: "number",
1232
- default: -1,
1371
+
1372
+ "providers.codeSearch": {
1373
+ type: "enum",
1374
+ values: ["grep", "exa"] as const,
1375
+ default: "grep",
1233
1376
  ui: {
1234
- tab: "agent",
1235
- label: "Min P",
1236
- description: "Minimum probability threshold (0-1, -1 = provider default)",
1377
+ tab: "providers",
1378
+ label: "Code Search Provider",
1379
+ description: "Provider for code search tool",
1237
1380
  submenu: true,
1238
1381
  },
1239
1382
  },
1240
- presencePenalty: {
1241
- type: "number",
1242
- default: -1,
1383
+
1384
+ "providers.image": {
1385
+ type: "enum",
1386
+ values: ["auto", "gemini", "openrouter"] as const,
1387
+ default: "auto",
1243
1388
  ui: {
1244
- tab: "agent",
1245
- label: "Presence penalty",
1246
- description: "Penalty for introducing already-present tokens (-1 = provider default)",
1389
+ tab: "providers",
1390
+ label: "Image Provider",
1391
+ description: "Provider for image generation tool",
1247
1392
  submenu: true,
1248
1393
  },
1249
1394
  },
1250
- repetitionPenalty: {
1251
- type: "number",
1252
- default: -1,
1395
+
1396
+ "providers.kimiApiFormat": {
1397
+ type: "enum",
1398
+ values: ["openai", "anthropic"] as const,
1399
+ default: "anthropic",
1253
1400
  ui: {
1254
- tab: "agent",
1255
- label: "Repetition penalty",
1256
- description: "Penalty for repeated tokens (-1 = provider default)",
1401
+ tab: "providers",
1402
+ label: "Kimi API Format",
1403
+ description: "API format for Kimi Code provider",
1257
1404
  submenu: true,
1258
1405
  },
1259
1406
  },
1260
- serviceTier: {
1407
+
1408
+ "providers.openaiWebsockets": {
1261
1409
  type: "enum",
1262
- values: ["none", "auto", "default", "flex", "scale", "priority"] as const,
1263
- default: "none",
1410
+ values: ["auto", "off", "on"] as const,
1411
+ default: "auto",
1264
1412
  ui: {
1265
- tab: "agent",
1266
- label: "Service tier",
1267
- description: "OpenAI processing priority (none = omit parameter)",
1413
+ tab: "providers",
1414
+ label: "OpenAI WebSockets",
1415
+ description: "Websocket policy for OpenAI Codex models (auto uses model defaults, on forces, off disables)",
1268
1416
  submenu: true,
1269
1417
  },
1270
1418
  },
1419
+
1420
+ "providers.parallelFetch": {
1421
+ type: "boolean",
1422
+ default: true,
1423
+ ui: {
1424
+ tab: "providers",
1425
+ label: "Parallel Fetch",
1426
+ description: "Use Parallel extract API for URL fetching when credentials are available",
1427
+ },
1428
+ },
1429
+
1430
+ // Exa
1431
+ "exa.enabled": {
1432
+ type: "boolean",
1433
+ default: true,
1434
+ ui: { tab: "providers", label: "Exa", description: "Master toggle for all Exa search tools" },
1435
+ },
1436
+
1437
+ "exa.enableSearch": {
1438
+ type: "boolean",
1439
+ default: true,
1440
+ ui: { tab: "providers", label: "Exa Search", description: "Basic search, deep search, code search, crawl" },
1441
+ },
1442
+
1443
+ "exa.enableResearcher": {
1444
+ type: "boolean",
1445
+ default: false,
1446
+ ui: { tab: "providers", label: "Exa Researcher", description: "AI-powered deep research tasks" },
1447
+ },
1448
+
1449
+ "exa.enableWebsets": {
1450
+ type: "boolean",
1451
+ default: false,
1452
+ ui: { tab: "providers", label: "Exa Websets", description: "Webset management and enrichment tools" },
1453
+ },
1454
+
1455
+ // ────────────────────────────────────────────────────────────────────────
1456
+ // Advanced settings (no UI)
1457
+ // ────────────────────────────────────────────────────────────────────────
1458
+ "commit.mapReduceEnabled": { type: "boolean", default: true },
1459
+
1460
+ "commit.mapReduceMinFiles": { type: "number", default: 4 },
1461
+
1462
+ "commit.mapReduceMaxFileTokens": { type: "number", default: 50000 },
1463
+
1464
+ "commit.mapReduceTimeoutMs": { type: "number", default: 120000 },
1465
+
1466
+ "commit.mapReduceMaxConcurrency": { type: "number", default: 5 },
1467
+
1468
+ "commit.changelogMaxDiffChars": { type: "number", default: 120000 },
1469
+
1470
+ "thinkingBudgets.minimal": { type: "number", default: 1024 },
1471
+
1472
+ "thinkingBudgets.low": { type: "number", default: 2048 },
1473
+
1474
+ "thinkingBudgets.medium": { type: "number", default: 8192 },
1475
+
1476
+ "thinkingBudgets.high": { type: "number", default: 16384 },
1271
1477
  } as const;
1272
1478
 
1273
1479
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1352,6 +1558,7 @@ export interface CompactionSettings {
1352
1558
  enabled: boolean;
1353
1559
  strategy: "context-full" | "handoff" | "off";
1354
1560
  thresholdPercent: number;
1561
+ thresholdTokens: number;
1355
1562
  reserveTokens: number;
1356
1563
  keepRecentTokens: number;
1357
1564
  handoffSaveToDisk: boolean;
@@ -1408,6 +1615,7 @@ export interface SkillsSettings {
1408
1615
  customDirectories?: string[];
1409
1616
  ignoredSkills?: string[];
1410
1617
  includeSkills?: string[];
1618
+ disabledExtensions?: string[];
1411
1619
  }
1412
1620
 
1413
1621
  export interface CommitSettings {