@mastra/code-sdk 1.12.0-alpha.5 → 1.12.0-alpha.7

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":"tool-availability.js","names":[],"sources":["../../src/agents/tool-availability.ts"],"sourcesContent":["import { WORKSPACE_TOOLS } from '@mastra/core/workspace';\nimport type { WorkspaceToolHookContext, WorkspaceToolsConfig } from '@mastra/core/workspace';\nimport { MC_TOOLS, TOOL_NAME_OVERRIDES } from '../tool-names.js';\nimport { getLocalPlansRelativeDir, isPlanFilePath } from '../utils/plans.js';\n\nconst PLAN_MODE_WRITE_TOOL_NAMES = new Set<string>([\n WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE,\n WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE,\n]);\n\nfunction getRequestContextValue(requestContext: unknown, key: string): unknown {\n if (!requestContext) return undefined;\n if (typeof (requestContext as { get?: unknown }).get === 'function') {\n return (requestContext as { get: (key: string) => unknown }).get(key);\n }\n return (requestContext as Record<string, unknown>)[key];\n}\n\n/**\n * Subset of the real `HarnessRequestContext` shape (see\n * packages/core/src/harness/types.ts). The mode is a string property\n * (`session.modeId`) and live state is read via `session.state.get()`.\n */\ninterface PlanModeGuardHarness {\n session?: {\n modeId?: unknown;\n state?: { get?: () => unknown };\n };\n}\n\nfunction getHarnessContext(context: unknown): PlanModeGuardHarness | undefined {\n const requestContext = (context as { requestContext?: unknown } | undefined)?.requestContext;\n const harness = getRequestContextValue(requestContext, 'harness');\n return harness && typeof harness === 'object' ? (harness as PlanModeGuardHarness) : undefined;\n}\n\nfunction getHarnessState(harness: PlanModeGuardHarness | undefined): Record<string, unknown> | undefined {\n const state = harness?.session?.state?.get?.();\n return state && typeof state === 'object' ? (state as Record<string, unknown>) : undefined;\n}\n\nfunction getHarnessModeId(harness: PlanModeGuardHarness | undefined): string | undefined {\n const modeId = harness?.session?.modeId ?? getHarnessState(harness)?.modeId;\n return typeof modeId === 'string' ? modeId : undefined;\n}\n\nfunction getHarnessProjectPath(harness: PlanModeGuardHarness | undefined): string | undefined {\n const projectPath = getHarnessState(harness)?.projectPath;\n return typeof projectPath === 'string' ? projectPath : undefined;\n}\n\nfunction getHarnessFactoryProjectId(harness: PlanModeGuardHarness | undefined): string | undefined {\n const factoryProjectId = getHarnessState(harness)?.factoryProjectId;\n return typeof factoryProjectId === 'string' ? factoryProjectId : undefined;\n}\n\nfunction getToolInputPath(input: unknown): string | undefined {\n const toolPath = (input as { path?: unknown } | undefined)?.path;\n return typeof toolPath === 'string' ? toolPath : undefined;\n}\n\nexport function guardPlanModePlanFileWrites({ workspaceToolName, input, context }: WorkspaceToolHookContext) {\n if (!PLAN_MODE_WRITE_TOOL_NAMES.has(workspaceToolName)) return;\n\n const harness = getHarnessContext(context);\n if (getHarnessModeId(harness) !== 'plan') return;\n\n const factoryProjectId = getHarnessFactoryProjectId(harness);\n const planOptions = { factoryProjectId };\n const planDirHint = `${getLocalPlansRelativeDir(planOptions)}/`;\n const projectPath = getHarnessProjectPath(harness);\n const inputPath = getToolInputPath(input);\n if (!projectPath || !inputPath) {\n return {\n proceed: false as const,\n output: `Plan mode can only write plan files inside ${planDirHint}.`,\n };\n }\n\n // Plan mode may write any `.md` file directly inside the configured plan directory,\n // but nothing else in the project.\n if (isPlanFilePath(projectPath, inputPath, planOptions)) return;\n\n return {\n proceed: false as const,\n output: `Plan mode can only write plan files inside ${planDirHint}. Refusing to edit ${inputPath}.`,\n };\n}\n\nconst BACKGROUND_TOOL_CONFIG = { enabled: true, defaultDisposition: 'foreground' } as const;\n\nexport function createMastraCodeWorkspaceTools(backgroundToolsEnabled = false): WorkspaceToolsConfig {\n const background = backgroundToolsEnabled ? BACKGROUND_TOOL_CONFIG : undefined;\n return {\n ...TOOL_NAME_OVERRIDES,\n // Quiet mode shows this description in place of the raw command.\n [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND],\n requireDescription: true,\n },\n [WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.GREP]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.GREP],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.LSP.LSP_INSPECT]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.LSP.LSP_INSPECT],\n ...(background ? { background } : {}),\n },\n hooks: {\n beforeToolCall: guardPlanModePlanFileWrites,\n },\n };\n}\n\n/** Default foreground-only configuration for consumers without Mastra Code settings. */\nexport const MASTRACODE_WORKSPACE_TOOLS = createMastraCodeWorkspaceTools();\n\nexport const PLAN_MODE_AVAILABLE_TOOLS: readonly string[] = [\n // Read-only exploration tools\n MC_TOOLS.VIEW,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n // Plan file writing. Tool hooks enforce that these can only write `.md`\n // files inside the session's configured plan directory while in plan mode.\n MC_TOOLS.WRITE_FILE,\n MC_TOOLS.STRING_REPLACE_LSP,\n // Plan delivery tools\n 'ask_user',\n 'submit_plan',\n // Task tools for plan-stage tracking\n 'task_write',\n 'task_update',\n 'task_complete',\n 'task_check',\n // Notification access\n MC_TOOLS.NOTIFICATION_INBOX,\n // Read-only workflow inspection (no create/run/delete in plan mode).\n 'list-workflows',\n 'get-workflow',\n];\n\nexport const EXPLORE_MODE_AVAILABLE_TOOLS: readonly string[] = [\n MC_TOOLS.VIEW,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n 'ask_user',\n // Read-only workflow inspection (no create/run/delete in fast mode either).\n 'list-workflows',\n 'get-workflow',\n];\n\nexport const GOAL_JUDGE_READONLY_TOOLS: readonly string[] = [\n MC_TOOLS.VIEW,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n];\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool-availability.js","names":[],"sources":["../../src/agents/tool-availability.ts"],"sourcesContent":["import { WORKSPACE_TOOLS } from '@mastra/core/workspace';\nimport type { WorkspaceToolHookContext, WorkspaceToolsConfig } from '@mastra/core/workspace';\nimport { MC_TOOLS, TOOL_NAME_OVERRIDES } from '../tool-names.js';\nimport { getLocalPlansRelativeDir, isPlanFilePath } from '../utils/plans.js';\n\nconst PLAN_MODE_WRITE_TOOL_NAMES = new Set<string>([\n WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE,\n WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE,\n]);\n\nfunction getRequestContextValue(requestContext: unknown, key: string): unknown {\n if (!requestContext) return undefined;\n if (typeof (requestContext as { get?: unknown }).get === 'function') {\n return (requestContext as { get: (key: string) => unknown }).get(key);\n }\n return (requestContext as Record<string, unknown>)[key];\n}\n\n/**\n * Subset of the real `HarnessRequestContext` shape (see\n * packages/core/src/harness/types.ts). The mode is a string property\n * (`session.modeId`) and live state is read via `session.state.get()`.\n */\ninterface PlanModeGuardHarness {\n session?: {\n modeId?: unknown;\n state?: { get?: () => unknown };\n };\n}\n\nfunction getHarnessContext(context: unknown): PlanModeGuardHarness | undefined {\n const requestContext = (context as { requestContext?: unknown } | undefined)?.requestContext;\n const harness = getRequestContextValue(requestContext, 'harness');\n return harness && typeof harness === 'object' ? (harness as PlanModeGuardHarness) : undefined;\n}\n\nfunction getHarnessState(harness: PlanModeGuardHarness | undefined): Record<string, unknown> | undefined {\n const state = harness?.session?.state?.get?.();\n return state && typeof state === 'object' ? (state as Record<string, unknown>) : undefined;\n}\n\nfunction getHarnessModeId(harness: PlanModeGuardHarness | undefined): string | undefined {\n const modeId = harness?.session?.modeId ?? getHarnessState(harness)?.modeId;\n return typeof modeId === 'string' ? modeId : undefined;\n}\n\nfunction getHarnessProjectPath(harness: PlanModeGuardHarness | undefined): string | undefined {\n const projectPath = getHarnessState(harness)?.projectPath;\n return typeof projectPath === 'string' ? projectPath : undefined;\n}\n\nfunction getHarnessFactoryProjectId(harness: PlanModeGuardHarness | undefined): string | undefined {\n const factoryProjectId = getHarnessState(harness)?.factoryProjectId;\n return typeof factoryProjectId === 'string' ? factoryProjectId : undefined;\n}\n\nfunction getToolInputPath(input: unknown): string | undefined {\n const toolPath = (input as { path?: unknown } | undefined)?.path;\n return typeof toolPath === 'string' ? toolPath : undefined;\n}\n\nexport function guardPlanModePlanFileWrites({ workspaceToolName, input, context }: WorkspaceToolHookContext) {\n if (!PLAN_MODE_WRITE_TOOL_NAMES.has(workspaceToolName)) return;\n\n const harness = getHarnessContext(context);\n if (getHarnessModeId(harness) !== 'plan') return;\n\n const factoryProjectId = getHarnessFactoryProjectId(harness);\n const planOptions = { factoryProjectId };\n const planDirHint = `${getLocalPlansRelativeDir(planOptions)}/`;\n const projectPath = getHarnessProjectPath(harness);\n const inputPath = getToolInputPath(input);\n if (!projectPath || !inputPath) {\n return {\n proceed: false as const,\n output: `Plan mode can only write plan files inside ${planDirHint}.`,\n };\n }\n\n // Plan mode may write any `.md` file directly inside the configured plan directory,\n // but nothing else in the project.\n if (isPlanFilePath(projectPath, inputPath, planOptions)) return;\n\n return {\n proceed: false as const,\n output: `Plan mode can only write plan files inside ${planDirHint}. Refusing to edit ${inputPath}.`,\n };\n}\n\nconst BACKGROUND_TOOL_CONFIG = { enabled: true, defaultDisposition: 'foreground' } as const;\n\nexport function createMastraCodeWorkspaceTools(backgroundToolsEnabled = false): WorkspaceToolsConfig {\n const background = backgroundToolsEnabled ? BACKGROUND_TOOL_CONFIG : undefined;\n return {\n ...TOOL_NAME_OVERRIDES,\n // The TUI shows this description in place of the raw command.\n [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND],\n requireDescription: true,\n },\n [WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.FILESYSTEM.GREP]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.FILESYSTEM.GREP],\n ...(background ? { background } : {}),\n },\n [WORKSPACE_TOOLS.LSP.LSP_INSPECT]: {\n ...TOOL_NAME_OVERRIDES[WORKSPACE_TOOLS.LSP.LSP_INSPECT],\n ...(background ? { background } : {}),\n },\n hooks: {\n beforeToolCall: guardPlanModePlanFileWrites,\n },\n };\n}\n\n/** Default foreground-only configuration for consumers without Mastra Code settings. */\nexport const MASTRACODE_WORKSPACE_TOOLS = createMastraCodeWorkspaceTools();\n\nexport const PLAN_MODE_AVAILABLE_TOOLS: readonly string[] = [\n // Read-only exploration tools\n MC_TOOLS.VIEW,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n // Plan file writing. Tool hooks enforce that these can only write `.md`\n // files inside the session's configured plan directory while in plan mode.\n MC_TOOLS.WRITE_FILE,\n MC_TOOLS.STRING_REPLACE_LSP,\n // Plan delivery tools\n 'ask_user',\n 'submit_plan',\n // Task tools for plan-stage tracking\n 'task_write',\n 'task_update',\n 'task_complete',\n 'task_check',\n // Notification access\n MC_TOOLS.NOTIFICATION_INBOX,\n // Read-only workflow inspection (no create/run/delete in plan mode).\n 'list-workflows',\n 'get-workflow',\n];\n\nexport const EXPLORE_MODE_AVAILABLE_TOOLS: readonly string[] = [\n MC_TOOLS.VIEW,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n 'ask_user',\n // Read-only workflow inspection (no create/run/delete in fast mode either).\n 'list-workflows',\n 'get-workflow',\n];\n\nexport const GOAL_JUDGE_READONLY_TOOLS: readonly string[] = [\n MC_TOOLS.VIEW,\n MC_TOOLS.SEARCH_CONTENT,\n MC_TOOLS.FIND_FILES,\n MC_TOOLS.FILE_STAT,\n MC_TOOLS.LSP_INSPECT,\n];\n"],"mappings":"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"}
@@ -185,7 +185,6 @@ export interface GlobalSettings {
185
185
  version: number;
186
186
  modePackId: string | null;
187
187
  omPackId: string | null;
188
- quietModePreferenceSelected: boolean;
189
188
  };
190
189
  models: {
191
190
  /**
@@ -275,10 +274,8 @@ export interface GlobalSettings {
275
274
  thinkingLevel: ThinkingLevelSetting;
276
275
  /** Whether native subagents are enabled for Mastra Code TUI sessions. */
277
276
  subagentsEnabled: boolean;
278
- /** When true, components like subagent output collapse to compact summaries on completion. */
279
- quietMode: boolean;
280
- /** Maximum quiet-mode detail preview lines for compact tool calls. Set to 0 to hide previews. */
281
- quietModeMaxToolPreviewLines: number;
277
+ /** Maximum detail preview lines shown under compact tool calls (0-8). Set to 0 to hide previews. */
278
+ previewLines: number;
282
279
  /**
283
280
  * Default web search/extract provider. `auto` picks the first configured
284
281
  * provider key (Tavily, then Parallel). An explicit provider is only
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/onboarding/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/onboarding/settings.ts"],"names":[],"mappings":"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"}
@@ -99,8 +99,7 @@ const DEFAULTS = {
99
99
  skippedAt: null,
100
100
  version: 0,
101
101
  modePackId: null,
102
- omPackId: null,
103
- quietModePreferenceSelected: true
102
+ omPackId: null
104
103
  },
105
104
  models: {
106
105
  activeModelPackId: null,
@@ -128,8 +127,7 @@ const DEFAULTS = {
128
127
  theme: "auto",
129
128
  thinkingLevel: "off",
130
129
  subagentsEnabled: false,
131
- quietMode: false,
132
- quietModeMaxToolPreviewLines: 2,
130
+ previewLines: 2,
133
131
  webSearchProvider: "auto"
134
132
  },
135
133
  storage: { ...STORAGE_DEFAULTS },
@@ -175,7 +173,7 @@ const WEB_SEARCH_PROVIDER_VALUES = [
175
173
  "tavily",
176
174
  "parallel"
177
175
  ];
178
- const QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX = 8;
176
+ const PREVIEW_LINES_MAX = 8;
179
177
  const loadedSignalSettings = /* @__PURE__ */ new WeakMap();
180
178
  function cloneSignalSettings(signals) {
181
179
  return { ...signals };
@@ -248,9 +246,16 @@ function pruneRemovedAccountPreferences(settings, removedAccountIds) {
248
246
  }
249
247
  settings.models.packAccountPreferences = next;
250
248
  }
251
- function parseQuietModeMaxToolPreviewLines(value) {
252
- const rawValue = typeof value === "number" && Number.isFinite(value) ? value : DEFAULTS.preferences.quietModeMaxToolPreviewLines;
253
- return Math.min(QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX, Math.max(0, Math.floor(rawValue)));
249
+ function isFiniteNumber(value) {
250
+ return typeof value === "number" && Number.isFinite(value);
251
+ }
252
+ /**
253
+ * Resolves the preview line limit. `previewLines` wins when valid; otherwise the legacy
254
+ * `quietModeMaxToolPreviewLines` key (still written by older Mastra Code versions) is used.
255
+ */
256
+ function parsePreviewLines(raw) {
257
+ const value = isFiniteNumber(raw.previewLines) ? raw.previewLines : isFiniteNumber(raw.quietModeMaxToolPreviewLines) ? raw.quietModeMaxToolPreviewLines : DEFAULTS.preferences.previewLines;
258
+ return Math.min(PREVIEW_LINES_MAX, Math.max(0, Math.floor(value)));
254
259
  }
255
260
  function parsePreferences(rawPreferences) {
256
261
  const raw = rawPreferences && typeof rawPreferences === "object" ? rawPreferences : {};
@@ -259,7 +264,7 @@ function parsePreferences(rawPreferences) {
259
264
  ...raw,
260
265
  thinkingLevel: parseThinkingLevel(raw.thinkingLevel),
261
266
  subagentsEnabled: typeof raw.subagentsEnabled === "boolean" ? raw.subagentsEnabled : DEFAULTS.preferences.subagentsEnabled,
262
- quietModeMaxToolPreviewLines: parseQuietModeMaxToolPreviewLines(raw.quietModeMaxToolPreviewLines),
267
+ previewLines: parsePreviewLines(raw),
263
268
  webSearchProvider: parseWebSearchProvider(raw.webSearchProvider)
264
269
  };
265
270
  }
@@ -306,19 +311,6 @@ function parseMcpDiscoverySettings(rawMcp) {
306
311
  codexGlobal: typeof raw.codexGlobal === "boolean" ? raw.codexGlobal : DEFAULTS.mcp.codexGlobal
307
312
  };
308
313
  }
309
- function hasQuietModePreferenceSelected(rawOnboarding) {
310
- return Boolean(rawOnboarding && typeof rawOnboarding === "object" && Object.prototype.hasOwnProperty.call(rawOnboarding, "quietModePreferenceSelected"));
311
- }
312
- function applyQuietModePreferenceRollout(settings, rawOnboarding) {
313
- if (hasQuietModePreferenceSelected(rawOnboarding)) return;
314
- settings.onboarding.quietModePreferenceSelected = settings.preferences.quietMode === true;
315
- }
316
- function getNewInstallDefaults() {
317
- const settings = structuredClone(DEFAULTS);
318
- settings.preferences.quietMode = true;
319
- settings.onboarding.quietModePreferenceSelected = true;
320
- return settings;
321
- }
322
314
  function getSettingsPath() {
323
315
  return join(getAppDataDir(), "settings.json");
324
316
  }
@@ -572,7 +564,6 @@ function migrateFromAuth(settingsPath) {
572
564
  mcp: parseMcpDiscoverySettings(raw.mcp),
573
565
  observability: parseObservabilitySettings(raw.observability)
574
566
  };
575
- applyQuietModePreferenceRollout(settings, raw.onboarding);
576
567
  } catch {
577
568
  settings = structuredClone(DEFAULTS);
578
569
  }
@@ -624,7 +615,7 @@ function migrateLegacyVariedPack(settings) {
624
615
  }
625
616
  function loadSettings(filePath = getSettingsPath()) {
626
617
  migrateFromAuth(filePath);
627
- if (!existsSync(filePath)) return rememberLoadedSettings(getNewInstallDefaults());
618
+ if (!existsSync(filePath)) return rememberLoadedSettings(structuredClone(DEFAULTS));
628
619
  try {
629
620
  const raw = JSON.parse(readFileSync(filePath, "utf-8"));
630
621
  const rawCustomPacks = Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [];
@@ -674,10 +665,7 @@ function loadSettings(filePath = getSettingsPath()) {
674
665
  observability: parseObservabilitySettings(raw.observability)
675
666
  };
676
667
  let settingsChanged = false;
677
- if (!hasQuietModePreferenceSelected(raw.onboarding)) {
678
- applyQuietModePreferenceRollout(settings, raw.onboarding);
679
- settingsChanged = true;
680
- }
668
+ if (!isFiniteNumber(raw.preferences?.previewLines)) settingsChanged = true;
681
669
  if (raw.models?.omModelId && !settings.models.omModelOverride) {
682
670
  settings.models.omModelOverride = raw.models.omModelId;
683
671
  settingsChanged = true;
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","names":["resolveThinkingDefault"],"sources":["../../src/onboarding/settings.ts"],"sourcesContent":["/**\n * Persistent global settings stored in the app data directory as settings.json.\n * This file persists onboarding state AND user preferences (model choices, yolo, etc.)\n * so they carry across threads and restarts.\n */\n\nimport { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { OMModel } from '@mastra/core/agent-controller';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { AuthStorage, PROVIDER_DEFAULT_MODELS } from '../auth/storage.js';\nimport {\n ANTHROPIC_PREFIX,\n normalizeAnthropicModelId,\n OPENAI_PREFIX,\n remapOpenAIModelForCodexOAuth,\n stripMastraGatewayPrefix,\n} from '../providers/model-ids.js';\nimport { buildCodexStagehandFetch, createCodexMiddleware } from '../providers/openai-codex.js';\nimport {\n isThinkingLevelSetting,\n resolveDefaultThinkingLevel as resolveThinkingDefault,\n THINKING_LEVEL_VALUES,\n} from '../thinking.js';\nimport type { ThinkingLevelSetting, ThinkingLevelSource } from '../thinking.js';\nexport { isThinkingLevelSetting, THINKING_LEVEL_VALUES } from '../thinking.js';\nexport type { ThinkingLevelSetting, ThinkingLevelSource } from '../thinking.js';\nimport { getAppDataDir } from '../utils/project.js';\nimport { DEFAULT_STT_PROVIDER, resolveSTTModel } from '../voice/stt-registry.js';\nimport { pruneUnknownModePackFallbacks, pruneUnknownPackAccountPreferences } from './packs.js';\n\n/** A saved custom pack — user-defined model selections for each mode. */\nexport interface CustomPack {\n name: string;\n models: Record<string, string>;\n createdAt: string;\n}\n\n/** A saved custom provider for OpenAI-compatible endpoints. */\nexport interface CustomProviderSetting {\n name: string;\n url: string;\n apiKey?: string;\n models: string[];\n}\n\n/** Storage backend type. */\nexport type StorageBackend = 'libsql' | 'pg';\n\n/** Experimental agent implementation used by MastraCode. */\nexport type ExperimentalAgent = 'durable' | 'evented';\n\nexport class ExperimentalAgentSettingsError extends Error {\n readonly value: unknown;\n\n constructor(value: unknown, settingsPath?: string) {\n super(\n `Invalid \"experimentalAgent\" setting${settingsPath ? ` in ${settingsPath}` : ''}: ${JSON.stringify(value)}. ` +\n `Remove the \"experimentalAgent\" key or set it to \"durable\", \"evented\", or null.`,\n );\n this.name = 'ExperimentalAgentSettingsError';\n this.value = value;\n }\n}\n\n/** LibSQL-specific storage settings. */\nexport interface LibSQLStorageSettings {\n url?: string;\n authToken?: string;\n}\n\n/** PostgreSQL-specific storage settings. */\nexport interface PgStorageSettings {\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n schemaName?: string;\n disableInit?: boolean;\n skipDefaultIndexes?: boolean;\n}\n\n/** Storage configuration persisted in global settings. */\nexport interface StorageSettings {\n /** Which backend to use. Default: 'libsql'. */\n backend: StorageBackend;\n /** LibSQL-specific config (used when backend is 'libsql'). */\n libsql: LibSQLStorageSettings;\n /** PostgreSQL-specific config (used when backend is 'pg'). */\n pg: PgStorageSettings;\n}\n\n/** Gateway provider key used in AuthStorage. */\nexport const MASTRA_GATEWAY_PROVIDER = 'mastra-gateway';\n\n/** Default gateway URL. */\nexport const MASTRA_GATEWAY_DEFAULT_URL = 'https://gateway-api.mastra.ai';\n\n/** @deprecated Renamed to {@link MASTRA_GATEWAY_PROVIDER}. */\nexport const MEMORY_GATEWAY_PROVIDER = MASTRA_GATEWAY_PROVIDER;\n\n/** @deprecated Renamed to {@link MASTRA_GATEWAY_DEFAULT_URL}. */\nexport const MEMORY_GATEWAY_DEFAULT_URL = MASTRA_GATEWAY_DEFAULT_URL;\n\n/** Preferred model-independent web search/extract provider. */\nexport type WebSearchProviderSetting = 'auto' | 'tavily' | 'parallel';\n\n/** Browser provider type. */\nexport type BrowserProvider = 'stagehand' | 'agent-browser';\n\n/** Direct TUI `!` shell passthrough mode. */\nexport type ShellPassthroughSettingsMode = 'default' | 'path' | 'login';\n\n/** Direct TUI `!` shell command language. */\nexport type ShellPassthroughSettingsFamily = 'posix' | 'cmd' | 'powershell';\n\n/** Direct TUI `!` shell passthrough configuration. */\nexport interface ShellPassthroughSettings {\n mode?: ShellPassthroughSettingsMode | string;\n executable?: string;\n family?: ShellPassthroughSettingsFamily | string;\n}\n\n/** STT engine: on-device macOS recognizer or a cloud provider. */\nexport type VoiceEngine = 'macos-native' | 'cloud';\n\n/** Voice (hold-space dictation) configuration persisted in global settings. */\nexport interface VoiceSettings {\n /** Whether hold-space voice input is enabled. */\n enabled: boolean;\n /** Which STT engine to use. Defaults to macOS native on darwin, else cloud. */\n engine: VoiceEngine;\n /** Cloud provider id (matches an STT registry entry). Cloud engine only. */\n provider: string;\n /** Cloud model id; defaults to the provider's first registry model. */\n model?: string;\n}\n\n/** Stagehand environment type. */\nexport type StagehandEnv = 'LOCAL' | 'BROWSERBASE';\n\n/**\n * Browser viewport: explicit dimensions, or `'window'` to follow the real\n * browser window instead of emulating a fixed size.\n */\nexport type BrowserViewport = { width: number; height: number } | 'window';\n\n/** Named viewport sizes offered by `/browser set viewport`. */\nexport const VIEWPORT_PRESETS = {\n desktop: { width: 1280, height: 720 },\n 'desktop-hd': { width: 1920, height: 1080 },\n laptop: { width: 1440, height: 900 },\n tablet: { width: 768, height: 1024 },\n mobile: { width: 390, height: 844 },\n} as const satisfies Record<string, { width: number; height: number }>;\n\nexport type ViewportPreset = keyof typeof VIEWPORT_PRESETS;\n\n/**\n * Largest viewport dimension accepted. Guards against typos that would launch a\n * browser far larger than any display.\n */\nconst MAX_VIEWPORT_DIMENSION = 10000;\n\nfunction isValidDimension(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 && value <= MAX_VIEWPORT_DIMENSION;\n}\n\n/**\n * Parse a `WIDTHxHEIGHT` string (e.g. `1280x720`), a preset name, or `window`.\n * Returns undefined when the input is not a usable viewport.\n */\nexport function parseViewportInput(input: string): BrowserViewport | undefined {\n const value = input.trim().toLowerCase();\n if (!value) return undefined;\n if (value === 'window') return 'window';\n if (value in VIEWPORT_PRESETS) return { ...VIEWPORT_PRESETS[value as ViewportPreset] };\n\n const match = /^(\\d+)\\s*[x×]\\s*(\\d+)$/.exec(value);\n if (!match) return undefined;\n const width = Number(match[1]);\n const height = Number(match[2]);\n if (!isValidDimension(width) || !isValidDimension(height)) return undefined;\n return { width, height };\n}\n\n/** Stagehand-specific browser settings. */\nexport interface StagehandSettings {\n env: StagehandEnv;\n apiKey?: string;\n projectId?: string;\n /**\n * Model Stagehand uses for its AI operations, as `provider/model`\n * (for example `anthropic/claude-sonnet-4-5`). Stagehand resolves the\n * provider's API key from the environment (`ANTHROPIC_API_KEY`,\n * `OPENAI_API_KEY`, and so on). Defaults to Stagehand's own default.\n */\n model?: string;\n /** Whether to preserve the user data directory after the browser closes. */\n preserveUserDataDir?: boolean;\n}\n\n/** AgentBrowser-specific browser settings. */\nexport interface AgentBrowserSettings {\n /** Path to a Playwright storage state file (JSON) containing cookies and localStorage. */\n storageState?: string;\n}\n\n/** Browser configuration persisted in global settings. */\nexport interface BrowserSettings {\n /** Whether browser automation is enabled. */\n enabled: boolean;\n /** Which browser provider to use. */\n provider: BrowserProvider;\n /** Whether to run headless (no visible browser window). */\n headless: boolean;\n /**\n * Browser viewport dimensions, or `'window'` to disable viewport emulation so\n * the page follows the real browser window.\n */\n viewport?: BrowserViewport;\n /** CDP URL for connecting to an existing browser. */\n cdpUrl?: string;\n /** Path to a Chrome/Chromium user data directory (profile). */\n profile?: string;\n /** Path to the browser executable to use. */\n executablePath?: string;\n /** Browser scope — 'shared' (all threads share one browser) or 'thread' (each thread gets its own). */\n scope?: 'shared' | 'thread';\n /** Stagehand-specific settings. */\n stagehand?: StagehandSettings;\n /** AgentBrowser-specific settings. */\n agentBrowser?: AgentBrowserSettings;\n}\n\nexport type PackAccountPreferences = Record<string, Record<string, string>>;\n\nexport interface GlobalSettings {\n // Onboarding tracking\n onboarding: {\n completedAt: string | null;\n skippedAt: string | null;\n version: number;\n modePackId: string | null;\n omPackId: string | null;\n quietModePreferenceSelected: boolean;\n };\n // Global model preferences (applied to new threads)\n models: {\n /**\n * Active model pack ID. Built-in packs use their id directly (\"anthropic\",\n * \"openai\"). Custom packs use \"custom:<name>\".\n * When set, models are resolved from the pack at startup so pack updates\n * (e.g. new model versions) apply automatically. Built-in packs may layer\n * explicit modePackOverrides over these defaults.\n */\n activeModelPackId: string | null;\n /** Per-mode overrides keyed by built-in pack ID. */\n modePackOverrides: Record<string, Record<string, string>>;\n /**\n * Fallback pack per pack ID (packId → packId; builtin ids and\n * \"custom:<name>\" both allowed). When every account serving a pack's\n * provider is exhausted — or the provider is persistently down — the turn\n * hops to the fallback pack's model. Chains are allowed; a cycle is\n * capped at one revisit per cascade, then the error surfaces.\n */\n packFallbacks: Record<string, string>;\n /** Preferred OAuth account by pack ID and resolved model ID. */\n packAccountPreferences: Record<string, Record<string, string>>;\n /** Explicit per-mode defaults — used when no activeModelPackId is set. */\n modeDefaults: Record<string, string>;\n /**\n * Per-mode reasoning-effort defaults (e.g. { build: \"high\", plan: \"xhigh\" }).\n * Resolved at request time; falls back to `preferences.thinkingLevel` for\n * modes without an entry. Overridden per-session via /think or the session\n * settings panel.\n */\n modeThinkingDefaults: Record<string, ThinkingLevelSetting>;\n /**\n * Active OM pack ID (e.g. \"gemini\", \"anthropic\", \"custom\").\n * When set, the OM model is resolved from the pack at startup so pack\n * updates (e.g. new model versions) apply automatically.\n * Cleared when the user manually overrides via /om (falls back to omModelOverride).\n */\n activeOmPackId: string | null;\n /**\n * Shared OM model override — used for both observer and reflector when a\n * role-specific override is not set. Kept for back-compat with older settings\n * files and set by onboarding when the user picks a custom OM pack.\n */\n omModelOverride: string | null;\n /**\n * Explicit Observer model override — takes precedence over `omModelOverride`\n * when set. Written by `/om` when the observer model is changed independently.\n */\n observerModelOverride: string | null;\n /** Persisted Observer model intent. Missing values use legacy-field compatibility. */\n observerModelSelection: OMModel | null;\n /**\n * Explicit Reflector model override — takes precedence over `omModelOverride`\n * when set. Written by `/om` when the reflector model is changed independently.\n */\n reflectorModelOverride: string | null;\n /** Persisted Reflector model intent. Missing values use legacy-field compatibility. */\n reflectorModelSelection: OMModel | null;\n /** Default OM observation threshold used for new threads unless overridden per-thread. */\n omObservationThreshold: number | null;\n /** Default OM reflection threshold used for new threads unless overridden per-thread. */\n omReflectionThreshold: number | null;\n /**\n * Whether observations and reflections use the terse caveman-style instruction.\n * `null` means inherit the built-in default (currently `false` — caveman is\n * opt-in via `/om` settings). Used as the default for new threads unless\n * overridden per-thread.\n */\n omCavemanObservations: boolean | null;\n /**\n * Whether Observational Memory forwards image/file attachment parts to the\n * Observer LLM. `null` ⇒ inherit built-in default ('auto'). 'auto' checks\n * model capabilities; true/false forces the setting.\n */\n omObserveAttachments: 'auto' | boolean | null;\n /** Per-agent-type subagent model overrides (e.g. { explore: \"openai/gpt-5.1-codex-mini\" }) */\n subagentModels: Record<string, string>;\n /** Default judge model for /goal. */\n goalJudgeModel: string | null;\n /** Default max attempts for /goal. */\n goalMaxTurns: number | null;\n };\n // Global behavior preferences\n preferences: {\n yolo: boolean | null;\n theme: 'auto' | 'dark' | 'light';\n /** Default reasoning effort level used for all threads/models unless overridden in-session. */\n thinkingLevel: ThinkingLevelSetting;\n /** Whether native subagents are enabled for Mastra Code TUI sessions. */\n subagentsEnabled: boolean;\n /** When true, components like subagent output collapse to compact summaries on completion. */\n quietMode: boolean;\n /** Maximum quiet-mode detail preview lines for compact tool calls. Set to 0 to hide previews. */\n quietModeMaxToolPreviewLines: number;\n /**\n * Default web search/extract provider. `auto` picks the first configured\n * provider key (Tavily, then Parallel). An explicit provider is only\n * honored while its API key is configured.\n */\n webSearchProvider: WebSearchProviderSetting;\n };\n // Storage backend configuration\n storage: StorageSettings;\n // User-created custom model packs\n customModelPacks: CustomPack[];\n // User-created custom providers with custom models\n customProviders: CustomProviderSetting[];\n // Model usage counts for ranking in the selector\n modelUseCounts: Record<string, number>;\n // Version the user dismissed the update prompt for (skip until they manually update past this)\n updateDismissedVersion: string | null;\n // Mastra gateway configuration\n memoryGateway: { baseUrl?: string };\n // LSP configuration forwarded to the workspace. Disabled unless the user\n // opts in with `true` or an LSPConfig object.\n lsp?: boolean | LSPConfig;\n // Browser automation configuration\n browser: BrowserSettings;\n // Direct TUI `!` shell passthrough configuration\n shellPassthrough: ShellPassthroughSettings;\n // Hold-space voice input configuration\n voice: VoiceSettings;\n // Raw persisted experimental agent value. Resolve through resolveExperimentalAgent() before use.\n experimentalAgent: unknown;\n // Internal load diagnostic retained on clones until the user repairs the setting.\n _experimentalAgentSettingsPath?: string;\n // Native background execution for eligible Mastra Code tools\n backgroundTools: BackgroundToolSettings;\n // Signal routing configuration\n signals: SignalSettings;\n // Read-only discovery of MCP servers configured by other coding agents\n mcp: McpDiscoverySettings;\n // Cloud observability configuration (per-resource project IDs; tokens stored in auth.json)\n observability: ObservabilitySettings;\n}\n\nexport interface McpDiscoverySettings {\n /** Reuse top-level MCP servers from ~/.claude.json. */\n claudeCodeGlobal: boolean;\n /** Reuse MCP servers from $CODEX_HOME/config.toml or ~/.codex/config.toml. */\n codexGlobal: boolean;\n}\n\nexport interface BackgroundToolSettings {\n /** Allow eligible Mastra Code tools to accept per-call background execution overrides. */\n enabled: boolean;\n}\n\nexport interface SignalSettings {\n /** Opt into local Unix socket PubSub for cross-process signal routing. */\n unixSocketPubSub: boolean;\n /** Experimental: enable GitHub PR subscription signals backed by gitcrawl. */\n experimentalGithubSignals: boolean;\n /** Experimental: enable cross-agent communication (thread ownership advertisement, peer discovery, and agent connection tools). */\n experimentalCrossAgentSignals: boolean;\n /** Experimental: give the agent tools to create and manage `/schedules` schedules on its thread. */\n experimentalScheduleTools: boolean;\n /** Poll interval for GitHub PR subscriptions. */\n githubPollIntervalMs: number;\n}\n\nexport interface ObservabilityResourceConfig {\n /** Cloud project ID for this resource */\n projectId: string;\n /** When this config was created */\n configuredAt: string;\n}\n\nexport interface ObservabilitySettings {\n /** Per-resource cloud project configs, keyed by resourceId */\n resources: Record<string, ObservabilityResourceConfig>;\n /** Whether to store traces locally in DuckDB. Off by default to avoid disk usage. */\n localTracing: boolean;\n}\n\n/** Auth key prefix for observability tokens stored per-resource in auth.json */\nexport const OBSERVABILITY_AUTH_PREFIX = 'observability:';\n\nexport const GITHUB_POLL_INTERVAL_DEFAULT_MS = 300_000;\nexport const GITHUB_POLL_INTERVAL_MIN_MS = 10_000;\nexport const GITHUB_POLL_INTERVAL_MAX_MS = 2_147_483_647;\n\nexport const STORAGE_DEFAULTS: StorageSettings = {\n backend: 'libsql',\n libsql: {},\n pg: {},\n};\n\n/** Default STT engine: on-device macOS recognizer where available, else cloud. */\nexport function defaultVoiceEngine(): VoiceEngine {\n return process.platform === 'darwin' ? 'macos-native' : 'cloud';\n}\n\nconst DEFAULTS: GlobalSettings = {\n onboarding: {\n completedAt: null,\n skippedAt: null,\n version: 0,\n modePackId: null,\n omPackId: null,\n quietModePreferenceSelected: true,\n },\n models: {\n activeModelPackId: null,\n modePackOverrides: {},\n packFallbacks: {},\n packAccountPreferences: {},\n modeDefaults: {},\n modeThinkingDefaults: {},\n activeOmPackId: null,\n omModelOverride: null,\n observerModelOverride: null,\n observerModelSelection: null,\n reflectorModelOverride: null,\n reflectorModelSelection: null,\n omObservationThreshold: null,\n omReflectionThreshold: null,\n omCavemanObservations: null,\n omObserveAttachments: null,\n subagentModels: {},\n goalJudgeModel: null,\n goalMaxTurns: null,\n },\n preferences: {\n yolo: null,\n theme: 'auto',\n thinkingLevel: 'off',\n subagentsEnabled: false,\n quietMode: false,\n quietModeMaxToolPreviewLines: 2,\n webSearchProvider: 'auto',\n },\n storage: { ...STORAGE_DEFAULTS },\n customModelPacks: [],\n customProviders: [],\n modelUseCounts: {},\n updateDismissedVersion: null,\n memoryGateway: {},\n lsp: false,\n browser: {\n enabled: false,\n provider: 'stagehand',\n headless: false,\n viewport: { ...VIEWPORT_PRESETS.desktop },\n stagehand: { env: 'LOCAL' },\n },\n shellPassthrough: { mode: 'default' },\n voice: { enabled: false, engine: defaultVoiceEngine(), provider: DEFAULT_STT_PROVIDER },\n experimentalAgent: null,\n backgroundTools: { enabled: false },\n signals: {\n unixSocketPubSub: false,\n experimentalGithubSignals: false,\n experimentalCrossAgentSignals: false,\n experimentalScheduleTools: false,\n githubPollIntervalMs: GITHUB_POLL_INTERVAL_DEFAULT_MS,\n },\n mcp: { claudeCodeGlobal: false, codexGlobal: false },\n observability: { resources: {}, localTracing: false },\n};\n\nexport const WEB_SEARCH_PROVIDER_VALUES: WebSearchProviderSetting[] = ['auto', 'tavily', 'parallel'];\nconst QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX = 8;\nconst loadedSignalSettings = new WeakMap<GlobalSettings, SignalSettings>();\n\nfunction cloneSignalSettings(signals: SignalSettings): SignalSettings {\n return { ...signals };\n}\n\nfunction rememberLoadedSettings(settings: GlobalSettings): GlobalSettings {\n loadedSignalSettings.set(settings, cloneSignalSettings(settings.signals));\n return settings;\n}\n\nfunction signalSettingsEqual(left: SignalSettings, right: SignalSettings): boolean {\n return (\n left.unixSocketPubSub === right.unixSocketPubSub &&\n left.experimentalGithubSignals === right.experimentalGithubSignals &&\n left.experimentalCrossAgentSignals === right.experimentalCrossAgentSignals &&\n left.experimentalScheduleTools === right.experimentalScheduleTools &&\n left.githubPollIntervalMs === right.githubPollIntervalMs\n );\n}\n\nfunction parseWebSearchProvider(value: unknown): WebSearchProviderSetting {\n return typeof value === 'string' && WEB_SEARCH_PROVIDER_VALUES.includes(value as WebSearchProviderSetting)\n ? (value as WebSearchProviderSetting)\n : DEFAULTS.preferences.webSearchProvider;\n}\n\nfunction parseThinkingLevel(value: unknown): ThinkingLevelSetting {\n return isThinkingLevelSetting(value) ? value : DEFAULTS.preferences.thinkingLevel;\n}\n\nfunction parseModeThinkingDefaults(value: unknown): Record<string, ThinkingLevelSetting> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, ThinkingLevelSetting> = {};\n for (const [mode, level] of Object.entries(value as Record<string, unknown>)) {\n if (isThinkingLevelSetting(level)) {\n result[mode] = level;\n }\n }\n return result;\n}\n\nfunction parseModePackOverrides(value: unknown): Record<string, Record<string, string>> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, Record<string, string>> = {};\n for (const [packId, overrides] of Object.entries(value as Record<string, unknown>)) {\n if (!overrides || typeof overrides !== 'object') continue;\n const parsedOverrides = Object.fromEntries(\n Object.entries(overrides as Record<string, unknown>).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].length > 0,\n ),\n );\n if (Object.keys(parsedOverrides).length > 0) result[packId] = parsedOverrides;\n }\n return result;\n}\n\nfunction parsePackFallbacks(value: unknown): Record<string, string> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, string> = {};\n for (const [packId, fallbackId] of Object.entries(value as Record<string, unknown>)) {\n if (typeof fallbackId === 'string' && fallbackId.length > 0) result[packId] = fallbackId;\n }\n return result;\n}\n\n/** Shape-parse + drop entries whose source or target pack no longer exists. */\nfunction loadPackFallbacks(value: unknown, customModelPacks: Array<{ name: string }>): Record<string, string> {\n return pruneUnknownModePackFallbacks(parsePackFallbacks(value), customModelPacks);\n}\n\nfunction parsePackAccountPreferences(value: unknown): Record<string, Record<string, string>> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, Record<string, string>> = {};\n for (const [packId, modelPreferences] of Object.entries(value as Record<string, unknown>)) {\n if (!modelPreferences || typeof modelPreferences !== 'object') continue;\n const parsed = Object.fromEntries(\n Object.entries(modelPreferences as Record<string, unknown>).filter(\n (entry): entry is [string, string] =>\n entry[0].length > 0 && typeof entry[1] === 'string' && entry[1].length > 0,\n ),\n );\n if (Object.keys(parsed).length > 0) result[packId] = parsed;\n }\n return result;\n}\n\nfunction loadPackAccountPreferences(\n value: unknown,\n customModelPacks: CustomPack[],\n modePackOverrides: Record<string, Record<string, string>>,\n): PackAccountPreferences {\n return pruneUnknownPackAccountPreferences(parsePackAccountPreferences(value), customModelPacks, modePackOverrides);\n}\n\n/** Move persisted routing choices when re-authentication changes an account instance id. */\nexport function migrateAccountPreferences(\n settings: GlobalSettings,\n previousAccountId: string,\n nextAccountId: string,\n): void {\n if (previousAccountId === nextAccountId) return;\n for (const modelPreferences of Object.values(settings.models.packAccountPreferences ?? {})) {\n for (const [modelId, accountInstanceId] of Object.entries(modelPreferences)) {\n if (accountInstanceId === previousAccountId) modelPreferences[modelId] = nextAccountId;\n }\n }\n}\n\n/** Remove persisted routing choices that point at deleted OAuth account instances. */\nexport function pruneRemovedAccountPreferences(settings: GlobalSettings, removedAccountIds: Iterable<string>): void {\n const removed = new Set(removedAccountIds);\n if (removed.size === 0) return;\n\n const next: PackAccountPreferences = {};\n for (const [packId, modelPreferences] of Object.entries(settings.models.packAccountPreferences ?? {})) {\n const retained = Object.fromEntries(\n Object.entries(modelPreferences).filter(([, accountInstanceId]) => !removed.has(accountInstanceId)),\n );\n if (Object.keys(retained).length > 0) next[packId] = retained;\n }\n settings.models.packAccountPreferences = next;\n}\n\nfunction parseQuietModeMaxToolPreviewLines(value: unknown): number {\n const rawValue =\n typeof value === 'number' && Number.isFinite(value) ? value : DEFAULTS.preferences.quietModeMaxToolPreviewLines;\n return Math.min(QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX, Math.max(0, Math.floor(rawValue)));\n}\n\nfunction parsePreferences(rawPreferences: unknown): GlobalSettings['preferences'] {\n const raw = rawPreferences && typeof rawPreferences === 'object' ? (rawPreferences as Record<string, unknown>) : {};\n\n return {\n ...DEFAULTS.preferences,\n ...raw,\n thinkingLevel: parseThinkingLevel(raw.thinkingLevel),\n subagentsEnabled:\n typeof raw.subagentsEnabled === 'boolean' ? raw.subagentsEnabled : DEFAULTS.preferences.subagentsEnabled,\n quietModeMaxToolPreviewLines: parseQuietModeMaxToolPreviewLines(raw.quietModeMaxToolPreviewLines),\n webSearchProvider: parseWebSearchProvider(raw.webSearchProvider),\n };\n}\n\nfunction parseGithubPollIntervalMs(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return DEFAULTS.signals.githubPollIntervalMs;\n const intervalMs = Math.floor(value);\n if (intervalMs < GITHUB_POLL_INTERVAL_MIN_MS) return DEFAULTS.signals.githubPollIntervalMs;\n return Math.min(intervalMs, GITHUB_POLL_INTERVAL_MAX_MS);\n}\n\nexport function parseExperimentalAgentSetting(value: unknown, settingsPath?: string): ExperimentalAgent | null {\n if (value === undefined || value === null) return null;\n if (value === 'durable' || value === 'evented') return value;\n throw new ExperimentalAgentSettingsError(value, settingsPath);\n}\n\nfunction loadExperimentalAgentSetting(\n value: unknown,\n settingsPath: string,\n): { selection: unknown; settingsPath?: string } {\n try {\n return { selection: parseExperimentalAgentSetting(value, settingsPath) };\n } catch (error) {\n if (error instanceof ExperimentalAgentSettingsError) {\n return { selection: error.value, settingsPath };\n }\n throw error;\n }\n}\n\nfunction parseBackgroundToolSettings(rawBackgroundTools: unknown): BackgroundToolSettings {\n const raw =\n rawBackgroundTools && typeof rawBackgroundTools === 'object' ? (rawBackgroundTools as Record<string, unknown>) : {};\n return {\n enabled: typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.backgroundTools.enabled,\n };\n}\n\nfunction parseSignalSettings(rawSignals: unknown): SignalSettings {\n const raw = rawSignals && typeof rawSignals === 'object' ? (rawSignals as Record<string, unknown>) : {};\n return {\n unixSocketPubSub:\n typeof raw.unixSocketPubSub === 'boolean' ? raw.unixSocketPubSub : DEFAULTS.signals.unixSocketPubSub,\n experimentalGithubSignals:\n typeof raw.experimentalGithubSignals === 'boolean'\n ? raw.experimentalGithubSignals\n : DEFAULTS.signals.experimentalGithubSignals,\n experimentalCrossAgentSignals:\n typeof raw.experimentalCrossAgentSignals === 'boolean'\n ? raw.experimentalCrossAgentSignals\n : DEFAULTS.signals.experimentalCrossAgentSignals,\n experimentalScheduleTools:\n typeof raw.experimentalScheduleTools === 'boolean'\n ? raw.experimentalScheduleTools\n : DEFAULTS.signals.experimentalScheduleTools,\n githubPollIntervalMs: parseGithubPollIntervalMs(raw.githubPollIntervalMs),\n };\n}\n\nfunction parseMcpDiscoverySettings(rawMcp: unknown): McpDiscoverySettings {\n const raw = rawMcp && typeof rawMcp === 'object' ? (rawMcp as Record<string, unknown>) : {};\n return {\n claudeCodeGlobal: typeof raw.claudeCodeGlobal === 'boolean' ? raw.claudeCodeGlobal : DEFAULTS.mcp.claudeCodeGlobal,\n codexGlobal: typeof raw.codexGlobal === 'boolean' ? raw.codexGlobal : DEFAULTS.mcp.codexGlobal,\n };\n}\n\nfunction hasQuietModePreferenceSelected(rawOnboarding: unknown): boolean {\n return Boolean(\n rawOnboarding &&\n typeof rawOnboarding === 'object' &&\n Object.prototype.hasOwnProperty.call(rawOnboarding, 'quietModePreferenceSelected'),\n );\n}\n\nfunction applyQuietModePreferenceRollout(settings: GlobalSettings, rawOnboarding: unknown): void {\n if (hasQuietModePreferenceSelected(rawOnboarding)) return;\n settings.onboarding.quietModePreferenceSelected = settings.preferences.quietMode === true;\n}\n\nfunction getNewInstallDefaults(): GlobalSettings {\n const settings = structuredClone(DEFAULTS);\n settings.preferences.quietMode = true;\n settings.onboarding.quietModePreferenceSelected = true;\n return settings;\n}\n\nexport function getSettingsPath(): string {\n return join(getAppDataDir(), 'settings.json');\n}\n\nexport function getCustomProviderId(name: string): string {\n const slug = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'provider';\n}\n\nexport function toCustomProviderModelId(providerName: string, modelName: string): string {\n const providerId = getCustomProviderId(providerName);\n const trimmedModelName = modelName.trim();\n const providerPrefix = `${providerId}/`;\n if (trimmedModelName.startsWith(providerPrefix)) {\n return trimmedModelName;\n }\n return `${providerId}/${trimmedModelName}`;\n}\n\n/**\n * The shared gateway catalog namespaces provider keys under their owning\n * gateway id, so a custom provider's models surface in the `/models` catalog\n * as `mastracode/<providerId>/<model>` instead of the canonical\n * `<providerId>/<model>` that model resolution expects. Persisting the\n * gateway-qualified id verbatim breaks lookup later (the provider is parsed\n * as `mastracode`). Strip the prefix before saving — but only when the\n * middle segment matches one of the user's configured custom providers, so\n * legitimate `mastracode/...` gateway-routed ids are left untouched.\n */\nexport function stripMastraCodeCustomProviderPrefix(\n modelId: string,\n customProviders: Array<Pick<CustomProviderSetting, 'name'>>,\n): string {\n const gatewayPrefix = 'mastracode/';\n if (!modelId.startsWith(gatewayPrefix)) return modelId;\n\n const rest = modelId.slice(gatewayPrefix.length);\n const [providerId, ...modelParts] = rest.split('/');\n if (!providerId || modelParts.length === 0 || modelParts.some(part => part.length === 0)) return modelId;\n\n const isCustomProvider = customProviders.some(provider => getCustomProviderId(provider.name) === providerId);\n return isCustomProvider ? rest : modelId;\n}\n\nexport function parseCustomProviders(rawProviders: unknown): CustomProviderSetting[] {\n if (!Array.isArray(rawProviders)) return [];\n\n const parsedProviders: CustomProviderSetting[] = [];\n for (const rawProvider of rawProviders) {\n if (!rawProvider || typeof rawProvider !== 'object') continue;\n\n const candidate = rawProvider as Record<string, unknown>;\n const name = typeof candidate.name === 'string' ? candidate.name.trim() : '';\n const url = typeof candidate.url === 'string' ? candidate.url.trim() : '';\n if (!name || !url) continue;\n\n const providerId = getCustomProviderId(name);\n const models = Array.isArray(candidate.models)\n ? [\n ...new Set(\n candidate.models\n .filter((model): model is string => typeof model === 'string')\n .map(model => model.trim())\n .map(model => {\n const providerPrefix = `${providerId}/`;\n if (model.startsWith(providerPrefix)) {\n return model.slice(providerPrefix.length);\n }\n return model;\n }),\n ),\n ].filter(model => model.length > 0)\n : [];\n\n const apiKey =\n typeof candidate.apiKey === 'string' && candidate.apiKey.trim().length > 0 ? candidate.apiKey.trim() : undefined;\n\n parsedProviders.push({\n name,\n url,\n ...(apiKey ? { apiKey } : {}),\n models,\n });\n }\n\n return parsedProviders;\n}\n\nconst BROWSER_PROVIDERS = new Set<BrowserProvider>(['stagehand', 'agent-browser']);\nconst STAGEHAND_ENVS = new Set<StagehandEnv>(['LOCAL', 'BROWSERBASE']);\n\n/**\n * Normalize a Stagehand model id, which must be provider-qualified.\n *\n * Stagehand reads the segment before the first slash as the provider, so a\n * bare id like `gpt-4.1` is rejected as an unknown provider and a trailing\n * slash leaves an empty model name that only fails once a request is made.\n * Neither is usable, so both are dropped here rather than persisted.\n *\n * The provider name itself is checked where the command is issued, which can\n * name the supported providers in an error; this module is on the startup path\n * and only imports Stagehand lazily.\n *\n * @returns the trimmed model id, or undefined when it is unusable.\n */\nfunction parseStagehandModel(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const model = value.trim();\n const separator = model.indexOf('/');\n if (separator <= 0) return undefined;\n return model.slice(separator + 1).trim() ? model : undefined;\n}\n\n/**\n * Validate a viewport read from settings.json, falling back to the default when\n * it is missing or malformed.\n */\nfunction parseStoredViewport(raw: unknown): BrowserViewport {\n if (raw === 'window') return 'window';\n if (raw && typeof raw === 'object') {\n const { width, height } = raw as Record<string, unknown>;\n if (isValidDimension(width) && isValidDimension(height)) return { width, height };\n }\n return { ...VIEWPORT_PRESETS.desktop };\n}\n\n/**\n * Validate the `lsp` setting from JSON. Accepts both the boolean opt-in/opt-out\n * form and the full LSPConfig object; anything else is treated as unset.\n */\nfunction parseLspSettings(raw: unknown): boolean | LSPConfig | undefined {\n if (typeof raw === 'boolean') return raw;\n if (raw && typeof raw === 'object') return raw as LSPConfig;\n return undefined;\n}\n\n/**\n * Resolve the effective LSP config. LSP is opt-in: `false` and an absent\n * setting both mean disabled, `true` means enabled with defaults.\n */\nexport function resolveLspSetting(lsp: boolean | LSPConfig | undefined): LSPConfig | false {\n if (lsp === true) return {};\n if (!lsp) return false;\n return lsp;\n}\n\n/**\n * Deep-merge and validate browser settings from JSON.\n * Explicitly validates types to handle malformed settings.json gracefully.\n */\nfunction parseBrowserSettings(rawBrowser: unknown): BrowserSettings {\n const raw = rawBrowser && typeof rawBrowser === 'object' ? (rawBrowser as Record<string, unknown>) : {};\n const rawStagehand =\n raw.stagehand && typeof raw.stagehand === 'object' ? (raw.stagehand as Record<string, unknown>) : {};\n const stagehandModel = parseStagehandModel(rawStagehand.model);\n const rawAgentBrowser =\n raw.agentBrowser && typeof raw.agentBrowser === 'object' ? (raw.agentBrowser as Record<string, unknown>) : {};\n\n return {\n enabled: typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.browser.enabled,\n provider:\n typeof raw.provider === 'string' && BROWSER_PROVIDERS.has(raw.provider as BrowserProvider)\n ? (raw.provider as BrowserProvider)\n : DEFAULTS.browser.provider,\n headless: typeof raw.headless === 'boolean' ? raw.headless : DEFAULTS.browser.headless,\n cdpUrl: typeof raw.cdpUrl === 'string' && raw.cdpUrl.trim() ? raw.cdpUrl.trim() : undefined,\n profile: typeof raw.profile === 'string' && raw.profile.trim() ? raw.profile.trim() : undefined,\n executablePath:\n typeof raw.executablePath === 'string' && raw.executablePath.trim() ? raw.executablePath.trim() : undefined,\n viewport: parseStoredViewport(raw.viewport),\n scope: typeof raw.scope === 'string' && (raw.scope === 'shared' || raw.scope === 'thread') ? raw.scope : undefined,\n stagehand: {\n env:\n typeof rawStagehand.env === 'string' && STAGEHAND_ENVS.has(rawStagehand.env as StagehandEnv)\n ? (rawStagehand.env as StagehandEnv)\n : DEFAULTS.browser.stagehand!.env,\n ...(typeof rawStagehand.apiKey === 'string' && rawStagehand.apiKey.trim()\n ? { apiKey: rawStagehand.apiKey.trim() }\n : {}),\n ...(typeof rawStagehand.projectId === 'string' && rawStagehand.projectId.trim()\n ? { projectId: rawStagehand.projectId.trim() }\n : {}),\n ...(stagehandModel ? { model: stagehandModel } : {}),\n ...(typeof rawStagehand.preserveUserDataDir === 'boolean'\n ? { preserveUserDataDir: rawStagehand.preserveUserDataDir }\n : {}),\n },\n agentBrowser:\n typeof rawAgentBrowser.storageState === 'string' && rawAgentBrowser.storageState.trim()\n ? { storageState: rawAgentBrowser.storageState.trim() }\n : undefined,\n };\n}\n\nfunction parseShellPassthroughSettings(rawShellPassthrough: unknown): ShellPassthroughSettings {\n const raw =\n rawShellPassthrough && typeof rawShellPassthrough === 'object'\n ? (rawShellPassthrough as Record<string, unknown>)\n : {};\n const executable = typeof raw.executable === 'string' && raw.executable.trim() ? raw.executable.trim() : undefined;\n const family = typeof raw.family === 'string' && raw.family.trim() ? raw.family.trim() : undefined;\n const mode = typeof raw.mode === 'string' && raw.mode.trim() ? raw.mode.trim() : undefined;\n const defaultMode = executable ? undefined : DEFAULTS.shellPassthrough.mode;\n\n return {\n ...((mode ?? defaultMode) ? { mode: mode ?? defaultMode } : {}),\n ...(executable ? { executable } : {}),\n ...(family ? { family } : {}),\n };\n}\n\nfunction parseVoiceSettings(rawVoice: unknown): VoiceSettings {\n const raw = rawVoice && typeof rawVoice === 'object' ? (rawVoice as Record<string, unknown>) : {};\n const enabled = typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.voice.enabled;\n const engine: VoiceEngine =\n raw.engine === 'macos-native' || raw.engine === 'cloud' ? raw.engine : defaultVoiceEngine();\n // Validate provider/model against the registry, falling back to a usable entry\n // so old `{ enabled }`-only files and unknown values still resolve cleanly.\n const provider = typeof raw.provider === 'string' ? raw.provider : DEFAULTS.voice.provider;\n const model = typeof raw.model === 'string' ? raw.model : undefined;\n const resolved = resolveSTTModel(provider, model);\n return {\n enabled,\n engine,\n provider: resolved.provider,\n model: resolved.model,\n };\n}\n\nconst VALID_PROJECT_ID = /^[a-zA-Z0-9_-]+$/;\n\nfunction parseObservabilitySettings(raw: unknown): ObservabilitySettings {\n if (!raw || typeof raw !== 'object') return { resources: {}, localTracing: false };\n const obj = raw as Record<string, unknown>;\n const localTracing = obj.localTracing === true;\n const rawResources = obj.resources;\n if (!rawResources || typeof rawResources !== 'object') return { resources: {}, localTracing };\n const resources: Record<string, ObservabilityResourceConfig> = {};\n for (const [key, val] of Object.entries(rawResources as Record<string, unknown>)) {\n if (val && typeof val === 'object') {\n const v = val as Record<string, unknown>;\n if (typeof v.projectId === 'string' && VALID_PROJECT_ID.test(v.projectId)) {\n resources[key] = {\n projectId: v.projectId,\n configuredAt: typeof v.configuredAt === 'string' ? v.configuredAt : new Date().toISOString(),\n };\n }\n }\n }\n return { resources, localTracing };\n}\n\n/**\n * One-time migration: move model-related data from auth.json to settings.json.\n * Reads `_modelRanks`, `_modeModelId_*`, `_subagentModelId*` from auth.json,\n * merges them into settings, removes them from auth.json, and writes both files.\n * No-ops if auth.json has no _ prefixed model data.\n */\nfunction migrateFromAuth(settingsPath: string): boolean {\n const authPath = join(getAppDataDir(), 'auth.json');\n if (!existsSync(authPath)) return false;\n\n let authData: Record<string, any>;\n try {\n authData = JSON.parse(readFileSync(authPath, 'utf-8'));\n } catch {\n return false;\n }\n\n const modelKeys = Object.keys(authData).filter(k => k.startsWith('_'));\n if (modelKeys.length === 0) return false;\n\n // Load existing settings (or defaults) and merge auth data into it\n let settings: GlobalSettings;\n if (existsSync(settingsPath)) {\n try {\n const raw = JSON.parse(readFileSync(settingsPath, 'utf-8'));\n const rawCustomPacks: CustomPack[] = Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [];\n const modePackOverrides = parseModePackOverrides(raw.models?.modePackOverrides);\n const experimentalAgentSetting = loadExperimentalAgentSetting(raw.experimentalAgent, settingsPath);\n settings = {\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides,\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\n packFallbacks: loadPackFallbacks(raw.models?.packFallbacks, rawCustomPacks),\n packAccountPreferences: loadPackAccountPreferences(\n raw.models?.packAccountPreferences,\n rawCustomPacks,\n modePackOverrides,\n ),\n },\n preferences: parsePreferences(raw.preferences),\n storage: {\n ...STORAGE_DEFAULTS,\n ...raw.storage,\n libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },\n pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg },\n },\n customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],\n customProviders: parseCustomProviders(raw.customProviders),\n modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === 'object' ? raw.modelUseCounts : {},\n updateDismissedVersion: typeof raw.updateDismissedVersion === 'string' ? raw.updateDismissedVersion : null,\n memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === 'object' ? raw.memoryGateway : {},\n lsp: parseLspSettings(raw.lsp),\n browser: parseBrowserSettings(raw.browser),\n shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),\n voice: parseVoiceSettings(raw.voice),\n experimentalAgent: experimentalAgentSetting.selection,\n _experimentalAgentSettingsPath: experimentalAgentSetting.settingsPath,\n backgroundTools: parseBackgroundToolSettings(raw.backgroundTools),\n signals: parseSignalSettings(raw.signals),\n mcp: parseMcpDiscoverySettings(raw.mcp),\n observability: parseObservabilitySettings(raw.observability),\n };\n applyQuietModePreferenceRollout(settings, raw.onboarding);\n } catch {\n settings = structuredClone(DEFAULTS);\n }\n } else {\n settings = structuredClone(DEFAULTS);\n }\n\n // Migrate model use counts (only if settings doesn't already have them)\n if (authData._modelRanks && typeof authData._modelRanks === 'object') {\n settings.modelUseCounts = { ...authData._modelRanks, ...settings.modelUseCounts };\n }\n\n // Migrate per-mode model defaults (don't overwrite existing settings)\n for (const key of modelKeys) {\n const modeMatch = key.match(/^_modeModelId_(.+)$/);\n if (modeMatch?.[1] && typeof authData[key] === 'string' && !settings.models.modeDefaults[modeMatch[1]]) {\n settings.models.modeDefaults[modeMatch[1]] = authData[key];\n }\n }\n\n // Migrate subagent models (don't overwrite existing settings)\n for (const key of modelKeys) {\n if (key === '_subagentModelId' && typeof authData[key] === 'string' && !settings.models.subagentModels['default']) {\n settings.models.subagentModels['default'] = authData[key];\n }\n const saMatch = key.match(/^_subagentModelId_(.+)$/);\n if (saMatch?.[1] && typeof authData[key] === 'string' && !settings.models.subagentModels[saMatch[1]]) {\n settings.models.subagentModels[saMatch[1]] = authData[key];\n }\n }\n\n // Write migrated settings\n saveSettings(settings, settingsPath);\n\n // Clean up auth.json — remove _ prefixed keys\n for (const key of modelKeys) {\n delete authData[key];\n }\n try {\n writeFileAtomically(authPath, JSON.stringify(authData, null, 2));\n } catch {\n // Non-fatal — settings are saved, auth cleanup can fail\n }\n\n return true;\n}\n\nconst LEGACY_VARIED_MODELS: Record<string, string> = {\n plan: 'openai/gpt-5.4',\n build: 'anthropic/claude-sonnet-4-5',\n fast: 'anthropic/claude-haiku-4-5',\n};\n\nexport function migrateLegacyVariedPack(settings: GlobalSettings): boolean {\n const legacyPackId = 'varied';\n const customPackId = 'custom:varied';\n const hasLegacyReference =\n settings.models.activeModelPackId === legacyPackId || settings.onboarding.modePackId === legacyPackId;\n\n if (!hasLegacyReference) return false;\n\n const existingIdx = settings.customModelPacks.findIndex(p => p.name === 'varied');\n if (existingIdx >= 0) {\n const existing = settings.customModelPacks[existingIdx]!;\n const modelsMatch = Object.entries(LEGACY_VARIED_MODELS).every(([k, v]) => existing.models[k] === v);\n if (!modelsMatch) {\n existing.models = { ...LEGACY_VARIED_MODELS };\n }\n } else {\n settings.customModelPacks.push({\n name: 'varied',\n models: { ...LEGACY_VARIED_MODELS },\n createdAt: new Date().toISOString(),\n });\n }\n\n if (settings.models.activeModelPackId === legacyPackId) {\n settings.models.activeModelPackId = customPackId;\n if (Object.keys(settings.models.modeDefaults).length === 0) {\n settings.models.modeDefaults = { ...LEGACY_VARIED_MODELS };\n }\n }\n\n if (settings.onboarding.modePackId === legacyPackId) {\n settings.onboarding.modePackId = customPackId;\n }\n\n return true;\n}\n\nexport function loadSettings(filePath: string = getSettingsPath()): GlobalSettings {\n // One-time migration: move model data from auth.json into settings.json\n migrateFromAuth(filePath);\n\n if (!existsSync(filePath)) return rememberLoadedSettings(getNewInstallDefaults());\n try {\n const raw = JSON.parse(readFileSync(filePath, 'utf-8'));\n const rawCustomPacks: CustomPack[] = Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [];\n const modePackOverrides = parseModePackOverrides(raw.models?.modePackOverrides);\n const experimentalAgentSetting = loadExperimentalAgentSetting(raw.experimentalAgent, filePath);\n // Spread raw first to preserve unknown top-level keys (forward-compatibility),\n // then overlay with parsed/typed fields so known keys are always correct.\n const settings: GlobalSettings = {\n ...raw,\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides,\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\n packFallbacks: loadPackFallbacks(raw.models?.packFallbacks, rawCustomPacks),\n packAccountPreferences: loadPackAccountPreferences(\n raw.models?.packAccountPreferences,\n rawCustomPacks,\n modePackOverrides,\n ),\n },\n preferences: parsePreferences(raw.preferences),\n storage: {\n ...STORAGE_DEFAULTS,\n ...raw.storage,\n libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },\n pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg },\n },\n customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],\n customProviders: parseCustomProviders(raw.customProviders),\n modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === 'object' ? raw.modelUseCounts : {},\n updateDismissedVersion: typeof raw.updateDismissedVersion === 'string' ? raw.updateDismissedVersion : null,\n memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === 'object' ? raw.memoryGateway : {},\n lsp: parseLspSettings(raw.lsp),\n browser: parseBrowserSettings(raw.browser),\n shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),\n voice: parseVoiceSettings(raw.voice),\n experimentalAgent: experimentalAgentSetting.selection,\n _experimentalAgentSettingsPath: experimentalAgentSetting.settingsPath,\n backgroundTools: parseBackgroundToolSettings(raw.backgroundTools),\n signals: parseSignalSettings(raw.signals),\n mcp: parseMcpDiscoverySettings(raw.mcp),\n observability: parseObservabilitySettings(raw.observability),\n };\n\n // Migrate legacy omModelId → omModelOverride\n let settingsChanged = false;\n if (!hasQuietModePreferenceSelected(raw.onboarding)) {\n applyQuietModePreferenceRollout(settings, raw.onboarding);\n settingsChanged = true;\n }\n if (raw.models?.omModelId && !settings.models.omModelOverride) {\n settings.models.omModelOverride = raw.models.omModelId;\n settingsChanged = true;\n }\n\n if (migrateLegacyVariedPack(settings)) {\n settingsChanged = true;\n }\n\n if (settingsChanged) {\n saveSettings(settings, filePath);\n }\n\n return rememberLoadedSettings(settings);\n } catch {\n return rememberLoadedSettings(structuredClone(DEFAULTS));\n }\n}\n\nexport const THREAD_ACTIVE_MODEL_PACK_ID_KEY = 'activeModelPackId';\nexport const THREAD_FALLBACK_STATUS_KEY = 'mastracodeFallbackStatus';\n\nexport interface ThreadSettings {\n activeModelPackId: string | null;\n modeModelIds: Record<string, string>;\n}\n\nexport function parseThreadSettings(metadata: Record<string, unknown> | undefined): ThreadSettings {\n const modeModelIds: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata ?? {})) {\n const modeMatch = key.match(/^modeModelId_(.+)$/);\n if (modeMatch?.[1] && typeof value === 'string' && value.length > 0) {\n modeModelIds[modeMatch[1]] = value;\n }\n }\n\n const rawPackId = metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY];\n const activeModelPackId = typeof rawPackId === 'string' && rawPackId.length > 0 ? rawPackId : null;\n\n return {\n activeModelPackId,\n modeModelIds,\n };\n}\n\n/**\n * Resolve active model pack id for the current thread.\n *\n * Priority:\n * 1) explicit thread metadata activeModelPackId\n * 2) inferred from thread modeModelId_* values\n * 3) global settings.models.activeModelPackId\n */\nexport function resolveThreadActiveModelPackId(\n settings: GlobalSettings,\n builtinPacks: Array<{ id: string; models: Record<string, string> }>,\n metadata: Record<string, unknown> | undefined,\n): string | null {\n const threadSettings = parseThreadSettings(metadata);\n\n const isKnownPack = (packId: string): boolean => {\n if (packId.startsWith('custom:')) {\n const name = packId.slice('custom:'.length);\n return settings.customModelPacks.some(p => p.name === name);\n }\n return builtinPacks.some(p => p.id === packId);\n };\n\n if (threadSettings.activeModelPackId && isKnownPack(threadSettings.activeModelPackId)) {\n return threadSettings.activeModelPackId;\n }\n\n const allPacks: Array<{ id: string; models: Record<string, string> }> = [\n ...builtinPacks,\n ...settings.customModelPacks.map(p => ({ id: `custom:${p.name}`, models: p.models })),\n ];\n\n for (const pack of allPacks) {\n const packEntries = Object.entries(pack.models);\n const threadEntries = Object.keys(threadSettings.modeModelIds);\n const matches =\n packEntries.length === threadEntries.length &&\n packEntries.every(([modeId, modelId]) => threadSettings.modeModelIds[modeId] === modelId);\n if (matches) return pack.id;\n }\n\n if (settings.models.activeModelPackId && isKnownPack(settings.models.activeModelPackId)) {\n return settings.models.activeModelPackId;\n }\n\n return null;\n}\n\n/**\n * Resolve effective per-mode model defaults.\n *\n * If `activeModelPackId` is set, looks up the pack (built-in or custom) and\n * returns its models. Falls back to the explicit `modeDefaults` map.\n *\n * @param settings The loaded global settings.\n * @param builtinPacks Built-in packs for the current provider access\n * (from `getAvailableModePacks`). Pass `[]` if unavailable.\n */\nexport function resolveModePackModels(\n settings: GlobalSettings,\n pack: { id: string; models: Record<string, string> },\n): Record<string, string> {\n if (pack.id.startsWith('custom:') || pack.id === 'custom') return pack.models;\n return { ...pack.models, ...settings.models.modePackOverrides?.[pack.id] };\n}\n\n/**\n * Resolve a session's explicitly active pack when its mode model still matches.\n * Model matching alone is not pack identity: multiple packs may intentionally\n * use the same model, and inference would attach an unrelated fallback chain.\n */\nexport function findModePackForModel(\n settings: GlobalSettings,\n packs: Array<{ id: string; models: Record<string, string> }>,\n modelId: string,\n modeId: string,\n activePackId: string | undefined,\n): { id: string; models: Record<string, string> } | undefined {\n const activePack = packs.find(pack => pack.id === activePackId);\n return activePack && resolveModePackModels(settings, activePack)[modeId] === modelId ? activePack : undefined;\n}\n\nexport function resolveModelDefaults(\n settings: GlobalSettings,\n builtinPacks: Array<{ id: string; models: Record<string, string> }>,\n): Record<string, string> {\n const { activeModelPackId, modeDefaults } = settings.models;\n if (!activeModelPackId) return modeDefaults;\n\n // Custom pack: \"custom:<name>\"\n if (activeModelPackId.startsWith('custom:')) {\n const name = activeModelPackId.slice('custom:'.length);\n const pack = settings.customModelPacks.find(p => p.name === name);\n if (pack) return pack.models;\n // Custom pack was deleted — fall through to modeDefaults\n return modeDefaults;\n }\n\n // Built-in pack\n const builtin = builtinPacks.find(p => p.id === activeModelPackId);\n if (builtin) return resolveModePackModels(settings, builtin);\n\n // Unknown pack id — fall through\n return modeDefaults;\n}\n\n/**\n * Resolve the default reasoning-effort level for a mode.\n *\n * Lookup order:\n * 1. `models.modeThinkingDefaults[mode]` when set for the mode.\n * 2. The global `preferences.thinkingLevel`.\n *\n * Session-level overrides (via /think or the session settings panel) take\n * precedence over both and are handled by the caller.\n */\nexport function resolveDefaultThinkingLevel(\n settings: GlobalSettings,\n mode?: string | null,\n): { level: ThinkingLevelSetting; source: ThinkingLevelSource } {\n return resolveThinkingDefault(\n {\n globalDefault: settings.preferences.thinkingLevel,\n modeDefaults: settings.models.modeThinkingDefaults,\n },\n mode,\n );\n}\n\n/**\n * Resolve the effective model ID for one of the two OM roles.\n *\n * Lookup order:\n * 1. The role-specific override (`observerModelOverride` /\n * `reflectorModelOverride`) if set.\n * 2. If `activeOmPackId` points at a built-in pack, that pack's model.\n * 3. The shared `omModelOverride` fallback.\n *\n * @param settings The loaded global settings.\n * @param role Which OM role to resolve (`'observer'` or `'reflector'`).\n * @param builtinOmPacks Built-in OM packs for the current provider access\n * (from `getAvailableOmPacks`). Pass `[]` if unavailable.\n */\nexport function resolveOmRoleModel(\n settings: GlobalSettings,\n role: 'observer' | 'reflector',\n builtinOmPacks: Array<{ id: string; modelId: string }>,\n): string | null {\n const {\n activeOmPackId,\n omModelOverride,\n observerModelOverride,\n observerModelSelection,\n reflectorModelOverride,\n reflectorModelSelection,\n } = settings.models;\n const model = role === 'observer' ? observerModelSelection : reflectorModelSelection;\n if (model === 'auto') return null;\n if (model) return model;\n\n const roleOverride = role === 'observer' ? observerModelOverride : reflectorModelOverride;\n if (roleOverride) return roleOverride;\n\n if (!activeOmPackId) return omModelOverride;\n if (activeOmPackId === 'custom') return omModelOverride;\n\n const pack = builtinOmPacks.find(p => p.id === activeOmPackId);\n if (pack) return pack.modelId;\n\n return omModelOverride;\n}\n\n/**\n * @deprecated Use `resolveOmRoleModel(settings, 'observer' | 'reflector', ...)`.\n * Equivalent to resolving the observer role (existing callers set both observer\n * and reflector to the same value).\n */\nexport function resolveOmModel(\n settings: GlobalSettings,\n builtinOmPacks: Array<{ id: string; modelId: string }>,\n): string | null {\n return resolveOmRoleModel(settings, 'observer', builtinOmPacks);\n}\n\nfunction getSignalSettingsForSave(settings: GlobalSettings, filePath: string): SignalSettings {\n const loadedSignals = loadedSignalSettings.get(settings);\n if (!loadedSignals || !signalSettingsEqual(settings.signals, loadedSignals) || !existsSync(filePath)) {\n return settings.signals;\n }\n\n try {\n const currentRaw = JSON.parse(readFileSync(filePath, 'utf-8')) as Record<string, unknown>;\n const currentSignals = parseSignalSettings(currentRaw.signals);\n if (!signalSettingsEqual(currentSignals, loadedSignals)) {\n return currentSignals;\n }\n } catch {\n // If the current file is unreadable, fall back to the caller's settings.\n }\n\n return settings.signals;\n}\n\nfunction writeFileAtomically(filePath: string, content: string): void {\n const tempPath = `${filePath}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;\n try {\n // Preserve the target's mode across the rename (auth.json keeps its 0600);\n // new files default to owner-only since these are local app-data files.\n const mode = existsSync(filePath) ? statSync(filePath).mode & 0o777 : 0o600;\n writeFileSync(tempPath, content, { encoding: 'utf-8', mode });\n renameSync(tempPath, filePath);\n } finally {\n rmSync(tempPath, { force: true });\n }\n}\n\nexport function saveSettings(settings: GlobalSettings, filePath: string = getSettingsPath()): void {\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const signals = getSignalSettingsForSave(settings, filePath);\n settings.signals = signals;\n loadedSignalSettings.set(settings, cloneSignalSettings(signals));\n const settingsToSave: Record<string, unknown> = { ...settings };\n delete settingsToSave._experimentalAgentSettingsPath;\n writeFileAtomically(filePath, JSON.stringify(settingsToSave, null, 2));\n}\n\n/** Marker file name to track which provider last used a profile. */\nconst PROFILE_PROVIDER_MARKER = '.mastra-provider';\n\n/**\n * Check which provider last used a profile directory.\n * Returns the provider name if the marker exists, undefined otherwise.\n */\nexport function getProfileProvider(profilePath: string): BrowserProvider | undefined {\n const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);\n if (!existsSync(markerPath)) {\n return undefined;\n }\n try {\n const content = readFileSync(markerPath, 'utf-8').trim();\n if (content === 'stagehand' || content === 'agent-browser') {\n return content;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Write the provider marker to a profile directory.\n * Creates the directory if it doesn't exist.\n */\nexport function setProfileProvider(profilePath: string, provider: BrowserProvider): void {\n const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);\n if (!existsSync(profilePath)) {\n mkdirSync(profilePath, { recursive: true });\n }\n writeFileSync(markerPath, provider, 'utf-8');\n}\n\n/**\n * Check if a profile has a provider mismatch.\n * Returns the existing provider if there's a mismatch, undefined otherwise.\n */\nexport function checkProfileProviderMismatch(\n profilePath: string | undefined,\n targetProvider: BrowserProvider,\n): BrowserProvider | undefined {\n if (!profilePath) {\n return undefined;\n }\n const existingProvider = getProfileProvider(profilePath);\n if (existingProvider && existingProvider !== targetProvider) {\n return existingProvider;\n }\n return undefined;\n}\n\nfunction browserRecordingOptions() {\n return { outputDir: join(getAppDataDir(), 'browser-recordings') };\n}\n\n/**\n * Snapshot of browser settings safe to store in session state (which session clients can read).\n * Strips credentials; keeps everything `/browser status` needs for drift detection.\n */\nexport function toActiveBrowserSettings(settings: BrowserSettings): BrowserSettings {\n if (!settings.stagehand) return { ...settings };\n const { apiKey: _apiKey, ...stagehand } = settings.stagehand;\n return { ...settings, stagehand };\n}\n\nexport type StagehandModelSource =\n /** `browser.stagehand.model` in settings. */\n | 'settings'\n /** No model configured; reusing the chat model that was active when the browser launched. */\n | 'chat-model'\n /** No usable model otherwise; the default model for the user's OpenAI Codex (ChatGPT) login. */\n | 'codex-oauth'\n /** Nothing else applies; Stagehand picks its own default from env API keys. */\n | 'stagehand-default';\n\nexport interface ResolvedStagehandModel {\n /** `provider/model` id, or undefined when Stagehand's own default applies. */\n modelName: string | undefined;\n source: StagehandModelSource;\n /** True when requests go through the user's OpenAI Codex OAuth login instead of an API key. */\n viaCodexOAuth: boolean;\n}\n\nexport interface ResolveStagehandModelOptions {\n /**\n * Chat model id at the moment the browser launches (`session.model.get()`).\n * The Stagehand instance is fixed once created and shared across threads, so\n * later chat-model switches do not affect it.\n */\n chatModelId?: string;\n authStorage?: AuthStorage;\n}\n\n/**\n * Env vars Stagehand reads for each provider it can route (mirrors\n * `STAGEHAND_MODEL_PROVIDERS` in `@mastra/stagehand` and Stagehand's own\n * `providerEnvVarMap`). `null` means the provider needs no API key.\n * Kept here instead of importing `@mastra/stagehand`, which would eagerly\n * load the browser stack into every settings consumer.\n */\nexport const STAGEHAND_PROVIDER_ENV_VARS: Record<string, readonly string[] | null> = {\n openai: ['OPENAI_API_KEY'],\n anthropic: ['ANTHROPIC_API_KEY'],\n google: ['GEMINI_API_KEY', 'GOOGLE_GENERATIVE_AI_API_KEY', 'GOOGLE_API_KEY'],\n vertex: ['GOOGLE_VERTEX_AI_API_KEY'],\n groq: ['GROQ_API_KEY'],\n cerebras: ['CEREBRAS_API_KEY'],\n togetherai: ['TOGETHER_AI_API_KEY'],\n mistral: ['MISTRAL_API_KEY'],\n deepseek: ['DEEPSEEK_API_KEY'],\n perplexity: ['PERPLEXITY_API_KEY'],\n azure: ['AZURE_API_KEY'],\n xai: ['XAI_API_KEY'],\n gateway: ['AI_GATEWAY_API_KEY'],\n bedrock: null,\n ollama: null,\n};\n\nfunction hasCodexOAuthLogin(authStorage: AuthStorage): boolean {\n return authStorage.get('openai-codex')?.type === 'oauth';\n}\n\nfunction isOpenAIModel(modelId: string): boolean {\n return modelId.startsWith(OPENAI_PREFIX);\n}\n\n/**\n * Stagehand hands the segment after `provider/` straight to the AI SDK provider,\n * so apply the same id normalization the chat gateway does before it does.\n */\nfunction normalizeForStagehand(modelId: string): string {\n const bare = stripMastraGatewayPrefix(modelId.trim());\n return bare.startsWith(ANTHROPIC_PREFIX) ? normalizeAnthropicModelId(bare) : bare;\n}\n\n/** Whether Stagehand could run `provider/model` with the credentials available right now. */\nfunction stagehandCanRoute(modelId: string, codexOAuth: boolean): boolean {\n const provider = modelId.split('/', 1)[0];\n if (!provider || provider === modelId) return false;\n if (provider === 'openai' && codexOAuth) return true;\n const envVars = STAGEHAND_PROVIDER_ENV_VARS[provider];\n if (envVars === undefined) return false;\n if (envVars === null) return true;\n return envVars.some(name => Boolean(process.env[name]?.trim()));\n}\n\n/**\n * Resolve which model Stagehand will use and why, without creating a browser.\n * Order: configured `browser.stagehand.model` → the launch-time chat model when\n * Stagehand can route it → the Codex login's default model → Stagehand's own\n * default. Mirrors the selection in `createBrowserFromSettings` so the UI can\n * show it.\n */\nexport function resolveStagehandModel(\n settings: Pick<BrowserSettings, 'provider' | 'stagehand'>,\n { chatModelId, authStorage = new AuthStorage() }: ResolveStagehandModelOptions = {},\n): ResolvedStagehandModel {\n if (settings.provider !== 'stagehand') {\n return { modelName: undefined, source: 'stagehand-default', viaCodexOAuth: false };\n }\n const codexOAuth = hasCodexOAuthLogin(authStorage);\n const configured = settings.stagehand?.model ? normalizeForStagehand(settings.stagehand.model) : undefined;\n if (configured) {\n return { modelName: configured, source: 'settings', viaCodexOAuth: codexOAuth && isOpenAIModel(configured) };\n }\n const chatModel = chatModelId ? normalizeForStagehand(chatModelId) : undefined;\n if (chatModel && stagehandCanRoute(chatModel, codexOAuth)) {\n return { modelName: chatModel, source: 'chat-model', viaCodexOAuth: codexOAuth && isOpenAIModel(chatModel) };\n }\n if (codexOAuth) {\n return { modelName: PROVIDER_DEFAULT_MODELS['openai-codex'], source: 'codex-oauth', viaCodexOAuth: true };\n }\n return { modelName: undefined, source: 'stagehand-default', viaCodexOAuth: false };\n}\n\nexport interface CreateBrowserOptions {\n /** Chat model id at launch; see `ResolveStagehandModelOptions.chatModelId`. */\n chatModelId?: string;\n}\n\n/**\n * Create a browser instance from settings.\n * Shared by startup (main.ts) and live reconfiguration (/browser command).\n * Returns undefined if browser is disabled.\n */\nexport async function createBrowserFromSettings(\n settings: BrowserSettings,\n { chatModelId }: CreateBrowserOptions = {},\n): Promise<MastraBrowser | undefined> {\n if (!settings.enabled) {\n return undefined;\n }\n\n const { provider, headless, viewport, cdpUrl, profile, executablePath, stagehand, agentBrowser } = settings;\n\n // Chrome only allows one process per profile directory, so force 'shared' scope\n // when a profile is set. Otherwise use the user's setting (or provider default).\n const scope = profile ? ('shared' as const) : settings.scope;\n\n // Common launch options (no CDP)\n const launchConfig = { headless, viewport, profile, executablePath, scope } as const;\n\n if (provider === 'stagehand') {\n const { StagehandBrowser } = await import('@mastra/stagehand');\n const stagehandOpts: Record<string, unknown> = {\n env: stagehand?.env ?? 'LOCAL',\n apiKey: stagehand?.apiKey ?? process.env.BROWSERBASE_API_KEY,\n projectId: stagehand?.projectId ?? process.env.BROWSERBASE_PROJECT_ID,\n preserveUserDataDir: stagehand?.preserveUserDataDir,\n recording: browserRecordingOptions(),\n };\n\n // See resolveStagehandModel() for which model is picked. How it is reached\n // depends on the user's OpenAI auth, not on where the model came from:\n // any `openai/*` model goes through the Codex (ChatGPT) endpoint when the\n // user signed in with Codex OAuth, matching the chat agents. Everything\n // else is passed as a plain `provider/model` string and Stagehand resolves\n // the provider's API key from the environment.\n //\n // The Codex route uses the AI SDK provider's standard hooks:\n // - baseURL: target Codex's Responses API directly (no URL rewriting).\n // - headers: static Codex identifiers (originator, UA, account id).\n // - fetch: a tiny refresher that injects the live OAuth bearer per call,\n // since AI SDK takes `apiKey` as a static string.\n // - middleware: createCodexMiddleware() sets `store: false`, which Codex\n // requires on every request.\n const authStorage = new AuthStorage();\n const resolved = resolveStagehandModel(settings, { chatModelId, authStorage });\n if (resolved.modelName && resolved.viaCodexOAuth) {\n const accountId = (authStorage.get('openai-codex') as any)?.accountId as string | undefined;\n stagehandOpts.model = {\n modelName: remapOpenAIModelForCodexOAuth(resolved.modelName),\n apiKey: 'codex-oauth',\n baseURL: 'https://chatgpt.com/backend-api/codex',\n headers: {\n originator: 'mastracode',\n 'User-Agent': 'mastracode',\n ...(accountId ? { 'ChatGPT-Account-ID': accountId } : {}),\n },\n fetch: buildCodexStagehandFetch(authStorage),\n middleware: createCodexMiddleware(),\n } as any;\n } else if (resolved.modelName) {\n stagehandOpts.model = resolved.modelName;\n }\n\n return cdpUrl\n ? new StagehandBrowser({ ...launchConfig, cdpUrl, scope: 'shared', ...stagehandOpts })\n : new StagehandBrowser({ ...launchConfig, ...stagehandOpts });\n } else if (provider === 'agent-browser') {\n const { AgentBrowser } = await import('@mastra/agent-browser');\n const agentBrowserOpts = {\n storageState: agentBrowser?.storageState,\n recording: browserRecordingOptions(),\n };\n return cdpUrl\n ? new AgentBrowser({ ...launchConfig, cdpUrl, scope: 'shared', ...agentBrowserOpts })\n : new AgentBrowser({ ...launchConfig, ...agentBrowserOpts, scope });\n }\n\n throw new Error(`Unsupported browser provider: ${provider}`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"settings.js","names":["resolveThinkingDefault"],"sources":["../../src/onboarding/settings.ts"],"sourcesContent":["/**\n * Persistent global settings stored in the app data directory as settings.json.\n * This file persists onboarding state AND user preferences (model choices, yolo, etc.)\n * so they carry across threads and restarts.\n */\n\nimport { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { OMModel } from '@mastra/core/agent-controller';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { AuthStorage, PROVIDER_DEFAULT_MODELS } from '../auth/storage.js';\nimport {\n ANTHROPIC_PREFIX,\n normalizeAnthropicModelId,\n OPENAI_PREFIX,\n remapOpenAIModelForCodexOAuth,\n stripMastraGatewayPrefix,\n} from '../providers/model-ids.js';\nimport { buildCodexStagehandFetch, createCodexMiddleware } from '../providers/openai-codex.js';\nimport {\n isThinkingLevelSetting,\n resolveDefaultThinkingLevel as resolveThinkingDefault,\n THINKING_LEVEL_VALUES,\n} from '../thinking.js';\nimport type { ThinkingLevelSetting, ThinkingLevelSource } from '../thinking.js';\nexport { isThinkingLevelSetting, THINKING_LEVEL_VALUES } from '../thinking.js';\nexport type { ThinkingLevelSetting, ThinkingLevelSource } from '../thinking.js';\nimport { getAppDataDir } from '../utils/project.js';\nimport { DEFAULT_STT_PROVIDER, resolveSTTModel } from '../voice/stt-registry.js';\nimport { pruneUnknownModePackFallbacks, pruneUnknownPackAccountPreferences } from './packs.js';\n\n/** A saved custom pack — user-defined model selections for each mode. */\nexport interface CustomPack {\n name: string;\n models: Record<string, string>;\n createdAt: string;\n}\n\n/** A saved custom provider for OpenAI-compatible endpoints. */\nexport interface CustomProviderSetting {\n name: string;\n url: string;\n apiKey?: string;\n models: string[];\n}\n\n/** Storage backend type. */\nexport type StorageBackend = 'libsql' | 'pg';\n\n/** Experimental agent implementation used by MastraCode. */\nexport type ExperimentalAgent = 'durable' | 'evented';\n\nexport class ExperimentalAgentSettingsError extends Error {\n readonly value: unknown;\n\n constructor(value: unknown, settingsPath?: string) {\n super(\n `Invalid \"experimentalAgent\" setting${settingsPath ? ` in ${settingsPath}` : ''}: ${JSON.stringify(value)}. ` +\n `Remove the \"experimentalAgent\" key or set it to \"durable\", \"evented\", or null.`,\n );\n this.name = 'ExperimentalAgentSettingsError';\n this.value = value;\n }\n}\n\n/** LibSQL-specific storage settings. */\nexport interface LibSQLStorageSettings {\n url?: string;\n authToken?: string;\n}\n\n/** PostgreSQL-specific storage settings. */\nexport interface PgStorageSettings {\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n schemaName?: string;\n disableInit?: boolean;\n skipDefaultIndexes?: boolean;\n}\n\n/** Storage configuration persisted in global settings. */\nexport interface StorageSettings {\n /** Which backend to use. Default: 'libsql'. */\n backend: StorageBackend;\n /** LibSQL-specific config (used when backend is 'libsql'). */\n libsql: LibSQLStorageSettings;\n /** PostgreSQL-specific config (used when backend is 'pg'). */\n pg: PgStorageSettings;\n}\n\n/** Gateway provider key used in AuthStorage. */\nexport const MASTRA_GATEWAY_PROVIDER = 'mastra-gateway';\n\n/** Default gateway URL. */\nexport const MASTRA_GATEWAY_DEFAULT_URL = 'https://gateway-api.mastra.ai';\n\n/** @deprecated Renamed to {@link MASTRA_GATEWAY_PROVIDER}. */\nexport const MEMORY_GATEWAY_PROVIDER = MASTRA_GATEWAY_PROVIDER;\n\n/** @deprecated Renamed to {@link MASTRA_GATEWAY_DEFAULT_URL}. */\nexport const MEMORY_GATEWAY_DEFAULT_URL = MASTRA_GATEWAY_DEFAULT_URL;\n\n/** Preferred model-independent web search/extract provider. */\nexport type WebSearchProviderSetting = 'auto' | 'tavily' | 'parallel';\n\n/** Browser provider type. */\nexport type BrowserProvider = 'stagehand' | 'agent-browser';\n\n/** Direct TUI `!` shell passthrough mode. */\nexport type ShellPassthroughSettingsMode = 'default' | 'path' | 'login';\n\n/** Direct TUI `!` shell command language. */\nexport type ShellPassthroughSettingsFamily = 'posix' | 'cmd' | 'powershell';\n\n/** Direct TUI `!` shell passthrough configuration. */\nexport interface ShellPassthroughSettings {\n mode?: ShellPassthroughSettingsMode | string;\n executable?: string;\n family?: ShellPassthroughSettingsFamily | string;\n}\n\n/** STT engine: on-device macOS recognizer or a cloud provider. */\nexport type VoiceEngine = 'macos-native' | 'cloud';\n\n/** Voice (hold-space dictation) configuration persisted in global settings. */\nexport interface VoiceSettings {\n /** Whether hold-space voice input is enabled. */\n enabled: boolean;\n /** Which STT engine to use. Defaults to macOS native on darwin, else cloud. */\n engine: VoiceEngine;\n /** Cloud provider id (matches an STT registry entry). Cloud engine only. */\n provider: string;\n /** Cloud model id; defaults to the provider's first registry model. */\n model?: string;\n}\n\n/** Stagehand environment type. */\nexport type StagehandEnv = 'LOCAL' | 'BROWSERBASE';\n\n/**\n * Browser viewport: explicit dimensions, or `'window'` to follow the real\n * browser window instead of emulating a fixed size.\n */\nexport type BrowserViewport = { width: number; height: number } | 'window';\n\n/** Named viewport sizes offered by `/browser set viewport`. */\nexport const VIEWPORT_PRESETS = {\n desktop: { width: 1280, height: 720 },\n 'desktop-hd': { width: 1920, height: 1080 },\n laptop: { width: 1440, height: 900 },\n tablet: { width: 768, height: 1024 },\n mobile: { width: 390, height: 844 },\n} as const satisfies Record<string, { width: number; height: number }>;\n\nexport type ViewportPreset = keyof typeof VIEWPORT_PRESETS;\n\n/**\n * Largest viewport dimension accepted. Guards against typos that would launch a\n * browser far larger than any display.\n */\nconst MAX_VIEWPORT_DIMENSION = 10000;\n\nfunction isValidDimension(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 && value <= MAX_VIEWPORT_DIMENSION;\n}\n\n/**\n * Parse a `WIDTHxHEIGHT` string (e.g. `1280x720`), a preset name, or `window`.\n * Returns undefined when the input is not a usable viewport.\n */\nexport function parseViewportInput(input: string): BrowserViewport | undefined {\n const value = input.trim().toLowerCase();\n if (!value) return undefined;\n if (value === 'window') return 'window';\n if (value in VIEWPORT_PRESETS) return { ...VIEWPORT_PRESETS[value as ViewportPreset] };\n\n const match = /^(\\d+)\\s*[x×]\\s*(\\d+)$/.exec(value);\n if (!match) return undefined;\n const width = Number(match[1]);\n const height = Number(match[2]);\n if (!isValidDimension(width) || !isValidDimension(height)) return undefined;\n return { width, height };\n}\n\n/** Stagehand-specific browser settings. */\nexport interface StagehandSettings {\n env: StagehandEnv;\n apiKey?: string;\n projectId?: string;\n /**\n * Model Stagehand uses for its AI operations, as `provider/model`\n * (for example `anthropic/claude-sonnet-4-5`). Stagehand resolves the\n * provider's API key from the environment (`ANTHROPIC_API_KEY`,\n * `OPENAI_API_KEY`, and so on). Defaults to Stagehand's own default.\n */\n model?: string;\n /** Whether to preserve the user data directory after the browser closes. */\n preserveUserDataDir?: boolean;\n}\n\n/** AgentBrowser-specific browser settings. */\nexport interface AgentBrowserSettings {\n /** Path to a Playwright storage state file (JSON) containing cookies and localStorage. */\n storageState?: string;\n}\n\n/** Browser configuration persisted in global settings. */\nexport interface BrowserSettings {\n /** Whether browser automation is enabled. */\n enabled: boolean;\n /** Which browser provider to use. */\n provider: BrowserProvider;\n /** Whether to run headless (no visible browser window). */\n headless: boolean;\n /**\n * Browser viewport dimensions, or `'window'` to disable viewport emulation so\n * the page follows the real browser window.\n */\n viewport?: BrowserViewport;\n /** CDP URL for connecting to an existing browser. */\n cdpUrl?: string;\n /** Path to a Chrome/Chromium user data directory (profile). */\n profile?: string;\n /** Path to the browser executable to use. */\n executablePath?: string;\n /** Browser scope — 'shared' (all threads share one browser) or 'thread' (each thread gets its own). */\n scope?: 'shared' | 'thread';\n /** Stagehand-specific settings. */\n stagehand?: StagehandSettings;\n /** AgentBrowser-specific settings. */\n agentBrowser?: AgentBrowserSettings;\n}\n\nexport type PackAccountPreferences = Record<string, Record<string, string>>;\n\nexport interface GlobalSettings {\n // Onboarding tracking\n onboarding: {\n completedAt: string | null;\n skippedAt: string | null;\n version: number;\n modePackId: string | null;\n omPackId: string | null;\n };\n // Global model preferences (applied to new threads)\n models: {\n /**\n * Active model pack ID. Built-in packs use their id directly (\"anthropic\",\n * \"openai\"). Custom packs use \"custom:<name>\".\n * When set, models are resolved from the pack at startup so pack updates\n * (e.g. new model versions) apply automatically. Built-in packs may layer\n * explicit modePackOverrides over these defaults.\n */\n activeModelPackId: string | null;\n /** Per-mode overrides keyed by built-in pack ID. */\n modePackOverrides: Record<string, Record<string, string>>;\n /**\n * Fallback pack per pack ID (packId → packId; builtin ids and\n * \"custom:<name>\" both allowed). When every account serving a pack's\n * provider is exhausted — or the provider is persistently down — the turn\n * hops to the fallback pack's model. Chains are allowed; a cycle is\n * capped at one revisit per cascade, then the error surfaces.\n */\n packFallbacks: Record<string, string>;\n /** Preferred OAuth account by pack ID and resolved model ID. */\n packAccountPreferences: Record<string, Record<string, string>>;\n /** Explicit per-mode defaults — used when no activeModelPackId is set. */\n modeDefaults: Record<string, string>;\n /**\n * Per-mode reasoning-effort defaults (e.g. { build: \"high\", plan: \"xhigh\" }).\n * Resolved at request time; falls back to `preferences.thinkingLevel` for\n * modes without an entry. Overridden per-session via /think or the session\n * settings panel.\n */\n modeThinkingDefaults: Record<string, ThinkingLevelSetting>;\n /**\n * Active OM pack ID (e.g. \"gemini\", \"anthropic\", \"custom\").\n * When set, the OM model is resolved from the pack at startup so pack\n * updates (e.g. new model versions) apply automatically.\n * Cleared when the user manually overrides via /om (falls back to omModelOverride).\n */\n activeOmPackId: string | null;\n /**\n * Shared OM model override — used for both observer and reflector when a\n * role-specific override is not set. Kept for back-compat with older settings\n * files and set by onboarding when the user picks a custom OM pack.\n */\n omModelOverride: string | null;\n /**\n * Explicit Observer model override — takes precedence over `omModelOverride`\n * when set. Written by `/om` when the observer model is changed independently.\n */\n observerModelOverride: string | null;\n /** Persisted Observer model intent. Missing values use legacy-field compatibility. */\n observerModelSelection: OMModel | null;\n /**\n * Explicit Reflector model override — takes precedence over `omModelOverride`\n * when set. Written by `/om` when the reflector model is changed independently.\n */\n reflectorModelOverride: string | null;\n /** Persisted Reflector model intent. Missing values use legacy-field compatibility. */\n reflectorModelSelection: OMModel | null;\n /** Default OM observation threshold used for new threads unless overridden per-thread. */\n omObservationThreshold: number | null;\n /** Default OM reflection threshold used for new threads unless overridden per-thread. */\n omReflectionThreshold: number | null;\n /**\n * Whether observations and reflections use the terse caveman-style instruction.\n * `null` means inherit the built-in default (currently `false` — caveman is\n * opt-in via `/om` settings). Used as the default for new threads unless\n * overridden per-thread.\n */\n omCavemanObservations: boolean | null;\n /**\n * Whether Observational Memory forwards image/file attachment parts to the\n * Observer LLM. `null` ⇒ inherit built-in default ('auto'). 'auto' checks\n * model capabilities; true/false forces the setting.\n */\n omObserveAttachments: 'auto' | boolean | null;\n /** Per-agent-type subagent model overrides (e.g. { explore: \"openai/gpt-5.1-codex-mini\" }) */\n subagentModels: Record<string, string>;\n /** Default judge model for /goal. */\n goalJudgeModel: string | null;\n /** Default max attempts for /goal. */\n goalMaxTurns: number | null;\n };\n // Global behavior preferences\n preferences: {\n yolo: boolean | null;\n theme: 'auto' | 'dark' | 'light';\n /** Default reasoning effort level used for all threads/models unless overridden in-session. */\n thinkingLevel: ThinkingLevelSetting;\n /** Whether native subagents are enabled for Mastra Code TUI sessions. */\n subagentsEnabled: boolean;\n /** Maximum detail preview lines shown under compact tool calls (0-8). Set to 0 to hide previews. */\n previewLines: number;\n /**\n * Default web search/extract provider. `auto` picks the first configured\n * provider key (Tavily, then Parallel). An explicit provider is only\n * honored while its API key is configured.\n */\n webSearchProvider: WebSearchProviderSetting;\n };\n // Storage backend configuration\n storage: StorageSettings;\n // User-created custom model packs\n customModelPacks: CustomPack[];\n // User-created custom providers with custom models\n customProviders: CustomProviderSetting[];\n // Model usage counts for ranking in the selector\n modelUseCounts: Record<string, number>;\n // Version the user dismissed the update prompt for (skip until they manually update past this)\n updateDismissedVersion: string | null;\n // Mastra gateway configuration\n memoryGateway: { baseUrl?: string };\n // LSP configuration forwarded to the workspace. Disabled unless the user\n // opts in with `true` or an LSPConfig object.\n lsp?: boolean | LSPConfig;\n // Browser automation configuration\n browser: BrowserSettings;\n // Direct TUI `!` shell passthrough configuration\n shellPassthrough: ShellPassthroughSettings;\n // Hold-space voice input configuration\n voice: VoiceSettings;\n // Raw persisted experimental agent value. Resolve through resolveExperimentalAgent() before use.\n experimentalAgent: unknown;\n // Internal load diagnostic retained on clones until the user repairs the setting.\n _experimentalAgentSettingsPath?: string;\n // Native background execution for eligible Mastra Code tools\n backgroundTools: BackgroundToolSettings;\n // Signal routing configuration\n signals: SignalSettings;\n // Read-only discovery of MCP servers configured by other coding agents\n mcp: McpDiscoverySettings;\n // Cloud observability configuration (per-resource project IDs; tokens stored in auth.json)\n observability: ObservabilitySettings;\n}\n\nexport interface McpDiscoverySettings {\n /** Reuse top-level MCP servers from ~/.claude.json. */\n claudeCodeGlobal: boolean;\n /** Reuse MCP servers from $CODEX_HOME/config.toml or ~/.codex/config.toml. */\n codexGlobal: boolean;\n}\n\nexport interface BackgroundToolSettings {\n /** Allow eligible Mastra Code tools to accept per-call background execution overrides. */\n enabled: boolean;\n}\n\nexport interface SignalSettings {\n /** Opt into local Unix socket PubSub for cross-process signal routing. */\n unixSocketPubSub: boolean;\n /** Experimental: enable GitHub PR subscription signals backed by gitcrawl. */\n experimentalGithubSignals: boolean;\n /** Experimental: enable cross-agent communication (thread ownership advertisement, peer discovery, and agent connection tools). */\n experimentalCrossAgentSignals: boolean;\n /** Experimental: give the agent tools to create and manage `/schedules` schedules on its thread. */\n experimentalScheduleTools: boolean;\n /** Poll interval for GitHub PR subscriptions. */\n githubPollIntervalMs: number;\n}\n\nexport interface ObservabilityResourceConfig {\n /** Cloud project ID for this resource */\n projectId: string;\n /** When this config was created */\n configuredAt: string;\n}\n\nexport interface ObservabilitySettings {\n /** Per-resource cloud project configs, keyed by resourceId */\n resources: Record<string, ObservabilityResourceConfig>;\n /** Whether to store traces locally in DuckDB. Off by default to avoid disk usage. */\n localTracing: boolean;\n}\n\n/** Auth key prefix for observability tokens stored per-resource in auth.json */\nexport const OBSERVABILITY_AUTH_PREFIX = 'observability:';\n\nexport const GITHUB_POLL_INTERVAL_DEFAULT_MS = 300_000;\nexport const GITHUB_POLL_INTERVAL_MIN_MS = 10_000;\nexport const GITHUB_POLL_INTERVAL_MAX_MS = 2_147_483_647;\n\nexport const STORAGE_DEFAULTS: StorageSettings = {\n backend: 'libsql',\n libsql: {},\n pg: {},\n};\n\n/** Default STT engine: on-device macOS recognizer where available, else cloud. */\nexport function defaultVoiceEngine(): VoiceEngine {\n return process.platform === 'darwin' ? 'macos-native' : 'cloud';\n}\n\nconst DEFAULTS: GlobalSettings = {\n onboarding: {\n completedAt: null,\n skippedAt: null,\n version: 0,\n modePackId: null,\n omPackId: null,\n },\n models: {\n activeModelPackId: null,\n modePackOverrides: {},\n packFallbacks: {},\n packAccountPreferences: {},\n modeDefaults: {},\n modeThinkingDefaults: {},\n activeOmPackId: null,\n omModelOverride: null,\n observerModelOverride: null,\n observerModelSelection: null,\n reflectorModelOverride: null,\n reflectorModelSelection: null,\n omObservationThreshold: null,\n omReflectionThreshold: null,\n omCavemanObservations: null,\n omObserveAttachments: null,\n subagentModels: {},\n goalJudgeModel: null,\n goalMaxTurns: null,\n },\n preferences: {\n yolo: null,\n theme: 'auto',\n thinkingLevel: 'off',\n subagentsEnabled: false,\n previewLines: 2,\n webSearchProvider: 'auto',\n },\n storage: { ...STORAGE_DEFAULTS },\n customModelPacks: [],\n customProviders: [],\n modelUseCounts: {},\n updateDismissedVersion: null,\n memoryGateway: {},\n lsp: false,\n browser: {\n enabled: false,\n provider: 'stagehand',\n headless: false,\n viewport: { ...VIEWPORT_PRESETS.desktop },\n stagehand: { env: 'LOCAL' },\n },\n shellPassthrough: { mode: 'default' },\n voice: { enabled: false, engine: defaultVoiceEngine(), provider: DEFAULT_STT_PROVIDER },\n experimentalAgent: null,\n backgroundTools: { enabled: false },\n signals: {\n unixSocketPubSub: false,\n experimentalGithubSignals: false,\n experimentalCrossAgentSignals: false,\n experimentalScheduleTools: false,\n githubPollIntervalMs: GITHUB_POLL_INTERVAL_DEFAULT_MS,\n },\n mcp: { claudeCodeGlobal: false, codexGlobal: false },\n observability: { resources: {}, localTracing: false },\n};\n\nexport const WEB_SEARCH_PROVIDER_VALUES: WebSearchProviderSetting[] = ['auto', 'tavily', 'parallel'];\nconst PREVIEW_LINES_MAX = 8;\nconst loadedSignalSettings = new WeakMap<GlobalSettings, SignalSettings>();\n\nfunction cloneSignalSettings(signals: SignalSettings): SignalSettings {\n return { ...signals };\n}\n\nfunction rememberLoadedSettings(settings: GlobalSettings): GlobalSettings {\n loadedSignalSettings.set(settings, cloneSignalSettings(settings.signals));\n return settings;\n}\n\nfunction signalSettingsEqual(left: SignalSettings, right: SignalSettings): boolean {\n return (\n left.unixSocketPubSub === right.unixSocketPubSub &&\n left.experimentalGithubSignals === right.experimentalGithubSignals &&\n left.experimentalCrossAgentSignals === right.experimentalCrossAgentSignals &&\n left.experimentalScheduleTools === right.experimentalScheduleTools &&\n left.githubPollIntervalMs === right.githubPollIntervalMs\n );\n}\n\nfunction parseWebSearchProvider(value: unknown): WebSearchProviderSetting {\n return typeof value === 'string' && WEB_SEARCH_PROVIDER_VALUES.includes(value as WebSearchProviderSetting)\n ? (value as WebSearchProviderSetting)\n : DEFAULTS.preferences.webSearchProvider;\n}\n\nfunction parseThinkingLevel(value: unknown): ThinkingLevelSetting {\n return isThinkingLevelSetting(value) ? value : DEFAULTS.preferences.thinkingLevel;\n}\n\nfunction parseModeThinkingDefaults(value: unknown): Record<string, ThinkingLevelSetting> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, ThinkingLevelSetting> = {};\n for (const [mode, level] of Object.entries(value as Record<string, unknown>)) {\n if (isThinkingLevelSetting(level)) {\n result[mode] = level;\n }\n }\n return result;\n}\n\nfunction parseModePackOverrides(value: unknown): Record<string, Record<string, string>> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, Record<string, string>> = {};\n for (const [packId, overrides] of Object.entries(value as Record<string, unknown>)) {\n if (!overrides || typeof overrides !== 'object') continue;\n const parsedOverrides = Object.fromEntries(\n Object.entries(overrides as Record<string, unknown>).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].length > 0,\n ),\n );\n if (Object.keys(parsedOverrides).length > 0) result[packId] = parsedOverrides;\n }\n return result;\n}\n\nfunction parsePackFallbacks(value: unknown): Record<string, string> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, string> = {};\n for (const [packId, fallbackId] of Object.entries(value as Record<string, unknown>)) {\n if (typeof fallbackId === 'string' && fallbackId.length > 0) result[packId] = fallbackId;\n }\n return result;\n}\n\n/** Shape-parse + drop entries whose source or target pack no longer exists. */\nfunction loadPackFallbacks(value: unknown, customModelPacks: Array<{ name: string }>): Record<string, string> {\n return pruneUnknownModePackFallbacks(parsePackFallbacks(value), customModelPacks);\n}\n\nfunction parsePackAccountPreferences(value: unknown): Record<string, Record<string, string>> {\n if (!value || typeof value !== 'object') return {};\n const result: Record<string, Record<string, string>> = {};\n for (const [packId, modelPreferences] of Object.entries(value as Record<string, unknown>)) {\n if (!modelPreferences || typeof modelPreferences !== 'object') continue;\n const parsed = Object.fromEntries(\n Object.entries(modelPreferences as Record<string, unknown>).filter(\n (entry): entry is [string, string] =>\n entry[0].length > 0 && typeof entry[1] === 'string' && entry[1].length > 0,\n ),\n );\n if (Object.keys(parsed).length > 0) result[packId] = parsed;\n }\n return result;\n}\n\nfunction loadPackAccountPreferences(\n value: unknown,\n customModelPacks: CustomPack[],\n modePackOverrides: Record<string, Record<string, string>>,\n): PackAccountPreferences {\n return pruneUnknownPackAccountPreferences(parsePackAccountPreferences(value), customModelPacks, modePackOverrides);\n}\n\n/** Move persisted routing choices when re-authentication changes an account instance id. */\nexport function migrateAccountPreferences(\n settings: GlobalSettings,\n previousAccountId: string,\n nextAccountId: string,\n): void {\n if (previousAccountId === nextAccountId) return;\n for (const modelPreferences of Object.values(settings.models.packAccountPreferences ?? {})) {\n for (const [modelId, accountInstanceId] of Object.entries(modelPreferences)) {\n if (accountInstanceId === previousAccountId) modelPreferences[modelId] = nextAccountId;\n }\n }\n}\n\n/** Remove persisted routing choices that point at deleted OAuth account instances. */\nexport function pruneRemovedAccountPreferences(settings: GlobalSettings, removedAccountIds: Iterable<string>): void {\n const removed = new Set(removedAccountIds);\n if (removed.size === 0) return;\n\n const next: PackAccountPreferences = {};\n for (const [packId, modelPreferences] of Object.entries(settings.models.packAccountPreferences ?? {})) {\n const retained = Object.fromEntries(\n Object.entries(modelPreferences).filter(([, accountInstanceId]) => !removed.has(accountInstanceId)),\n );\n if (Object.keys(retained).length > 0) next[packId] = retained;\n }\n settings.models.packAccountPreferences = next;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\n/**\n * Resolves the preview line limit. `previewLines` wins when valid; otherwise the legacy\n * `quietModeMaxToolPreviewLines` key (still written by older Mastra Code versions) is used.\n */\nfunction parsePreviewLines(raw: Record<string, unknown>): number {\n const value = isFiniteNumber(raw.previewLines)\n ? raw.previewLines\n : isFiniteNumber(raw.quietModeMaxToolPreviewLines)\n ? raw.quietModeMaxToolPreviewLines\n : DEFAULTS.preferences.previewLines;\n return Math.min(PREVIEW_LINES_MAX, Math.max(0, Math.floor(value)));\n}\n\nfunction parsePreferences(rawPreferences: unknown): GlobalSettings['preferences'] {\n const raw = rawPreferences && typeof rawPreferences === 'object' ? (rawPreferences as Record<string, unknown>) : {};\n\n return {\n ...DEFAULTS.preferences,\n ...raw,\n thinkingLevel: parseThinkingLevel(raw.thinkingLevel),\n subagentsEnabled:\n typeof raw.subagentsEnabled === 'boolean' ? raw.subagentsEnabled : DEFAULTS.preferences.subagentsEnabled,\n previewLines: parsePreviewLines(raw),\n webSearchProvider: parseWebSearchProvider(raw.webSearchProvider),\n };\n}\n\nfunction parseGithubPollIntervalMs(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return DEFAULTS.signals.githubPollIntervalMs;\n const intervalMs = Math.floor(value);\n if (intervalMs < GITHUB_POLL_INTERVAL_MIN_MS) return DEFAULTS.signals.githubPollIntervalMs;\n return Math.min(intervalMs, GITHUB_POLL_INTERVAL_MAX_MS);\n}\n\nexport function parseExperimentalAgentSetting(value: unknown, settingsPath?: string): ExperimentalAgent | null {\n if (value === undefined || value === null) return null;\n if (value === 'durable' || value === 'evented') return value;\n throw new ExperimentalAgentSettingsError(value, settingsPath);\n}\n\nfunction loadExperimentalAgentSetting(\n value: unknown,\n settingsPath: string,\n): { selection: unknown; settingsPath?: string } {\n try {\n return { selection: parseExperimentalAgentSetting(value, settingsPath) };\n } catch (error) {\n if (error instanceof ExperimentalAgentSettingsError) {\n return { selection: error.value, settingsPath };\n }\n throw error;\n }\n}\n\nfunction parseBackgroundToolSettings(rawBackgroundTools: unknown): BackgroundToolSettings {\n const raw =\n rawBackgroundTools && typeof rawBackgroundTools === 'object' ? (rawBackgroundTools as Record<string, unknown>) : {};\n return {\n enabled: typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.backgroundTools.enabled,\n };\n}\n\nfunction parseSignalSettings(rawSignals: unknown): SignalSettings {\n const raw = rawSignals && typeof rawSignals === 'object' ? (rawSignals as Record<string, unknown>) : {};\n return {\n unixSocketPubSub:\n typeof raw.unixSocketPubSub === 'boolean' ? raw.unixSocketPubSub : DEFAULTS.signals.unixSocketPubSub,\n experimentalGithubSignals:\n typeof raw.experimentalGithubSignals === 'boolean'\n ? raw.experimentalGithubSignals\n : DEFAULTS.signals.experimentalGithubSignals,\n experimentalCrossAgentSignals:\n typeof raw.experimentalCrossAgentSignals === 'boolean'\n ? raw.experimentalCrossAgentSignals\n : DEFAULTS.signals.experimentalCrossAgentSignals,\n experimentalScheduleTools:\n typeof raw.experimentalScheduleTools === 'boolean'\n ? raw.experimentalScheduleTools\n : DEFAULTS.signals.experimentalScheduleTools,\n githubPollIntervalMs: parseGithubPollIntervalMs(raw.githubPollIntervalMs),\n };\n}\n\nfunction parseMcpDiscoverySettings(rawMcp: unknown): McpDiscoverySettings {\n const raw = rawMcp && typeof rawMcp === 'object' ? (rawMcp as Record<string, unknown>) : {};\n return {\n claudeCodeGlobal: typeof raw.claudeCodeGlobal === 'boolean' ? raw.claudeCodeGlobal : DEFAULTS.mcp.claudeCodeGlobal,\n codexGlobal: typeof raw.codexGlobal === 'boolean' ? raw.codexGlobal : DEFAULTS.mcp.codexGlobal,\n };\n}\n\nexport function getSettingsPath(): string {\n return join(getAppDataDir(), 'settings.json');\n}\n\nexport function getCustomProviderId(name: string): string {\n const slug = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'provider';\n}\n\nexport function toCustomProviderModelId(providerName: string, modelName: string): string {\n const providerId = getCustomProviderId(providerName);\n const trimmedModelName = modelName.trim();\n const providerPrefix = `${providerId}/`;\n if (trimmedModelName.startsWith(providerPrefix)) {\n return trimmedModelName;\n }\n return `${providerId}/${trimmedModelName}`;\n}\n\n/**\n * The shared gateway catalog namespaces provider keys under their owning\n * gateway id, so a custom provider's models surface in the `/models` catalog\n * as `mastracode/<providerId>/<model>` instead of the canonical\n * `<providerId>/<model>` that model resolution expects. Persisting the\n * gateway-qualified id verbatim breaks lookup later (the provider is parsed\n * as `mastracode`). Strip the prefix before saving — but only when the\n * middle segment matches one of the user's configured custom providers, so\n * legitimate `mastracode/...` gateway-routed ids are left untouched.\n */\nexport function stripMastraCodeCustomProviderPrefix(\n modelId: string,\n customProviders: Array<Pick<CustomProviderSetting, 'name'>>,\n): string {\n const gatewayPrefix = 'mastracode/';\n if (!modelId.startsWith(gatewayPrefix)) return modelId;\n\n const rest = modelId.slice(gatewayPrefix.length);\n const [providerId, ...modelParts] = rest.split('/');\n if (!providerId || modelParts.length === 0 || modelParts.some(part => part.length === 0)) return modelId;\n\n const isCustomProvider = customProviders.some(provider => getCustomProviderId(provider.name) === providerId);\n return isCustomProvider ? rest : modelId;\n}\n\nexport function parseCustomProviders(rawProviders: unknown): CustomProviderSetting[] {\n if (!Array.isArray(rawProviders)) return [];\n\n const parsedProviders: CustomProviderSetting[] = [];\n for (const rawProvider of rawProviders) {\n if (!rawProvider || typeof rawProvider !== 'object') continue;\n\n const candidate = rawProvider as Record<string, unknown>;\n const name = typeof candidate.name === 'string' ? candidate.name.trim() : '';\n const url = typeof candidate.url === 'string' ? candidate.url.trim() : '';\n if (!name || !url) continue;\n\n const providerId = getCustomProviderId(name);\n const models = Array.isArray(candidate.models)\n ? [\n ...new Set(\n candidate.models\n .filter((model): model is string => typeof model === 'string')\n .map(model => model.trim())\n .map(model => {\n const providerPrefix = `${providerId}/`;\n if (model.startsWith(providerPrefix)) {\n return model.slice(providerPrefix.length);\n }\n return model;\n }),\n ),\n ].filter(model => model.length > 0)\n : [];\n\n const apiKey =\n typeof candidate.apiKey === 'string' && candidate.apiKey.trim().length > 0 ? candidate.apiKey.trim() : undefined;\n\n parsedProviders.push({\n name,\n url,\n ...(apiKey ? { apiKey } : {}),\n models,\n });\n }\n\n return parsedProviders;\n}\n\nconst BROWSER_PROVIDERS = new Set<BrowserProvider>(['stagehand', 'agent-browser']);\nconst STAGEHAND_ENVS = new Set<StagehandEnv>(['LOCAL', 'BROWSERBASE']);\n\n/**\n * Normalize a Stagehand model id, which must be provider-qualified.\n *\n * Stagehand reads the segment before the first slash as the provider, so a\n * bare id like `gpt-4.1` is rejected as an unknown provider and a trailing\n * slash leaves an empty model name that only fails once a request is made.\n * Neither is usable, so both are dropped here rather than persisted.\n *\n * The provider name itself is checked where the command is issued, which can\n * name the supported providers in an error; this module is on the startup path\n * and only imports Stagehand lazily.\n *\n * @returns the trimmed model id, or undefined when it is unusable.\n */\nfunction parseStagehandModel(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const model = value.trim();\n const separator = model.indexOf('/');\n if (separator <= 0) return undefined;\n return model.slice(separator + 1).trim() ? model : undefined;\n}\n\n/**\n * Validate a viewport read from settings.json, falling back to the default when\n * it is missing or malformed.\n */\nfunction parseStoredViewport(raw: unknown): BrowserViewport {\n if (raw === 'window') return 'window';\n if (raw && typeof raw === 'object') {\n const { width, height } = raw as Record<string, unknown>;\n if (isValidDimension(width) && isValidDimension(height)) return { width, height };\n }\n return { ...VIEWPORT_PRESETS.desktop };\n}\n\n/**\n * Validate the `lsp` setting from JSON. Accepts both the boolean opt-in/opt-out\n * form and the full LSPConfig object; anything else is treated as unset.\n */\nfunction parseLspSettings(raw: unknown): boolean | LSPConfig | undefined {\n if (typeof raw === 'boolean') return raw;\n if (raw && typeof raw === 'object') return raw as LSPConfig;\n return undefined;\n}\n\n/**\n * Resolve the effective LSP config. LSP is opt-in: `false` and an absent\n * setting both mean disabled, `true` means enabled with defaults.\n */\nexport function resolveLspSetting(lsp: boolean | LSPConfig | undefined): LSPConfig | false {\n if (lsp === true) return {};\n if (!lsp) return false;\n return lsp;\n}\n\n/**\n * Deep-merge and validate browser settings from JSON.\n * Explicitly validates types to handle malformed settings.json gracefully.\n */\nfunction parseBrowserSettings(rawBrowser: unknown): BrowserSettings {\n const raw = rawBrowser && typeof rawBrowser === 'object' ? (rawBrowser as Record<string, unknown>) : {};\n const rawStagehand =\n raw.stagehand && typeof raw.stagehand === 'object' ? (raw.stagehand as Record<string, unknown>) : {};\n const stagehandModel = parseStagehandModel(rawStagehand.model);\n const rawAgentBrowser =\n raw.agentBrowser && typeof raw.agentBrowser === 'object' ? (raw.agentBrowser as Record<string, unknown>) : {};\n\n return {\n enabled: typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.browser.enabled,\n provider:\n typeof raw.provider === 'string' && BROWSER_PROVIDERS.has(raw.provider as BrowserProvider)\n ? (raw.provider as BrowserProvider)\n : DEFAULTS.browser.provider,\n headless: typeof raw.headless === 'boolean' ? raw.headless : DEFAULTS.browser.headless,\n cdpUrl: typeof raw.cdpUrl === 'string' && raw.cdpUrl.trim() ? raw.cdpUrl.trim() : undefined,\n profile: typeof raw.profile === 'string' && raw.profile.trim() ? raw.profile.trim() : undefined,\n executablePath:\n typeof raw.executablePath === 'string' && raw.executablePath.trim() ? raw.executablePath.trim() : undefined,\n viewport: parseStoredViewport(raw.viewport),\n scope: typeof raw.scope === 'string' && (raw.scope === 'shared' || raw.scope === 'thread') ? raw.scope : undefined,\n stagehand: {\n env:\n typeof rawStagehand.env === 'string' && STAGEHAND_ENVS.has(rawStagehand.env as StagehandEnv)\n ? (rawStagehand.env as StagehandEnv)\n : DEFAULTS.browser.stagehand!.env,\n ...(typeof rawStagehand.apiKey === 'string' && rawStagehand.apiKey.trim()\n ? { apiKey: rawStagehand.apiKey.trim() }\n : {}),\n ...(typeof rawStagehand.projectId === 'string' && rawStagehand.projectId.trim()\n ? { projectId: rawStagehand.projectId.trim() }\n : {}),\n ...(stagehandModel ? { model: stagehandModel } : {}),\n ...(typeof rawStagehand.preserveUserDataDir === 'boolean'\n ? { preserveUserDataDir: rawStagehand.preserveUserDataDir }\n : {}),\n },\n agentBrowser:\n typeof rawAgentBrowser.storageState === 'string' && rawAgentBrowser.storageState.trim()\n ? { storageState: rawAgentBrowser.storageState.trim() }\n : undefined,\n };\n}\n\nfunction parseShellPassthroughSettings(rawShellPassthrough: unknown): ShellPassthroughSettings {\n const raw =\n rawShellPassthrough && typeof rawShellPassthrough === 'object'\n ? (rawShellPassthrough as Record<string, unknown>)\n : {};\n const executable = typeof raw.executable === 'string' && raw.executable.trim() ? raw.executable.trim() : undefined;\n const family = typeof raw.family === 'string' && raw.family.trim() ? raw.family.trim() : undefined;\n const mode = typeof raw.mode === 'string' && raw.mode.trim() ? raw.mode.trim() : undefined;\n const defaultMode = executable ? undefined : DEFAULTS.shellPassthrough.mode;\n\n return {\n ...((mode ?? defaultMode) ? { mode: mode ?? defaultMode } : {}),\n ...(executable ? { executable } : {}),\n ...(family ? { family } : {}),\n };\n}\n\nfunction parseVoiceSettings(rawVoice: unknown): VoiceSettings {\n const raw = rawVoice && typeof rawVoice === 'object' ? (rawVoice as Record<string, unknown>) : {};\n const enabled = typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULTS.voice.enabled;\n const engine: VoiceEngine =\n raw.engine === 'macos-native' || raw.engine === 'cloud' ? raw.engine : defaultVoiceEngine();\n // Validate provider/model against the registry, falling back to a usable entry\n // so old `{ enabled }`-only files and unknown values still resolve cleanly.\n const provider = typeof raw.provider === 'string' ? raw.provider : DEFAULTS.voice.provider;\n const model = typeof raw.model === 'string' ? raw.model : undefined;\n const resolved = resolveSTTModel(provider, model);\n return {\n enabled,\n engine,\n provider: resolved.provider,\n model: resolved.model,\n };\n}\n\nconst VALID_PROJECT_ID = /^[a-zA-Z0-9_-]+$/;\n\nfunction parseObservabilitySettings(raw: unknown): ObservabilitySettings {\n if (!raw || typeof raw !== 'object') return { resources: {}, localTracing: false };\n const obj = raw as Record<string, unknown>;\n const localTracing = obj.localTracing === true;\n const rawResources = obj.resources;\n if (!rawResources || typeof rawResources !== 'object') return { resources: {}, localTracing };\n const resources: Record<string, ObservabilityResourceConfig> = {};\n for (const [key, val] of Object.entries(rawResources as Record<string, unknown>)) {\n if (val && typeof val === 'object') {\n const v = val as Record<string, unknown>;\n if (typeof v.projectId === 'string' && VALID_PROJECT_ID.test(v.projectId)) {\n resources[key] = {\n projectId: v.projectId,\n configuredAt: typeof v.configuredAt === 'string' ? v.configuredAt : new Date().toISOString(),\n };\n }\n }\n }\n return { resources, localTracing };\n}\n\n/**\n * One-time migration: move model-related data from auth.json to settings.json.\n * Reads `_modelRanks`, `_modeModelId_*`, `_subagentModelId*` from auth.json,\n * merges them into settings, removes them from auth.json, and writes both files.\n * No-ops if auth.json has no _ prefixed model data.\n */\nfunction migrateFromAuth(settingsPath: string): boolean {\n const authPath = join(getAppDataDir(), 'auth.json');\n if (!existsSync(authPath)) return false;\n\n let authData: Record<string, any>;\n try {\n authData = JSON.parse(readFileSync(authPath, 'utf-8'));\n } catch {\n return false;\n }\n\n const modelKeys = Object.keys(authData).filter(k => k.startsWith('_'));\n if (modelKeys.length === 0) return false;\n\n // Load existing settings (or defaults) and merge auth data into it\n let settings: GlobalSettings;\n if (existsSync(settingsPath)) {\n try {\n const raw = JSON.parse(readFileSync(settingsPath, 'utf-8'));\n const rawCustomPacks: CustomPack[] = Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [];\n const modePackOverrides = parseModePackOverrides(raw.models?.modePackOverrides);\n const experimentalAgentSetting = loadExperimentalAgentSetting(raw.experimentalAgent, settingsPath);\n settings = {\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides,\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\n packFallbacks: loadPackFallbacks(raw.models?.packFallbacks, rawCustomPacks),\n packAccountPreferences: loadPackAccountPreferences(\n raw.models?.packAccountPreferences,\n rawCustomPacks,\n modePackOverrides,\n ),\n },\n preferences: parsePreferences(raw.preferences),\n storage: {\n ...STORAGE_DEFAULTS,\n ...raw.storage,\n libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },\n pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg },\n },\n customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],\n customProviders: parseCustomProviders(raw.customProviders),\n modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === 'object' ? raw.modelUseCounts : {},\n updateDismissedVersion: typeof raw.updateDismissedVersion === 'string' ? raw.updateDismissedVersion : null,\n memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === 'object' ? raw.memoryGateway : {},\n lsp: parseLspSettings(raw.lsp),\n browser: parseBrowserSettings(raw.browser),\n shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),\n voice: parseVoiceSettings(raw.voice),\n experimentalAgent: experimentalAgentSetting.selection,\n _experimentalAgentSettingsPath: experimentalAgentSetting.settingsPath,\n backgroundTools: parseBackgroundToolSettings(raw.backgroundTools),\n signals: parseSignalSettings(raw.signals),\n mcp: parseMcpDiscoverySettings(raw.mcp),\n observability: parseObservabilitySettings(raw.observability),\n };\n } catch {\n settings = structuredClone(DEFAULTS);\n }\n } else {\n settings = structuredClone(DEFAULTS);\n }\n\n // Migrate model use counts (only if settings doesn't already have them)\n if (authData._modelRanks && typeof authData._modelRanks === 'object') {\n settings.modelUseCounts = { ...authData._modelRanks, ...settings.modelUseCounts };\n }\n\n // Migrate per-mode model defaults (don't overwrite existing settings)\n for (const key of modelKeys) {\n const modeMatch = key.match(/^_modeModelId_(.+)$/);\n if (modeMatch?.[1] && typeof authData[key] === 'string' && !settings.models.modeDefaults[modeMatch[1]]) {\n settings.models.modeDefaults[modeMatch[1]] = authData[key];\n }\n }\n\n // Migrate subagent models (don't overwrite existing settings)\n for (const key of modelKeys) {\n if (key === '_subagentModelId' && typeof authData[key] === 'string' && !settings.models.subagentModels['default']) {\n settings.models.subagentModels['default'] = authData[key];\n }\n const saMatch = key.match(/^_subagentModelId_(.+)$/);\n if (saMatch?.[1] && typeof authData[key] === 'string' && !settings.models.subagentModels[saMatch[1]]) {\n settings.models.subagentModels[saMatch[1]] = authData[key];\n }\n }\n\n // Write migrated settings\n saveSettings(settings, settingsPath);\n\n // Clean up auth.json — remove _ prefixed keys\n for (const key of modelKeys) {\n delete authData[key];\n }\n try {\n writeFileAtomically(authPath, JSON.stringify(authData, null, 2));\n } catch {\n // Non-fatal — settings are saved, auth cleanup can fail\n }\n\n return true;\n}\n\nconst LEGACY_VARIED_MODELS: Record<string, string> = {\n plan: 'openai/gpt-5.4',\n build: 'anthropic/claude-sonnet-4-5',\n fast: 'anthropic/claude-haiku-4-5',\n};\n\nexport function migrateLegacyVariedPack(settings: GlobalSettings): boolean {\n const legacyPackId = 'varied';\n const customPackId = 'custom:varied';\n const hasLegacyReference =\n settings.models.activeModelPackId === legacyPackId || settings.onboarding.modePackId === legacyPackId;\n\n if (!hasLegacyReference) return false;\n\n const existingIdx = settings.customModelPacks.findIndex(p => p.name === 'varied');\n if (existingIdx >= 0) {\n const existing = settings.customModelPacks[existingIdx]!;\n const modelsMatch = Object.entries(LEGACY_VARIED_MODELS).every(([k, v]) => existing.models[k] === v);\n if (!modelsMatch) {\n existing.models = { ...LEGACY_VARIED_MODELS };\n }\n } else {\n settings.customModelPacks.push({\n name: 'varied',\n models: { ...LEGACY_VARIED_MODELS },\n createdAt: new Date().toISOString(),\n });\n }\n\n if (settings.models.activeModelPackId === legacyPackId) {\n settings.models.activeModelPackId = customPackId;\n if (Object.keys(settings.models.modeDefaults).length === 0) {\n settings.models.modeDefaults = { ...LEGACY_VARIED_MODELS };\n }\n }\n\n if (settings.onboarding.modePackId === legacyPackId) {\n settings.onboarding.modePackId = customPackId;\n }\n\n return true;\n}\n\nexport function loadSettings(filePath: string = getSettingsPath()): GlobalSettings {\n // One-time migration: move model data from auth.json into settings.json\n migrateFromAuth(filePath);\n\n if (!existsSync(filePath)) return rememberLoadedSettings(structuredClone(DEFAULTS));\n try {\n const raw = JSON.parse(readFileSync(filePath, 'utf-8'));\n const rawCustomPacks: CustomPack[] = Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [];\n const modePackOverrides = parseModePackOverrides(raw.models?.modePackOverrides);\n const experimentalAgentSetting = loadExperimentalAgentSetting(raw.experimentalAgent, filePath);\n // Spread raw first to preserve unknown top-level keys (forward-compatibility),\n // then overlay with parsed/typed fields so known keys are always correct.\n const settings: GlobalSettings = {\n ...raw,\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides,\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\n packFallbacks: loadPackFallbacks(raw.models?.packFallbacks, rawCustomPacks),\n packAccountPreferences: loadPackAccountPreferences(\n raw.models?.packAccountPreferences,\n rawCustomPacks,\n modePackOverrides,\n ),\n },\n preferences: parsePreferences(raw.preferences),\n storage: {\n ...STORAGE_DEFAULTS,\n ...raw.storage,\n libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },\n pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg },\n },\n customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],\n customProviders: parseCustomProviders(raw.customProviders),\n modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === 'object' ? raw.modelUseCounts : {},\n updateDismissedVersion: typeof raw.updateDismissedVersion === 'string' ? raw.updateDismissedVersion : null,\n memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === 'object' ? raw.memoryGateway : {},\n lsp: parseLspSettings(raw.lsp),\n browser: parseBrowserSettings(raw.browser),\n shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),\n voice: parseVoiceSettings(raw.voice),\n experimentalAgent: experimentalAgentSetting.selection,\n _experimentalAgentSettingsPath: experimentalAgentSetting.settingsPath,\n backgroundTools: parseBackgroundToolSettings(raw.backgroundTools),\n signals: parseSignalSettings(raw.signals),\n mcp: parseMcpDiscoverySettings(raw.mcp),\n observability: parseObservabilitySettings(raw.observability),\n };\n\n let settingsChanged = false;\n // Persist the resolved preview line limit under its current key. Legacy quiet-mode keys are\n // left untouched so older Mastra Code instances that are still running keep working.\n if (!isFiniteNumber(raw.preferences?.previewLines)) {\n settingsChanged = true;\n }\n // Migrate legacy omModelId → omModelOverride\n if (raw.models?.omModelId && !settings.models.omModelOverride) {\n settings.models.omModelOverride = raw.models.omModelId;\n settingsChanged = true;\n }\n\n if (migrateLegacyVariedPack(settings)) {\n settingsChanged = true;\n }\n\n if (settingsChanged) {\n saveSettings(settings, filePath);\n }\n\n return rememberLoadedSettings(settings);\n } catch {\n return rememberLoadedSettings(structuredClone(DEFAULTS));\n }\n}\n\nexport const THREAD_ACTIVE_MODEL_PACK_ID_KEY = 'activeModelPackId';\nexport const THREAD_FALLBACK_STATUS_KEY = 'mastracodeFallbackStatus';\n\nexport interface ThreadSettings {\n activeModelPackId: string | null;\n modeModelIds: Record<string, string>;\n}\n\nexport function parseThreadSettings(metadata: Record<string, unknown> | undefined): ThreadSettings {\n const modeModelIds: Record<string, string> = {};\n for (const [key, value] of Object.entries(metadata ?? {})) {\n const modeMatch = key.match(/^modeModelId_(.+)$/);\n if (modeMatch?.[1] && typeof value === 'string' && value.length > 0) {\n modeModelIds[modeMatch[1]] = value;\n }\n }\n\n const rawPackId = metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY];\n const activeModelPackId = typeof rawPackId === 'string' && rawPackId.length > 0 ? rawPackId : null;\n\n return {\n activeModelPackId,\n modeModelIds,\n };\n}\n\n/**\n * Resolve active model pack id for the current thread.\n *\n * Priority:\n * 1) explicit thread metadata activeModelPackId\n * 2) inferred from thread modeModelId_* values\n * 3) global settings.models.activeModelPackId\n */\nexport function resolveThreadActiveModelPackId(\n settings: GlobalSettings,\n builtinPacks: Array<{ id: string; models: Record<string, string> }>,\n metadata: Record<string, unknown> | undefined,\n): string | null {\n const threadSettings = parseThreadSettings(metadata);\n\n const isKnownPack = (packId: string): boolean => {\n if (packId.startsWith('custom:')) {\n const name = packId.slice('custom:'.length);\n return settings.customModelPacks.some(p => p.name === name);\n }\n return builtinPacks.some(p => p.id === packId);\n };\n\n if (threadSettings.activeModelPackId && isKnownPack(threadSettings.activeModelPackId)) {\n return threadSettings.activeModelPackId;\n }\n\n const allPacks: Array<{ id: string; models: Record<string, string> }> = [\n ...builtinPacks,\n ...settings.customModelPacks.map(p => ({ id: `custom:${p.name}`, models: p.models })),\n ];\n\n for (const pack of allPacks) {\n const packEntries = Object.entries(pack.models);\n const threadEntries = Object.keys(threadSettings.modeModelIds);\n const matches =\n packEntries.length === threadEntries.length &&\n packEntries.every(([modeId, modelId]) => threadSettings.modeModelIds[modeId] === modelId);\n if (matches) return pack.id;\n }\n\n if (settings.models.activeModelPackId && isKnownPack(settings.models.activeModelPackId)) {\n return settings.models.activeModelPackId;\n }\n\n return null;\n}\n\n/**\n * Resolve effective per-mode model defaults.\n *\n * If `activeModelPackId` is set, looks up the pack (built-in or custom) and\n * returns its models. Falls back to the explicit `modeDefaults` map.\n *\n * @param settings The loaded global settings.\n * @param builtinPacks Built-in packs for the current provider access\n * (from `getAvailableModePacks`). Pass `[]` if unavailable.\n */\nexport function resolveModePackModels(\n settings: GlobalSettings,\n pack: { id: string; models: Record<string, string> },\n): Record<string, string> {\n if (pack.id.startsWith('custom:') || pack.id === 'custom') return pack.models;\n return { ...pack.models, ...settings.models.modePackOverrides?.[pack.id] };\n}\n\n/**\n * Resolve a session's explicitly active pack when its mode model still matches.\n * Model matching alone is not pack identity: multiple packs may intentionally\n * use the same model, and inference would attach an unrelated fallback chain.\n */\nexport function findModePackForModel(\n settings: GlobalSettings,\n packs: Array<{ id: string; models: Record<string, string> }>,\n modelId: string,\n modeId: string,\n activePackId: string | undefined,\n): { id: string; models: Record<string, string> } | undefined {\n const activePack = packs.find(pack => pack.id === activePackId);\n return activePack && resolveModePackModels(settings, activePack)[modeId] === modelId ? activePack : undefined;\n}\n\nexport function resolveModelDefaults(\n settings: GlobalSettings,\n builtinPacks: Array<{ id: string; models: Record<string, string> }>,\n): Record<string, string> {\n const { activeModelPackId, modeDefaults } = settings.models;\n if (!activeModelPackId) return modeDefaults;\n\n // Custom pack: \"custom:<name>\"\n if (activeModelPackId.startsWith('custom:')) {\n const name = activeModelPackId.slice('custom:'.length);\n const pack = settings.customModelPacks.find(p => p.name === name);\n if (pack) return pack.models;\n // Custom pack was deleted — fall through to modeDefaults\n return modeDefaults;\n }\n\n // Built-in pack\n const builtin = builtinPacks.find(p => p.id === activeModelPackId);\n if (builtin) return resolveModePackModels(settings, builtin);\n\n // Unknown pack id — fall through\n return modeDefaults;\n}\n\n/**\n * Resolve the default reasoning-effort level for a mode.\n *\n * Lookup order:\n * 1. `models.modeThinkingDefaults[mode]` when set for the mode.\n * 2. The global `preferences.thinkingLevel`.\n *\n * Session-level overrides (via /think or the session settings panel) take\n * precedence over both and are handled by the caller.\n */\nexport function resolveDefaultThinkingLevel(\n settings: GlobalSettings,\n mode?: string | null,\n): { level: ThinkingLevelSetting; source: ThinkingLevelSource } {\n return resolveThinkingDefault(\n {\n globalDefault: settings.preferences.thinkingLevel,\n modeDefaults: settings.models.modeThinkingDefaults,\n },\n mode,\n );\n}\n\n/**\n * Resolve the effective model ID for one of the two OM roles.\n *\n * Lookup order:\n * 1. The role-specific override (`observerModelOverride` /\n * `reflectorModelOverride`) if set.\n * 2. If `activeOmPackId` points at a built-in pack, that pack's model.\n * 3. The shared `omModelOverride` fallback.\n *\n * @param settings The loaded global settings.\n * @param role Which OM role to resolve (`'observer'` or `'reflector'`).\n * @param builtinOmPacks Built-in OM packs for the current provider access\n * (from `getAvailableOmPacks`). Pass `[]` if unavailable.\n */\nexport function resolveOmRoleModel(\n settings: GlobalSettings,\n role: 'observer' | 'reflector',\n builtinOmPacks: Array<{ id: string; modelId: string }>,\n): string | null {\n const {\n activeOmPackId,\n omModelOverride,\n observerModelOverride,\n observerModelSelection,\n reflectorModelOverride,\n reflectorModelSelection,\n } = settings.models;\n const model = role === 'observer' ? observerModelSelection : reflectorModelSelection;\n if (model === 'auto') return null;\n if (model) return model;\n\n const roleOverride = role === 'observer' ? observerModelOverride : reflectorModelOverride;\n if (roleOverride) return roleOverride;\n\n if (!activeOmPackId) return omModelOverride;\n if (activeOmPackId === 'custom') return omModelOverride;\n\n const pack = builtinOmPacks.find(p => p.id === activeOmPackId);\n if (pack) return pack.modelId;\n\n return omModelOverride;\n}\n\n/**\n * @deprecated Use `resolveOmRoleModel(settings, 'observer' | 'reflector', ...)`.\n * Equivalent to resolving the observer role (existing callers set both observer\n * and reflector to the same value).\n */\nexport function resolveOmModel(\n settings: GlobalSettings,\n builtinOmPacks: Array<{ id: string; modelId: string }>,\n): string | null {\n return resolveOmRoleModel(settings, 'observer', builtinOmPacks);\n}\n\nfunction getSignalSettingsForSave(settings: GlobalSettings, filePath: string): SignalSettings {\n const loadedSignals = loadedSignalSettings.get(settings);\n if (!loadedSignals || !signalSettingsEqual(settings.signals, loadedSignals) || !existsSync(filePath)) {\n return settings.signals;\n }\n\n try {\n const currentRaw = JSON.parse(readFileSync(filePath, 'utf-8')) as Record<string, unknown>;\n const currentSignals = parseSignalSettings(currentRaw.signals);\n if (!signalSettingsEqual(currentSignals, loadedSignals)) {\n return currentSignals;\n }\n } catch {\n // If the current file is unreadable, fall back to the caller's settings.\n }\n\n return settings.signals;\n}\n\nfunction writeFileAtomically(filePath: string, content: string): void {\n const tempPath = `${filePath}.${process.pid}.${globalThis.crypto.randomUUID()}.tmp`;\n try {\n // Preserve the target's mode across the rename (auth.json keeps its 0600);\n // new files default to owner-only since these are local app-data files.\n const mode = existsSync(filePath) ? statSync(filePath).mode & 0o777 : 0o600;\n writeFileSync(tempPath, content, { encoding: 'utf-8', mode });\n renameSync(tempPath, filePath);\n } finally {\n rmSync(tempPath, { force: true });\n }\n}\n\nexport function saveSettings(settings: GlobalSettings, filePath: string = getSettingsPath()): void {\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n const signals = getSignalSettingsForSave(settings, filePath);\n settings.signals = signals;\n loadedSignalSettings.set(settings, cloneSignalSettings(signals));\n const settingsToSave: Record<string, unknown> = { ...settings };\n delete settingsToSave._experimentalAgentSettingsPath;\n writeFileAtomically(filePath, JSON.stringify(settingsToSave, null, 2));\n}\n\n/** Marker file name to track which provider last used a profile. */\nconst PROFILE_PROVIDER_MARKER = '.mastra-provider';\n\n/**\n * Check which provider last used a profile directory.\n * Returns the provider name if the marker exists, undefined otherwise.\n */\nexport function getProfileProvider(profilePath: string): BrowserProvider | undefined {\n const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);\n if (!existsSync(markerPath)) {\n return undefined;\n }\n try {\n const content = readFileSync(markerPath, 'utf-8').trim();\n if (content === 'stagehand' || content === 'agent-browser') {\n return content;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Write the provider marker to a profile directory.\n * Creates the directory if it doesn't exist.\n */\nexport function setProfileProvider(profilePath: string, provider: BrowserProvider): void {\n const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);\n if (!existsSync(profilePath)) {\n mkdirSync(profilePath, { recursive: true });\n }\n writeFileSync(markerPath, provider, 'utf-8');\n}\n\n/**\n * Check if a profile has a provider mismatch.\n * Returns the existing provider if there's a mismatch, undefined otherwise.\n */\nexport function checkProfileProviderMismatch(\n profilePath: string | undefined,\n targetProvider: BrowserProvider,\n): BrowserProvider | undefined {\n if (!profilePath) {\n return undefined;\n }\n const existingProvider = getProfileProvider(profilePath);\n if (existingProvider && existingProvider !== targetProvider) {\n return existingProvider;\n }\n return undefined;\n}\n\nfunction browserRecordingOptions() {\n return { outputDir: join(getAppDataDir(), 'browser-recordings') };\n}\n\n/**\n * Snapshot of browser settings safe to store in session state (which session clients can read).\n * Strips credentials; keeps everything `/browser status` needs for drift detection.\n */\nexport function toActiveBrowserSettings(settings: BrowserSettings): BrowserSettings {\n if (!settings.stagehand) return { ...settings };\n const { apiKey: _apiKey, ...stagehand } = settings.stagehand;\n return { ...settings, stagehand };\n}\n\nexport type StagehandModelSource =\n /** `browser.stagehand.model` in settings. */\n | 'settings'\n /** No model configured; reusing the chat model that was active when the browser launched. */\n | 'chat-model'\n /** No usable model otherwise; the default model for the user's OpenAI Codex (ChatGPT) login. */\n | 'codex-oauth'\n /** Nothing else applies; Stagehand picks its own default from env API keys. */\n | 'stagehand-default';\n\nexport interface ResolvedStagehandModel {\n /** `provider/model` id, or undefined when Stagehand's own default applies. */\n modelName: string | undefined;\n source: StagehandModelSource;\n /** True when requests go through the user's OpenAI Codex OAuth login instead of an API key. */\n viaCodexOAuth: boolean;\n}\n\nexport interface ResolveStagehandModelOptions {\n /**\n * Chat model id at the moment the browser launches (`session.model.get()`).\n * The Stagehand instance is fixed once created and shared across threads, so\n * later chat-model switches do not affect it.\n */\n chatModelId?: string;\n authStorage?: AuthStorage;\n}\n\n/**\n * Env vars Stagehand reads for each provider it can route (mirrors\n * `STAGEHAND_MODEL_PROVIDERS` in `@mastra/stagehand` and Stagehand's own\n * `providerEnvVarMap`). `null` means the provider needs no API key.\n * Kept here instead of importing `@mastra/stagehand`, which would eagerly\n * load the browser stack into every settings consumer.\n */\nexport const STAGEHAND_PROVIDER_ENV_VARS: Record<string, readonly string[] | null> = {\n openai: ['OPENAI_API_KEY'],\n anthropic: ['ANTHROPIC_API_KEY'],\n google: ['GEMINI_API_KEY', 'GOOGLE_GENERATIVE_AI_API_KEY', 'GOOGLE_API_KEY'],\n vertex: ['GOOGLE_VERTEX_AI_API_KEY'],\n groq: ['GROQ_API_KEY'],\n cerebras: ['CEREBRAS_API_KEY'],\n togetherai: ['TOGETHER_AI_API_KEY'],\n mistral: ['MISTRAL_API_KEY'],\n deepseek: ['DEEPSEEK_API_KEY'],\n perplexity: ['PERPLEXITY_API_KEY'],\n azure: ['AZURE_API_KEY'],\n xai: ['XAI_API_KEY'],\n gateway: ['AI_GATEWAY_API_KEY'],\n bedrock: null,\n ollama: null,\n};\n\nfunction hasCodexOAuthLogin(authStorage: AuthStorage): boolean {\n return authStorage.get('openai-codex')?.type === 'oauth';\n}\n\nfunction isOpenAIModel(modelId: string): boolean {\n return modelId.startsWith(OPENAI_PREFIX);\n}\n\n/**\n * Stagehand hands the segment after `provider/` straight to the AI SDK provider,\n * so apply the same id normalization the chat gateway does before it does.\n */\nfunction normalizeForStagehand(modelId: string): string {\n const bare = stripMastraGatewayPrefix(modelId.trim());\n return bare.startsWith(ANTHROPIC_PREFIX) ? normalizeAnthropicModelId(bare) : bare;\n}\n\n/** Whether Stagehand could run `provider/model` with the credentials available right now. */\nfunction stagehandCanRoute(modelId: string, codexOAuth: boolean): boolean {\n const provider = modelId.split('/', 1)[0];\n if (!provider || provider === modelId) return false;\n if (provider === 'openai' && codexOAuth) return true;\n const envVars = STAGEHAND_PROVIDER_ENV_VARS[provider];\n if (envVars === undefined) return false;\n if (envVars === null) return true;\n return envVars.some(name => Boolean(process.env[name]?.trim()));\n}\n\n/**\n * Resolve which model Stagehand will use and why, without creating a browser.\n * Order: configured `browser.stagehand.model` → the launch-time chat model when\n * Stagehand can route it → the Codex login's default model → Stagehand's own\n * default. Mirrors the selection in `createBrowserFromSettings` so the UI can\n * show it.\n */\nexport function resolveStagehandModel(\n settings: Pick<BrowserSettings, 'provider' | 'stagehand'>,\n { chatModelId, authStorage = new AuthStorage() }: ResolveStagehandModelOptions = {},\n): ResolvedStagehandModel {\n if (settings.provider !== 'stagehand') {\n return { modelName: undefined, source: 'stagehand-default', viaCodexOAuth: false };\n }\n const codexOAuth = hasCodexOAuthLogin(authStorage);\n const configured = settings.stagehand?.model ? normalizeForStagehand(settings.stagehand.model) : undefined;\n if (configured) {\n return { modelName: configured, source: 'settings', viaCodexOAuth: codexOAuth && isOpenAIModel(configured) };\n }\n const chatModel = chatModelId ? normalizeForStagehand(chatModelId) : undefined;\n if (chatModel && stagehandCanRoute(chatModel, codexOAuth)) {\n return { modelName: chatModel, source: 'chat-model', viaCodexOAuth: codexOAuth && isOpenAIModel(chatModel) };\n }\n if (codexOAuth) {\n return { modelName: PROVIDER_DEFAULT_MODELS['openai-codex'], source: 'codex-oauth', viaCodexOAuth: true };\n }\n return { modelName: undefined, source: 'stagehand-default', viaCodexOAuth: false };\n}\n\nexport interface CreateBrowserOptions {\n /** Chat model id at launch; see `ResolveStagehandModelOptions.chatModelId`. */\n chatModelId?: string;\n}\n\n/**\n * Create a browser instance from settings.\n * Shared by startup (main.ts) and live reconfiguration (/browser command).\n * Returns undefined if browser is disabled.\n */\nexport async function createBrowserFromSettings(\n settings: BrowserSettings,\n { chatModelId }: CreateBrowserOptions = {},\n): Promise<MastraBrowser | undefined> {\n if (!settings.enabled) {\n return undefined;\n }\n\n const { provider, headless, viewport, cdpUrl, profile, executablePath, stagehand, agentBrowser } = settings;\n\n // Chrome only allows one process per profile directory, so force 'shared' scope\n // when a profile is set. Otherwise use the user's setting (or provider default).\n const scope = profile ? ('shared' as const) : settings.scope;\n\n // Common launch options (no CDP)\n const launchConfig = { headless, viewport, profile, executablePath, scope } as const;\n\n if (provider === 'stagehand') {\n const { StagehandBrowser } = await import('@mastra/stagehand');\n const stagehandOpts: Record<string, unknown> = {\n env: stagehand?.env ?? 'LOCAL',\n apiKey: stagehand?.apiKey ?? process.env.BROWSERBASE_API_KEY,\n projectId: stagehand?.projectId ?? process.env.BROWSERBASE_PROJECT_ID,\n preserveUserDataDir: stagehand?.preserveUserDataDir,\n recording: browserRecordingOptions(),\n };\n\n // See resolveStagehandModel() for which model is picked. How it is reached\n // depends on the user's OpenAI auth, not on where the model came from:\n // any `openai/*` model goes through the Codex (ChatGPT) endpoint when the\n // user signed in with Codex OAuth, matching the chat agents. Everything\n // else is passed as a plain `provider/model` string and Stagehand resolves\n // the provider's API key from the environment.\n //\n // The Codex route uses the AI SDK provider's standard hooks:\n // - baseURL: target Codex's Responses API directly (no URL rewriting).\n // - headers: static Codex identifiers (originator, UA, account id).\n // - fetch: a tiny refresher that injects the live OAuth bearer per call,\n // since AI SDK takes `apiKey` as a static string.\n // - middleware: createCodexMiddleware() sets `store: false`, which Codex\n // requires on every request.\n const authStorage = new AuthStorage();\n const resolved = resolveStagehandModel(settings, { chatModelId, authStorage });\n if (resolved.modelName && resolved.viaCodexOAuth) {\n const accountId = (authStorage.get('openai-codex') as any)?.accountId as string | undefined;\n stagehandOpts.model = {\n modelName: remapOpenAIModelForCodexOAuth(resolved.modelName),\n apiKey: 'codex-oauth',\n baseURL: 'https://chatgpt.com/backend-api/codex',\n headers: {\n originator: 'mastracode',\n 'User-Agent': 'mastracode',\n ...(accountId ? { 'ChatGPT-Account-ID': accountId } : {}),\n },\n fetch: buildCodexStagehandFetch(authStorage),\n middleware: createCodexMiddleware(),\n } as any;\n } else if (resolved.modelName) {\n stagehandOpts.model = resolved.modelName;\n }\n\n return cdpUrl\n ? new StagehandBrowser({ ...launchConfig, cdpUrl, scope: 'shared', ...stagehandOpts })\n : new StagehandBrowser({ ...launchConfig, ...stagehandOpts });\n } else if (provider === 'agent-browser') {\n const { AgentBrowser } = await import('@mastra/agent-browser');\n const agentBrowserOpts = {\n storageState: agentBrowser?.storageState,\n recording: browserRecordingOptions(),\n };\n return cdpUrl\n ? new AgentBrowser({ ...launchConfig, cdpUrl, scope: 'shared', ...agentBrowserOpts })\n : new AgentBrowser({ ...launchConfig, ...agentBrowserOpts, scope });\n }\n\n throw new Error(`Unsupported browser provider: ${provider}`);\n}\n"],"mappings":"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"}
@@ -30,7 +30,8 @@ export declare function getCurrentVersion(): string;
30
30
  export declare function fetchLatestVersion(): Promise<string | null>;
31
31
  /**
32
32
  * Simple semver comparison: returns true if `latest` is newer than `current`.
33
- * Handles standard x.y.z versions. Ignores pre-release tags.
33
+ * Handles standard x.y.z versions. Pre-release tags only matter against the
34
+ * matching release; two pre-releases of the same version compare equal.
34
35
  */
35
36
  export declare function isNewerVersion(current: string, latest: string): boolean;
36
37
  /**
@@ -64,15 +65,35 @@ export declare function locateOwnInstall(): {
64
65
  dir: string;
65
66
  version: string | null;
66
67
  } | null;
68
+ /**
69
+ * Result of an update attempt. `message` is a ready-made sentence; the other
70
+ * fields let callers lay the result out themselves.
71
+ */
67
72
  export type UpdateOutcome = {
68
73
  status: 'updated';
69
74
  message: string;
75
+ /** The package manager or tool that installed the update. */
76
+ via: string;
70
77
  } | {
71
78
  status: 'unchanged';
72
79
  message: string;
80
+ /** Command the user can run to update the install they're running. */
81
+ command: string;
82
+ /** Where the running install lives, when known. */
83
+ installDir?: string;
84
+ /** Version still on disk after the update ran, when the update ran at all. */
85
+ runningVersion?: string;
86
+ /** Tool that ran the update (when it ran but didn't change the running install). */
87
+ ranWith?: string;
88
+ /** Tool that owns the install when we only suggest its command (e.g. Homebrew). */
89
+ managedBy?: string;
73
90
  } | {
74
91
  status: 'failed';
75
92
  message: string;
93
+ /** Command the user can run instead, when there is one. */
94
+ command?: string;
95
+ /** Why it failed: the tail of the package manager's stderr, or our own reason. */
96
+ details?: string;
76
97
  };
77
98
  /**
78
99
  * Decide what to tell the user after {@link runUpdate}: `updated` when the
@@ -90,12 +111,41 @@ export declare function resolveUpdateOutcome(opts: {
90
111
  } | null;
91
112
  /** Overrides the suggested manual command, e.g. when the update was delegated to the owning tool. */
92
113
  manualCommand?: string;
114
+ /** Tool that ran the update when it wasn't `pm`, e.g. vite-plus. */
115
+ via?: string;
93
116
  }): UpdateOutcome;
94
117
  /**
95
- * Update mastracode and verify the result: delegates to the tool that owns the
96
- * running install when we recognize it, skips the install when it isn't
97
- * managed by `pm`, otherwise runs the package manager. Every executed update
98
- * is verified against the on-disk version.
118
+ * What an update will do for the running install: run an install (with the
119
+ * tool and command it will use), or nothing, with the result to show instead.
120
+ */
121
+ export type UpdatePlan = {
122
+ willInstall: true;
123
+ /** The package manager or tool that will run the install. */
124
+ via: string;
125
+ /** The install command, as the user would type it. */
126
+ command: string;
127
+ exec: {
128
+ cmd: string;
129
+ args: string[];
130
+ };
131
+ } | {
132
+ willInstall: false;
133
+ outcome: Extract<UpdateOutcome, {
134
+ status: 'unchanged' | 'failed';
135
+ }>;
136
+ };
137
+ /**
138
+ * Decide how to update the running install, without changing anything:
139
+ * delegate to the tool that owns it when we recognize it, only suggest a
140
+ * command when that tool can't be run for the user (Homebrew) or `pm` doesn't
141
+ * manage it, otherwise run `pm`. {@link performUpdate} carries out this plan,
142
+ * so callers can show what will happen before it starts.
143
+ */
144
+ export declare function planUpdate(pm: PackageManager, targetVersion: string): Promise<UpdatePlan>;
145
+ /**
146
+ * Update mastracode following {@link planUpdate} (pass a plan already shown to
147
+ * the user, or let this make one), then verify the result against the version
148
+ * on disk.
99
149
  */
100
- export declare function performUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateOutcome>;
150
+ export declare function performUpdate(pm: PackageManager, targetVersion: string, plan?: UpdatePlan): Promise<UpdateOutcome>;
101
151
  //# sourceMappingURL=update-check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAW7D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CA+CpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAY9E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAevE;AAKD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe5E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiD/E;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE1F;AA0CD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CA6BjF;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,EAAE,EAAE,cAAc,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,qGAAqG;IACrG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,aAAa,CAsBhB;AAuDD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoCrG"}
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"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"}
@@ -106,9 +106,11 @@ async function fetchLatestVersion() {
106
106
  return null;
107
107
  }
108
108
  }
109
+ const isPrerelease = (v) => v.includes("-");
109
110
  /**
110
111
  * Simple semver comparison: returns true if `latest` is newer than `current`.
111
- * Handles standard x.y.z versions. Ignores pre-release tags.
112
+ * Handles standard x.y.z versions. Pre-release tags only matter against the
113
+ * matching release; two pre-releases of the same version compare equal.
112
114
  */
113
115
  function isNewerVersion(current, latest) {
114
116
  const parse = (v) => v.replace(/^v/, "").split("-")[0].split(".").map((s) => {
@@ -119,7 +121,8 @@ function isNewerVersion(current, latest) {
119
121
  const [lMajor = 0, lMinor = 0, lPatch = 0] = parse(latest);
120
122
  if (lMajor !== cMajor) return lMajor > cMajor;
121
123
  if (lMinor !== cMinor) return lMinor > cMinor;
122
- return lPatch > cPatch;
124
+ if (lPatch !== cPatch) return lPatch > cPatch;
125
+ return isPrerelease(current) && !isPrerelease(latest);
123
126
  }
124
127
  /** Max entries to show in the changelog summary. */
125
128
  const MAX_CHANGELOG_ENTRIES = 20;
@@ -274,22 +277,30 @@ function locateOwnInstall() {
274
277
  function resolveUpdateOutcome(opts) {
275
278
  const { pm, targetVersion, result, install } = opts;
276
279
  const cmd = opts.manualCommand ?? getInstallCommand(pm, targetVersion);
280
+ const via = opts.via ?? pm;
277
281
  if (!result.ok) {
278
- const details = formatUpdaterError(result.stderr);
282
+ const details = formatUpdaterError(result.stderr) ?? void 0;
279
283
  let message = `Auto-update failed. Run \`${cmd}\` manually.`;
280
284
  if (details) message += `\n\n${details}`;
281
285
  return {
282
286
  status: "failed",
283
- message
287
+ message,
288
+ command: cmd,
289
+ ...details ? { details } : {}
284
290
  };
285
291
  }
286
292
  if (install?.version != null && install.version !== targetVersion) return {
287
293
  status: "unchanged",
288
- message: opts.manualCommand ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still v${install.version}. Try \`${cmd}\` manually.` : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still v${install.version} — it looks like it is managed by another tool. Update it with that tool, or try \`${cmd}\`.`
294
+ message: opts.manualCommand ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still v${install.version}. Try \`${cmd}\` manually.` : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still v${install.version} — it looks like it is managed by another tool. Update it with that tool, or try \`${cmd}\`.`,
295
+ command: cmd,
296
+ installDir: install.dir,
297
+ runningVersion: install.version,
298
+ ranWith: via
289
299
  };
290
300
  return {
291
301
  status: "updated",
292
- message: `Updated to v${targetVersion}. Please restart Mastra Code.`
302
+ message: `Updated to v${targetVersion}. Please restart Mastra Code.`,
303
+ via
293
304
  };
294
305
  }
295
306
  /** Global node_modules directory the package manager installs into, or null when unknown. */
@@ -341,43 +352,81 @@ function findInstallOwner(dir, version) {
341
352
  return null;
342
353
  }
343
354
  /**
344
- * Update mastracode and verify the result: delegates to the tool that owns the
345
- * running install when we recognize it, skips the install when it isn't
346
- * managed by `pm`, otherwise runs the package manager. Every executed update
347
- * is verified against the on-disk version.
355
+ * Decide how to update the running install, without changing anything:
356
+ * delegate to the tool that owns it when we recognize it, only suggest a
357
+ * command when that tool can't be run for the user (Homebrew) or `pm` doesn't
358
+ * manage it, otherwise run `pm`. {@link performUpdate} carries out this plan,
359
+ * so callers can show what will happen before it starts.
348
360
  */
349
- async function performUpdate(pm, targetVersion) {
361
+ async function planUpdate(pm, targetVersion) {
350
362
  if (!/^[\w.+-]+$/.test(targetVersion)) return {
351
- status: "failed",
352
- message: `Auto-update aborted: unexpected version "${targetVersion}".`
363
+ willInstall: false,
364
+ outcome: {
365
+ status: "failed",
366
+ message: `Auto-update aborted: unexpected version "${targetVersion}".`,
367
+ details: `The npm registry returned an unexpected version: "${targetVersion}".`
368
+ }
353
369
  };
354
370
  const install = locateOwnInstall();
355
371
  const owner = install ? findInstallOwner(install.dir, targetVersion) : null;
356
372
  if (owner) {
357
373
  if (!owner.exec) return {
358
- status: "unchanged",
359
- message: `Your Mastra Code install (at ${install.dir}) is managed by ${owner.name}. Update it with \`${owner.command}\`.`
374
+ willInstall: false,
375
+ outcome: {
376
+ status: "unchanged",
377
+ message: `Your Mastra Code install (at ${install.dir}) is managed by ${owner.name}. Update it with \`${owner.command}\`.`,
378
+ command: owner.command,
379
+ installDir: install.dir,
380
+ managedBy: owner.name
381
+ }
382
+ };
383
+ return {
384
+ willInstall: true,
385
+ via: owner.name,
386
+ command: owner.command,
387
+ exec: owner.exec
360
388
  };
361
- return resolveUpdateOutcome({
362
- pm,
363
- targetVersion,
364
- result: await execUpdate(owner.exec.cmd, owner.exec.args),
365
- install: locateOwnInstall(),
366
- manualCommand: owner.command
367
- });
368
389
  }
390
+ const command = getInstallCommand(pm, targetVersion);
369
391
  if (!await isOwnInstallManagedBy(pm, install)) return {
370
- status: "unchanged",
371
- message: `Your Mastra Code install (at ${install.dir}) is not managed by ${pm} — it looks like it was installed by another tool. Update it with that tool, or try \`${getInstallCommand(pm, targetVersion)}\`.`
392
+ willInstall: false,
393
+ outcome: {
394
+ status: "unchanged",
395
+ message: `Your Mastra Code install (at ${install.dir}) is not managed by ${pm} — it looks like it was installed by another tool. Update it with that tool, or try \`${command}\`.`,
396
+ command,
397
+ installDir: install.dir
398
+ }
372
399
  };
400
+ return {
401
+ willInstall: true,
402
+ via: pm,
403
+ command,
404
+ exec: {
405
+ cmd: pm,
406
+ args: buildInstallArgs(pm, targetVersion)
407
+ }
408
+ };
409
+ }
410
+ /**
411
+ * Update mastracode following {@link planUpdate} (pass a plan already shown to
412
+ * the user, or let this make one), then verify the result against the version
413
+ * on disk.
414
+ */
415
+ async function performUpdate(pm, targetVersion, plan) {
416
+ plan ??= await planUpdate(pm, targetVersion);
417
+ if (!plan.willInstall) return plan.outcome;
373
418
  return resolveUpdateOutcome({
374
419
  pm,
375
420
  targetVersion,
376
- result: await runUpdate(pm, targetVersion),
377
- install: locateOwnInstall()
421
+ result: await execUpdate(plan.exec.cmd, plan.exec.args),
422
+ install: locateOwnInstall(),
423
+ ...plan.via === pm ? {} : {
424
+ manualCommand: plan.command,
425
+ via: plan.via
426
+ }
378
427
  });
379
428
  }
380
429
  //#endregion
381
- export { detectPackageManager, fetchChangelog, fetchLatestVersion, getCurrentVersion, getInstallCommand, isNewerVersion, locateOwnInstall, parseChangelog, performUpdate, resolveUpdateOutcome, runUpdate };
430
+ export { detectPackageManager, fetchChangelog, fetchLatestVersion, getCurrentVersion, getInstallCommand, isNewerVersion, locateOwnInstall, parseChangelog, performUpdate, planUpdate, resolveUpdateOutcome, runUpdate };
382
431
 
383
432
  //# sourceMappingURL=update-check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.js","names":[],"sources":["../../src/utils/update-check.ts"],"sourcesContent":["/**\n * Check for newer versions of mastracode on npm.\n */\n\nimport { execFile } from 'node:child_process';\nimport { readFileSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nconst PACKAGE_NAME = 'mastracode';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\n/** Timeout for the npm registry fetch (ms). */\nconst FETCH_TIMEOUT_MS = 5_000;\n\n// Package managers and vp are .cmd shims on Windows; execFile can't spawn those without a shell (EINVAL).\nconst USE_SHELL = process.platform === 'win32';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nfunction matchPM(str: string): PackageManager | null {\n // Order matters: check pnpm before npm since \"npm\" is a substring of some paths\n if (/pnpm/i.test(str)) return 'pnpm';\n if (/\\byarn\\b/i.test(str)) return 'yarn';\n if (/\\bbun\\b/i.test(str)) return 'bun';\n if (/\\bnpm\\b/i.test(str)) return 'npm';\n return null;\n}\n\n/**\n * Detect which package manager was used to install mastracode globally.\n *\n * Uses a multi-tier approach:\n * 1. npm_config_user_agent env var (set when run via `pnpm run`, `npm run`, etc.)\n * 2. npm_execpath env var (fallback for script-based invocation)\n * 3. NODE_PATH env var (set by pnpm global bin stubs)\n * 4. Resolved path of the running script (process.argv[1])\n * 5. Shell-out to `pnpm list -g` to check if pnpm manages the package\n * 6. Falls back to 'npm'\n */\nexport async function detectPackageManager(): Promise<PackageManager> {\n // Tier 1: npm_config_user_agent (most reliable when available)\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n const pm = matchPM(userAgent);\n if (pm) return pm;\n }\n\n // Tier 2: npm_execpath\n const execPath = process.env.npm_execpath;\n if (execPath) {\n const pm = matchPM(execPath);\n if (pm) return pm;\n }\n\n // Tier 3: NODE_PATH (pnpm global stubs set this to paths containing .pnpm)\n const nodePath = process.env.NODE_PATH;\n if (nodePath) {\n if (/[/\\\\]\\.pnpm[/\\\\]/.test(nodePath) || /[/\\\\]pnpm[/\\\\]/.test(nodePath)) return 'pnpm';\n if (/[/\\\\]\\.yarn[/\\\\]/.test(nodePath)) return 'yarn';\n if (/[/\\\\]\\.bun[/\\\\]/.test(nodePath)) return 'bun';\n }\n\n // Tier 4: Resolved script path\n try {\n const scriptPath = realpathSync(process.argv[1] ?? '');\n if (/[/\\\\]\\.?pnpm[/\\\\]/.test(scriptPath)) return 'pnpm';\n if (/[/\\\\]\\.?yarn[/\\\\]/.test(scriptPath)) return 'yarn';\n if (/[/\\\\]\\.?bun[/\\\\]/.test(scriptPath)) return 'bun';\n } catch {\n // realpathSync can fail if argv[1] is missing/broken — fall through\n }\n\n // Tier 5: Check if the package is in pnpm's global store (non-blocking)\n const pnpmResult = await new Promise<boolean>(resolve => {\n execFile(\n 'pnpm',\n ['list', '-g', '--depth=0', PACKAGE_NAME],\n { timeout: 3_000, shell: USE_SHELL },\n (error, stdout) => {\n resolve(!error && stdout.includes(PACKAGE_NAME));\n },\n );\n });\n if (pnpmResult) return 'pnpm';\n\n return 'npm';\n}\n\n/**\n * Build the shell command string a user would run to install/update globally.\n */\nexport function getInstallCommand(pm: PackageManager, version?: string): string {\n const pkg = version ? `${PACKAGE_NAME}@${version}` : `${PACKAGE_NAME}@latest`;\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g ${pkg}`;\n case 'yarn':\n return `yarn global add ${pkg}`;\n case 'bun':\n return `bun add -g ${pkg}`;\n default:\n return `npm install -g ${pkg}`;\n }\n}\n\n/**\n * Read the current version, injected at build time by tsdown's `define` option.\n * Falls back to reading package.json at runtime (e.g. when running from source with tsx).\n */\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n // Fallback for running from source (e.g. pnpx tsx mastracode/src/main.ts)\n const dir = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(dir, '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version;\n}\n\n/**\n * Fetch the latest published version from npm.\n * Returns null if the fetch fails (network error, timeout, etc.).\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_LATEST_VERSION) return process.env.MASTRACODE_UPDATE_LATEST_VERSION;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(NPM_REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Simple semver comparison: returns true if `latest` is newer than `current`.\n * Handles standard x.y.z versions. Ignores pre-release tags.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const parse = (v: string) =>\n v\n .replace(/^v/, '')\n .split('-')[0]!\n .split('.')\n .map(s => {\n const n = Number(s);\n return Number.isFinite(n) ? n : 0;\n });\n const [cMajor = 0, cMinor = 0, cPatch = 0] = parse(current);\n const [lMajor = 0, lMinor = 0, lPatch = 0] = parse(latest);\n if (lMajor !== cMajor) return lMajor > cMajor;\n if (lMinor !== cMinor) return lMinor > cMinor;\n return lPatch > cPatch;\n}\n\n/** Max entries to show in the changelog summary. */\nconst MAX_CHANGELOG_ENTRIES = 20;\n\n/**\n * Fetch the CHANGELOG.md for a specific published version from the npm CDN\n * and extract a human-readable summary of changes.\n * Returns null if the fetch fails or the changelog can't be parsed.\n */\nexport async function fetchChangelog(version: string): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_CHANGELOG) return process.env.MASTRACODE_UPDATE_CHANGELOG;\n\n try {\n const url = `https://unpkg.com/${PACKAGE_NAME}@${version}/CHANGELOG.md`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const text = await res.text();\n return parseChangelog(text, version);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract the changelog section for a specific version and format it\n * as a concise bullet list suitable for terminal display.\n */\nexport function parseChangelog(markdown: string, version: string): string | null {\n const versionHeader = `## ${version}`;\n const startIdx = markdown.indexOf(versionHeader);\n if (startIdx === -1) return null;\n\n const afterHeader = startIdx + versionHeader.length;\n const nextHeaderIdx = markdown.indexOf('\\n## ', afterHeader);\n const section = nextHeaderIdx === -1 ? markdown.slice(afterHeader) : markdown.slice(afterHeader, nextHeaderIdx);\n\n const lines = section.split('\\n');\n const entries: string[] = [];\n let skipIndented = false;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!;\n const trimmed = raw.trim();\n\n // Only match top-level entries (no leading whitespace before \"- \")\n const isTopLevel = raw === trimmed && trimmed.startsWith('- ');\n if (!isTopLevel) {\n // Skip indented sub-items (e.g. dependency list entries)\n if (skipIndented && /^\\s+-\\s/.test(raw)) continue;\n skipIndented = false;\n continue;\n }\n\n // Skip dependency update entries and their sub-items\n if (/^- Updated dependenc/i.test(trimmed)) {\n skipIndented = true;\n continue;\n }\n skipIndented = false;\n\n let entry = trimmed.slice(2);\n // Strip markdown links: [text](url) → text\n entry = entry.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n // Strip PR references like (#15760)\n entry = entry.replace(/\\s*\\(#\\d+\\)\\s*/g, ' ');\n // Strip commit SHA references like (`abc123`)\n entry = entry.replace(/\\s*\\(`[a-f0-9]+`\\)\\s*/g, ' ');\n // Trim trailing periods for cleaner bullet display\n entry = entry.replace(/\\.\\s*$/, '');\n entry = entry.trim();\n if (entry) entries.push(entry);\n if (entries.length >= MAX_CHANGELOG_ENTRIES) break;\n }\n\n if (entries.length === 0) return null;\n return entries.map(e => ` • ${e}`).join('\\n');\n}\n\n/** Result of attempting an auto-update: exit status plus captured stderr. */\nexport interface UpdateResult {\n ok: boolean;\n stderr?: string;\n}\n\n/**\n * Run the appropriate global install command to update mastracode.\n * Exit code 0 does not prove the running binary changed (the install may land\n * in a location the PATH shim doesn't use) — verify with {@link locateOwnInstall}.\n */\nexport function runUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateResult> {\n return execUpdate(pm, buildInstallArgs(pm, targetVersion));\n}\n\nfunction execUpdate(cmd: string, args: string[]): Promise<UpdateResult> {\n return new Promise(resolve => {\n execFile(cmd, args, { timeout: 60_000, shell: USE_SHELL }, (error, _stdout, stderr) => {\n const captured = (stderr ?? '').trim();\n if (error) {\n resolve({ ok: false, stderr: captured || error.message });\n } else {\n resolve({ ok: true, stderr: captured || undefined });\n }\n });\n });\n}\n\nfunction buildInstallArgs(pm: PackageManager, version: string): string[] {\n const pkg = `${PACKAGE_NAME}@${version}`;\n switch (pm) {\n case 'pnpm':\n return ['add', '-g', pkg];\n case 'yarn':\n return ['global', 'add', pkg];\n case 'bun':\n return ['add', '-g', pkg];\n default:\n return ['install', '-g', pkg];\n }\n}\n\n/** Max stderr lines to surface when an update fails. */\nconst MAX_UPDATE_ERROR_LINES = 5;\n\nfunction formatUpdaterError(stderr: string | undefined): string | null {\n if (!stderr) return null;\n const lines = stderr\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line.trim().length > 0);\n if (lines.length === 0) return null;\n return lines.slice(-MAX_UPDATE_ERROR_LINES).join('\\n');\n}\n\n/**\n * Find the installed mastracode package the running binary belongs to (walking\n * up from `process.argv[1]`) and read its version fresh from disk. Returns\n * null when it can't be determined, e.g. when running from source.\n */\nexport function locateOwnInstall(): { dir: string; version: string | null } | null {\n const entry = process.argv[1];\n if (!entry) return null;\n\n let dir: string;\n try {\n dir = dirname(realpathSync(entry));\n } catch {\n return null;\n }\n\n let previous = '';\n while (dir && dir !== previous) {\n try {\n const pkg = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === PACKAGE_NAME) {\n return { dir, version: typeof pkg.version === 'string' ? pkg.version : null };\n }\n } catch {\n // Not a readable manifest — keep walking up.\n }\n previous = dir;\n dir = dirname(dir);\n }\n\n return null;\n}\n\nexport type UpdateOutcome =\n | { status: 'updated'; message: string }\n | { status: 'unchanged'; message: string }\n | { status: 'failed'; message: string };\n\n/**\n * Decide what to tell the user after {@link runUpdate}: `updated` when the\n * on-disk version matches the target (or can't be determined), `unchanged`\n * when the package manager succeeded but the running install didn't change,\n * `failed` on error (with the package manager's stderr).\n */\nexport function resolveUpdateOutcome(opts: {\n pm: PackageManager;\n targetVersion: string;\n result: UpdateResult;\n install: { dir: string; version: string | null } | null;\n /** Overrides the suggested manual command, e.g. when the update was delegated to the owning tool. */\n manualCommand?: string;\n}): UpdateOutcome {\n const { pm, targetVersion, result, install } = opts;\n const cmd = opts.manualCommand ?? getInstallCommand(pm, targetVersion);\n\n if (!result.ok) {\n const details = formatUpdaterError(result.stderr);\n let message = `Auto-update failed. Run \\`${cmd}\\` manually.`;\n if (details) message += `\\n\\n${details}`;\n return { status: 'failed', message };\n }\n\n if (install?.version != null && install.version !== targetVersion) {\n const message = opts.manualCommand\n ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version}. Try \\`${cmd}\\` manually.`\n : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version} — it looks like it is managed by another tool. Update it with that tool, ` +\n `or try \\`${cmd}\\`.`;\n return { status: 'unchanged', message };\n }\n\n return { status: 'updated', message: `Updated to v${targetVersion}. Please restart Mastra Code.` };\n}\n\n/** Global node_modules directory the package manager installs into, or null when unknown. */\nfunction getGlobalRoot(pm: PackageManager): Promise<string | null> {\n const args = pm === 'yarn' ? ['global', 'dir'] : ['root', '-g'];\n return new Promise(res => {\n execFile(pm, args, { timeout: 10_000, shell: USE_SHELL }, (error, stdout) => {\n const out = (stdout ?? '').trim().split('\\n').pop()?.trim();\n if (error || !out) return res(null);\n res(pm === 'yarn' ? resolve(out, 'node_modules') : out);\n });\n });\n}\n\n/**\n * Whether updating via `pm` would touch the install the running binary uses.\n * Fail-open: returns true when either side can't be determined, so the update\n * proceeds and the post-install verification has the final word.\n */\nasync function isOwnInstallManagedBy(pm: PackageManager, install: { dir: string } | null): Promise<boolean> {\n if (!install) return true;\n const root = await getGlobalRoot(pm);\n if (!root) return true;\n try {\n return realpathSync(resolve(root, PACKAGE_NAME)) === install.dir;\n } catch {\n // Package absent from the pm's global root: installing there can't affect the running binary.\n return false;\n }\n}\n\n/** A tool other than a package manager that owns the running install, matched by path. */\ninterface InstallOwner {\n name: string;\n /** Command to run to delegate the update; omitted when we only suggest `command` to the user. */\n exec?: { cmd: string; args: string[] };\n command: string;\n}\n\nfunction findInstallOwner(dir: string, version: string): InstallOwner | null {\n if (dir.startsWith(join(homedir(), '.vite-plus') + sep)) {\n return {\n name: 'vite-plus',\n exec: { cmd: 'vp', args: ['install', '-g', `${PACKAGE_NAME}@${version}`] },\n command: `vp install -g ${PACKAGE_NAME}@${version}`,\n };\n }\n // Homebrew keeps formulas under <prefix>/Cellar/ whatever the prefix, so match the path segment.\n if (dir.split(sep).includes('Cellar')) {\n // Suggest-only: brew formulas lag npm, and `brew upgrade` can pull unrelated updates.\n return { name: 'Homebrew', command: `brew upgrade ${PACKAGE_NAME}` };\n }\n return null;\n}\n\n/**\n * Update mastracode and verify the result: delegates to the tool that owns the\n * running install when we recognize it, skips the install when it isn't\n * managed by `pm`, otherwise runs the package manager. Every executed update\n * is verified against the on-disk version.\n */\nexport async function performUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateOutcome> {\n // The registry-provided version reaches shell commands on Windows — accept only version tokens.\n if (!/^[\\w.+-]+$/.test(targetVersion)) {\n return { status: 'failed', message: `Auto-update aborted: unexpected version \"${targetVersion}\".` };\n }\n\n const install = locateOwnInstall();\n\n const owner = install ? findInstallOwner(install.dir, targetVersion) : null;\n if (owner) {\n if (!owner.exec) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is managed by ${owner.name}. ` +\n `Update it with \\`${owner.command}\\`.`;\n return { status: 'unchanged', message };\n }\n const result = await execUpdate(owner.exec.cmd, owner.exec.args);\n return resolveUpdateOutcome({\n pm,\n targetVersion,\n result,\n install: locateOwnInstall(),\n manualCommand: owner.command,\n });\n }\n\n if (!(await isOwnInstallManagedBy(pm, install))) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is not managed by ${pm} — it looks like it was ` +\n `installed by another tool. Update it with that tool, or try \\`${getInstallCommand(pm, targetVersion)}\\`.`;\n return { status: 'unchanged', message };\n }\n\n const result = await runUpdate(pm, targetVersion);\n // Re-locate so the version reflects what the install just wrote to disk.\n return resolveUpdateOutcome({ pm, targetVersion, result, install: locateOwnInstall() });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"update-check.js","names":[],"sources":["../../src/utils/update-check.ts"],"sourcesContent":["/**\n * Check for newer versions of mastracode on npm.\n */\n\nimport { execFile } from 'node:child_process';\nimport { readFileSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nconst PACKAGE_NAME = 'mastracode';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\n/** Timeout for the npm registry fetch (ms). */\nconst FETCH_TIMEOUT_MS = 5_000;\n\n// Package managers and vp are .cmd shims on Windows; execFile can't spawn those without a shell (EINVAL).\nconst USE_SHELL = process.platform === 'win32';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nfunction matchPM(str: string): PackageManager | null {\n // Order matters: check pnpm before npm since \"npm\" is a substring of some paths\n if (/pnpm/i.test(str)) return 'pnpm';\n if (/\\byarn\\b/i.test(str)) return 'yarn';\n if (/\\bbun\\b/i.test(str)) return 'bun';\n if (/\\bnpm\\b/i.test(str)) return 'npm';\n return null;\n}\n\n/**\n * Detect which package manager was used to install mastracode globally.\n *\n * Uses a multi-tier approach:\n * 1. npm_config_user_agent env var (set when run via `pnpm run`, `npm run`, etc.)\n * 2. npm_execpath env var (fallback for script-based invocation)\n * 3. NODE_PATH env var (set by pnpm global bin stubs)\n * 4. Resolved path of the running script (process.argv[1])\n * 5. Shell-out to `pnpm list -g` to check if pnpm manages the package\n * 6. Falls back to 'npm'\n */\nexport async function detectPackageManager(): Promise<PackageManager> {\n // Tier 1: npm_config_user_agent (most reliable when available)\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n const pm = matchPM(userAgent);\n if (pm) return pm;\n }\n\n // Tier 2: npm_execpath\n const execPath = process.env.npm_execpath;\n if (execPath) {\n const pm = matchPM(execPath);\n if (pm) return pm;\n }\n\n // Tier 3: NODE_PATH (pnpm global stubs set this to paths containing .pnpm)\n const nodePath = process.env.NODE_PATH;\n if (nodePath) {\n if (/[/\\\\]\\.pnpm[/\\\\]/.test(nodePath) || /[/\\\\]pnpm[/\\\\]/.test(nodePath)) return 'pnpm';\n if (/[/\\\\]\\.yarn[/\\\\]/.test(nodePath)) return 'yarn';\n if (/[/\\\\]\\.bun[/\\\\]/.test(nodePath)) return 'bun';\n }\n\n // Tier 4: Resolved script path\n try {\n const scriptPath = realpathSync(process.argv[1] ?? '');\n if (/[/\\\\]\\.?pnpm[/\\\\]/.test(scriptPath)) return 'pnpm';\n if (/[/\\\\]\\.?yarn[/\\\\]/.test(scriptPath)) return 'yarn';\n if (/[/\\\\]\\.?bun[/\\\\]/.test(scriptPath)) return 'bun';\n } catch {\n // realpathSync can fail if argv[1] is missing/broken — fall through\n }\n\n // Tier 5: Check if the package is in pnpm's global store (non-blocking)\n const pnpmResult = await new Promise<boolean>(resolve => {\n execFile(\n 'pnpm',\n ['list', '-g', '--depth=0', PACKAGE_NAME],\n { timeout: 3_000, shell: USE_SHELL },\n (error, stdout) => {\n resolve(!error && stdout.includes(PACKAGE_NAME));\n },\n );\n });\n if (pnpmResult) return 'pnpm';\n\n return 'npm';\n}\n\n/**\n * Build the shell command string a user would run to install/update globally.\n */\nexport function getInstallCommand(pm: PackageManager, version?: string): string {\n const pkg = version ? `${PACKAGE_NAME}@${version}` : `${PACKAGE_NAME}@latest`;\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g ${pkg}`;\n case 'yarn':\n return `yarn global add ${pkg}`;\n case 'bun':\n return `bun add -g ${pkg}`;\n default:\n return `npm install -g ${pkg}`;\n }\n}\n\n/**\n * Read the current version, injected at build time by tsdown's `define` option.\n * Falls back to reading package.json at runtime (e.g. when running from source with tsx).\n */\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n // Fallback for running from source (e.g. pnpx tsx mastracode/src/main.ts)\n const dir = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(dir, '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version;\n}\n\n/**\n * Fetch the latest published version from npm.\n * Returns null if the fetch fails (network error, timeout, etc.).\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_LATEST_VERSION) return process.env.MASTRACODE_UPDATE_LATEST_VERSION;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(NPM_REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\nconst isPrerelease = (v: string) => v.includes('-');\n\n/**\n * Simple semver comparison: returns true if `latest` is newer than `current`.\n * Handles standard x.y.z versions. Pre-release tags only matter against the\n * matching release; two pre-releases of the same version compare equal.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const parse = (v: string) =>\n v\n .replace(/^v/, '')\n .split('-')[0]!\n .split('.')\n .map(s => {\n const n = Number(s);\n return Number.isFinite(n) ? n : 0;\n });\n const [cMajor = 0, cMinor = 0, cPatch = 0] = parse(current);\n const [lMajor = 0, lMinor = 0, lPatch = 0] = parse(latest);\n if (lMajor !== cMajor) return lMajor > cMajor;\n if (lMinor !== cMinor) return lMinor > cMinor;\n if (lPatch !== cPatch) return lPatch > cPatch;\n // Same x.y.z: a release is newer than its own prerelease (1.2.0 > 1.2.0-rc.1).\n return isPrerelease(current) && !isPrerelease(latest);\n}\n\n/** Max entries to show in the changelog summary. */\nconst MAX_CHANGELOG_ENTRIES = 20;\n\n/**\n * Fetch the CHANGELOG.md for a specific published version from the npm CDN\n * and extract a human-readable summary of changes.\n * Returns null if the fetch fails or the changelog can't be parsed.\n */\nexport async function fetchChangelog(version: string): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_CHANGELOG) return process.env.MASTRACODE_UPDATE_CHANGELOG;\n\n try {\n const url = `https://unpkg.com/${PACKAGE_NAME}@${version}/CHANGELOG.md`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const text = await res.text();\n return parseChangelog(text, version);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract the changelog section for a specific version and format it\n * as a concise bullet list suitable for terminal display.\n */\nexport function parseChangelog(markdown: string, version: string): string | null {\n const versionHeader = `## ${version}`;\n const startIdx = markdown.indexOf(versionHeader);\n if (startIdx === -1) return null;\n\n const afterHeader = startIdx + versionHeader.length;\n const nextHeaderIdx = markdown.indexOf('\\n## ', afterHeader);\n const section = nextHeaderIdx === -1 ? markdown.slice(afterHeader) : markdown.slice(afterHeader, nextHeaderIdx);\n\n const lines = section.split('\\n');\n const entries: string[] = [];\n let skipIndented = false;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!;\n const trimmed = raw.trim();\n\n // Only match top-level entries (no leading whitespace before \"- \")\n const isTopLevel = raw === trimmed && trimmed.startsWith('- ');\n if (!isTopLevel) {\n // Skip indented sub-items (e.g. dependency list entries)\n if (skipIndented && /^\\s+-\\s/.test(raw)) continue;\n skipIndented = false;\n continue;\n }\n\n // Skip dependency update entries and their sub-items\n if (/^- Updated dependenc/i.test(trimmed)) {\n skipIndented = true;\n continue;\n }\n skipIndented = false;\n\n let entry = trimmed.slice(2);\n // Strip markdown links: [text](url) → text\n entry = entry.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n // Strip PR references like (#15760)\n entry = entry.replace(/\\s*\\(#\\d+\\)\\s*/g, ' ');\n // Strip commit SHA references like (`abc123`)\n entry = entry.replace(/\\s*\\(`[a-f0-9]+`\\)\\s*/g, ' ');\n // Trim trailing periods for cleaner bullet display\n entry = entry.replace(/\\.\\s*$/, '');\n entry = entry.trim();\n if (entry) entries.push(entry);\n if (entries.length >= MAX_CHANGELOG_ENTRIES) break;\n }\n\n if (entries.length === 0) return null;\n return entries.map(e => ` • ${e}`).join('\\n');\n}\n\n/** Result of attempting an auto-update: exit status plus captured stderr. */\nexport interface UpdateResult {\n ok: boolean;\n stderr?: string;\n}\n\n/**\n * Run the appropriate global install command to update mastracode.\n * Exit code 0 does not prove the running binary changed (the install may land\n * in a location the PATH shim doesn't use) — verify with {@link locateOwnInstall}.\n */\nexport function runUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateResult> {\n return execUpdate(pm, buildInstallArgs(pm, targetVersion));\n}\n\nfunction execUpdate(cmd: string, args: string[]): Promise<UpdateResult> {\n return new Promise(resolve => {\n execFile(cmd, args, { timeout: 60_000, shell: USE_SHELL }, (error, _stdout, stderr) => {\n const captured = (stderr ?? '').trim();\n if (error) {\n resolve({ ok: false, stderr: captured || error.message });\n } else {\n resolve({ ok: true, stderr: captured || undefined });\n }\n });\n });\n}\n\nfunction buildInstallArgs(pm: PackageManager, version: string): string[] {\n const pkg = `${PACKAGE_NAME}@${version}`;\n switch (pm) {\n case 'pnpm':\n return ['add', '-g', pkg];\n case 'yarn':\n return ['global', 'add', pkg];\n case 'bun':\n return ['add', '-g', pkg];\n default:\n return ['install', '-g', pkg];\n }\n}\n\n/** Max stderr lines to surface when an update fails. */\nconst MAX_UPDATE_ERROR_LINES = 5;\n\nfunction formatUpdaterError(stderr: string | undefined): string | null {\n if (!stderr) return null;\n const lines = stderr\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line.trim().length > 0);\n if (lines.length === 0) return null;\n return lines.slice(-MAX_UPDATE_ERROR_LINES).join('\\n');\n}\n\n/**\n * Find the installed mastracode package the running binary belongs to (walking\n * up from `process.argv[1]`) and read its version fresh from disk. Returns\n * null when it can't be determined, e.g. when running from source.\n */\nexport function locateOwnInstall(): { dir: string; version: string | null } | null {\n const entry = process.argv[1];\n if (!entry) return null;\n\n let dir: string;\n try {\n dir = dirname(realpathSync(entry));\n } catch {\n return null;\n }\n\n let previous = '';\n while (dir && dir !== previous) {\n try {\n const pkg = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === PACKAGE_NAME) {\n return { dir, version: typeof pkg.version === 'string' ? pkg.version : null };\n }\n } catch {\n // Not a readable manifest — keep walking up.\n }\n previous = dir;\n dir = dirname(dir);\n }\n\n return null;\n}\n\n/**\n * Result of an update attempt. `message` is a ready-made sentence; the other\n * fields let callers lay the result out themselves.\n */\nexport type UpdateOutcome =\n | {\n status: 'updated';\n message: string;\n /** The package manager or tool that installed the update. */\n via: string;\n }\n | {\n status: 'unchanged';\n message: string;\n /** Command the user can run to update the install they're running. */\n command: string;\n /** Where the running install lives, when known. */\n installDir?: string;\n /** Version still on disk after the update ran, when the update ran at all. */\n runningVersion?: string;\n /** Tool that ran the update (when it ran but didn't change the running install). */\n ranWith?: string;\n /** Tool that owns the install when we only suggest its command (e.g. Homebrew). */\n managedBy?: string;\n }\n | {\n status: 'failed';\n message: string;\n /** Command the user can run instead, when there is one. */\n command?: string;\n /** Why it failed: the tail of the package manager's stderr, or our own reason. */\n details?: string;\n };\n\n/**\n * Decide what to tell the user after {@link runUpdate}: `updated` when the\n * on-disk version matches the target (or can't be determined), `unchanged`\n * when the package manager succeeded but the running install didn't change,\n * `failed` on error (with the package manager's stderr).\n */\nexport function resolveUpdateOutcome(opts: {\n pm: PackageManager;\n targetVersion: string;\n result: UpdateResult;\n install: { dir: string; version: string | null } | null;\n /** Overrides the suggested manual command, e.g. when the update was delegated to the owning tool. */\n manualCommand?: string;\n /** Tool that ran the update when it wasn't `pm`, e.g. vite-plus. */\n via?: string;\n}): UpdateOutcome {\n const { pm, targetVersion, result, install } = opts;\n const cmd = opts.manualCommand ?? getInstallCommand(pm, targetVersion);\n const via = opts.via ?? pm;\n\n if (!result.ok) {\n const details = formatUpdaterError(result.stderr) ?? undefined;\n let message = `Auto-update failed. Run \\`${cmd}\\` manually.`;\n if (details) message += `\\n\\n${details}`;\n return { status: 'failed', message, command: cmd, ...(details ? { details } : {}) };\n }\n\n if (install?.version != null && install.version !== targetVersion) {\n const message = opts.manualCommand\n ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version}. Try \\`${cmd}\\` manually.`\n : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version} — it looks like it is managed by another tool. Update it with that tool, ` +\n `or try \\`${cmd}\\`.`;\n return {\n status: 'unchanged',\n message,\n command: cmd,\n installDir: install.dir,\n runningVersion: install.version,\n ranWith: via,\n };\n }\n\n return { status: 'updated', message: `Updated to v${targetVersion}. Please restart Mastra Code.`, via };\n}\n\n/** Global node_modules directory the package manager installs into, or null when unknown. */\nfunction getGlobalRoot(pm: PackageManager): Promise<string | null> {\n const args = pm === 'yarn' ? ['global', 'dir'] : ['root', '-g'];\n return new Promise(res => {\n execFile(pm, args, { timeout: 10_000, shell: USE_SHELL }, (error, stdout) => {\n const out = (stdout ?? '').trim().split('\\n').pop()?.trim();\n if (error || !out) return res(null);\n res(pm === 'yarn' ? resolve(out, 'node_modules') : out);\n });\n });\n}\n\n/**\n * Whether updating via `pm` would touch the install the running binary uses.\n * Fail-open: returns true when either side can't be determined, so the update\n * proceeds and the post-install verification has the final word.\n */\nasync function isOwnInstallManagedBy(pm: PackageManager, install: { dir: string } | null): Promise<boolean> {\n if (!install) return true;\n const root = await getGlobalRoot(pm);\n if (!root) return true;\n try {\n return realpathSync(resolve(root, PACKAGE_NAME)) === install.dir;\n } catch {\n // Package absent from the pm's global root: installing there can't affect the running binary.\n return false;\n }\n}\n\n/** A tool other than a package manager that owns the running install, matched by path. */\ninterface InstallOwner {\n name: string;\n /** Command to run to delegate the update; omitted when we only suggest `command` to the user. */\n exec?: { cmd: string; args: string[] };\n command: string;\n}\n\nfunction findInstallOwner(dir: string, version: string): InstallOwner | null {\n if (dir.startsWith(join(homedir(), '.vite-plus') + sep)) {\n return {\n name: 'vite-plus',\n exec: { cmd: 'vp', args: ['install', '-g', `${PACKAGE_NAME}@${version}`] },\n command: `vp install -g ${PACKAGE_NAME}@${version}`,\n };\n }\n // Homebrew keeps formulas under <prefix>/Cellar/ whatever the prefix, so match the path segment.\n if (dir.split(sep).includes('Cellar')) {\n // Suggest-only: brew formulas lag npm, and `brew upgrade` can pull unrelated updates.\n return { name: 'Homebrew', command: `brew upgrade ${PACKAGE_NAME}` };\n }\n return null;\n}\n\n/**\n * What an update will do for the running install: run an install (with the\n * tool and command it will use), or nothing, with the result to show instead.\n */\nexport type UpdatePlan =\n | {\n willInstall: true;\n /** The package manager or tool that will run the install. */\n via: string;\n /** The install command, as the user would type it. */\n command: string;\n exec: { cmd: string; args: string[] };\n }\n | { willInstall: false; outcome: Extract<UpdateOutcome, { status: 'unchanged' | 'failed' }> };\n\n/**\n * Decide how to update the running install, without changing anything:\n * delegate to the tool that owns it when we recognize it, only suggest a\n * command when that tool can't be run for the user (Homebrew) or `pm` doesn't\n * manage it, otherwise run `pm`. {@link performUpdate} carries out this plan,\n * so callers can show what will happen before it starts.\n */\nexport async function planUpdate(pm: PackageManager, targetVersion: string): Promise<UpdatePlan> {\n // The registry-provided version reaches shell commands on Windows — accept only version tokens.\n if (!/^[\\w.+-]+$/.test(targetVersion)) {\n return {\n willInstall: false,\n outcome: {\n status: 'failed',\n message: `Auto-update aborted: unexpected version \"${targetVersion}\".`,\n details: `The npm registry returned an unexpected version: \"${targetVersion}\".`,\n },\n };\n }\n\n const install = locateOwnInstall();\n\n const owner = install ? findInstallOwner(install.dir, targetVersion) : null;\n if (owner) {\n if (!owner.exec) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is managed by ${owner.name}. ` +\n `Update it with \\`${owner.command}\\`.`;\n return {\n willInstall: false,\n outcome: {\n status: 'unchanged',\n message,\n command: owner.command,\n installDir: install!.dir,\n managedBy: owner.name,\n },\n };\n }\n return { willInstall: true, via: owner.name, command: owner.command, exec: owner.exec };\n }\n\n const command = getInstallCommand(pm, targetVersion);\n if (!(await isOwnInstallManagedBy(pm, install))) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is not managed by ${pm} — it looks like it was ` +\n `installed by another tool. Update it with that tool, or try \\`${command}\\`.`;\n return { willInstall: false, outcome: { status: 'unchanged', message, command, installDir: install!.dir } };\n }\n\n return { willInstall: true, via: pm, command, exec: { cmd: pm, args: buildInstallArgs(pm, targetVersion) } };\n}\n\n/**\n * Update mastracode following {@link planUpdate} (pass a plan already shown to\n * the user, or let this make one), then verify the result against the version\n * on disk.\n */\nexport async function performUpdate(\n pm: PackageManager,\n targetVersion: string,\n plan?: UpdatePlan,\n): Promise<UpdateOutcome> {\n plan ??= await planUpdate(pm, targetVersion);\n if (!plan.willInstall) return plan.outcome;\n\n const result = await execUpdate(plan.exec.cmd, plan.exec.args);\n // Re-locate so the version reflects what the install just wrote to disk.\n return resolveUpdateOutcome({\n pm,\n targetVersion,\n result,\n install: locateOwnInstall(),\n // A delegated update keeps the owning tool's command; `pm` updates keep the default wording.\n ...(plan.via === pm ? {} : { manualCommand: plan.command, via: plan.via }),\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "1.12.0-alpha.5",
3
+ "version": "1.12.0-alpha.7",
4
4
  "description": "Mastra Code SDK: the agent core behind Mastra Code (everything except the TUI) — build your own UIs and surfaces on top of it",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -63,19 +63,19 @@
63
63
  "yaml": "^2.7.1",
64
64
  "zod": "^4.6.4",
65
65
  "@mastra/agent-browser": "0.5.3",
66
- "@mastra/fastembed": "1.3.2",
66
+ "@mastra/core": "1.76.0-alpha.7",
67
+ "@mastra/github-signals": "0.5.1",
67
68
  "@mastra/duckdb": "1.14.0-alpha.0",
68
69
  "@mastra/libsql": "1.26.0-alpha.2",
69
- "@mastra/mcp": "2.2.1-alpha.0",
70
- "@mastra/core": "1.76.0-alpha.5",
71
- "@mastra/github-signals": "0.5.1",
70
+ "@mastra/fastembed": "1.3.2",
71
+ "@mastra/observability": "1.19.0-alpha.4",
72
+ "@mastra/mcp": "2.3.0-alpha.1",
72
73
  "@mastra/memory": "1.37.0-alpha.2",
73
- "@mastra/parallel": "0.1.2",
74
- "@mastra/schema-compat": "1.3.13",
75
74
  "@mastra/pg": "1.31.0-alpha.3",
76
75
  "@mastra/stagehand": "0.3.5",
77
- "@mastra/tavily": "1.1.2",
78
- "@mastra/observability": "1.19.0-alpha.2"
76
+ "@mastra/parallel": "0.1.2",
77
+ "@mastra/schema-compat": "1.3.13",
78
+ "@mastra/tavily": "1.1.2"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@libsql/client": "^0.18.0",
@@ -87,8 +87,8 @@
87
87
  "typescript-eslint": "^8.57.0",
88
88
  "vitest": "4.1.11",
89
89
  "@internal/lint": "0.0.141",
90
- "@internal/types-builder": "0.0.116",
91
- "@internal/workspace-test-utils": "0.0.85"
90
+ "@internal/workspace-test-utils": "0.0.85",
91
+ "@internal/types-builder": "0.0.116"
92
92
  },
93
93
  "engines": {
94
94
  "node": ">=22.19.0"