@dreb/coding-agent 2.61.2 → 2.62.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"settings-manager.js","sourceRoot":"","sources":["../../src/core/settings-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { homedir } from \"node:os\";\nimport type { Transport } from \"@dreb/ai\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join, resolve } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"../config.js\";\nimport type { ContextTrustPolicy } from \"./context-trust.js\";\nimport { log } from \"./logger.js\";\nimport { expandPath } from \"./tools/path-utils.js\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface ContextSettings {\n\t/**\n\t * Expert-only global opt-in to lazy-load nested context from every strictly resolvable\n\t * tool target. This is disabled by default because context files can contain prompt\n\t * injection. Project settings cannot affect this policy.\n\t */\n\tautoLoadNested?: boolean;\n\t/** Global-only folder roots allowed to lazy-load context for themselves and descendants. */\n\ttrustedFolders?: string[];\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n\tskipPrompt?: boolean; // default: false - when true, skips \"Summarize branch?\" prompt and defaults to no summary\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tmaxDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport const DEFAULT_BG_PARENT_TURN_LIMIT = 3;\nexport const DEFAULT_MAX_CONCURRENT_SUBAGENTS = 4;\n\nexport interface BackgroundAgentsSettings {\n\t/**\n\t * Whether the parent agent is paused after `parentTurnLimit` turns while background\n\t * agents are still running. Disable (false) to let the parent keep running while\n\t * subagents work — an advanced opt-out with no upper bound on parent turns. default: true\n\t */\n\tparentTurnGuardrail?: boolean;\n\t/** Number of parent turns allowed while background agents run before pausing. default: 3 */\n\tparentTurnLimit?: number;\n\t/** Maximum child agents that one parent session may run concurrently. Zero disables the tool. default: 4 */\n\tmaxConcurrentSubagents?: number;\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\nexport interface AgentModelsSettings {\n\tmodels?: Record<string, string[]>;\n}\n\n/** Global-only configuration for the fail-closed pre-spawn Dispatch Arbiter. */\nexport interface SubagentArbiterSettings {\n\tenabled?: boolean;\n\t/** Exact canonical provider/model used for the tool-less arbiter call. */\n\tmodel?: string;\n\tthinking?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\tguidePath?: string;\n}\n\nexport interface ModelSpecificSettings {\n\t/** Thinking display preference for this model: \"summarized\" shows thinking text, \"omitted\" hides it (lower latency). */\n\tthinkingDisplay?: \"summarized\" | \"omitted\";\n\t/** Custom system prompt for an exact provider/model key. Replaces dreb's built-in prompt. */\n\tsystemPrompt?: string;\n\t/** Text appended to the system prompt for an exact provider/model key. */\n\tappendSystemPrompt?: string;\n}\n\nexport type ModelPromptSettings = Pick<ModelSpecificSettings, \"systemPrompt\" | \"appendSystemPrompt\">;\n\nexport type TransportSetting = Transport;\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tprompts?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ttransport?: TransportSetting; // default: \"sse\"\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tcontext?: ContextSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\tbackgroundAgents?: BackgroundAgentsSettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tnpmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., [\"mise\", \"exec\", \"node@20\", \"--\", \"npm\"])\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tprompts?: string[]; // Array of local prompt template paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\ttreeFilterMode?: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"; // Default filter when opening /tree\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n\tsessionDir?: string; // Custom session storage directory (same format as --session-dir CLI flag)\n\tforbiddenCommands?: string[]; // Regex patterns for commands blocked by the forbidden-commands guard\n\tsensitiveFilePaths?: string[]; // Additional glob patterns for sensitive file paths blocked by the read/bash guard\n\tsecretOutputPatterns?: { name: string; pattern: string }[]; // Additional regex patterns for secret scrubbing in tool output\n\tagentModels?: AgentModelsSettings;\n\t/** Global-only. Project settings must never enable or reconfigure arbitration. */\n\tsubagentArbiter?: SubagentArbiterSettings;\n\t// Per-model overrides. Thinking display supports legacy model-ID keys; prompt settings require exact provider/model keys.\n\tmodelSettings?: Record<string, ModelSpecificSettings>;\n\tdream?: {\n\t\tarchivePath?: string; // Custom archive location for dream backups (default: ~/.dreb/memory-archive/)\n\t};\n\ttabTitle?: TabTitleSettings;\n}\n\nexport interface TabTitleSettings {\n\tenabled?: boolean; // default: true — auto-generate terminal tab title from session task\n\ttriggerAfter?: number; // default: 9 — number of tool calls before generating title\n\tmaxTitleLength?: number; // default: 60 — soft target length hint for generated titles (hard-capped at 300)\n}\n\n/** Deep merge settings: project/overrides take precedence, nested objects merge recursively */\nfunction deepMergeSettings(base: Settings, overrides: Settings): Settings {\n\tconst result: Settings = { ...base };\n\n\tfor (const key of Object.keys(overrides) as (keyof Settings)[]) {\n\t\tconst overrideValue = overrides[key];\n\t\tconst baseValue = base[key];\n\n\t\tif (overrideValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For nested objects, merge recursively\n\t\tif (\n\t\t\ttypeof overrideValue === \"object\" &&\n\t\t\toverrideValue !== null &&\n\t\t\t!Array.isArray(overrideValue) &&\n\t\t\ttypeof baseValue === \"object\" &&\n\t\t\tbaseValue !== null &&\n\t\t\t!Array.isArray(baseValue)\n\t\t) {\n\t\t\t(result as Record<string, unknown>)[key] = { ...baseValue, ...overrideValue };\n\t\t} else {\n\t\t\t// For primitives and arrays, override value wins\n\t\t\t(result as Record<string, unknown>)[key] = overrideValue;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport type SettingsScope = \"global\" | \"project\";\n\nexport interface SettingsStorage {\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;\n}\n\nexport interface SettingsError {\n\tscope: SettingsScope;\n\terror: Error;\n}\n\nexport class FileSettingsStorage implements SettingsStorage {\n\tprivate globalSettingsPath: string;\n\tprivate projectSettingsPath: string;\n\n\tconstructor(cwd: string = process.cwd(), agentDir: string = getAgentDir()) {\n\t\tthis.globalSettingsPath = join(agentDir, \"settings.json\");\n\t\tthis.projectSettingsPath = join(cwd, CONFIG_DIR_NAME, \"settings.json\");\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire settings lock\");\n\t}\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst path = scope === \"global\" ? this.globalSettingsPath : this.projectSettingsPath;\n\t\tconst dir = dirname(path);\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\t// Only create directory and lock if file exists or we need to write\n\t\t\tconst fileExists = existsSync(path);\n\t\t\tif (fileExists) {\n\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t}\n\t\t\tconst current = fileExists ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\tconst next = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\t// Only create directory when we actually need to write\n\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t\t}\n\t\t\t\tif (!release) {\n\t\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t\t}\n\t\t\t\twriteFileSync(path, next, \"utf-8\");\n\t\t\t}\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemorySettingsStorage implements SettingsStorage {\n\tprivate global: string | undefined;\n\tprivate project: string | undefined;\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst current = scope === \"global\" ? this.global : this.project;\n\t\tconst next = fn(current);\n\t\tif (next !== undefined) {\n\t\t\tif (scope === \"global\") {\n\t\t\t\tthis.global = next;\n\t\t\t} else {\n\t\t\t\tthis.project = next;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class SettingsManager {\n\tprivate storage: SettingsStorage;\n\tprivate globalSettings: Settings;\n\tprivate projectSettings: Settings;\n\tprivate settings: Settings;\n\tprivate modifiedFields = new Set<keyof Settings>(); // Track global fields modified during session\n\tprivate modifiedNestedFields = new Map<keyof Settings, Set<string>>(); // Track global nested field modifications\n\tprivate modifiedProjectFields = new Set<keyof Settings>(); // Track project fields modified during session\n\tprivate modifiedProjectNestedFields = new Map<keyof Settings, Set<string>>(); // Track project nested field modifications\n\tprivate globalSettingsLoadError: Error | null = null; // Track if global settings file had parse errors\n\tprivate projectSettingsLoadError: Error | null = null; // Track if project settings file had parse errors\n\tprivate writeQueue: Promise<void> = Promise.resolve();\n\tprivate errors: SettingsError[];\n\n\tprivate constructor(\n\t\tstorage: SettingsStorage,\n\t\tinitialGlobal: Settings,\n\t\tinitialProject: Settings,\n\t\tglobalLoadError: Error | null = null,\n\t\tprojectLoadError: Error | null = null,\n\t\tinitialErrors: SettingsError[] = [],\n\t) {\n\t\tthis.storage = storage;\n\t\tthis.globalSettings = initialGlobal;\n\t\tthis.projectSettings = initialProject;\n\t\tthis.globalSettingsLoadError = globalLoadError;\n\t\tthis.projectSettingsLoadError = projectLoadError;\n\t\tthis.errors = [...initialErrors];\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Create a SettingsManager that loads from files */\n\tstatic create(cwd: string = process.cwd(), agentDir: string = getAgentDir()): SettingsManager {\n\t\tconst storage = new FileSettingsStorage(cwd, agentDir);\n\t\treturn SettingsManager.fromStorage(storage);\n\t}\n\n\t/** Create a SettingsManager from an arbitrary storage backend */\n\tstatic fromStorage(storage: SettingsStorage): SettingsManager {\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(storage, \"global\");\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(storage, \"project\");\n\t\tconst initialErrors: SettingsError[] = [];\n\t\tif (globalLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"global\", error: globalLoad.error });\n\t\t}\n\t\tif (projectLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"project\", error: projectLoad.error });\n\t\t}\n\n\t\treturn new SettingsManager(\n\t\t\tstorage,\n\t\t\tglobalLoad.settings,\n\t\t\tprojectLoad.settings,\n\t\t\tglobalLoad.error,\n\t\t\tprojectLoad.error,\n\t\t\tinitialErrors,\n\t\t);\n\t}\n\n\t/** Create an in-memory SettingsManager (no file I/O) */\n\tstatic inMemory(settings: Partial<Settings> = {}): SettingsManager {\n\t\tconst storage = new InMemorySettingsStorage();\n\t\treturn new SettingsManager(storage, settings, {});\n\t}\n\n\tprivate static loadFromStorage(storage: SettingsStorage, scope: SettingsScope): Settings {\n\t\tlet content: string | undefined;\n\t\tstorage.withLock(scope, (current) => {\n\t\t\tcontent = current;\n\t\t\treturn undefined;\n\t\t});\n\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\tconst settings = JSON.parse(content);\n\t\treturn SettingsManager.migrateSettings(settings);\n\t}\n\n\tprivate static tryLoadFromStorage(\n\t\tstorage: SettingsStorage,\n\t\tscope: SettingsScope,\n\t): { settings: Settings; error: Error | null } {\n\t\ttry {\n\t\t\treturn { settings: SettingsManager.loadFromStorage(storage, scope), error: null };\n\t\t} catch (error) {\n\t\t\treturn { settings: {}, error: error as Error };\n\t\t}\n\t}\n\n\t/**\n\t * Normalize the two known lazy-context trust fields of a `context` slice to fail-closed\n\t * defaults when malformed, preserving valid values and any unrelated keys. Used at persist\n\t * time so a single-field trust write cannot leave a malformed sibling (read fresh from disk)\n\t * that would invalidate — and therefore silently disable — the entire trust policy.\n\t */\n\tprivate static sanitizeContextTrustSlice(nested: Record<string, unknown>): Record<string, unknown> {\n\t\tconst sanitized = { ...nested };\n\t\tif (\"autoLoadNested\" in sanitized && typeof sanitized.autoLoadNested !== \"boolean\") {\n\t\t\tsanitized.autoLoadNested = false;\n\t\t}\n\t\tif (\n\t\t\t\"trustedFolders\" in sanitized &&\n\t\t\t(!Array.isArray(sanitized.trustedFolders) ||\n\t\t\t\tsanitized.trustedFolders.some((folder) => typeof folder !== \"string\"))\n\t\t) {\n\t\t\tsanitized.trustedFolders = [];\n\t\t}\n\t\treturn sanitized;\n\t}\n\n\t/** Migrate old settings format to new format */\n\tprivate static migrateSettings(settings: Record<string, unknown>): Settings {\n\t\t// Migrate queueMode -> steeringMode\n\t\tif (\"queueMode\" in settings && !(\"steeringMode\" in settings)) {\n\t\t\tsettings.steeringMode = settings.queueMode;\n\t\t\tdelete settings.queueMode;\n\t\t}\n\n\t\t// Migrate legacy websockets boolean -> transport enum\n\t\tif (!(\"transport\" in settings) && typeof settings.websockets === \"boolean\") {\n\t\t\tsettings.transport = settings.websockets ? \"websocket\" : \"sse\";\n\t\t\tdelete settings.websockets;\n\t\t}\n\n\t\t// Migrate old skills object format to new array format\n\t\tif (\n\t\t\t\"skills\" in settings &&\n\t\t\ttypeof settings.skills === \"object\" &&\n\t\t\tsettings.skills !== null &&\n\t\t\t!Array.isArray(settings.skills)\n\t\t) {\n\t\t\tconst skillsSettings = settings.skills as {\n\t\t\t\tenableSkillCommands?: boolean;\n\t\t\t\tcustomDirectories?: unknown;\n\t\t\t};\n\t\t\tif (skillsSettings.enableSkillCommands !== undefined && settings.enableSkillCommands === undefined) {\n\t\t\t\tsettings.enableSkillCommands = skillsSettings.enableSkillCommands;\n\t\t\t}\n\t\t\tif (Array.isArray(skillsSettings.customDirectories) && skillsSettings.customDirectories.length > 0) {\n\t\t\t\tsettings.skills = skillsSettings.customDirectories;\n\t\t\t} else {\n\t\t\t\tdelete settings.skills;\n\t\t\t}\n\t\t}\n\n\t\treturn settings as Settings;\n\t}\n\n\tgetGlobalSettings(): Settings {\n\t\treturn structuredClone(this.globalSettings);\n\t}\n\n\tgetProjectSettings(): Settings {\n\t\treturn structuredClone(this.projectSettings);\n\t}\n\n\treload(): void {\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (!globalLoad.error) {\n\t\t\tthis.globalSettings = globalLoad.settings;\n\t\t\tthis.globalSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.globalSettingsLoadError = globalLoad.error;\n\t\t\tthis.recordError(\"global\", globalLoad.error);\n\t\t}\n\n\t\tthis.modifiedFields.clear();\n\t\tthis.modifiedNestedFields.clear();\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(this.storage, \"project\");\n\t\tif (!projectLoad.error) {\n\t\t\tthis.projectSettings = projectLoad.settings;\n\t\t\tthis.projectSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.projectSettingsLoadError = projectLoad.error;\n\t\t\tthis.recordError(\"project\", projectLoad.error);\n\t\t}\n\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Apply additional overrides on top of current settings */\n\tapplyOverrides(overrides: Partial<Settings>): void {\n\t\tthis.settings = deepMergeSettings(this.settings, overrides);\n\t}\n\n\t/** Mark a global field as modified during this session */\n\tprivate markModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedNestedFields.has(field)) {\n\t\t\t\tthis.modifiedNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\t/** Mark a project field as modified during this session */\n\tprivate markProjectModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedProjectFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedProjectNestedFields.has(field)) {\n\t\t\t\tthis.modifiedProjectNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedProjectNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\tprivate recordError(scope: SettingsScope, error: unknown): void {\n\t\tconst normalizedError = error instanceof Error ? error : new Error(String(error));\n\t\tthis.errors.push({ scope, error: normalizedError });\n\t}\n\n\tprivate refreshGlobalContextFromStorage(options: { clearContextOnError?: boolean } = {}): boolean {\n\t\t// Keep a just-selected UI value effective until its queued durable write completes;\n\t\t// otherwise always re-read the external global source for cross-process changes.\n\t\tif (this.storage instanceof InMemorySettingsStorage || this.modifiedFields.has(\"context\")) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst loaded = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (loaded.error) {\n\t\t\tthis.recordError(\"global\", loaded.error);\n\t\t\tif (options.clearContextOnError) {\n\t\t\t\tthis.globalSettings = { ...this.globalSettings, context: undefined };\n\t\t\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// This re-read owns only the security-policy slice. Preserve every other\n\t\t// in-memory global field, including writes that are queued but not yet durable.\n\t\tthis.globalSettings = { ...this.globalSettings, context: loaded.settings.context };\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\treturn true;\n\t}\n\n\tprivate refreshGlobalSubagentArbiterFromStorage(): void {\n\t\t// Keep a locally selected policy effective until its queued write completes;\n\t\t// otherwise re-read the global slice so long-lived sessions observe dashboard\n\t\t// and TUI changes made by another runtime.\n\t\tif (this.storage instanceof InMemorySettingsStorage || this.modifiedFields.has(\"subagentArbiter\")) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst loaded = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (loaded.error) {\n\t\t\tthis.recordError(\"global\", loaded.error);\n\t\t\tthis.globalSettings = { ...this.globalSettings, subagentArbiter: undefined };\n\t\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\t\tthrow new Error(`Could not reload global Dispatch Arbiter settings: ${loaded.error.message}`);\n\t\t}\n\n\t\t// This refresh owns only the global-only arbiter slice. Preserve unrelated\n\t\t// in-memory settings, including writes that are queued but not yet durable.\n\t\tthis.globalSettings = { ...this.globalSettings, subagentArbiter: loaded.settings.subagentArbiter };\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\tprivate clearModifiedScope(scope: SettingsScope): void {\n\t\tif (scope === \"global\") {\n\t\t\tthis.modifiedFields.clear();\n\t\t\tthis.modifiedNestedFields.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\t}\n\n\tprivate enqueueWrite(scope: SettingsScope, task: () => void): void {\n\t\tthis.writeQueue = this.writeQueue\n\t\t\t.then(() => {\n\t\t\t\ttask();\n\t\t\t\tthis.clearModifiedScope(scope);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.recordError(scope, error);\n\t\t\t});\n\t}\n\n\tprivate cloneModifiedNestedFields(source: Map<keyof Settings, Set<string>>): Map<keyof Settings, Set<string>> {\n\t\tconst snapshot = new Map<keyof Settings, Set<string>>();\n\t\tfor (const [key, value] of source.entries()) {\n\t\t\tsnapshot.set(key, new Set(value));\n\t\t}\n\t\treturn snapshot;\n\t}\n\n\tprivate persistScopedSettings(\n\t\tscope: SettingsScope,\n\t\tsnapshotSettings: Settings,\n\t\tmodifiedFields: Set<keyof Settings>,\n\t\tmodifiedNestedFields: Map<keyof Settings, Set<string>>,\n\t): void {\n\t\tthis.storage.withLock(scope, (current) => {\n\t\t\tconst currentFileSettings = current\n\t\t\t\t? SettingsManager.migrateSettings(JSON.parse(current) as Record<string, unknown>)\n\t\t\t\t: {};\n\t\t\tconst mergedSettings: Settings = { ...currentFileSettings };\n\t\t\tfor (const field of modifiedFields) {\n\t\t\t\tconst value = snapshotSettings[field];\n\t\t\t\tif (modifiedNestedFields.has(field) && typeof value === \"object\" && value !== null) {\n\t\t\t\t\tconst nestedModified = modifiedNestedFields.get(field)!;\n\t\t\t\t\tconst baseNested = (currentFileSettings[field] as Record<string, unknown>) ?? {};\n\t\t\t\t\tconst inMemoryNested = value as Record<string, unknown>;\n\t\t\t\t\tlet mergedNested = { ...baseNested };\n\t\t\t\t\tfor (const nestedKey of nestedModified) {\n\t\t\t\t\t\tmergedNested[nestedKey] = inMemoryNested[nestedKey];\n\t\t\t\t\t}\n\t\t\t\t\t// The global context-trust slice is security-sensitive: an untouched sibling\n\t\t\t\t\t// is preserved from the fresh on-disk read above, but a malformed on-disk\n\t\t\t\t\t// sibling must still collapse to a fail-closed default so a successful trust\n\t\t\t\t\t// mutation cannot leave the whole policy invalid (and thus silently disabled).\n\t\t\t\t\tif (scope === \"global\" && field === \"context\") {\n\t\t\t\t\t\tmergedNested = SettingsManager.sanitizeContextTrustSlice(mergedNested);\n\t\t\t\t\t}\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = mergedNested;\n\t\t\t\t} else {\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn JSON.stringify(mergedSettings, null, 2);\n\t\t});\n\t}\n\n\tprivate save(): void {\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.globalSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotGlobalSettings = structuredClone(this.globalSettings);\n\t\tconst modifiedFields = new Set(this.modifiedFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedNestedFields);\n\n\t\tthis.enqueueWrite(\"global\", () => {\n\t\t\tthis.persistScopedSettings(\"global\", snapshotGlobalSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tprivate saveProjectSettings(settings: Settings): void {\n\t\tthis.projectSettings = structuredClone(settings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.projectSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotProjectSettings = structuredClone(this.projectSettings);\n\t\tconst modifiedFields = new Set(this.modifiedProjectFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedProjectNestedFields);\n\t\tthis.enqueueWrite(\"project\", () => {\n\t\t\tthis.persistScopedSettings(\"project\", snapshotProjectSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.writeQueue;\n\t}\n\n\t/**\n\t * True when the global settings file failed to load/parse. In that state {@link save}\n\t * silently no-ops (to avoid stomping the corrupt file), so callers that need write\n\t * durability must check this and fail loudly instead of reporting success.\n\t */\n\thasGlobalSettingsLoadError(): boolean {\n\t\treturn this.globalSettingsLoadError !== null;\n\t}\n\n\t/** True when the project settings file failed to load or parse. */\n\thasProjectSettingsLoadError(): boolean {\n\t\treturn this.projectSettingsLoadError !== null;\n\t}\n\n\tdrainErrors(): SettingsError[] {\n\t\tconst drained = [...this.errors];\n\t\tthis.errors = [];\n\t\treturn drained;\n\t}\n\n\tgetSessionDir(): string | undefined {\n\t\treturn this.settings.sessionDir;\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tsetDefaultProvider(provider: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModel(modelId: string): void {\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.steeringMode || \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.steeringMode = mode;\n\t\tthis.markModified(\"steeringMode\");\n\t\tthis.save();\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.followUpMode || \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.followUpMode = mode;\n\t\tthis.markModified(\"followUpMode\");\n\t\tthis.save();\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn this.settings.theme;\n\t}\n\n\tsetTheme(theme: string): void {\n\t\tthis.globalSettings.theme = theme;\n\t\tthis.markModified(\"theme\");\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\" | undefined {\n\t\treturn this.settings.defaultThinkingLevel;\n\t}\n\n\tsetDefaultThinkingLevel(level: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\"): void {\n\t\tthis.globalSettings.defaultThinkingLevel = level;\n\t\tthis.markModified(\"defaultThinkingLevel\");\n\t\tthis.save();\n\t}\n\n\tgetTransport(): TransportSetting {\n\t\treturn this.settings.transport ?? \"sse\";\n\t}\n\n\tsetTransport(transport: TransportSetting): void {\n\t\tthis.globalSettings.transport = transport;\n\t\tthis.markModified(\"transport\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? true;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.compaction) {\n\t\t\tthis.globalSettings.compaction = {};\n\t\t}\n\t\tthis.globalSettings.compaction.enabled = enabled;\n\t\tthis.markModified(\"compaction\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\t/**\n\t * Read the global-only lazy-context policy. File-backed managers re-read this small\n\t * policy on each decision so independently running main/subagent processes observe\n\t * external global settings writes without ever consulting project settings. A malformed\n\t * global file fails closed rather than retaining a previously permissive value.\n\t */\n\tgetGlobalContextTrustPolicy(): ContextTrustPolicy {\n\t\tif (!this.refreshGlobalContextFromStorage()) {\n\t\t\treturn { unrestricted: false, trustedFolders: [] };\n\t\t}\n\n\t\tconst context = this.globalSettings.context;\n\t\t// A valid JSON file with a malformed security policy is also fail-closed. Do not\n\t\t// coerce strings/truthy values or partially accept an invalid trusted-folder list.\n\t\tif (\n\t\t\tcontext !== undefined &&\n\t\t\t(typeof context !== \"object\" ||\n\t\t\t\tcontext === null ||\n\t\t\t\t(context.autoLoadNested !== undefined && typeof context.autoLoadNested !== \"boolean\") ||\n\t\t\t\t(context.trustedFolders !== undefined &&\n\t\t\t\t\t(!Array.isArray(context.trustedFolders) ||\n\t\t\t\t\t\tcontext.trustedFolders.some((folder) => typeof folder !== \"string\"))))\n\t\t) {\n\t\t\tconst error = new Error(\n\t\t\t\t\"Global context trust settings are malformed; lazy nested context loading is disabled\",\n\t\t\t);\n\t\t\tthis.recordError(\"global\", error);\n\t\t\treturn { unrestricted: false, trustedFolders: [] };\n\t\t}\n\n\t\treturn {\n\t\t\tunrestricted: context?.autoLoadNested ?? false,\n\t\t\ttrustedFolders: context?.trustedFolders ? [...context.trustedFolders] : [],\n\t\t};\n\t}\n\n\t/** Effective unrestricted flag; intentionally reads global settings only. */\n\tgetAutoLoadNestedContext(): boolean {\n\t\treturn this.getGlobalContextTrustPolicy().unrestricted;\n\t}\n\n\tgetTrustedContextFolders(): string[] {\n\t\treturn this.getGlobalContextTrustPolicy().trustedFolders;\n\t}\n\n\tgetConfiguredTrustedContextFolders(): string[] {\n\t\tif (!this.refreshGlobalContextFromStorage()) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst context = this.globalSettings.context;\n\t\tif (context === undefined || typeof context !== \"object\" || context === null || Array.isArray(context)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst trustedFolders = (context as Record<string, unknown>).trustedFolders;\n\t\tif (trustedFolders === undefined) {\n\t\t\treturn [];\n\t\t}\n\t\tif (!Array.isArray(trustedFolders) || trustedFolders.some((folder) => typeof folder !== \"string\")) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn [...trustedFolders];\n\t}\n\n\tsetAutoLoadNestedContext(enabled: boolean): void {\n\t\tthis.setContextTrust({ autoLoadNested: enabled });\n\t}\n\n\t/**\n\t * Atomically persist one or both global lazy-context trust policy fields. Every trust\n\t * write normalizes both known fields, so a malformed on-disk sibling cannot make an\n\t * otherwise successful mutation silently fail closed.\n\t */\n\tsetContextTrust(update: { autoLoadNested?: boolean; trustedFolders?: string[] }): void {\n\t\tif (update.autoLoadNested !== undefined && typeof update.autoLoadNested !== \"boolean\") {\n\t\t\tthrow new Error(\"Auto-load nested context must be a boolean\");\n\t\t}\n\t\tif (\n\t\t\tupdate.trustedFolders !== undefined &&\n\t\t\t(!Array.isArray(update.trustedFolders) || update.trustedFolders.some((folder) => typeof folder !== \"string\"))\n\t\t) {\n\t\t\tthrow new Error(\"Trusted context folders must be an array of strings\");\n\t\t}\n\n\t\t// Refresh the in-memory context slice from the external global file unless a context\n\t\t// write is already pending, so an unspecified sibling reflects concurrent cross-process\n\t\t// changes (e.g. a folder just untrusted elsewhere) instead of a stale in-memory value.\n\t\t// A pending context write already owns the authoritative in-memory value; do not stomp\n\t\t// it. Fail closed if the external file is unreadable.\n\t\tthis.refreshGlobalContextFromStorage({ clearContextOnError: true });\n\n\t\tconst currentContext = this.globalSettings.context;\n\t\tconst current =\n\t\t\ttypeof currentContext === \"object\" && currentContext !== null && !Array.isArray(currentContext)\n\t\t\t\t? (currentContext as Record<string, unknown>)\n\t\t\t\t: {};\n\t\tconst autoLoadNested =\n\t\t\tupdate.autoLoadNested ?? (typeof current.autoLoadNested === \"boolean\" ? current.autoLoadNested : false);\n\t\tconst currentTrustedFolders =\n\t\t\tArray.isArray(current.trustedFolders) && current.trustedFolders.every((folder) => typeof folder === \"string\")\n\t\t\t\t? (current.trustedFolders as string[])\n\t\t\t\t: [];\n\t\tconst trustedFolders = update.trustedFolders ?? currentTrustedFolders;\n\n\t\tthis.globalSettings.context = {\n\t\t\t...current,\n\t\t\tautoLoadNested,\n\t\t\ttrustedFolders: [...trustedFolders],\n\t\t};\n\t\t// Mark only the explicitly-supplied fields modified. persistScopedSettings then\n\t\t// preserves an untouched sibling from the fresh on-disk slice read inside the storage\n\t\t// lock, so a single-field write can no longer clobber a concurrent external change to\n\t\t// the other field. Malformed on-disk siblings are still normalized fail-closed there.\n\t\tif (update.autoLoadNested !== undefined) {\n\t\t\tthis.markModified(\"context\", \"autoLoadNested\");\n\t\t}\n\t\tif (update.trustedFolders !== undefined) {\n\t\t\tthis.markModified(\"context\", \"trustedFolders\");\n\t\t}\n\t\tthis.save();\n\t}\n\n\tsetTrustedContextFolders(folders: string[]): void {\n\t\tthis.setContextTrust({ trustedFolders: folders });\n\t}\n\n\taddTrustedContextFolder(folder: string): void {\n\t\tif (typeof folder !== \"string\" || folder === \"\") {\n\t\t\tthrow new Error(\"Trusted context folder must be a non-empty string\");\n\t\t}\n\t\tconst folders = this.getConfiguredTrustedContextFolders();\n\t\tif (!folders.includes(folder)) folders.push(folder);\n\t\tthis.setTrustedContextFolders(folders);\n\t}\n\n\tremoveTrustedContextFolder(folder: string): void {\n\t\tthis.setTrustedContextFolders(this.getConfiguredTrustedContextFolders().filter((current) => current !== folder));\n\t}\n\n\tgetCompactionReserveTokens(): number {\n\t\treturn this.settings.compaction?.reserveTokens ?? 16384;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn this.settings.compaction?.keepRecentTokens ?? 20000;\n\t}\n\n\tgetCompactionSettings(): { enabled: boolean; reserveTokens: number; keepRecentTokens: number } {\n\t\treturn {\n\t\t\tenabled: this.getCompactionEnabled(),\n\t\t\treserveTokens: this.getCompactionReserveTokens(),\n\t\t\tkeepRecentTokens: this.getCompactionKeepRecentTokens(),\n\t\t};\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number; skipPrompt: boolean } {\n\t\treturn {\n\t\t\treserveTokens: this.settings.branchSummary?.reserveTokens ?? 16384,\n\t\t\tskipPrompt: this.settings.branchSummary?.skipPrompt ?? false,\n\t\t};\n\t}\n\n\tgetBranchSummarySkipPrompt(): boolean {\n\t\treturn this.settings.branchSummary?.skipPrompt ?? false;\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? true;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.retry) {\n\t\t\tthis.globalSettings.retry = {};\n\t\t}\n\t\tthis.globalSettings.retry.enabled = enabled;\n\t\tthis.markModified(\"retry\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): { enabled: boolean; maxRetries: number; baseDelayMs: number; maxDelayMs: number } {\n\t\treturn {\n\t\t\tenabled: this.getRetryEnabled(),\n\t\t\tmaxRetries: this.settings.retry?.maxRetries ?? 3,\n\t\t\tbaseDelayMs: this.settings.retry?.baseDelayMs ?? 2000,\n\t\t\tmaxDelayMs: this.settings.retry?.maxDelayMs ?? 60000,\n\t\t};\n\t}\n\n\tgetBackgroundAgentGuardrailEnabled(): boolean {\n\t\treturn this.settings.backgroundAgents?.parentTurnGuardrail ?? true;\n\t}\n\n\tsetBackgroundAgentGuardrailEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.backgroundAgents) {\n\t\t\tthis.globalSettings.backgroundAgents = {};\n\t\t}\n\t\tthis.globalSettings.backgroundAgents.parentTurnGuardrail = enabled;\n\t\tthis.markModified(\"backgroundAgents\", \"parentTurnGuardrail\");\n\t\tthis.save();\n\t}\n\n\tgetBackgroundAgentGuardrailSettings(): { enabled: boolean; turnLimit: number } {\n\t\tconst rawLimit = this.settings.backgroundAgents?.parentTurnLimit;\n\t\tconst turnLimit =\n\t\t\ttypeof rawLimit === \"number\" && Number.isFinite(rawLimit) && rawLimit >= 1\n\t\t\t\t? rawLimit\n\t\t\t\t: DEFAULT_BG_PARENT_TURN_LIMIT;\n\t\treturn {\n\t\t\tenabled: this.getBackgroundAgentGuardrailEnabled(),\n\t\t\tturnLimit,\n\t\t};\n\t}\n\n\tgetMaxConcurrentSubagents(): number {\n\t\tconst value = this.settings.backgroundAgents?.maxConcurrentSubagents;\n\t\tif (value === undefined) {\n\t\t\treturn DEFAULT_MAX_CONCURRENT_SUBAGENTS;\n\t\t}\n\t\tif (typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0) {\n\t\t\treturn value;\n\t\t}\n\t\tlog.warn(\n\t\t\t`[settings] Ignoring invalid backgroundAgents.maxConcurrentSubagents ${JSON.stringify(value)}; ` +\n\t\t\t\t`it must be a non-negative whole number. Falling back to ${DEFAULT_MAX_CONCURRENT_SUBAGENTS}. ` +\n\t\t\t\t\"Fix the value in your settings file to silence this warning.\",\n\t\t);\n\t\treturn DEFAULT_MAX_CONCURRENT_SUBAGENTS;\n\t}\n\n\tsetMaxConcurrentSubagents(value: number): void {\n\t\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\t\tthrow new Error(\"maxConcurrentSubagents must be a non-negative whole number\");\n\t\t}\n\t\tif (!this.globalSettings.backgroundAgents) {\n\t\t\tthis.globalSettings.backgroundAgents = {};\n\t\t}\n\t\tthis.globalSettings.backgroundAgents.maxConcurrentSubagents = value;\n\t\tthis.markModified(\"backgroundAgents\", \"maxConcurrentSubagents\");\n\t\tthis.save();\n\t}\n\n\tgetHideThinkingBlock(): boolean {\n\t\treturn this.settings.hideThinkingBlock ?? false;\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.globalSettings.hideThinkingBlock = hide;\n\t\tthis.markModified(\"hideThinkingBlock\");\n\t\tthis.save();\n\t}\n\n\tgetShellPath(): string | undefined {\n\t\treturn this.settings.shellPath;\n\t}\n\n\tsetShellPath(path: string | undefined): void {\n\t\tthis.globalSettings.shellPath = path;\n\t\tthis.markModified(\"shellPath\");\n\t\tthis.save();\n\t}\n\n\tgetQuietStartup(): boolean {\n\t\treturn this.settings.quietStartup ?? false;\n\t}\n\n\tsetQuietStartup(quiet: boolean): void {\n\t\tthis.globalSettings.quietStartup = quiet;\n\t\tthis.markModified(\"quietStartup\");\n\t\tthis.save();\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn this.settings.shellCommandPrefix;\n\t}\n\n\tsetShellCommandPrefix(prefix: string | undefined): void {\n\t\tthis.globalSettings.shellCommandPrefix = prefix;\n\t\tthis.markModified(\"shellCommandPrefix\");\n\t\tthis.save();\n\t}\n\n\tgetNpmCommand(): string[] | undefined {\n\t\treturn this.settings.npmCommand ? [...this.settings.npmCommand] : undefined;\n\t}\n\n\tsetNpmCommand(command: string[] | undefined): void {\n\t\tthis.globalSettings.npmCommand = command ? [...command] : undefined;\n\t\tthis.markModified(\"npmCommand\");\n\t\tthis.save();\n\t}\n\n\tgetPackages(): PackageSource[] {\n\t\treturn [...(this.settings.packages ?? [])];\n\t}\n\n\tsetPackages(packages: PackageSource[]): void {\n\t\tthis.globalSettings.packages = packages;\n\t\tthis.markModified(\"packages\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPackages(packages: PackageSource[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.packages = packages;\n\t\tthis.markProjectModified(\"packages\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [...(this.settings.extensions ?? [])];\n\t}\n\n\tsetExtensionPaths(paths: string[]): void {\n\t\tthis.globalSettings.extensions = paths;\n\t\tthis.markModified(\"extensions\");\n\t\tthis.save();\n\t}\n\n\tsetProjectExtensionPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.extensions = paths;\n\t\tthis.markProjectModified(\"extensions\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [...(this.settings.skills ?? [])];\n\t}\n\n\tsetSkillPaths(paths: string[]): void {\n\t\tthis.globalSettings.skills = paths;\n\t\tthis.markModified(\"skills\");\n\t\tthis.save();\n\t}\n\n\tsetProjectSkillPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.skills = paths;\n\t\tthis.markProjectModified(\"skills\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [...(this.settings.prompts ?? [])];\n\t}\n\n\tsetPromptTemplatePaths(paths: string[]): void {\n\t\tthis.globalSettings.prompts = paths;\n\t\tthis.markModified(\"prompts\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPromptTemplatePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.prompts = paths;\n\t\tthis.markProjectModified(\"prompts\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [...(this.settings.themes ?? [])];\n\t}\n\n\tsetThemePaths(paths: string[]): void {\n\t\tthis.globalSettings.themes = paths;\n\t\tthis.markModified(\"themes\");\n\t\tthis.save();\n\t}\n\n\tsetProjectThemePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.themes = paths;\n\t\tthis.markProjectModified(\"themes\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn this.settings.enableSkillCommands ?? true;\n\t}\n\n\tsetEnableSkillCommands(enabled: boolean): void {\n\t\tthis.globalSettings.enableSkillCommands = enabled;\n\t\tthis.markModified(\"enableSkillCommands\");\n\t\tthis.save();\n\t}\n\n\tgetThinkingBudgets(): ThinkingBudgetsSettings | undefined {\n\t\treturn this.settings.thinkingBudgets;\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn this.settings.terminal?.showImages ?? true;\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.showImages = show;\n\t\tthis.markModified(\"terminal\", \"showImages\");\n\t\tthis.save();\n\t}\n\n\tgetImageAutoResize(): boolean {\n\t\treturn this.settings.images?.autoResize ?? true;\n\t}\n\n\tsetImageAutoResize(enabled: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.autoResize = enabled;\n\t\tthis.markModified(\"images\", \"autoResize\");\n\t\tthis.save();\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn this.settings.images?.blockImages ?? false;\n\t}\n\n\tsetBlockImages(blocked: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.blockImages = blocked;\n\t\tthis.markModified(\"images\", \"blockImages\");\n\t\tthis.save();\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn this.settings.enabledModels;\n\t}\n\n\tsetEnabledModels(patterns: string[] | undefined): void {\n\t\tthis.globalSettings.enabledModels = patterns;\n\t\tthis.markModified(\"enabledModels\");\n\t\tthis.save();\n\t}\n\n\t/** Whether project settings explicitly replace the global enabled-model scope. */\n\thasProjectEnabledModelsOverride(): boolean {\n\t\treturn this.projectSettings.enabledModels !== undefined;\n\t}\n\n\tgetDoubleEscapeAction(): \"fork\" | \"tree\" | \"none\" {\n\t\treturn this.settings.doubleEscapeAction ?? \"tree\";\n\t}\n\n\tsetDoubleEscapeAction(action: \"fork\" | \"tree\" | \"none\"): void {\n\t\tthis.globalSettings.doubleEscapeAction = action;\n\t\tthis.markModified(\"doubleEscapeAction\");\n\t\tthis.save();\n\t}\n\n\tgetTreeFilterMode(): \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\" {\n\t\tconst mode = this.settings.treeFilterMode;\n\t\tconst valid = [\"default\", \"no-tools\", \"user-only\", \"labeled-only\", \"all\"];\n\t\treturn mode && valid.includes(mode) ? mode : \"default\";\n\t}\n\n\tsetTreeFilterMode(mode: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"): void {\n\t\tthis.globalSettings.treeFilterMode = mode;\n\t\tthis.markModified(\"treeFilterMode\");\n\t\tthis.save();\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.settings.showHardwareCursor ?? process.env.DREB_HARDWARE_CURSOR === \"1\";\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tthis.globalSettings.showHardwareCursor = enabled;\n\t\tthis.markModified(\"showHardwareCursor\");\n\t\tthis.save();\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn this.settings.editorPaddingX ?? 0;\n\t}\n\n\tsetEditorPaddingX(padding: number): void {\n\t\tthis.globalSettings.editorPaddingX = Math.max(0, Math.min(3, Math.floor(padding)));\n\t\tthis.markModified(\"editorPaddingX\");\n\t\tthis.save();\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn this.settings.autocompleteMaxVisible ?? 5;\n\t}\n\n\tsetAutocompleteMaxVisible(maxVisible: number): void {\n\t\tthis.globalSettings.autocompleteMaxVisible = Math.max(3, Math.min(20, Math.floor(maxVisible)));\n\t\tthis.markModified(\"autocompleteMaxVisible\");\n\t\tthis.save();\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn this.settings.markdown?.codeBlockIndent ?? \" \";\n\t}\n\n\tgetForbiddenCommands(): string[] | undefined {\n\t\treturn this.settings.forbiddenCommands;\n\t}\n\n\tgetSensitiveFilePaths(): string[] | undefined {\n\t\treturn this.settings.sensitiveFilePaths;\n\t}\n\n\tgetSecretOutputPatterns(): { name: string; pattern: string }[] | undefined {\n\t\treturn this.settings.secretOutputPatterns;\n\t}\n\n\t/**\n\t * Read only the global arbiter policy; project settings are intentionally ignored.\n\t * File-backed managers refresh this slice for every dispatch so independently\n\t * running sessions observe dashboard and TUI writes without a restart.\n\t */\n\tgetGlobalSubagentArbiterSettings(): SubagentArbiterSettings | undefined {\n\t\tthis.refreshGlobalSubagentArbiterFromStorage();\n\t\treturn this.globalSettings.subagentArbiter ? structuredClone(this.globalSettings.subagentArbiter) : undefined;\n\t}\n\n\tsetGlobalSubagentArbiterSettings(settings: SubagentArbiterSettings | undefined): void {\n\t\tthis.globalSettings.subagentArbiter = settings ? structuredClone(settings) : undefined;\n\t\tthis.markModified(\"subagentArbiter\");\n\t\tthis.save();\n\t}\n\n\tgetDreamArchivePath(): string {\n\t\tconst configured = this.settings.dream?.archivePath;\n\t\tif (configured) {\n\t\t\treturn resolve(expandPath(configured));\n\t\t}\n\t\treturn join(homedir(), \".dreb\", \"memory-archive\");\n\t}\n\n\tsetDreamArchivePath(path: string): void {\n\t\tif (!this.globalSettings.dream) this.globalSettings.dream = {};\n\t\tthis.globalSettings.dream.archivePath = path;\n\t\tthis.markModified(\"dream\", \"archivePath\");\n\t\tthis.save();\n\t}\n\n\tgetAgentModels(): Record<string, string[]> {\n\t\t// Merge global + project at the per-agent-name level, with project winning per-key.\n\t\t// Reading directly from globalSettings/projectSettings avoids the wholesale\n\t\t// replacement that deepMergeSettings would do for the shared `models` sub-key.\n\t\tconst merged: Record<string, string[]> = {\n\t\t\t...this.globalSettings.agentModels?.models,\n\t\t\t...this.projectSettings.agentModels?.models,\n\t\t};\n\t\t// Deep-copy inner arrays so callers can't mutate stored state.\n\t\treturn Object.fromEntries(Object.entries(merged).map(([k, v]) => [k, [...v]]));\n\t}\n\n\tgetAgentModelsForAgent(agentName: string): string[] | undefined {\n\t\tconst models = this.getAgentModels()[agentName];\n\t\treturn models && models.length > 0 ? models : undefined;\n\t}\n\n\t/**\n\t * Whether a project-level (`.dreb/settings.json`) agentModels entry exists for this agent.\n\t * Project entries win over global ones in {@link getAgentModels}, so a global write/remove\n\t * via the TUI has no effect when this returns true — callers should surface this loudly.\n\t */\n\thasProjectAgentModelOverride(agentName: string): boolean {\n\t\treturn this.projectSettings.agentModels?.models?.[agentName] !== undefined;\n\t}\n\n\tsetAgentModelsForAgent(agentName: string, models: string[]): void {\n\t\tif (!this.globalSettings.agentModels) {\n\t\t\tthis.globalSettings.agentModels = {};\n\t\t}\n\t\tif (!this.globalSettings.agentModels.models) {\n\t\t\tthis.globalSettings.agentModels.models = {};\n\t\t}\n\t\tthis.globalSettings.agentModels.models[agentName] = [...models];\n\t\tthis.markModified(\"agentModels\", \"models\");\n\t\tthis.save();\n\t}\n\n\tremoveAgentModelsForAgent(agentName: string): void {\n\t\tif (this.globalSettings.agentModels?.models?.[agentName] !== undefined) {\n\t\t\tdelete this.globalSettings.agentModels.models[agentName];\n\t\t\tthis.markModified(\"agentModels\", \"models\");\n\t\t\tthis.save();\n\t\t}\n\t}\n\n\t/**\n\t * Per-model settings merged global + project at the entry-key level, with project\n\t * winning per property. Entry keys are bare model IDs for legacy settings or canonical\n\t * provider/model references for provider-aware settings. Reading directly from the two\n\t * scopes avoids wholesale replacement of the shared `modelSettings` object.\n\t */\n\tgetModelSettings(modelKey: string): ModelSpecificSettings | undefined {\n\t\tconst global = this.globalSettings.modelSettings?.[modelKey];\n\t\tconst project = this.projectSettings.modelSettings?.[modelKey];\n\t\tif (!global && !project) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { ...global, ...project };\n\t}\n\n\t/**\n\t * Resolve prompt settings for one exact provider/model pair. Prompt settings deliberately\n\t * do not fall back to the legacy bare-model-id keys used by thinkingDisplay because that\n\t * would leak instructions across providers exposing the same model ID.\n\t */\n\tgetModelPromptSettings(provider: string, modelId: string): ModelPromptSettings | undefined {\n\t\tconst modelRef = `${provider}/${modelId}`;\n\t\tconst settings = this.getModelSettings(modelRef);\n\t\tif (!settings) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { systemPrompt, appendSystemPrompt } = settings;\n\t\tif (systemPrompt !== undefined && (typeof systemPrompt !== \"string\" || systemPrompt.trim().length === 0)) {\n\t\t\tthrow new Error(`modelSettings.${modelRef}.systemPrompt must be a non-empty string`);\n\t\t}\n\t\tif (\n\t\t\tappendSystemPrompt !== undefined &&\n\t\t\t(typeof appendSystemPrompt !== \"string\" || appendSystemPrompt.trim().length === 0)\n\t\t) {\n\t\t\tthrow new Error(`modelSettings.${modelRef}.appendSystemPrompt must be a non-empty string`);\n\t\t}\n\t\tif (systemPrompt !== undefined && appendSystemPrompt !== undefined) {\n\t\t\tthrow new Error(`modelSettings.${modelRef} cannot define both systemPrompt and appendSystemPrompt`);\n\t\t}\n\t\tif (systemPrompt === undefined && appendSystemPrompt === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { systemPrompt, appendSystemPrompt };\n\t}\n\n\tgetModelThinkingDisplay(modelId: string): \"summarized\" | \"omitted\" | undefined {\n\t\treturn this.getModelSettings(modelId)?.thinkingDisplay;\n\t}\n\n\tsetModelThinkingDisplay(modelId: string, value: \"summarized\" | \"omitted\" | undefined): void {\n\t\tif (value === undefined) {\n\t\t\tconst existing = this.globalSettings.modelSettings?.[modelId];\n\t\t\tif (existing?.thinkingDisplay === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete existing.thinkingDisplay;\n\t\t\tif (Object.keys(existing).length === 0) {\n\t\t\t\tdelete this.globalSettings.modelSettings![modelId];\n\t\t\t}\n\t\t\tthis.markModified(\"modelSettings\", modelId);\n\t\t\tthis.save();\n\t\t\treturn;\n\t\t}\n\t\tif (!this.globalSettings.modelSettings) {\n\t\t\tthis.globalSettings.modelSettings = {};\n\t\t}\n\t\tif (!this.globalSettings.modelSettings[modelId]) {\n\t\t\tthis.globalSettings.modelSettings[modelId] = {};\n\t\t}\n\t\tthis.globalSettings.modelSettings[modelId].thinkingDisplay = value;\n\t\tthis.markModified(\"modelSettings\", modelId);\n\t\tthis.save();\n\t}\n\n\tgetTabTitleSettings(): TabTitleSettings | undefined {\n\t\treturn this.settings.tabTitle;\n\t}\n}\n"]}
1
+ {"version":3,"file":"settings-manager.js","sourceRoot":"","sources":["../../src/core/settings-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { homedir } from \"node:os\";\nimport type { Transport } from \"@dreb/ai\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join, resolve } from \"path\";\nimport lockfile from \"proper-lockfile\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"../config.js\";\nimport type { ContextTrustPolicy } from \"./context-trust.js\";\nimport { log } from \"./logger.js\";\nimport { expandPath } from \"./tools/path-utils.js\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface ContextSettings {\n\t/**\n\t * Expert-only global opt-in to lazy-load nested context from every strictly resolvable\n\t * tool target. This is disabled by default because context files can contain prompt\n\t * injection. Project settings cannot affect this policy.\n\t */\n\tautoLoadNested?: boolean;\n\t/** Global-only folder roots allowed to lazy-load context for themselves and descendants. */\n\ttrustedFolders?: string[];\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n\tskipPrompt?: boolean; // default: false - when true, skips \"Summarize branch?\" prompt and defaults to no summary\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tmaxDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport const DEFAULT_BG_PARENT_TURN_LIMIT = 3;\nexport const DEFAULT_MAX_CONCURRENT_SUBAGENTS = 4;\n\nexport interface BackgroundAgentsSettings {\n\t/**\n\t * Whether the parent agent is paused after `parentTurnLimit` turns while background\n\t * agents are still running. Disable (false) to let the parent keep running while\n\t * subagents work — an advanced opt-out with no upper bound on parent turns. default: true\n\t */\n\tparentTurnGuardrail?: boolean;\n\t/** Number of parent turns allowed while background agents run before pausing. default: 3 */\n\tparentTurnLimit?: number;\n\t/** Maximum child agents that one parent session may run concurrently. Zero disables the tool. default: 4 */\n\tmaxConcurrentSubagents?: number;\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\nexport interface AgentModelsSettings {\n\tmodels?: Record<string, string[]>;\n}\n\n/** Global-only configuration for the fail-closed pre-spawn Dispatch Arbiter. */\nexport interface SubagentArbiterSettings {\n\tenabled?: boolean;\n\t/** Exact canonical provider/model used for the tool-less arbiter call. */\n\tmodel?: string;\n\tthinking?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\tguidePath?: string;\n}\n\nexport interface ModelSpecificSettings {\n\t/** Thinking display preference for this model: \"summarized\" shows thinking text, \"omitted\" hides it (lower latency). */\n\tthinkingDisplay?: \"summarized\" | \"omitted\";\n\t/** Custom system prompt for an exact provider/model key. Replaces dreb's built-in prompt. */\n\tsystemPrompt?: string;\n\t/** Text appended to the system prompt for an exact provider/model key. */\n\tappendSystemPrompt?: string;\n}\n\nexport type ModelPromptSettings = Pick<ModelSpecificSettings, \"systemPrompt\" | \"appendSystemPrompt\">;\n\nexport type TransportSetting = Transport;\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tprompts?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\ttransport?: TransportSetting; // default: \"sse\"\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tcontext?: ContextSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\tbackgroundAgents?: BackgroundAgentsSettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tnpmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., [\"mise\", \"exec\", \"node@20\", \"--\", \"npm\"])\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tprompts?: string[]; // Array of local prompt template paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\ttreeFilterMode?: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"; // Default filter when opening /tree\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n\tsessionDir?: string; // Custom session storage directory (same format as --session-dir CLI flag)\n\tforbiddenCommands?: string[]; // Regex patterns for commands blocked by the forbidden-commands guard\n\tsensitiveFilePaths?: string[]; // Additional glob patterns for sensitive file paths blocked by the read/bash guard\n\tsecretOutputPatterns?: { name: string; pattern: string }[]; // Additional regex patterns for secret scrubbing in tool output\n\tagentModels?: AgentModelsSettings;\n\t/** Global-only. Project settings must never enable or reconfigure arbitration. */\n\tsubagentArbiter?: SubagentArbiterSettings;\n\t// Per-model overrides. Thinking display supports legacy model-ID keys; prompt settings require exact provider/model keys.\n\tmodelSettings?: Record<string, ModelSpecificSettings>;\n\tdream?: {\n\t\tarchivePath?: string; // Custom archive location for dream backups (default: ~/.dreb/memory-archive/)\n\t};\n\ttabTitle?: TabTitleSettings;\n}\n\nexport interface TabTitleSettings {\n\tenabled?: boolean; // default: true — auto-generate terminal tab title from session task\n\t/** Exact canonical provider/model used for title generation; absent preserves Explore-agent routing. */\n\tmodel?: string;\n\ttriggerAfter?: number; // default: 9 — number of tool calls before generating title\n\tmaxTitleLength?: number; // default: 60 — soft target length hint for generated titles (hard-capped at 300)\n}\n\n/** Partial tab-title update; `model: null` removes the pinned model, restoring Explore-agent routing. */\nexport type TabTitleSettingsUpdate = Omit<TabTitleSettings, \"model\"> & { model?: string | null };\n\n/** Deep merge settings: project/overrides take precedence, nested objects merge recursively */\nfunction deepMergeSettings(base: Settings, overrides: Settings): Settings {\n\tconst result: Settings = { ...base };\n\n\tfor (const key of Object.keys(overrides) as (keyof Settings)[]) {\n\t\tconst overrideValue = overrides[key];\n\t\tconst baseValue = base[key];\n\n\t\tif (overrideValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// For nested objects, merge recursively\n\t\tif (\n\t\t\ttypeof overrideValue === \"object\" &&\n\t\t\toverrideValue !== null &&\n\t\t\t!Array.isArray(overrideValue) &&\n\t\t\ttypeof baseValue === \"object\" &&\n\t\t\tbaseValue !== null &&\n\t\t\t!Array.isArray(baseValue)\n\t\t) {\n\t\t\t(result as Record<string, unknown>)[key] = { ...baseValue, ...overrideValue };\n\t\t} else {\n\t\t\t// For primitives and arrays, override value wins\n\t\t\t(result as Record<string, unknown>)[key] = overrideValue;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport type SettingsScope = \"global\" | \"project\";\n\nexport interface SettingsStorage {\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void;\n}\n\nexport interface SettingsError {\n\tscope: SettingsScope;\n\terror: Error;\n}\n\nexport class FileSettingsStorage implements SettingsStorage {\n\tprivate globalSettingsPath: string;\n\tprivate projectSettingsPath: string;\n\n\tconstructor(cwd: string = process.cwd(), agentDir: string = getAgentDir()) {\n\t\tthis.globalSettingsPath = join(agentDir, \"settings.json\");\n\t\tthis.projectSettingsPath = join(cwd, CONFIG_DIR_NAME, \"settings.json\");\n\t}\n\n\tprivate acquireLockSyncWithRetry(path: string): () => void {\n\t\tconst maxAttempts = 10;\n\t\tconst delayMs = 20;\n\t\tlet lastError: unknown;\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn lockfile.lockSync(path, { realpath: false });\n\t\t\t} catch (error) {\n\t\t\t\tconst code =\n\t\t\t\t\ttypeof error === \"object\" && error !== null && \"code\" in error\n\t\t\t\t\t\t? String((error as { code?: unknown }).code)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxAttempts) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tconst start = Date.now();\n\t\t\t\twhile (Date.now() - start < delayMs) {\n\t\t\t\t\t// Sleep synchronously to avoid changing callers to async.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow (lastError as Error) ?? new Error(\"Failed to acquire settings lock\");\n\t}\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst path = scope === \"global\" ? this.globalSettingsPath : this.projectSettingsPath;\n\t\tconst dir = dirname(path);\n\n\t\tlet release: (() => void) | undefined;\n\t\ttry {\n\t\t\t// Only create directory and lock if file exists or we need to write\n\t\t\tconst fileExists = existsSync(path);\n\t\t\tif (fileExists) {\n\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t}\n\t\t\tconst current = fileExists ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\tconst next = fn(current);\n\t\t\tif (next !== undefined) {\n\t\t\t\t// Only create directory when we actually need to write\n\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t\t}\n\t\t\t\tif (!release) {\n\t\t\t\t\trelease = this.acquireLockSyncWithRetry(path);\n\t\t\t\t}\n\t\t\t\twriteFileSync(path, next, \"utf-8\");\n\t\t\t}\n\t\t} finally {\n\t\t\tif (release) {\n\t\t\t\trelease();\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class InMemorySettingsStorage implements SettingsStorage {\n\tprivate global: string | undefined;\n\tprivate project: string | undefined;\n\n\twithLock(scope: SettingsScope, fn: (current: string | undefined) => string | undefined): void {\n\t\tconst current = scope === \"global\" ? this.global : this.project;\n\t\tconst next = fn(current);\n\t\tif (next !== undefined) {\n\t\t\tif (scope === \"global\") {\n\t\t\t\tthis.global = next;\n\t\t\t} else {\n\t\t\t\tthis.project = next;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class SettingsManager {\n\tprivate storage: SettingsStorage;\n\tprivate globalSettings: Settings;\n\tprivate projectSettings: Settings;\n\tprivate settings: Settings;\n\tprivate modifiedFields = new Set<keyof Settings>(); // Track global fields modified during session\n\tprivate modifiedNestedFields = new Map<keyof Settings, Set<string>>(); // Track global nested field modifications\n\tprivate modifiedProjectFields = new Set<keyof Settings>(); // Track project fields modified during session\n\tprivate modifiedProjectNestedFields = new Map<keyof Settings, Set<string>>(); // Track project nested field modifications\n\tprivate globalSettingsLoadError: Error | null = null; // Track if global settings file had parse errors\n\tprivate projectSettingsLoadError: Error | null = null; // Track if project settings file had parse errors\n\tprivate writeQueue: Promise<void> = Promise.resolve();\n\tprivate errors: SettingsError[];\n\n\tprivate constructor(\n\t\tstorage: SettingsStorage,\n\t\tinitialGlobal: Settings,\n\t\tinitialProject: Settings,\n\t\tglobalLoadError: Error | null = null,\n\t\tprojectLoadError: Error | null = null,\n\t\tinitialErrors: SettingsError[] = [],\n\t) {\n\t\tthis.storage = storage;\n\t\tthis.globalSettings = initialGlobal;\n\t\tthis.projectSettings = initialProject;\n\t\tthis.globalSettingsLoadError = globalLoadError;\n\t\tthis.projectSettingsLoadError = projectLoadError;\n\t\tthis.errors = [...initialErrors];\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Create a SettingsManager that loads from files */\n\tstatic create(cwd: string = process.cwd(), agentDir: string = getAgentDir()): SettingsManager {\n\t\tconst storage = new FileSettingsStorage(cwd, agentDir);\n\t\treturn SettingsManager.fromStorage(storage);\n\t}\n\n\t/** Create a SettingsManager from an arbitrary storage backend */\n\tstatic fromStorage(storage: SettingsStorage): SettingsManager {\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(storage, \"global\");\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(storage, \"project\");\n\t\tconst initialErrors: SettingsError[] = [];\n\t\tif (globalLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"global\", error: globalLoad.error });\n\t\t}\n\t\tif (projectLoad.error) {\n\t\t\tinitialErrors.push({ scope: \"project\", error: projectLoad.error });\n\t\t}\n\n\t\treturn new SettingsManager(\n\t\t\tstorage,\n\t\t\tglobalLoad.settings,\n\t\t\tprojectLoad.settings,\n\t\t\tglobalLoad.error,\n\t\t\tprojectLoad.error,\n\t\t\tinitialErrors,\n\t\t);\n\t}\n\n\t/** Create an in-memory SettingsManager (no file I/O) */\n\tstatic inMemory(settings: Partial<Settings> = {}): SettingsManager {\n\t\tconst storage = new InMemorySettingsStorage();\n\t\treturn new SettingsManager(storage, settings, {});\n\t}\n\n\tprivate static loadFromStorage(storage: SettingsStorage, scope: SettingsScope): Settings {\n\t\tlet content: string | undefined;\n\t\tstorage.withLock(scope, (current) => {\n\t\t\tcontent = current;\n\t\t\treturn undefined;\n\t\t});\n\n\t\tif (!content) {\n\t\t\treturn {};\n\t\t}\n\t\tconst settings = JSON.parse(content);\n\t\treturn SettingsManager.migrateSettings(settings);\n\t}\n\n\tprivate static tryLoadFromStorage(\n\t\tstorage: SettingsStorage,\n\t\tscope: SettingsScope,\n\t): { settings: Settings; error: Error | null } {\n\t\ttry {\n\t\t\treturn { settings: SettingsManager.loadFromStorage(storage, scope), error: null };\n\t\t} catch (error) {\n\t\t\treturn { settings: {}, error: error as Error };\n\t\t}\n\t}\n\n\t/**\n\t * Normalize the two known lazy-context trust fields of a `context` slice to fail-closed\n\t * defaults when malformed, preserving valid values and any unrelated keys. Used at persist\n\t * time so a single-field trust write cannot leave a malformed sibling (read fresh from disk)\n\t * that would invalidate — and therefore silently disable — the entire trust policy.\n\t */\n\tprivate static sanitizeContextTrustSlice(nested: Record<string, unknown>): Record<string, unknown> {\n\t\tconst sanitized = { ...nested };\n\t\tif (\"autoLoadNested\" in sanitized && typeof sanitized.autoLoadNested !== \"boolean\") {\n\t\t\tsanitized.autoLoadNested = false;\n\t\t}\n\t\tif (\n\t\t\t\"trustedFolders\" in sanitized &&\n\t\t\t(!Array.isArray(sanitized.trustedFolders) ||\n\t\t\t\tsanitized.trustedFolders.some((folder) => typeof folder !== \"string\"))\n\t\t) {\n\t\t\tsanitized.trustedFolders = [];\n\t\t}\n\t\treturn sanitized;\n\t}\n\n\t/** Migrate old settings format to new format */\n\tprivate static migrateSettings(settings: Record<string, unknown>): Settings {\n\t\t// Migrate queueMode -> steeringMode\n\t\tif (\"queueMode\" in settings && !(\"steeringMode\" in settings)) {\n\t\t\tsettings.steeringMode = settings.queueMode;\n\t\t\tdelete settings.queueMode;\n\t\t}\n\n\t\t// Migrate legacy websockets boolean -> transport enum\n\t\tif (!(\"transport\" in settings) && typeof settings.websockets === \"boolean\") {\n\t\t\tsettings.transport = settings.websockets ? \"websocket\" : \"sse\";\n\t\t\tdelete settings.websockets;\n\t\t}\n\n\t\t// Migrate old skills object format to new array format\n\t\tif (\n\t\t\t\"skills\" in settings &&\n\t\t\ttypeof settings.skills === \"object\" &&\n\t\t\tsettings.skills !== null &&\n\t\t\t!Array.isArray(settings.skills)\n\t\t) {\n\t\t\tconst skillsSettings = settings.skills as {\n\t\t\t\tenableSkillCommands?: boolean;\n\t\t\t\tcustomDirectories?: unknown;\n\t\t\t};\n\t\t\tif (skillsSettings.enableSkillCommands !== undefined && settings.enableSkillCommands === undefined) {\n\t\t\t\tsettings.enableSkillCommands = skillsSettings.enableSkillCommands;\n\t\t\t}\n\t\t\tif (Array.isArray(skillsSettings.customDirectories) && skillsSettings.customDirectories.length > 0) {\n\t\t\t\tsettings.skills = skillsSettings.customDirectories;\n\t\t\t} else {\n\t\t\t\tdelete settings.skills;\n\t\t\t}\n\t\t}\n\n\t\treturn settings as Settings;\n\t}\n\n\tgetGlobalSettings(): Settings {\n\t\treturn structuredClone(this.globalSettings);\n\t}\n\n\tgetProjectSettings(): Settings {\n\t\treturn structuredClone(this.projectSettings);\n\t}\n\n\treload(): void {\n\t\tconst globalLoad = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (!globalLoad.error) {\n\t\t\tthis.globalSettings = globalLoad.settings;\n\t\t\tthis.globalSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.globalSettingsLoadError = globalLoad.error;\n\t\t\tthis.recordError(\"global\", globalLoad.error);\n\t\t}\n\n\t\tthis.modifiedFields.clear();\n\t\tthis.modifiedNestedFields.clear();\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\n\t\tconst projectLoad = SettingsManager.tryLoadFromStorage(this.storage, \"project\");\n\t\tif (!projectLoad.error) {\n\t\t\tthis.projectSettings = projectLoad.settings;\n\t\t\tthis.projectSettingsLoadError = null;\n\t\t} else {\n\t\t\tthis.projectSettingsLoadError = projectLoad.error;\n\t\t\tthis.recordError(\"project\", projectLoad.error);\n\t\t}\n\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\t/** Apply additional overrides on top of current settings */\n\tapplyOverrides(overrides: Partial<Settings>): void {\n\t\tthis.settings = deepMergeSettings(this.settings, overrides);\n\t}\n\n\t/** Mark a global field as modified during this session */\n\tprivate markModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedNestedFields.has(field)) {\n\t\t\t\tthis.modifiedNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\t/** Mark a project field as modified during this session */\n\tprivate markProjectModified(field: keyof Settings, nestedKey?: string): void {\n\t\tthis.modifiedProjectFields.add(field);\n\t\tif (nestedKey) {\n\t\t\tif (!this.modifiedProjectNestedFields.has(field)) {\n\t\t\t\tthis.modifiedProjectNestedFields.set(field, new Set());\n\t\t\t}\n\t\t\tthis.modifiedProjectNestedFields.get(field)!.add(nestedKey);\n\t\t}\n\t}\n\n\tprivate recordError(scope: SettingsScope, error: unknown): void {\n\t\tconst normalizedError = error instanceof Error ? error : new Error(String(error));\n\t\tthis.errors.push({ scope, error: normalizedError });\n\t}\n\n\tprivate refreshGlobalContextFromStorage(options: { clearContextOnError?: boolean } = {}): boolean {\n\t\t// Keep a just-selected UI value effective until its queued durable write completes;\n\t\t// otherwise always re-read the external global source for cross-process changes.\n\t\tif (this.storage instanceof InMemorySettingsStorage || this.modifiedFields.has(\"context\")) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst loaded = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (loaded.error) {\n\t\t\tthis.recordError(\"global\", loaded.error);\n\t\t\tif (options.clearContextOnError) {\n\t\t\t\tthis.globalSettings = { ...this.globalSettings, context: undefined };\n\t\t\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// This re-read owns only the security-policy slice. Preserve every other\n\t\t// in-memory global field, including writes that are queued but not yet durable.\n\t\tthis.globalSettings = { ...this.globalSettings, context: loaded.settings.context };\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\treturn true;\n\t}\n\n\tprivate refreshGlobalSubagentArbiterFromStorage(): void {\n\t\t// Keep a locally selected policy effective until its queued write completes;\n\t\t// otherwise re-read the global slice so long-lived sessions observe dashboard\n\t\t// and TUI changes made by another runtime.\n\t\tif (this.storage instanceof InMemorySettingsStorage || this.modifiedFields.has(\"subagentArbiter\")) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst loaded = SettingsManager.tryLoadFromStorage(this.storage, \"global\");\n\t\tif (loaded.error) {\n\t\t\tthis.recordError(\"global\", loaded.error);\n\t\t\tthis.globalSettings = { ...this.globalSettings, subagentArbiter: undefined };\n\t\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t\t\tthrow new Error(`Could not reload global Dispatch Arbiter settings: ${loaded.error.message}`);\n\t\t}\n\n\t\t// This refresh owns only the global-only arbiter slice. Preserve unrelated\n\t\t// in-memory settings, including writes that are queued but not yet durable.\n\t\tthis.globalSettings = { ...this.globalSettings, subagentArbiter: loaded.settings.subagentArbiter };\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\t}\n\n\tprivate clearModifiedScope(scope: SettingsScope): void {\n\t\tif (scope === \"global\") {\n\t\t\tthis.modifiedFields.clear();\n\t\t\tthis.modifiedNestedFields.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.modifiedProjectFields.clear();\n\t\tthis.modifiedProjectNestedFields.clear();\n\t}\n\n\tprivate enqueueWrite(scope: SettingsScope, task: () => void): void {\n\t\tthis.writeQueue = this.writeQueue\n\t\t\t.then(() => {\n\t\t\t\ttask();\n\t\t\t\tthis.clearModifiedScope(scope);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.recordError(scope, error);\n\t\t\t});\n\t}\n\n\tprivate cloneModifiedNestedFields(source: Map<keyof Settings, Set<string>>): Map<keyof Settings, Set<string>> {\n\t\tconst snapshot = new Map<keyof Settings, Set<string>>();\n\t\tfor (const [key, value] of source.entries()) {\n\t\t\tsnapshot.set(key, new Set(value));\n\t\t}\n\t\treturn snapshot;\n\t}\n\n\tprivate persistScopedSettings(\n\t\tscope: SettingsScope,\n\t\tsnapshotSettings: Settings,\n\t\tmodifiedFields: Set<keyof Settings>,\n\t\tmodifiedNestedFields: Map<keyof Settings, Set<string>>,\n\t): void {\n\t\tthis.storage.withLock(scope, (current) => {\n\t\t\tconst currentFileSettings = current\n\t\t\t\t? SettingsManager.migrateSettings(JSON.parse(current) as Record<string, unknown>)\n\t\t\t\t: {};\n\t\t\tconst mergedSettings: Settings = { ...currentFileSettings };\n\t\t\tfor (const field of modifiedFields) {\n\t\t\t\tconst value = snapshotSettings[field];\n\t\t\t\tif (modifiedNestedFields.has(field) && typeof value === \"object\" && value !== null) {\n\t\t\t\t\tconst nestedModified = modifiedNestedFields.get(field)!;\n\t\t\t\t\tconst baseNested = (currentFileSettings[field] as Record<string, unknown>) ?? {};\n\t\t\t\t\tconst inMemoryNested = value as Record<string, unknown>;\n\t\t\t\t\tlet mergedNested = { ...baseNested };\n\t\t\t\t\tfor (const nestedKey of nestedModified) {\n\t\t\t\t\t\tmergedNested[nestedKey] = inMemoryNested[nestedKey];\n\t\t\t\t\t}\n\t\t\t\t\t// The global context-trust slice is security-sensitive: an untouched sibling\n\t\t\t\t\t// is preserved from the fresh on-disk read above, but a malformed on-disk\n\t\t\t\t\t// sibling must still collapse to a fail-closed default so a successful trust\n\t\t\t\t\t// mutation cannot leave the whole policy invalid (and thus silently disabled).\n\t\t\t\t\tif (scope === \"global\" && field === \"context\") {\n\t\t\t\t\t\tmergedNested = SettingsManager.sanitizeContextTrustSlice(mergedNested);\n\t\t\t\t\t}\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = mergedNested;\n\t\t\t\t} else {\n\t\t\t\t\t(mergedSettings as Record<string, unknown>)[field] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn JSON.stringify(mergedSettings, null, 2);\n\t\t});\n\t}\n\n\tprivate save(): void {\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.globalSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotGlobalSettings = structuredClone(this.globalSettings);\n\t\tconst modifiedFields = new Set(this.modifiedFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedNestedFields);\n\n\t\tthis.enqueueWrite(\"global\", () => {\n\t\t\tthis.persistScopedSettings(\"global\", snapshotGlobalSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tprivate saveProjectSettings(settings: Settings): void {\n\t\tthis.projectSettings = structuredClone(settings);\n\t\tthis.settings = deepMergeSettings(this.globalSettings, this.projectSettings);\n\n\t\tif (this.projectSettingsLoadError) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst snapshotProjectSettings = structuredClone(this.projectSettings);\n\t\tconst modifiedFields = new Set(this.modifiedProjectFields);\n\t\tconst modifiedNestedFields = this.cloneModifiedNestedFields(this.modifiedProjectNestedFields);\n\t\tthis.enqueueWrite(\"project\", () => {\n\t\t\tthis.persistScopedSettings(\"project\", snapshotProjectSettings, modifiedFields, modifiedNestedFields);\n\t\t});\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tawait this.writeQueue;\n\t}\n\n\t/**\n\t * True when the global settings file failed to load/parse. In that state {@link save}\n\t * silently no-ops (to avoid stomping the corrupt file), so callers that need write\n\t * durability must check this and fail loudly instead of reporting success.\n\t */\n\thasGlobalSettingsLoadError(): boolean {\n\t\treturn this.globalSettingsLoadError !== null;\n\t}\n\n\t/** True when the project settings file failed to load or parse. */\n\thasProjectSettingsLoadError(): boolean {\n\t\treturn this.projectSettingsLoadError !== null;\n\t}\n\n\tdrainErrors(): SettingsError[] {\n\t\tconst drained = [...this.errors];\n\t\tthis.errors = [];\n\t\treturn drained;\n\t}\n\n\tgetSessionDir(): string | undefined {\n\t\treturn this.settings.sessionDir;\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tsetDefaultProvider(provider: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModel(modelId: string): void {\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.globalSettings.defaultProvider = provider;\n\t\tthis.globalSettings.defaultModel = modelId;\n\t\tthis.markModified(\"defaultProvider\");\n\t\tthis.markModified(\"defaultModel\");\n\t\tthis.save();\n\t}\n\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.steeringMode || \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.steeringMode = mode;\n\t\tthis.markModified(\"steeringMode\");\n\t\tthis.save();\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn this.settings.followUpMode || \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(mode: \"all\" | \"one-at-a-time\"): void {\n\t\tthis.globalSettings.followUpMode = mode;\n\t\tthis.markModified(\"followUpMode\");\n\t\tthis.save();\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn this.settings.theme;\n\t}\n\n\tsetTheme(theme: string): void {\n\t\tthis.globalSettings.theme = theme;\n\t\tthis.markModified(\"theme\");\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\" | undefined {\n\t\treturn this.settings.defaultThinkingLevel;\n\t}\n\n\tsetDefaultThinkingLevel(level: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\"): void {\n\t\tthis.globalSettings.defaultThinkingLevel = level;\n\t\tthis.markModified(\"defaultThinkingLevel\");\n\t\tthis.save();\n\t}\n\n\tgetTransport(): TransportSetting {\n\t\treturn this.settings.transport ?? \"sse\";\n\t}\n\n\tsetTransport(transport: TransportSetting): void {\n\t\tthis.globalSettings.transport = transport;\n\t\tthis.markModified(\"transport\");\n\t\tthis.save();\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? true;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.compaction) {\n\t\t\tthis.globalSettings.compaction = {};\n\t\t}\n\t\tthis.globalSettings.compaction.enabled = enabled;\n\t\tthis.markModified(\"compaction\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\t/**\n\t * Read the global-only lazy-context policy. File-backed managers re-read this small\n\t * policy on each decision so independently running main/subagent processes observe\n\t * external global settings writes without ever consulting project settings. A malformed\n\t * global file fails closed rather than retaining a previously permissive value.\n\t */\n\tgetGlobalContextTrustPolicy(): ContextTrustPolicy {\n\t\tif (!this.refreshGlobalContextFromStorage()) {\n\t\t\treturn { unrestricted: false, trustedFolders: [] };\n\t\t}\n\n\t\tconst context = this.globalSettings.context;\n\t\t// A valid JSON file with a malformed security policy is also fail-closed. Do not\n\t\t// coerce strings/truthy values or partially accept an invalid trusted-folder list.\n\t\tif (\n\t\t\tcontext !== undefined &&\n\t\t\t(typeof context !== \"object\" ||\n\t\t\t\tcontext === null ||\n\t\t\t\t(context.autoLoadNested !== undefined && typeof context.autoLoadNested !== \"boolean\") ||\n\t\t\t\t(context.trustedFolders !== undefined &&\n\t\t\t\t\t(!Array.isArray(context.trustedFolders) ||\n\t\t\t\t\t\tcontext.trustedFolders.some((folder) => typeof folder !== \"string\"))))\n\t\t) {\n\t\t\tconst error = new Error(\n\t\t\t\t\"Global context trust settings are malformed; lazy nested context loading is disabled\",\n\t\t\t);\n\t\t\tthis.recordError(\"global\", error);\n\t\t\treturn { unrestricted: false, trustedFolders: [] };\n\t\t}\n\n\t\treturn {\n\t\t\tunrestricted: context?.autoLoadNested ?? false,\n\t\t\ttrustedFolders: context?.trustedFolders ? [...context.trustedFolders] : [],\n\t\t};\n\t}\n\n\t/** Effective unrestricted flag; intentionally reads global settings only. */\n\tgetAutoLoadNestedContext(): boolean {\n\t\treturn this.getGlobalContextTrustPolicy().unrestricted;\n\t}\n\n\tgetTrustedContextFolders(): string[] {\n\t\treturn this.getGlobalContextTrustPolicy().trustedFolders;\n\t}\n\n\tgetConfiguredTrustedContextFolders(): string[] {\n\t\tif (!this.refreshGlobalContextFromStorage()) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst context = this.globalSettings.context;\n\t\tif (context === undefined || typeof context !== \"object\" || context === null || Array.isArray(context)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst trustedFolders = (context as Record<string, unknown>).trustedFolders;\n\t\tif (trustedFolders === undefined) {\n\t\t\treturn [];\n\t\t}\n\t\tif (!Array.isArray(trustedFolders) || trustedFolders.some((folder) => typeof folder !== \"string\")) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn [...trustedFolders];\n\t}\n\n\tsetAutoLoadNestedContext(enabled: boolean): void {\n\t\tthis.setContextTrust({ autoLoadNested: enabled });\n\t}\n\n\t/**\n\t * Atomically persist one or both global lazy-context trust policy fields. Every trust\n\t * write normalizes both known fields, so a malformed on-disk sibling cannot make an\n\t * otherwise successful mutation silently fail closed.\n\t */\n\tsetContextTrust(update: { autoLoadNested?: boolean; trustedFolders?: string[] }): void {\n\t\tif (update.autoLoadNested !== undefined && typeof update.autoLoadNested !== \"boolean\") {\n\t\t\tthrow new Error(\"Auto-load nested context must be a boolean\");\n\t\t}\n\t\tif (\n\t\t\tupdate.trustedFolders !== undefined &&\n\t\t\t(!Array.isArray(update.trustedFolders) || update.trustedFolders.some((folder) => typeof folder !== \"string\"))\n\t\t) {\n\t\t\tthrow new Error(\"Trusted context folders must be an array of strings\");\n\t\t}\n\n\t\t// Refresh the in-memory context slice from the external global file unless a context\n\t\t// write is already pending, so an unspecified sibling reflects concurrent cross-process\n\t\t// changes (e.g. a folder just untrusted elsewhere) instead of a stale in-memory value.\n\t\t// A pending context write already owns the authoritative in-memory value; do not stomp\n\t\t// it. Fail closed if the external file is unreadable.\n\t\tthis.refreshGlobalContextFromStorage({ clearContextOnError: true });\n\n\t\tconst currentContext = this.globalSettings.context;\n\t\tconst current =\n\t\t\ttypeof currentContext === \"object\" && currentContext !== null && !Array.isArray(currentContext)\n\t\t\t\t? (currentContext as Record<string, unknown>)\n\t\t\t\t: {};\n\t\tconst autoLoadNested =\n\t\t\tupdate.autoLoadNested ?? (typeof current.autoLoadNested === \"boolean\" ? current.autoLoadNested : false);\n\t\tconst currentTrustedFolders =\n\t\t\tArray.isArray(current.trustedFolders) && current.trustedFolders.every((folder) => typeof folder === \"string\")\n\t\t\t\t? (current.trustedFolders as string[])\n\t\t\t\t: [];\n\t\tconst trustedFolders = update.trustedFolders ?? currentTrustedFolders;\n\n\t\tthis.globalSettings.context = {\n\t\t\t...current,\n\t\t\tautoLoadNested,\n\t\t\ttrustedFolders: [...trustedFolders],\n\t\t};\n\t\t// Mark only the explicitly-supplied fields modified. persistScopedSettings then\n\t\t// preserves an untouched sibling from the fresh on-disk slice read inside the storage\n\t\t// lock, so a single-field write can no longer clobber a concurrent external change to\n\t\t// the other field. Malformed on-disk siblings are still normalized fail-closed there.\n\t\tif (update.autoLoadNested !== undefined) {\n\t\t\tthis.markModified(\"context\", \"autoLoadNested\");\n\t\t}\n\t\tif (update.trustedFolders !== undefined) {\n\t\t\tthis.markModified(\"context\", \"trustedFolders\");\n\t\t}\n\t\tthis.save();\n\t}\n\n\tsetTrustedContextFolders(folders: string[]): void {\n\t\tthis.setContextTrust({ trustedFolders: folders });\n\t}\n\n\taddTrustedContextFolder(folder: string): void {\n\t\tif (typeof folder !== \"string\" || folder === \"\") {\n\t\t\tthrow new Error(\"Trusted context folder must be a non-empty string\");\n\t\t}\n\t\tconst folders = this.getConfiguredTrustedContextFolders();\n\t\tif (!folders.includes(folder)) folders.push(folder);\n\t\tthis.setTrustedContextFolders(folders);\n\t}\n\n\tremoveTrustedContextFolder(folder: string): void {\n\t\tthis.setTrustedContextFolders(this.getConfiguredTrustedContextFolders().filter((current) => current !== folder));\n\t}\n\n\tgetCompactionReserveTokens(): number {\n\t\treturn this.settings.compaction?.reserveTokens ?? 16384;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn this.settings.compaction?.keepRecentTokens ?? 20000;\n\t}\n\n\tgetCompactionSettings(): { enabled: boolean; reserveTokens: number; keepRecentTokens: number } {\n\t\treturn {\n\t\t\tenabled: this.getCompactionEnabled(),\n\t\t\treserveTokens: this.getCompactionReserveTokens(),\n\t\t\tkeepRecentTokens: this.getCompactionKeepRecentTokens(),\n\t\t};\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number; skipPrompt: boolean } {\n\t\treturn {\n\t\t\treserveTokens: this.settings.branchSummary?.reserveTokens ?? 16384,\n\t\t\tskipPrompt: this.settings.branchSummary?.skipPrompt ?? false,\n\t\t};\n\t}\n\n\tgetBranchSummarySkipPrompt(): boolean {\n\t\treturn this.settings.branchSummary?.skipPrompt ?? false;\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? true;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.retry) {\n\t\t\tthis.globalSettings.retry = {};\n\t\t}\n\t\tthis.globalSettings.retry.enabled = enabled;\n\t\tthis.markModified(\"retry\", \"enabled\");\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): { enabled: boolean; maxRetries: number; baseDelayMs: number; maxDelayMs: number } {\n\t\treturn {\n\t\t\tenabled: this.getRetryEnabled(),\n\t\t\tmaxRetries: this.settings.retry?.maxRetries ?? 3,\n\t\t\tbaseDelayMs: this.settings.retry?.baseDelayMs ?? 2000,\n\t\t\tmaxDelayMs: this.settings.retry?.maxDelayMs ?? 60000,\n\t\t};\n\t}\n\n\tgetBackgroundAgentGuardrailEnabled(): boolean {\n\t\treturn this.settings.backgroundAgents?.parentTurnGuardrail ?? true;\n\t}\n\n\tsetBackgroundAgentGuardrailEnabled(enabled: boolean): void {\n\t\tif (!this.globalSettings.backgroundAgents) {\n\t\t\tthis.globalSettings.backgroundAgents = {};\n\t\t}\n\t\tthis.globalSettings.backgroundAgents.parentTurnGuardrail = enabled;\n\t\tthis.markModified(\"backgroundAgents\", \"parentTurnGuardrail\");\n\t\tthis.save();\n\t}\n\n\tgetBackgroundAgentGuardrailSettings(): { enabled: boolean; turnLimit: number } {\n\t\tconst rawLimit = this.settings.backgroundAgents?.parentTurnLimit;\n\t\tconst turnLimit =\n\t\t\ttypeof rawLimit === \"number\" && Number.isFinite(rawLimit) && rawLimit >= 1\n\t\t\t\t? rawLimit\n\t\t\t\t: DEFAULT_BG_PARENT_TURN_LIMIT;\n\t\treturn {\n\t\t\tenabled: this.getBackgroundAgentGuardrailEnabled(),\n\t\t\tturnLimit,\n\t\t};\n\t}\n\n\tgetMaxConcurrentSubagents(): number {\n\t\tconst value = this.settings.backgroundAgents?.maxConcurrentSubagents;\n\t\tif (value === undefined) {\n\t\t\treturn DEFAULT_MAX_CONCURRENT_SUBAGENTS;\n\t\t}\n\t\tif (typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0) {\n\t\t\treturn value;\n\t\t}\n\t\tlog.warn(\n\t\t\t`[settings] Ignoring invalid backgroundAgents.maxConcurrentSubagents ${JSON.stringify(value)}; ` +\n\t\t\t\t`it must be a non-negative whole number. Falling back to ${DEFAULT_MAX_CONCURRENT_SUBAGENTS}. ` +\n\t\t\t\t\"Fix the value in your settings file to silence this warning.\",\n\t\t);\n\t\treturn DEFAULT_MAX_CONCURRENT_SUBAGENTS;\n\t}\n\n\tsetMaxConcurrentSubagents(value: number): void {\n\t\tif (!Number.isSafeInteger(value) || value < 0) {\n\t\t\tthrow new Error(\"maxConcurrentSubagents must be a non-negative whole number\");\n\t\t}\n\t\tif (!this.globalSettings.backgroundAgents) {\n\t\t\tthis.globalSettings.backgroundAgents = {};\n\t\t}\n\t\tthis.globalSettings.backgroundAgents.maxConcurrentSubagents = value;\n\t\tthis.markModified(\"backgroundAgents\", \"maxConcurrentSubagents\");\n\t\tthis.save();\n\t}\n\n\tgetHideThinkingBlock(): boolean {\n\t\treturn this.settings.hideThinkingBlock ?? false;\n\t}\n\n\tsetHideThinkingBlock(hide: boolean): void {\n\t\tthis.globalSettings.hideThinkingBlock = hide;\n\t\tthis.markModified(\"hideThinkingBlock\");\n\t\tthis.save();\n\t}\n\n\tgetShellPath(): string | undefined {\n\t\treturn this.settings.shellPath;\n\t}\n\n\tsetShellPath(path: string | undefined): void {\n\t\tthis.globalSettings.shellPath = path;\n\t\tthis.markModified(\"shellPath\");\n\t\tthis.save();\n\t}\n\n\tgetQuietStartup(): boolean {\n\t\treturn this.settings.quietStartup ?? false;\n\t}\n\n\tsetQuietStartup(quiet: boolean): void {\n\t\tthis.globalSettings.quietStartup = quiet;\n\t\tthis.markModified(\"quietStartup\");\n\t\tthis.save();\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn this.settings.shellCommandPrefix;\n\t}\n\n\tsetShellCommandPrefix(prefix: string | undefined): void {\n\t\tthis.globalSettings.shellCommandPrefix = prefix;\n\t\tthis.markModified(\"shellCommandPrefix\");\n\t\tthis.save();\n\t}\n\n\tgetNpmCommand(): string[] | undefined {\n\t\treturn this.settings.npmCommand ? [...this.settings.npmCommand] : undefined;\n\t}\n\n\tsetNpmCommand(command: string[] | undefined): void {\n\t\tthis.globalSettings.npmCommand = command ? [...command] : undefined;\n\t\tthis.markModified(\"npmCommand\");\n\t\tthis.save();\n\t}\n\n\tgetPackages(): PackageSource[] {\n\t\treturn [...(this.settings.packages ?? [])];\n\t}\n\n\tsetPackages(packages: PackageSource[]): void {\n\t\tthis.globalSettings.packages = packages;\n\t\tthis.markModified(\"packages\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPackages(packages: PackageSource[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.packages = packages;\n\t\tthis.markProjectModified(\"packages\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [...(this.settings.extensions ?? [])];\n\t}\n\n\tsetExtensionPaths(paths: string[]): void {\n\t\tthis.globalSettings.extensions = paths;\n\t\tthis.markModified(\"extensions\");\n\t\tthis.save();\n\t}\n\n\tsetProjectExtensionPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.extensions = paths;\n\t\tthis.markProjectModified(\"extensions\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [...(this.settings.skills ?? [])];\n\t}\n\n\tsetSkillPaths(paths: string[]): void {\n\t\tthis.globalSettings.skills = paths;\n\t\tthis.markModified(\"skills\");\n\t\tthis.save();\n\t}\n\n\tsetProjectSkillPaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.skills = paths;\n\t\tthis.markProjectModified(\"skills\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [...(this.settings.prompts ?? [])];\n\t}\n\n\tsetPromptTemplatePaths(paths: string[]): void {\n\t\tthis.globalSettings.prompts = paths;\n\t\tthis.markModified(\"prompts\");\n\t\tthis.save();\n\t}\n\n\tsetProjectPromptTemplatePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.prompts = paths;\n\t\tthis.markProjectModified(\"prompts\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [...(this.settings.themes ?? [])];\n\t}\n\n\tsetThemePaths(paths: string[]): void {\n\t\tthis.globalSettings.themes = paths;\n\t\tthis.markModified(\"themes\");\n\t\tthis.save();\n\t}\n\n\tsetProjectThemePaths(paths: string[]): void {\n\t\tconst projectSettings = structuredClone(this.projectSettings);\n\t\tprojectSettings.themes = paths;\n\t\tthis.markProjectModified(\"themes\");\n\t\tthis.saveProjectSettings(projectSettings);\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn this.settings.enableSkillCommands ?? true;\n\t}\n\n\tsetEnableSkillCommands(enabled: boolean): void {\n\t\tthis.globalSettings.enableSkillCommands = enabled;\n\t\tthis.markModified(\"enableSkillCommands\");\n\t\tthis.save();\n\t}\n\n\tgetThinkingBudgets(): ThinkingBudgetsSettings | undefined {\n\t\treturn this.settings.thinkingBudgets;\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn this.settings.terminal?.showImages ?? true;\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (!this.globalSettings.terminal) {\n\t\t\tthis.globalSettings.terminal = {};\n\t\t}\n\t\tthis.globalSettings.terminal.showImages = show;\n\t\tthis.markModified(\"terminal\", \"showImages\");\n\t\tthis.save();\n\t}\n\n\tgetImageAutoResize(): boolean {\n\t\treturn this.settings.images?.autoResize ?? true;\n\t}\n\n\tsetImageAutoResize(enabled: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.autoResize = enabled;\n\t\tthis.markModified(\"images\", \"autoResize\");\n\t\tthis.save();\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn this.settings.images?.blockImages ?? false;\n\t}\n\n\tsetBlockImages(blocked: boolean): void {\n\t\tif (!this.globalSettings.images) {\n\t\t\tthis.globalSettings.images = {};\n\t\t}\n\t\tthis.globalSettings.images.blockImages = blocked;\n\t\tthis.markModified(\"images\", \"blockImages\");\n\t\tthis.save();\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn this.settings.enabledModels;\n\t}\n\n\tsetEnabledModels(patterns: string[] | undefined): void {\n\t\tthis.globalSettings.enabledModels = patterns;\n\t\tthis.markModified(\"enabledModels\");\n\t\tthis.save();\n\t}\n\n\t/** Whether project settings explicitly replace the global enabled-model scope. */\n\thasProjectEnabledModelsOverride(): boolean {\n\t\treturn this.projectSettings.enabledModels !== undefined;\n\t}\n\n\tgetDoubleEscapeAction(): \"fork\" | \"tree\" | \"none\" {\n\t\treturn this.settings.doubleEscapeAction ?? \"tree\";\n\t}\n\n\tsetDoubleEscapeAction(action: \"fork\" | \"tree\" | \"none\"): void {\n\t\tthis.globalSettings.doubleEscapeAction = action;\n\t\tthis.markModified(\"doubleEscapeAction\");\n\t\tthis.save();\n\t}\n\n\tgetTreeFilterMode(): \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\" {\n\t\tconst mode = this.settings.treeFilterMode;\n\t\tconst valid = [\"default\", \"no-tools\", \"user-only\", \"labeled-only\", \"all\"];\n\t\treturn mode && valid.includes(mode) ? mode : \"default\";\n\t}\n\n\tsetTreeFilterMode(mode: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"): void {\n\t\tthis.globalSettings.treeFilterMode = mode;\n\t\tthis.markModified(\"treeFilterMode\");\n\t\tthis.save();\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.settings.showHardwareCursor ?? process.env.DREB_HARDWARE_CURSOR === \"1\";\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tthis.globalSettings.showHardwareCursor = enabled;\n\t\tthis.markModified(\"showHardwareCursor\");\n\t\tthis.save();\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn this.settings.editorPaddingX ?? 0;\n\t}\n\n\tsetEditorPaddingX(padding: number): void {\n\t\tthis.globalSettings.editorPaddingX = Math.max(0, Math.min(3, Math.floor(padding)));\n\t\tthis.markModified(\"editorPaddingX\");\n\t\tthis.save();\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn this.settings.autocompleteMaxVisible ?? 5;\n\t}\n\n\tsetAutocompleteMaxVisible(maxVisible: number): void {\n\t\tthis.globalSettings.autocompleteMaxVisible = Math.max(3, Math.min(20, Math.floor(maxVisible)));\n\t\tthis.markModified(\"autocompleteMaxVisible\");\n\t\tthis.save();\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn this.settings.markdown?.codeBlockIndent ?? \" \";\n\t}\n\n\tgetForbiddenCommands(): string[] | undefined {\n\t\treturn this.settings.forbiddenCommands;\n\t}\n\n\tgetSensitiveFilePaths(): string[] | undefined {\n\t\treturn this.settings.sensitiveFilePaths;\n\t}\n\n\tgetSecretOutputPatterns(): { name: string; pattern: string }[] | undefined {\n\t\treturn this.settings.secretOutputPatterns;\n\t}\n\n\t/**\n\t * Read only the global arbiter policy; project settings are intentionally ignored.\n\t * File-backed managers refresh this slice for every dispatch so independently\n\t * running sessions observe dashboard and TUI writes without a restart.\n\t */\n\tgetGlobalSubagentArbiterSettings(): SubagentArbiterSettings | undefined {\n\t\tthis.refreshGlobalSubagentArbiterFromStorage();\n\t\treturn this.globalSettings.subagentArbiter ? structuredClone(this.globalSettings.subagentArbiter) : undefined;\n\t}\n\n\tsetGlobalSubagentArbiterSettings(settings: SubagentArbiterSettings | undefined): void {\n\t\tthis.globalSettings.subagentArbiter = settings ? structuredClone(settings) : undefined;\n\t\tthis.markModified(\"subagentArbiter\");\n\t\tthis.save();\n\t}\n\n\tgetDreamArchivePath(): string {\n\t\tconst configured = this.settings.dream?.archivePath;\n\t\tif (configured) {\n\t\t\treturn resolve(expandPath(configured));\n\t\t}\n\t\treturn join(homedir(), \".dreb\", \"memory-archive\");\n\t}\n\n\tsetDreamArchivePath(path: string): void {\n\t\tif (!this.globalSettings.dream) this.globalSettings.dream = {};\n\t\tthis.globalSettings.dream.archivePath = path;\n\t\tthis.markModified(\"dream\", \"archivePath\");\n\t\tthis.save();\n\t}\n\n\tgetAgentModels(): Record<string, string[]> {\n\t\t// Merge global + project at the per-agent-name level, with project winning per-key.\n\t\t// Reading directly from globalSettings/projectSettings avoids the wholesale\n\t\t// replacement that deepMergeSettings would do for the shared `models` sub-key.\n\t\tconst merged: Record<string, string[]> = {\n\t\t\t...this.globalSettings.agentModels?.models,\n\t\t\t...this.projectSettings.agentModels?.models,\n\t\t};\n\t\t// Deep-copy inner arrays so callers can't mutate stored state.\n\t\treturn Object.fromEntries(Object.entries(merged).map(([k, v]) => [k, [...v]]));\n\t}\n\n\tgetAgentModelsForAgent(agentName: string): string[] | undefined {\n\t\tconst models = this.getAgentModels()[agentName];\n\t\treturn models && models.length > 0 ? models : undefined;\n\t}\n\n\t/**\n\t * Whether a project-level (`.dreb/settings.json`) agentModels entry exists for this agent.\n\t * Project entries win over global ones in {@link getAgentModels}, so a global write/remove\n\t * via the TUI has no effect when this returns true — callers should surface this loudly.\n\t */\n\thasProjectAgentModelOverride(agentName: string): boolean {\n\t\treturn this.projectSettings.agentModels?.models?.[agentName] !== undefined;\n\t}\n\n\tsetAgentModelsForAgent(agentName: string, models: string[]): void {\n\t\tif (!this.globalSettings.agentModels) {\n\t\t\tthis.globalSettings.agentModels = {};\n\t\t}\n\t\tif (!this.globalSettings.agentModels.models) {\n\t\t\tthis.globalSettings.agentModels.models = {};\n\t\t}\n\t\tthis.globalSettings.agentModels.models[agentName] = [...models];\n\t\tthis.markModified(\"agentModels\", \"models\");\n\t\tthis.save();\n\t}\n\n\tremoveAgentModelsForAgent(agentName: string): void {\n\t\tif (this.globalSettings.agentModels?.models?.[agentName] !== undefined) {\n\t\t\tdelete this.globalSettings.agentModels.models[agentName];\n\t\t\tthis.markModified(\"agentModels\", \"models\");\n\t\t\tthis.save();\n\t\t}\n\t}\n\n\t/**\n\t * Per-model settings merged global + project at the entry-key level, with project\n\t * winning per property. Entry keys are bare model IDs for legacy settings or canonical\n\t * provider/model references for provider-aware settings. Reading directly from the two\n\t * scopes avoids wholesale replacement of the shared `modelSettings` object.\n\t */\n\tgetModelSettings(modelKey: string): ModelSpecificSettings | undefined {\n\t\tconst global = this.globalSettings.modelSettings?.[modelKey];\n\t\tconst project = this.projectSettings.modelSettings?.[modelKey];\n\t\tif (!global && !project) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { ...global, ...project };\n\t}\n\n\t/**\n\t * Resolve prompt settings for one exact provider/model pair. Prompt settings deliberately\n\t * do not fall back to the legacy bare-model-id keys used by thinkingDisplay because that\n\t * would leak instructions across providers exposing the same model ID.\n\t */\n\tgetModelPromptSettings(provider: string, modelId: string): ModelPromptSettings | undefined {\n\t\tconst modelRef = `${provider}/${modelId}`;\n\t\tconst settings = this.getModelSettings(modelRef);\n\t\tif (!settings) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { systemPrompt, appendSystemPrompt } = settings;\n\t\tif (systemPrompt !== undefined && (typeof systemPrompt !== \"string\" || systemPrompt.trim().length === 0)) {\n\t\t\tthrow new Error(`modelSettings.${modelRef}.systemPrompt must be a non-empty string`);\n\t\t}\n\t\tif (\n\t\t\tappendSystemPrompt !== undefined &&\n\t\t\t(typeof appendSystemPrompt !== \"string\" || appendSystemPrompt.trim().length === 0)\n\t\t) {\n\t\t\tthrow new Error(`modelSettings.${modelRef}.appendSystemPrompt must be a non-empty string`);\n\t\t}\n\t\tif (systemPrompt !== undefined && appendSystemPrompt !== undefined) {\n\t\t\tthrow new Error(`modelSettings.${modelRef} cannot define both systemPrompt and appendSystemPrompt`);\n\t\t}\n\t\tif (systemPrompt === undefined && appendSystemPrompt === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { systemPrompt, appendSystemPrompt };\n\t}\n\n\tgetModelThinkingDisplay(modelId: string): \"summarized\" | \"omitted\" | undefined {\n\t\treturn this.getModelSettings(modelId)?.thinkingDisplay;\n\t}\n\n\tsetModelThinkingDisplay(modelId: string, value: \"summarized\" | \"omitted\" | undefined): void {\n\t\tif (value === undefined) {\n\t\t\tconst existing = this.globalSettings.modelSettings?.[modelId];\n\t\t\tif (existing?.thinkingDisplay === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdelete existing.thinkingDisplay;\n\t\t\tif (Object.keys(existing).length === 0) {\n\t\t\t\tdelete this.globalSettings.modelSettings![modelId];\n\t\t\t}\n\t\t\tthis.markModified(\"modelSettings\", modelId);\n\t\t\tthis.save();\n\t\t\treturn;\n\t\t}\n\t\tif (!this.globalSettings.modelSettings) {\n\t\t\tthis.globalSettings.modelSettings = {};\n\t\t}\n\t\tif (!this.globalSettings.modelSettings[modelId]) {\n\t\t\tthis.globalSettings.modelSettings[modelId] = {};\n\t\t}\n\t\tthis.globalSettings.modelSettings[modelId].thinkingDisplay = value;\n\t\tthis.markModified(\"modelSettings\", modelId);\n\t\tthis.save();\n\t}\n\n\tgetTabTitleSettings(): TabTitleSettings | undefined {\n\t\treturn this.settings.tabTitle ? structuredClone(this.settings.tabTitle) : undefined;\n\t}\n\n\tsetGlobalTabTitleSettings(update: TabTitleSettingsUpdate): void {\n\t\tif (!this.globalSettings.tabTitle) {\n\t\t\tthis.globalSettings.tabTitle = {};\n\t\t}\n\t\tfor (const [key, value] of Object.entries(update) as [keyof TabTitleSettingsUpdate, unknown][]) {\n\t\t\tif (value === undefined) continue;\n\t\t\tif (value === null) {\n\t\t\t\t// Explicit clear: remove the key in memory and mark it modified so the\n\t\t\t\t// nested persistence merge drops it from the file (JSON omits undefined).\n\t\t\t\tdelete (this.globalSettings.tabTitle as Record<keyof TabTitleSettingsUpdate, unknown>)[key];\n\t\t\t\tthis.markModified(\"tabTitle\", key);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t(this.globalSettings.tabTitle as Record<keyof TabTitleSettingsUpdate, unknown>)[key] = value;\n\t\t\tthis.markModified(\"tabTitle\", key);\n\t\t}\n\t\tthis.save();\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tab-title.d.ts","sourceRoot":"","sources":["../../src/core/tab-title.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,GAAG,EAAW,KAAK,EAAE,MAAM,UAAU,CAAC;AAIpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAiC9D,MAAM,WAAW,YAAY;IAC5B,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,6GAA6G;IAC7G,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,sDAAsD;IACtD,WAAW,EAAE,MAAM,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9D,yEAAuE;IACvE,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACvC,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,oCAAoC;IACpC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;IACrE,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACnC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAClC,uFAAuF;IACvF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,iBAAiB;IAQ5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IARtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IAErD,YACkB,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,IAAI,EAAE,YAAY,EAOnC;IAED,yCAAyC;IACzC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAalF;IAED,iEAA+D;IAC/D,YAAY,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAK/D;IAED,2DAAyD;IACzD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,oEAAkE;IAClE,IAAI,QAAQ,IAAI,OAAO,CAEtB;YAEa,aAAa;YA6Bb,0BAA0B;YA0B1B,iBAAiB;YAUjB,YAAY;IA4B1B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,YAAY;IA0CpB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAczB,mDAAmD;IACnD,OAAO,CAAC,aAAa;CAsBrB","sourcesContent":["/**\n * Auto-generates a terminal tab title from session context after a threshold\n * number of tool calls. Uses a lightweight single-shot LLM call to produce a\n * concise title — the model aims for a configurable soft target (default 60\n * characters, via TabTitleSettings.maxTitleLength) and the result is hard-capped\n * at 300 characters — then sets it via the terminal's OSC 0 escape.\n *\n * Fires at most once per session. Final failures are reported through the\n * optional onError hook while preserving fire-and-forget behavior.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Api, Context, Model } from \"@dreb/ai\";\nimport { completeSimple } from \"@dreb/ai\";\nimport { CONFIG_DIR_NAME, getPackageDir } from \"../config.js\";\nimport { extractUserText, labelMessageEnd, labelToolEnd, RollingContextBuffer } from \"./context-buffer.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { TabTitleSettings } from \"./settings-manager.js\";\nimport { parseAgentFrontmatter, resolveModelForSubagentSpawn } from \"./tools/subagent.js\";\n\nconst DEFAULT_TRIGGER_AFTER = 9;\n// Soft target communicated to the model — titles should aim for this length but\n// may run longer when clarity demands it. Configurable via TabTitleSettings.maxTitleLength.\nconst DEFAULT_TITLE_SOFT_TARGET = 60;\n// Hidden hard cap — a safety limit that titles are truncated to regardless of the\n// soft target. The dashboard has room for long names; the TUI truncates visually.\nconst TITLE_HARD_CAP = 300;\n// Cap on how much of a single user message we feed into the title context.\nconst MAX_USER_TEXT_CHARS = 2000;\nconst TITLE_GENERATION_TIMEOUT_MS = 60_000;\n\nfunction buildTitlePrompt(softTarget: number): string {\n\treturn (\n\t\t\"You are a headless terminal-tab title generator. You are NOT the assistant in the session — \" +\n\t\t\"you will never speak to the user. Your only job is to output a single short title string, nothing else. \" +\n\t\t\"No quotes, no explanation, no preamble. \" +\n\t\t\"The title disambiguates terminal windows for a human at a glance. \" +\n\t\t\"Base the title PRIMARILY on the user's actual request and the concrete actions taken in THIS session. \" +\n\t\t\"Describe what is being DONE (e.g. 'Fix auth bug', 'Plan subagent refactor', 'Review modal'), \" +\n\t\t\"not just label the invocation. \" +\n\t\t\"Branch, repo, and cwd metadata are SECONDARY — use them only to disambiguate when the user's \" +\n\t\t\"request is otherwise ambiguous. Never let a branch name override the user's actual intent: \" +\n\t\t\"if the branch is 'feature/dashboard-foundation' but the user asked to install a Playwright skill, \" +\n\t\t\"the title is about the Playwright skill, not the dashboard. \" +\n\t\t\"Avoid reference-only formats like '#N' or 'mach6-X #N'. \" +\n\t\t\"Do not include 'dreb' — the caller already adds it. \" +\n\t\t`Output ONLY the title text. Aim for about ${softTarget} characters; a little longer is fine if needed for clarity.`\n\t);\n}\n\nexport interface TabTitleDeps {\n\t/** Set the terminal tab title (OSC 0). */\n\tsetTitle: (title: string) => void;\n\t/** Persist the generated title as the session name. Called with the raw title (without \"dreb - \" prefix). */\n\tsetSessionName?: (name: string) => void;\n\t/**\n\t * Get the current session name, if the session is already named. When this returns a\n\t * non-empty string, title generation is skipped — auto-titling only names unnamed\n\t * sessions and must never overwrite an existing (e.g. resumed) session's name.\n\t */\n\tgetSessionName?: () => string | undefined;\n\t/** Get the current session messages (for context). */\n\tgetMessages: () => Array<{ role: string; content?: unknown }>;\n\t/** Get the current model (parent session model — used as fallback). */\n\tgetModel: () => Model<Api> | undefined;\n\t/** Get model registry for API key resolution. */\n\tgetModelRegistry: () => ModelRegistry;\n\t/** Get the parent provider name. */\n\tgetProvider: () => string | undefined;\n\t/**\n\t * Get the user's agentModels settings override for a given agent name, if any.\n\t * Returns a non-empty fallback list when the user has configured an override.\n\t */\n\tgetAgentModelsOverride?: (agentName: string) => string[] | undefined;\n\t/** Current git branch name, or null/undefined if unavailable. */\n\tgetBranch?: () => string | null | undefined;\n\t/** Repository name (e.g., dirname of cwd), or undefined. */\n\tgetRepo?: () => string | undefined;\n\t/** Current working directory, or undefined. */\n\tgetCwd?: () => string | undefined;\n\t/** Report final title-generation failures without breaking fire-and-forget callers. */\n\tonError?: (err: unknown) => void;\n}\n\nexport class TabTitleGenerator {\n\tprivate toolCallCount = 0;\n\tprivate fired = false;\n\tprivate readonly threshold: number;\n\tprivate readonly softTarget: number;\n\tprivate readonly contextBuffer: RollingContextBuffer;\n\n\tconstructor(\n\t\tprivate readonly settings: TabTitleSettings | undefined,\n\t\tprivate readonly deps: TabTitleDeps,\n\t) {\n\t\tthis.threshold = settings?.triggerAfter ?? DEFAULT_TRIGGER_AFTER;\n\t\t// Soft target is configurable but always clamped to the hidden hard cap.\n\t\tconst configured = settings?.maxTitleLength ?? DEFAULT_TITLE_SOFT_TARGET;\n\t\tthis.softTarget = Math.max(1, Math.min(configured, TITLE_HARD_CAP));\n\t\tthis.contextBuffer = new RollingContextBuffer({ maxEntries: 30, maxChars: 6000 });\n\t}\n\n\t/** Whether this generator is enabled. */\n\tget enabled(): boolean {\n\t\treturn this.settings?.enabled !== false;\n\t}\n\n\t/**\n\t * Called on each tool_execution_end event. Captures context from the event,\n\t * increments the counter, and fires title generation when threshold is reached.\n\t */\n\tonToolEnd(event?: { toolName?: string; isError?: boolean; result?: unknown }): void {\n\t\tif (event?.toolName) {\n\t\t\tthis.contextBuffer.append(labelToolEnd(event as { toolName: string; isError?: boolean; result?: unknown }));\n\t\t}\n\n\t\tif (this.fired || !this.enabled) return;\n\n\t\tthis.toolCallCount++;\n\t\tif (this.toolCallCount >= this.threshold) {\n\t\t\tthis.fired = true;\n\t\t\t// Fire-and-forget — report final failures without throwing into the event stream.\n\t\t\tthis.generateTitle().catch((err) => this.reportError(err));\n\t\t}\n\t}\n\n\t/** Called on message_end events — captures labeled context. */\n\tonMessageEnd(message: { role: string; content?: unknown }): void {\n\t\tif (this.fired) return; // no need to accumulate after fired\n\t\tfor (const entry of labelMessageEnd(message)) {\n\t\t\tthis.contextBuffer.append(entry);\n\t\t}\n\t}\n\n\t/** Exposed for testing — the current tool call count. */\n\tget currentCount(): number {\n\t\treturn this.toolCallCount;\n\t}\n\n\t/** Exposed for testing — whether the title has been generated. */\n\tget hasFired(): boolean {\n\t\treturn this.fired;\n\t}\n\n\tprivate async generateTitle(): Promise<void> {\n\t\t// Skip entirely if the session already has a name (e.g. resumed session).\n\t\t// This guards the race where a name is set between generator construction and firing.\n\t\tif (this.deps.getSessionName?.()) return;\n\n\t\t// Single timeout bounds the entire pipeline (model probing + API key + LLM call)\n\t\tconst signal = AbortSignal.timeout(TITLE_GENERATION_TIMEOUT_MS);\n\n\t\tconst model = await this.resolveModel(signal);\n\t\tif (!model) return;\n\n\t\tconst userContext = this.buildContext();\n\t\tif (!userContext) return;\n\n\t\tconst context: Context = {\n\t\t\tsystemPrompt: buildTitlePrompt(this.softTarget),\n\t\t\tmessages: [{ role: \"user\", content: userContext, timestamp: Date.now() }],\n\t\t};\n\n\t\tconst response = await this.completeWithParentFallback(model, context, signal);\n\t\tconst title = this.sanitizeTitle(response);\n\t\tif (title) {\n\t\t\t// Re-check: a name may have landed during the async LLM call.\n\t\t\tif (this.deps.getSessionName?.()) return;\n\t\t\tthis.deps.setTitle(`dreb - ${title}`);\n\t\t\tthis.deps.setSessionName?.(title);\n\t\t}\n\t}\n\n\tprivate async completeWithParentFallback(\n\t\tmodel: Model<Api>,\n\t\tcontext: Context,\n\t\tsignal: AbortSignal,\n\t): Promise<unknown> {\n\t\tconst primaryErrorPrefix = `Tab title generation failed with model ${this.formatModel(model)}`;\n\t\ttry {\n\t\t\treturn await this.completeWithModel(model, context, signal);\n\t\t} catch (primaryErr) {\n\t\t\tconst parentModel = this.deps.getModel();\n\t\t\tif (!parentModel || this.isSameModel(model, parentModel)) {\n\t\t\t\tthrow new Error(`${primaryErrorPrefix}: ${this.formatError(primaryErr)}`, { cause: primaryErr });\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn await this.completeWithModel(parentModel, context, signal);\n\t\t\t} catch (parentErr) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${primaryErrorPrefix}: ${this.formatError(primaryErr)}. ` +\n\t\t\t\t\t\t`Parent fallback ${this.formatModel(parentModel)} also failed: ${this.formatError(parentErr)}`,\n\t\t\t\t\t{ cause: parentErr },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async completeWithModel(model: Model<Api>, context: Context, signal: AbortSignal): Promise<unknown> {\n\t\tconst registry = this.deps.getModelRegistry();\n\t\tconst apiKey = await registry.getApiKey(model);\n\t\treturn completeSimple(model, context, {\n\t\t\tapiKey,\n\t\t\tmaxRetryDelayMs: 0,\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async resolveModel(signal?: AbortSignal): Promise<Model<Api> | undefined> {\n\t\t// Try to get the Explore agent's model fallback list\n\t\tconst exploreModels = this.getExploreAgentModels();\n\t\tconst parentModel = this.deps.getModel();\n\t\tconst parentProvider = this.deps.getProvider();\n\t\tconst registry = this.deps.getModelRegistry();\n\n\t\tif (exploreModels) {\n\t\t\tconst resolution = await resolveModelForSubagentSpawn(\n\t\t\t\texploreModels,\n\t\t\t\tparentProvider,\n\t\t\t\tregistry,\n\t\t\t\tparentModel?.id,\n\t\t\t\tsignal,\n\t\t\t\t\"[tab-title]\",\n\t\t\t);\n\t\t\tif (resolution.ok) {\n\t\t\t\tconst found = resolution.provider\n\t\t\t\t\t? registry.find(resolution.provider, resolution.modelId)\n\t\t\t\t\t: registry.getAvailable().find((m) => m.id === resolution.modelId);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to parent session model\n\t\treturn parentModel;\n\t}\n\n\tprivate isSameModel(a: Model<Api>, b: Model<Api>): boolean {\n\t\treturn a.id === b.id && a.provider === b.provider;\n\t}\n\n\tprivate formatModel(model: Model<Api>): string {\n\t\treturn `${model.provider}/${model.id}`;\n\t}\n\n\tprivate formatError(err: unknown): string {\n\t\tif (err instanceof Error) return err.message;\n\t\tif (typeof err === \"string\") return err;\n\t\treturn String(err);\n\t}\n\n\tprivate reportError(err: unknown): void {\n\t\tconst reportedError =\n\t\t\terr instanceof Error\n\t\t\t\t? err\n\t\t\t\t: new Error(`Tab title generation failed: ${this.formatError(err)}`, { cause: err });\n\t\tthis.deps.onError?.(reportedError);\n\t}\n\n\tprivate getExploreAgentModels(): string | string[] | undefined {\n\t\t// Honor the user's agentModels settings override first. The settings key must\n\t\t// match the agent name exactly (\"Explore\", as declared in explore.md frontmatter).\n\t\tconst override = this.deps.getAgentModelsOverride?.(\"Explore\");\n\t\tif (override && override.length > 0) {\n\t\t\treturn override;\n\t\t}\n\n\t\t// Resolution order mirrors discoverAgentTypes: user override > project > package.\n\t\t// First match with a valid model wins.\n\t\tconst candidates = [\n\t\t\tjoin(homedir(), CONFIG_DIR_NAME, \"agents\", \"explore.md\"),\n\t\t\tjoin(process.cwd(), \".dreb\", \"agents\", \"explore.md\"),\n\t\t\tjoin(getPackageDir(), \"agents\", \"explore.md\"),\n\t\t];\n\n\t\tfor (const agentFile of candidates) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(agentFile, \"utf-8\");\n\t\t\t\tconst parsed = parseAgentFrontmatter(content);\n\t\t\t\tif (parsed.ok && parsed.config.model) {\n\t\t\t\t\treturn parsed.config.model;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate buildContext(): string | undefined {\n\t\tconst lines: string[] = [];\n\n\t\t// Primary signal: the user's actual request(s) from the current session.\n\t\t// Pin the FIRST user message (session-defining intent) and append the LATEST\n\t\t// user message when it differs, to catch mid-session pivots. Sourced from the\n\t\t// live message list rather than the rolling buffer so early intent is never\n\t\t// evicted by later tool activity.\n\t\tconst userIntent = this.collectUserIntent();\n\t\tif (userIntent.length > 0) {\n\t\t\tlines.push(\"User request(s):\");\n\t\t\tfor (const req of userIntent) {\n\t\t\t\tlines.push(`- ${req}`);\n\t\t\t}\n\t\t}\n\n\t\t// Secondary signal: concrete current-session actions (assistant text + tools).\n\t\tconst bufferContent = this.contextBuffer.build();\n\t\tif (bufferContent) {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Session activity:\");\n\t\t\tlines.push(bufferContent);\n\t\t}\n\n\t\t// Tertiary signal: metadata, for disambiguation only.\n\t\tconst branch = this.deps.getBranch?.();\n\t\tconst repo = this.deps.getRepo?.();\n\t\tconst cwd = this.deps.getCwd?.();\n\t\tconst metadata: string[] = [];\n\t\tif (branch) metadata.push(`Branch: ${branch}`);\n\t\tif (repo) metadata.push(`Repo: ${repo}`);\n\t\tif (cwd) metadata.push(`Cwd: ${cwd}`);\n\t\tif (metadata.length > 0) {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Context metadata (secondary — disambiguation only):\");\n\t\t\tlines.push(...metadata);\n\t\t}\n\n\t\tif (lines.length === 0) return undefined;\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Collect the user's intent-bearing requests from the current session's messages.\n\t * Returns the first user message, plus the latest user message when it differs.\n\t */\n\tprivate collectUserIntent(): string[] {\n\t\tconst messages = this.deps.getMessages?.() ?? [];\n\t\tconst userTexts: string[] = [];\n\t\tfor (const message of messages) {\n\t\t\tconst text = extractUserText(message);\n\t\t\tif (text) userTexts.push(text.slice(0, MAX_USER_TEXT_CHARS));\n\t\t}\n\t\tif (userTexts.length === 0) return [];\n\n\t\tconst first = userTexts[0];\n\t\tconst last = userTexts[userTexts.length - 1];\n\t\treturn first === last ? [first] : [first, last];\n\t}\n\n\t/** Clean up LLM response to a usable tab title. */\n\tprivate sanitizeTitle(response: unknown): string | undefined {\n\t\tif (!response || typeof response !== \"object\") return undefined;\n\n\t\tconst msg = response as { content?: Array<{ type: string; text?: string }> };\n\t\tif (!msg.content || !Array.isArray(msg.content)) return undefined;\n\n\t\tconst textPart = msg.content.find((c) => c.type === \"text\");\n\t\tif (!textPart?.text) return undefined;\n\n\t\tlet title = textPart.text.trim();\n\t\t// Strip surrounding quotes if present\n\t\tif ((title.startsWith('\"') && title.endsWith('\"')) || (title.startsWith(\"'\") && title.endsWith(\"'\"))) {\n\t\t\ttitle = title.slice(1, -1).trim();\n\t\t}\n\t\t// Remove newlines\n\t\ttitle = title.replace(/[\\r\\n]+/g, \" \").trim();\n\t\t// Truncate to the hidden hard cap (safety limit; the soft target is a prompt hint)\n\t\tif (title.length > TITLE_HARD_CAP) {\n\t\t\ttitle = title.slice(0, TITLE_HARD_CAP);\n\t\t}\n\t\treturn title || undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"tab-title.d.ts","sourceRoot":"","sources":["../../src/core/tab-title.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,GAAG,EAAW,KAAK,EAAE,MAAM,UAAU,CAAC;AAIpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAiC9D,MAAM,WAAW,YAAY;IAC5B,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,6GAA6G;IAC7G,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,sDAAsD;IACtD,WAAW,EAAE,MAAM,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9D,yEAAuE;IACvE,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACvC,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,oCAAoC;IACpC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,SAAS,CAAC;IACrE,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACnC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAClC,uFAAuF;IACvF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,iBAAiB;IAQ5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IARtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IAErD,YACkB,QAAQ,EAAE,gBAAgB,GAAG,SAAS,EACtC,IAAI,EAAE,YAAY,EAOnC;IAED,yCAAyC;IACzC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAalF;IAED,iEAA+D;IAC/D,YAAY,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAK/D;IAED,2DAAyD;IACzD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,oEAAkE;IAClE,IAAI,QAAQ,IAAI,OAAO,CAEtB;YAEa,aAAa;YA6Bb,0BAA0B;YA0B1B,iBAAiB;YAUjB,YAAY;IAwC1B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,YAAY;IA0CpB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAczB,mDAAmD;IACnD,OAAO,CAAC,aAAa;CAsBrB","sourcesContent":["/**\n * Auto-generates a terminal tab title from session context after a threshold\n * number of tool calls. Uses a lightweight single-shot LLM call to produce a\n * concise title — the model aims for a configurable soft target (default 60\n * characters, via TabTitleSettings.maxTitleLength) and the result is hard-capped\n * at 300 characters — then sets it via the terminal's OSC 0 escape.\n *\n * Fires at most once per session. Final failures are reported through the\n * optional onError hook while preserving fire-and-forget behavior.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Api, Context, Model } from \"@dreb/ai\";\nimport { completeSimple } from \"@dreb/ai\";\nimport { CONFIG_DIR_NAME, getPackageDir } from \"../config.js\";\nimport { extractUserText, labelMessageEnd, labelToolEnd, RollingContextBuffer } from \"./context-buffer.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { TabTitleSettings } from \"./settings-manager.js\";\nimport { parseAgentFrontmatter, resolveModelForSubagentSpawn } from \"./tools/subagent.js\";\n\nconst DEFAULT_TRIGGER_AFTER = 9;\n// Soft target communicated to the model — titles should aim for this length but\n// may run longer when clarity demands it. Configurable via TabTitleSettings.maxTitleLength.\nconst DEFAULT_TITLE_SOFT_TARGET = 60;\n// Hidden hard cap — a safety limit that titles are truncated to regardless of the\n// soft target. The dashboard has room for long names; the TUI truncates visually.\nconst TITLE_HARD_CAP = 300;\n// Cap on how much of a single user message we feed into the title context.\nconst MAX_USER_TEXT_CHARS = 2000;\nconst TITLE_GENERATION_TIMEOUT_MS = 60_000;\n\nfunction buildTitlePrompt(softTarget: number): string {\n\treturn (\n\t\t\"You are a headless terminal-tab title generator. You are NOT the assistant in the session — \" +\n\t\t\"you will never speak to the user. Your only job is to output a single short title string, nothing else. \" +\n\t\t\"No quotes, no explanation, no preamble. \" +\n\t\t\"The title disambiguates terminal windows for a human at a glance. \" +\n\t\t\"Base the title PRIMARILY on the user's actual request and the concrete actions taken in THIS session. \" +\n\t\t\"Describe what is being DONE (e.g. 'Fix auth bug', 'Plan subagent refactor', 'Review modal'), \" +\n\t\t\"not just label the invocation. \" +\n\t\t\"Branch, repo, and cwd metadata are SECONDARY — use them only to disambiguate when the user's \" +\n\t\t\"request is otherwise ambiguous. Never let a branch name override the user's actual intent: \" +\n\t\t\"if the branch is 'feature/dashboard-foundation' but the user asked to install a Playwright skill, \" +\n\t\t\"the title is about the Playwright skill, not the dashboard. \" +\n\t\t\"Avoid reference-only formats like '#N' or 'mach6-X #N'. \" +\n\t\t\"Do not include 'dreb' — the caller already adds it. \" +\n\t\t`Output ONLY the title text. Aim for about ${softTarget} characters; a little longer is fine if needed for clarity.`\n\t);\n}\n\nexport interface TabTitleDeps {\n\t/** Set the terminal tab title (OSC 0). */\n\tsetTitle: (title: string) => void;\n\t/** Persist the generated title as the session name. Called with the raw title (without \"dreb - \" prefix). */\n\tsetSessionName?: (name: string) => void;\n\t/**\n\t * Get the current session name, if the session is already named. When this returns a\n\t * non-empty string, title generation is skipped — auto-titling only names unnamed\n\t * sessions and must never overwrite an existing (e.g. resumed) session's name.\n\t */\n\tgetSessionName?: () => string | undefined;\n\t/** Get the current session messages (for context). */\n\tgetMessages: () => Array<{ role: string; content?: unknown }>;\n\t/** Get the current model (parent session model — used as fallback). */\n\tgetModel: () => Model<Api> | undefined;\n\t/** Get model registry for API key resolution. */\n\tgetModelRegistry: () => ModelRegistry;\n\t/** Get the parent provider name. */\n\tgetProvider: () => string | undefined;\n\t/**\n\t * Get the user's agentModels settings override for a given agent name, if any.\n\t * Returns a non-empty fallback list when the user has configured an override.\n\t */\n\tgetAgentModelsOverride?: (agentName: string) => string[] | undefined;\n\t/** Current git branch name, or null/undefined if unavailable. */\n\tgetBranch?: () => string | null | undefined;\n\t/** Repository name (e.g., dirname of cwd), or undefined. */\n\tgetRepo?: () => string | undefined;\n\t/** Current working directory, or undefined. */\n\tgetCwd?: () => string | undefined;\n\t/** Report final title-generation failures without breaking fire-and-forget callers. */\n\tonError?: (err: unknown) => void;\n}\n\nexport class TabTitleGenerator {\n\tprivate toolCallCount = 0;\n\tprivate fired = false;\n\tprivate readonly threshold: number;\n\tprivate readonly softTarget: number;\n\tprivate readonly contextBuffer: RollingContextBuffer;\n\n\tconstructor(\n\t\tprivate readonly settings: TabTitleSettings | undefined,\n\t\tprivate readonly deps: TabTitleDeps,\n\t) {\n\t\tthis.threshold = settings?.triggerAfter ?? DEFAULT_TRIGGER_AFTER;\n\t\t// Soft target is configurable but always clamped to the hidden hard cap.\n\t\tconst configured = settings?.maxTitleLength ?? DEFAULT_TITLE_SOFT_TARGET;\n\t\tthis.softTarget = Math.max(1, Math.min(configured, TITLE_HARD_CAP));\n\t\tthis.contextBuffer = new RollingContextBuffer({ maxEntries: 30, maxChars: 6000 });\n\t}\n\n\t/** Whether this generator is enabled. */\n\tget enabled(): boolean {\n\t\treturn this.settings?.enabled !== false;\n\t}\n\n\t/**\n\t * Called on each tool_execution_end event. Captures context from the event,\n\t * increments the counter, and fires title generation when threshold is reached.\n\t */\n\tonToolEnd(event?: { toolName?: string; isError?: boolean; result?: unknown }): void {\n\t\tif (event?.toolName) {\n\t\t\tthis.contextBuffer.append(labelToolEnd(event as { toolName: string; isError?: boolean; result?: unknown }));\n\t\t}\n\n\t\tif (this.fired || !this.enabled) return;\n\n\t\tthis.toolCallCount++;\n\t\tif (this.toolCallCount >= this.threshold) {\n\t\t\tthis.fired = true;\n\t\t\t// Fire-and-forget — report final failures without throwing into the event stream.\n\t\t\tthis.generateTitle().catch((err) => this.reportError(err));\n\t\t}\n\t}\n\n\t/** Called on message_end events — captures labeled context. */\n\tonMessageEnd(message: { role: string; content?: unknown }): void {\n\t\tif (this.fired) return; // no need to accumulate after fired\n\t\tfor (const entry of labelMessageEnd(message)) {\n\t\t\tthis.contextBuffer.append(entry);\n\t\t}\n\t}\n\n\t/** Exposed for testing — the current tool call count. */\n\tget currentCount(): number {\n\t\treturn this.toolCallCount;\n\t}\n\n\t/** Exposed for testing — whether the title has been generated. */\n\tget hasFired(): boolean {\n\t\treturn this.fired;\n\t}\n\n\tprivate async generateTitle(): Promise<void> {\n\t\t// Skip entirely if the session already has a name (e.g. resumed session).\n\t\t// This guards the race where a name is set between generator construction and firing.\n\t\tif (this.deps.getSessionName?.()) return;\n\n\t\t// Single timeout bounds the entire pipeline (model probing + API key + LLM call)\n\t\tconst signal = AbortSignal.timeout(TITLE_GENERATION_TIMEOUT_MS);\n\n\t\tconst model = await this.resolveModel(signal);\n\t\tif (!model) return;\n\n\t\tconst userContext = this.buildContext();\n\t\tif (!userContext) return;\n\n\t\tconst context: Context = {\n\t\t\tsystemPrompt: buildTitlePrompt(this.softTarget),\n\t\t\tmessages: [{ role: \"user\", content: userContext, timestamp: Date.now() }],\n\t\t};\n\n\t\tconst response = await this.completeWithParentFallback(model, context, signal);\n\t\tconst title = this.sanitizeTitle(response);\n\t\tif (title) {\n\t\t\t// Re-check: a name may have landed during the async LLM call.\n\t\t\tif (this.deps.getSessionName?.()) return;\n\t\t\tthis.deps.setTitle(`dreb - ${title}`);\n\t\t\tthis.deps.setSessionName?.(title);\n\t\t}\n\t}\n\n\tprivate async completeWithParentFallback(\n\t\tmodel: Model<Api>,\n\t\tcontext: Context,\n\t\tsignal: AbortSignal,\n\t): Promise<unknown> {\n\t\tconst primaryErrorPrefix = `Tab title generation failed with model ${this.formatModel(model)}`;\n\t\ttry {\n\t\t\treturn await this.completeWithModel(model, context, signal);\n\t\t} catch (primaryErr) {\n\t\t\tconst parentModel = this.deps.getModel();\n\t\t\tif (!parentModel || this.isSameModel(model, parentModel)) {\n\t\t\t\tthrow new Error(`${primaryErrorPrefix}: ${this.formatError(primaryErr)}`, { cause: primaryErr });\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn await this.completeWithModel(parentModel, context, signal);\n\t\t\t} catch (parentErr) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${primaryErrorPrefix}: ${this.formatError(primaryErr)}. ` +\n\t\t\t\t\t\t`Parent fallback ${this.formatModel(parentModel)} also failed: ${this.formatError(parentErr)}`,\n\t\t\t\t\t{ cause: parentErr },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async completeWithModel(model: Model<Api>, context: Context, signal: AbortSignal): Promise<unknown> {\n\t\tconst registry = this.deps.getModelRegistry();\n\t\tconst apiKey = await registry.getApiKey(model);\n\t\treturn completeSimple(model, context, {\n\t\t\tapiKey,\n\t\t\tmaxRetryDelayMs: 0,\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async resolveModel(signal?: AbortSignal): Promise<Model<Api> | undefined> {\n\t\tconst parentModel = this.deps.getModel();\n\t\tconst parentProvider = this.deps.getProvider();\n\t\tconst registry = this.deps.getModelRegistry();\n\n\t\t// A dedicated exact model bypasses Explore-agent routing. Dashboard/RPC writes\n\t\t// validate availability; a stale hand-edited value falls back to the parent.\n\t\tconst configuredModel = this.settings?.model;\n\t\tif (configuredModel) {\n\t\t\tconst slash = configuredModel.indexOf(\"/\");\n\t\t\tif (slash > 0 && slash < configuredModel.length - 1) {\n\t\t\t\tconst found = registry.find(configuredModel.slice(0, slash), configuredModel.slice(slash + 1));\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t\treturn parentModel;\n\t\t}\n\n\t\t// Without a dedicated model, preserve the Explore agent fallback route.\n\t\tconst exploreModels = this.getExploreAgentModels();\n\t\tif (exploreModels) {\n\t\t\tconst resolution = await resolveModelForSubagentSpawn(\n\t\t\t\texploreModels,\n\t\t\t\tparentProvider,\n\t\t\t\tregistry,\n\t\t\t\tparentModel?.id,\n\t\t\t\tsignal,\n\t\t\t\t\"[tab-title]\",\n\t\t\t);\n\t\t\tif (resolution.ok) {\n\t\t\t\tconst found = resolution.provider\n\t\t\t\t\t? registry.find(resolution.provider, resolution.modelId)\n\t\t\t\t\t: registry.getAvailable().find((m) => m.id === resolution.modelId);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to parent session model\n\t\treturn parentModel;\n\t}\n\n\tprivate isSameModel(a: Model<Api>, b: Model<Api>): boolean {\n\t\treturn a.id === b.id && a.provider === b.provider;\n\t}\n\n\tprivate formatModel(model: Model<Api>): string {\n\t\treturn `${model.provider}/${model.id}`;\n\t}\n\n\tprivate formatError(err: unknown): string {\n\t\tif (err instanceof Error) return err.message;\n\t\tif (typeof err === \"string\") return err;\n\t\treturn String(err);\n\t}\n\n\tprivate reportError(err: unknown): void {\n\t\tconst reportedError =\n\t\t\terr instanceof Error\n\t\t\t\t? err\n\t\t\t\t: new Error(`Tab title generation failed: ${this.formatError(err)}`, { cause: err });\n\t\tthis.deps.onError?.(reportedError);\n\t}\n\n\tprivate getExploreAgentModels(): string | string[] | undefined {\n\t\t// Honor the user's agentModels settings override first. The settings key must\n\t\t// match the agent name exactly (\"Explore\", as declared in explore.md frontmatter).\n\t\tconst override = this.deps.getAgentModelsOverride?.(\"Explore\");\n\t\tif (override && override.length > 0) {\n\t\t\treturn override;\n\t\t}\n\n\t\t// Resolution order mirrors discoverAgentTypes: user override > project > package.\n\t\t// First match with a valid model wins.\n\t\tconst candidates = [\n\t\t\tjoin(homedir(), CONFIG_DIR_NAME, \"agents\", \"explore.md\"),\n\t\t\tjoin(process.cwd(), \".dreb\", \"agents\", \"explore.md\"),\n\t\t\tjoin(getPackageDir(), \"agents\", \"explore.md\"),\n\t\t];\n\n\t\tfor (const agentFile of candidates) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(agentFile, \"utf-8\");\n\t\t\t\tconst parsed = parseAgentFrontmatter(content);\n\t\t\t\tif (parsed.ok && parsed.config.model) {\n\t\t\t\t\treturn parsed.config.model;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate buildContext(): string | undefined {\n\t\tconst lines: string[] = [];\n\n\t\t// Primary signal: the user's actual request(s) from the current session.\n\t\t// Pin the FIRST user message (session-defining intent) and append the LATEST\n\t\t// user message when it differs, to catch mid-session pivots. Sourced from the\n\t\t// live message list rather than the rolling buffer so early intent is never\n\t\t// evicted by later tool activity.\n\t\tconst userIntent = this.collectUserIntent();\n\t\tif (userIntent.length > 0) {\n\t\t\tlines.push(\"User request(s):\");\n\t\t\tfor (const req of userIntent) {\n\t\t\t\tlines.push(`- ${req}`);\n\t\t\t}\n\t\t}\n\n\t\t// Secondary signal: concrete current-session actions (assistant text + tools).\n\t\tconst bufferContent = this.contextBuffer.build();\n\t\tif (bufferContent) {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Session activity:\");\n\t\t\tlines.push(bufferContent);\n\t\t}\n\n\t\t// Tertiary signal: metadata, for disambiguation only.\n\t\tconst branch = this.deps.getBranch?.();\n\t\tconst repo = this.deps.getRepo?.();\n\t\tconst cwd = this.deps.getCwd?.();\n\t\tconst metadata: string[] = [];\n\t\tif (branch) metadata.push(`Branch: ${branch}`);\n\t\tif (repo) metadata.push(`Repo: ${repo}`);\n\t\tif (cwd) metadata.push(`Cwd: ${cwd}`);\n\t\tif (metadata.length > 0) {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"Context metadata (secondary — disambiguation only):\");\n\t\t\tlines.push(...metadata);\n\t\t}\n\n\t\tif (lines.length === 0) return undefined;\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\t/**\n\t * Collect the user's intent-bearing requests from the current session's messages.\n\t * Returns the first user message, plus the latest user message when it differs.\n\t */\n\tprivate collectUserIntent(): string[] {\n\t\tconst messages = this.deps.getMessages?.() ?? [];\n\t\tconst userTexts: string[] = [];\n\t\tfor (const message of messages) {\n\t\t\tconst text = extractUserText(message);\n\t\t\tif (text) userTexts.push(text.slice(0, MAX_USER_TEXT_CHARS));\n\t\t}\n\t\tif (userTexts.length === 0) return [];\n\n\t\tconst first = userTexts[0];\n\t\tconst last = userTexts[userTexts.length - 1];\n\t\treturn first === last ? [first] : [first, last];\n\t}\n\n\t/** Clean up LLM response to a usable tab title. */\n\tprivate sanitizeTitle(response: unknown): string | undefined {\n\t\tif (!response || typeof response !== \"object\") return undefined;\n\n\t\tconst msg = response as { content?: Array<{ type: string; text?: string }> };\n\t\tif (!msg.content || !Array.isArray(msg.content)) return undefined;\n\n\t\tconst textPart = msg.content.find((c) => c.type === \"text\");\n\t\tif (!textPart?.text) return undefined;\n\n\t\tlet title = textPart.text.trim();\n\t\t// Strip surrounding quotes if present\n\t\tif ((title.startsWith('\"') && title.endsWith('\"')) || (title.startsWith(\"'\") && title.endsWith(\"'\"))) {\n\t\t\ttitle = title.slice(1, -1).trim();\n\t\t}\n\t\t// Remove newlines\n\t\ttitle = title.replace(/[\\r\\n]+/g, \" \").trim();\n\t\t// Truncate to the hidden hard cap (safety limit; the soft target is a prompt hint)\n\t\tif (title.length > TITLE_HARD_CAP) {\n\t\t\ttitle = title.slice(0, TITLE_HARD_CAP);\n\t\t}\n\t\treturn title || undefined;\n\t}\n}\n"]}
@@ -151,11 +151,23 @@ export class TabTitleGenerator {
151
151
  });
152
152
  }
153
153
  async resolveModel(signal) {
154
- // Try to get the Explore agent's model fallback list
155
- const exploreModels = this.getExploreAgentModels();
156
154
  const parentModel = this.deps.getModel();
157
155
  const parentProvider = this.deps.getProvider();
158
156
  const registry = this.deps.getModelRegistry();
157
+ // A dedicated exact model bypasses Explore-agent routing. Dashboard/RPC writes
158
+ // validate availability; a stale hand-edited value falls back to the parent.
159
+ const configuredModel = this.settings?.model;
160
+ if (configuredModel) {
161
+ const slash = configuredModel.indexOf("/");
162
+ if (slash > 0 && slash < configuredModel.length - 1) {
163
+ const found = registry.find(configuredModel.slice(0, slash), configuredModel.slice(slash + 1));
164
+ if (found)
165
+ return found;
166
+ }
167
+ return parentModel;
168
+ }
169
+ // Without a dedicated model, preserve the Explore agent fallback route.
170
+ const exploreModels = this.getExploreAgentModels();
159
171
  if (exploreModels) {
160
172
  const resolution = await resolveModelForSubagentSpawn(exploreModels, parentProvider, registry, parentModel?.id, signal, "[tab-title]");
161
173
  if (resolution.ok) {