@mastra/code-sdk 1.6.0-alpha.0 → 1.6.0-alpha.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @mastra/code-sdk
2
2
 
3
+ ## 1.6.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - Enabled first-message thread title generation for all Mastra Code clients. ([#22560](https://github.com/mastra-ai/mastra/pull/22560))
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`604da15`](https://github.com/mastra-ai/mastra/commit/604da153fe3170b7e4d9402b0f02ce417b39b417), [`d94e242`](https://github.com/mastra-ai/mastra/commit/d94e2423909cfc859eaf39827e83c832439e6b6d), [`8571a42`](https://github.com/mastra-ai/mastra/commit/8571a42c8039e938564e5c5fb0a6b75377c4fe67)]:
12
+ - @mastra/github-signals@0.4.0-alpha.0
13
+ - @mastra/memory@1.28.2-alpha.0
14
+
15
+ ## 1.6.0-alpha.1
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [[`a3606a0`](https://github.com/mastra-ai/mastra/commit/a3606a09f3deaeef17caf04b9c6a0d7cd6b80fe6), [`4095752`](https://github.com/mastra-ai/mastra/commit/40957529233d202446ebecab1f59c76e99910230), [`a3606a0`](https://github.com/mastra-ai/mastra/commit/a3606a09f3deaeef17caf04b9c6a0d7cd6b80fe6)]:
20
+ - @mastra/core@1.63.3-alpha.1
21
+
3
22
  ## 1.6.0-alpha.0
4
23
 
5
24
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAgB,MAAM,gBAAgB,CAAC;AAkEtD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AA6B9C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,YAAY,IAM3E,oBAAoB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,YAmH/D"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAgB,MAAM,gBAAgB,CAAC;AAkEtD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AA6B9C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,YAAY,IAM3E,oBAAoB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,YAkH/D"}
@@ -114,7 +114,7 @@ function getDynamicMemory(storage, vector) {
114
114
  vector: vector || false,
115
115
  embedder: vector ? fastembed.small : void 0,
116
116
  options: {
117
- ...isFactory ? { generateTitle: { model: getObserverModel } } : {},
117
+ generateTitle: { model: getObserverModel },
118
118
  observationalMemory: {
119
119
  enabled: true,
120
120
  temporalMarkers: true,
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","names":[],"sources":["../../src/agents/memory.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { fastembed } from '@mastra/fastembed';\nimport { Memory, Subconscious } from '@mastra/memory';\nimport { DEFAULT_OM_MODEL_ID, DEFAULT_OBS_THRESHOLD, DEFAULT_REF_THRESHOLD } from '../constants.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getOmScope } from '../utils/project.js';\nimport { resolveModel } from './model.js';\n\n/**\n * Read controller state from requestContext.\n * Used by both the memory factory and the OM model functions.\n */\nfunction getAgentControllerState(requestContext: RequestContext): MastraCodeState | undefined {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n return ctx?.getState() as MastraCodeState | undefined;\n}\n\n/**\n * Observer model function — reads the current observer model ID from\n * controller state via requestContext (now propagated by OM's agent.generate).\n */\nfunction getObserverModel({ requestContext }: { requestContext: RequestContext }) {\n const state = getAgentControllerState(requestContext);\n return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, {\n remapForCodexOAuth: true,\n requestContext,\n });\n}\n\n/**\n * Reflector model function — reads the current reflector model ID from\n * controller state via requestContext (now propagated by OM's agent.generate).\n */\nfunction getReflectorModel({ requestContext }: { requestContext: RequestContext }) {\n const state = getAgentControllerState(requestContext);\n return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, {\n remapForCodexOAuth: true,\n requestContext,\n });\n}\n\nconst DYNAMIC_AGENTS_MD_INSTRUCTION =\n 'Messages wrapped in <system-reminder type=\"dynamic-agents-md\" ...>...</system-reminder> are ephemeral project-context instructions injected from files on disk. Do NOT observe or extract information from these messages — they are reloaded automatically when needed and should not be stored in memory.';\n\n// Derived from https://github.com/JuliusBrussee/caveman and adapted for OM use with fixed full-level compression.\nconst CAVEMAN_OM_INSTRUCTION = `Respond terse like smart caveman. All technical substance stay. Only fluff die.\n\nUse full caveman compression style.\n\nDrop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not \"implement a solution for\"). Technical terms exact. Code blocks unchanged. Errors quoted exact. Leave out the words \"agent\" and \"assistant\" at the start of each observation line, it is assumed each line is referring to the assistant unless it specifically says it was about the user. Leave out parenthesis and other text characters like * that would not contribute to understanding the observations.\n\nPattern: \\`[thing] [action] [reason]. [next step]\\`\n\nNot: \"Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...\"\nYes: \"Bug in auth middleware. Token expiry check use < not <=. Fix:\"\n\nExample 1\n🔴 14:31 user asks why React component rerenders\n🟡 14:32 saw inline object prop create new ref each render, cause rerender\n✅ 14:34 fixed render issue by wrap object in useMemo\n\nExample 2\n🟡 15:10 explained pool reuse DB connections, skip repeat handshake overhead\n\nDon't say \"Agent did x\", say \"did x\". It will be assumed the agent did what was observed. The who should only be specified for the user or other third parties: \"user asked x\"\n\nDrop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;\n\n/**\n * The organization rung local (TUI/studio) knowledge is captured under. A fixed\n * literal on purpose: deriving it from a hostname or path would fragment local\n * knowledge per checkout into scopes nothing ever reads.\n */\nexport const LOCAL_KNOWLEDGE_ORG_ID = 'local';\n\n// One error per session, not per memory resolution. Keyed on the session id\n// rather than the controller object: the controller is read off the request\n// context on every resolution, so it is a fresh object per request and would\n// dedupe nothing. Bounded so a long-running Factory process cannot grow this\n// without limit — refusing sessions are rare, and losing the oldest ids only\n// costs one extra log line.\nconst REPORTED_ORG_UNRESOLVED_LIMIT = 500;\nconst reportedOrgUnresolved = new Set<string>();\n\nfunction reportOrgUnresolved(\n controller: AgentControllerRequestContext<MastraCodeState> | undefined,\n factoryProjectId: string | undefined,\n) {\n const sessionId = controller?.session?.id;\n if (sessionId) {\n if (reportedOrgUnresolved.has(sessionId)) return;\n if (reportedOrgUnresolved.size >= REPORTED_ORG_UNRESOLVED_LIMIT) {\n reportedOrgUnresolved.delete(reportedOrgUnresolved.values().next().value as string);\n }\n reportedOrgUnresolved.add(sessionId);\n }\n const session = controller?.session;\n console.error(\n `[Subconscious] Knowledge capture disabled: no organization resolved for session ${session?.id ?? 'unknown'} (project ${factoryProjectId ?? 'none'}). Knowledge is not written rather than written where it cannot be read.`,\n );\n}\n\n/**\n * Dynamic memory factory function.\n * Reads OM thresholds from controller state via requestContext.\n * Model functions also read from requestContext (no mutable bridge needed).\n */\nexport function getDynamicMemory(storage: MastraCompositeStore, vector?: MastraVector) {\n // Cache is scoped per storage instance (per getDynamicMemory call) so a\n // Memory bound to one storage is never reused after storage changes.\n let cachedMemory: Memory | null = null;\n let cachedMemoryKey: string | null = null;\n\n return ({ requestContext }: { requestContext: RequestContext }) => {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const subconsciousEnabled = Boolean(vector) && process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === '1';\n const factoryProjectId = state?.factoryProjectId;\n const isFactory = typeof factoryProjectId === 'string' && factoryProjectId.trim().length > 0;\n\n // A Factory-owned session that could not resolve its org refuses to capture:\n // writing under a substituted identity produces knowledge the fail-closed\n // read path can never see.\n let orgUnresolvedRefusal = false;\n\n if (subconsciousEnabled) {\n // Factory seeds the authoritative org id into session state. There is no\n // fallback: a session owner is a USER id, never an organization.\n const factoryOrgId = state?.factoryOrgId;\n const factoryOwned = isFactory || state?.factoryOrgUnresolved === true;\n if (typeof factoryOrgId === 'string' && factoryOrgId.trim()) {\n requestContext.set('organizationId', factoryOrgId);\n } else if (factoryOwned) {\n orgUnresolvedRefusal = true;\n reportOrgUnresolved(controller, factoryProjectId);\n } else {\n // TUI/studio: an explicit, named scope rather than a cascaded identity.\n requestContext.set('organizationId', LOCAL_KNOWLEDGE_ORG_ID);\n }\n // Factory runs share one knowledge graph per project: anchor the\n // subconscious knowledge scope's resource rung on the project id.\n if (isFactory) {\n requestContext.set('knowledgeResourceId', factoryProjectId);\n }\n }\n\n const captureEnabled = subconsciousEnabled && !orgUnresolvedRefusal;\n\n const omScope = state?.omScope ?? getOmScope(state?.projectPath);\n\n const obsThreshold = state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD;\n const refThreshold = state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD;\n const caveman = state?.cavemanObservations ?? false;\n\n const observerPreviousObservationTokens = 1000;\n const observeAttachments = state?.observeAttachments;\n // Factory sessions get a factory-only Subconscious config, so the cache key\n // carries a factory presence bit to keep the two configs from cross-serving.\n const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}:${captureEnabled ? 1 : 0}`;\n if (cachedMemory && cachedMemoryKey === cacheKey) {\n return cachedMemory;\n }\n\n // Async buffering is not supported with resource scope — disable it\n const isResourceScope = omScope === 'resource';\n\n const observerInstruction = caveman\n ? `${DYNAMIC_AGENTS_MD_INSTRUCTION}\\n\\n${CAVEMAN_OM_INSTRUCTION}`\n : DYNAMIC_AGENTS_MD_INSTRUCTION;\n const reflectionInstruction = caveman ? CAVEMAN_OM_INSTRUCTION : undefined;\n\n cachedMemory = new Memory({\n storage,\n vector: vector || false,\n embedder: vector ? fastembed.small : undefined,\n options: {\n // The factory sidebar shows a session the moment it exists, so it needs a\n // name on the first turn. The TUI names its threads from OM's `threadTitle`\n // as they grow and would only pay for an extra call here.\n ...(isFactory ? { generateTitle: { model: getObserverModel } } : {}),\n observationalMemory: {\n enabled: true,\n temporalMarkers: true,\n retrieval: vector ? { vector: true } : true,\n experimental_subconscious: captureEnabled\n ? new Subconscious({\n defaultScope: 'resource',\n maxScope: 'resource',\n // Capture-time pinning is a factory-only opinion; every other\n // client keeps plain curator-maintained pins.\n pins: isFactory ? { capturePinning: true } : true,\n // Factory sessions run the curator every 3 observation runs;\n // other clients leave the cadence trigger dormant.\n ...(isFactory ? { curationCadence: 3 } : {}),\n // Real curation over a factory worklist needs tool room: the\n // default 5-step budget exhausts mid-batch and the curator never\n // reaches its cursor acknowledgment (observed live 2026-08-13).\n ...(isFactory ? { maxSteps: 25 } : {}),\n })\n : undefined,\n scope: omScope,\n activateAfterIdle: 'auto',\n activateOnProviderChange: true,\n observation: {\n bufferTokens: isResourceScope ? false : 1 / 5,\n bufferActivation: isResourceScope ? undefined : 2000,\n model: getObserverModel,\n messageTokens: obsThreshold,\n blockAfter: 2,\n previousObserverTokens: observerPreviousObservationTokens,\n threadTitle: true,\n instruction: observerInstruction,\n observeAttachments,\n },\n reflection: {\n bufferActivation: isResourceScope ? undefined : 1 / 2,\n blockAfter: 1.1,\n model: getReflectorModel,\n observationTokens: refThreshold,\n instruction: reflectionInstruction,\n },\n },\n },\n });\n cachedMemoryKey = cacheKey;\n\n return cachedMemory;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","names":[],"sources":["../../src/agents/memory.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { fastembed } from '@mastra/fastembed';\nimport { Memory, Subconscious } from '@mastra/memory';\nimport { DEFAULT_OM_MODEL_ID, DEFAULT_OBS_THRESHOLD, DEFAULT_REF_THRESHOLD } from '../constants.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getOmScope } from '../utils/project.js';\nimport { resolveModel } from './model.js';\n\n/**\n * Read controller state from requestContext.\n * Used by both the memory factory and the OM model functions.\n */\nfunction getAgentControllerState(requestContext: RequestContext): MastraCodeState | undefined {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n return ctx?.getState() as MastraCodeState | undefined;\n}\n\n/**\n * Observer model function — reads the current observer model ID from\n * controller state via requestContext (now propagated by OM's agent.generate).\n */\nfunction getObserverModel({ requestContext }: { requestContext: RequestContext }) {\n const state = getAgentControllerState(requestContext);\n return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, {\n remapForCodexOAuth: true,\n requestContext,\n });\n}\n\n/**\n * Reflector model function — reads the current reflector model ID from\n * controller state via requestContext (now propagated by OM's agent.generate).\n */\nfunction getReflectorModel({ requestContext }: { requestContext: RequestContext }) {\n const state = getAgentControllerState(requestContext);\n return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, {\n remapForCodexOAuth: true,\n requestContext,\n });\n}\n\nconst DYNAMIC_AGENTS_MD_INSTRUCTION =\n 'Messages wrapped in <system-reminder type=\"dynamic-agents-md\" ...>...</system-reminder> are ephemeral project-context instructions injected from files on disk. Do NOT observe or extract information from these messages — they are reloaded automatically when needed and should not be stored in memory.';\n\n// Derived from https://github.com/JuliusBrussee/caveman and adapted for OM use with fixed full-level compression.\nconst CAVEMAN_OM_INSTRUCTION = `Respond terse like smart caveman. All technical substance stay. Only fluff die.\n\nUse full caveman compression style.\n\nDrop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not \"implement a solution for\"). Technical terms exact. Code blocks unchanged. Errors quoted exact. Leave out the words \"agent\" and \"assistant\" at the start of each observation line, it is assumed each line is referring to the assistant unless it specifically says it was about the user. Leave out parenthesis and other text characters like * that would not contribute to understanding the observations.\n\nPattern: \\`[thing] [action] [reason]. [next step]\\`\n\nNot: \"Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...\"\nYes: \"Bug in auth middleware. Token expiry check use < not <=. Fix:\"\n\nExample 1\n🔴 14:31 user asks why React component rerenders\n🟡 14:32 saw inline object prop create new ref each render, cause rerender\n✅ 14:34 fixed render issue by wrap object in useMemo\n\nExample 2\n🟡 15:10 explained pool reuse DB connections, skip repeat handshake overhead\n\nDon't say \"Agent did x\", say \"did x\". It will be assumed the agent did what was observed. The who should only be specified for the user or other third parties: \"user asked x\"\n\nDrop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;\n\n/**\n * The organization rung local (TUI/studio) knowledge is captured under. A fixed\n * literal on purpose: deriving it from a hostname or path would fragment local\n * knowledge per checkout into scopes nothing ever reads.\n */\nexport const LOCAL_KNOWLEDGE_ORG_ID = 'local';\n\n// One error per session, not per memory resolution. Keyed on the session id\n// rather than the controller object: the controller is read off the request\n// context on every resolution, so it is a fresh object per request and would\n// dedupe nothing. Bounded so a long-running Factory process cannot grow this\n// without limit — refusing sessions are rare, and losing the oldest ids only\n// costs one extra log line.\nconst REPORTED_ORG_UNRESOLVED_LIMIT = 500;\nconst reportedOrgUnresolved = new Set<string>();\n\nfunction reportOrgUnresolved(\n controller: AgentControllerRequestContext<MastraCodeState> | undefined,\n factoryProjectId: string | undefined,\n) {\n const sessionId = controller?.session?.id;\n if (sessionId) {\n if (reportedOrgUnresolved.has(sessionId)) return;\n if (reportedOrgUnresolved.size >= REPORTED_ORG_UNRESOLVED_LIMIT) {\n reportedOrgUnresolved.delete(reportedOrgUnresolved.values().next().value as string);\n }\n reportedOrgUnresolved.add(sessionId);\n }\n const session = controller?.session;\n console.error(\n `[Subconscious] Knowledge capture disabled: no organization resolved for session ${session?.id ?? 'unknown'} (project ${factoryProjectId ?? 'none'}). Knowledge is not written rather than written where it cannot be read.`,\n );\n}\n\n/**\n * Dynamic memory factory function.\n * Reads OM thresholds from controller state via requestContext.\n * Model functions also read from requestContext (no mutable bridge needed).\n */\nexport function getDynamicMemory(storage: MastraCompositeStore, vector?: MastraVector) {\n // Cache is scoped per storage instance (per getDynamicMemory call) so a\n // Memory bound to one storage is never reused after storage changes.\n let cachedMemory: Memory | null = null;\n let cachedMemoryKey: string | null = null;\n\n return ({ requestContext }: { requestContext: RequestContext }) => {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const subconsciousEnabled = Boolean(vector) && process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === '1';\n const factoryProjectId = state?.factoryProjectId;\n const isFactory = typeof factoryProjectId === 'string' && factoryProjectId.trim().length > 0;\n\n // A Factory-owned session that could not resolve its org refuses to capture:\n // writing under a substituted identity produces knowledge the fail-closed\n // read path can never see.\n let orgUnresolvedRefusal = false;\n\n if (subconsciousEnabled) {\n // Factory seeds the authoritative org id into session state. There is no\n // fallback: a session owner is a USER id, never an organization.\n const factoryOrgId = state?.factoryOrgId;\n const factoryOwned = isFactory || state?.factoryOrgUnresolved === true;\n if (typeof factoryOrgId === 'string' && factoryOrgId.trim()) {\n requestContext.set('organizationId', factoryOrgId);\n } else if (factoryOwned) {\n orgUnresolvedRefusal = true;\n reportOrgUnresolved(controller, factoryProjectId);\n } else {\n // TUI/studio: an explicit, named scope rather than a cascaded identity.\n requestContext.set('organizationId', LOCAL_KNOWLEDGE_ORG_ID);\n }\n // Factory runs share one knowledge graph per project: anchor the\n // subconscious knowledge scope's resource rung on the project id.\n if (isFactory) {\n requestContext.set('knowledgeResourceId', factoryProjectId);\n }\n }\n\n const captureEnabled = subconsciousEnabled && !orgUnresolvedRefusal;\n\n const omScope = state?.omScope ?? getOmScope(state?.projectPath);\n\n const obsThreshold = state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD;\n const refThreshold = state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD;\n const caveman = state?.cavemanObservations ?? false;\n\n const observerPreviousObservationTokens = 1000;\n const observeAttachments = state?.observeAttachments;\n // Factory sessions get a factory-only Subconscious config, so the cache key\n // carries a factory presence bit to keep the two configs from cross-serving.\n const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}:${captureEnabled ? 1 : 0}`;\n if (cachedMemory && cachedMemoryKey === cacheKey) {\n return cachedMemory;\n }\n\n // Async buffering is not supported with resource scope — disable it\n const isResourceScope = omScope === 'resource';\n\n const observerInstruction = caveman\n ? `${DYNAMIC_AGENTS_MD_INSTRUCTION}\\n\\n${CAVEMAN_OM_INSTRUCTION}`\n : DYNAMIC_AGENTS_MD_INSTRUCTION;\n const reflectionInstruction = caveman ? CAVEMAN_OM_INSTRUCTION : undefined;\n\n cachedMemory = new Memory({\n storage,\n vector: vector || false,\n embedder: vector ? fastembed.small : undefined,\n options: {\n // Generate a durable title from the first user message. Every client uses\n // the same title in its thread list and active-session chrome.\n generateTitle: { model: getObserverModel },\n observationalMemory: {\n enabled: true,\n temporalMarkers: true,\n retrieval: vector ? { vector: true } : true,\n experimental_subconscious: captureEnabled\n ? new Subconscious({\n defaultScope: 'resource',\n maxScope: 'resource',\n // Capture-time pinning is a factory-only opinion; every other\n // client keeps plain curator-maintained pins.\n pins: isFactory ? { capturePinning: true } : true,\n // Factory sessions run the curator every 3 observation runs;\n // other clients leave the cadence trigger dormant.\n ...(isFactory ? { curationCadence: 3 } : {}),\n // Real curation over a factory worklist needs tool room: the\n // default 5-step budget exhausts mid-batch and the curator never\n // reaches its cursor acknowledgment (observed live 2026-08-13).\n ...(isFactory ? { maxSteps: 25 } : {}),\n })\n : undefined,\n scope: omScope,\n activateAfterIdle: 'auto',\n activateOnProviderChange: true,\n observation: {\n bufferTokens: isResourceScope ? false : 1 / 5,\n bufferActivation: isResourceScope ? undefined : 2000,\n model: getObserverModel,\n messageTokens: obsThreshold,\n blockAfter: 2,\n previousObserverTokens: observerPreviousObservationTokens,\n threadTitle: true,\n instruction: observerInstruction,\n observeAttachments,\n },\n reflection: {\n bufferActivation: isResourceScope ? undefined : 1 / 2,\n blockAfter: 1.1,\n model: getReflectorModel,\n observationTokens: refThreshold,\n instruction: reflectionInstruction,\n },\n },\n },\n });\n cachedMemoryKey = cacheKey;\n\n return cachedMemory;\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -383,6 +383,7 @@ async function createMastraCodeAgentController(config) {
383
383
  };
384
384
  const githubSignals = globalSettings.signals?.experimentalGithubSignals && !config?.disableGithubSignals ? new GithubSignals({
385
385
  cwd: project.rootPath,
386
+ pollIntervalMs: globalSettings.signals.githubPollIntervalMs,
386
387
  gitcrawlCommand: process.env.MASTRACODE_GITCRAWL_BIN ?? process.env.GITCRAWL_BIN ?? process.env.MASTRACODE_GITCRAWL_COMMAND ?? process.env.GITCRAWL_COMMAND,
387
388
  getNotificationStreamOptions
388
389
  }) : void 0;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["createScopedKnowledgeInspector"],"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport path from 'node:path';\n\nimport type { Agent } from '@mastra/core/agent';\nimport { AgentController } from '@mastra/core/agent-controller';\nimport type {\n IntervalHandler,\n AgentControllerConfig,\n AgentControllerEvent,\n AgentControllerMode,\n AgentControllerSubagent,\n AgentControllerRequestContext,\n Session,\n} from '@mastra/core/agent-controller';\nimport { createCodingAgent } from '@mastra/core/coding-agent';\nimport type { PubSub } from '@mastra/core/events';\nimport { PROVIDER_REGISTRY } from '@mastra/core/llm';\nimport type { ProviderConfig } from '@mastra/core/llm';\nimport { Mastra } from '@mastra/core/mastra';\nimport { defaultNotificationDeliveryDecision } from '@mastra/core/notifications';\nimport {\n AgentsMDInjector,\n isBadRequestError,\n PrefillErrorHandler,\n ProviderHistoryCompat,\n StreamErrorRetryProcessor,\n} from '@mastra/core/processors';\nimport type { InputProcessor, Processor } from '@mastra/core/processors';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { PublicSchema } from '@mastra/core/schema';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { TaskSignalProvider } from '@mastra/core/signals';\nimport { InMemoryHarness, MastraCompositeStore } from '@mastra/core/storage';\nimport { DEFAULT_GOAL_JUDGE_PROMPT } from '@mastra/core/tools';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { DuckDBStore } from '@mastra/duckdb';\n\nimport { GithubSignals } from '@mastra/github-signals';\nimport { LibSQLStore, LibSQLVector } from '@mastra/libsql';\nimport {\n Observability,\n MastraStorageExporter,\n MastraPlatformExporter,\n SensitiveDataFilter,\n} from '@mastra/observability';\nimport { PostgresStore } from '@mastra/pg';\n\nimport { hasCredentialStoreProvider } from './agents/credential-resolver.js';\nimport { getDynamicInstructions } from './agents/instructions.js';\nimport { getDynamicMemory } from './agents/memory.js';\nimport { createMastraCodeGateway, getDynamicModel, getGoalJudgeModel, resolveModel } from './agents/model.js';\nimport { buildMode } from './agents/modes/build.js';\nimport { fastMode } from './agents/modes/explore.js';\nimport { planMode } from './agents/modes/plan.js';\nimport {\n createGitRefInstructionReader,\n createGitRefReminderReader,\n getStaticallyLoadedInstructionPaths,\n} from './agents/prompts/agent-instructions.js';\n// import { executeSubagent } from './agents/subagents/execute.js';\n// import { exploreSubagent } from './agents/subagents/explore.js';\n// import { planSubagent } from './agents/subagents/plan.js';\nimport { attachOMThreadStatePersistence, restoreOMThreadStateForCurrentThread } from './agents/thread-caveman-state.js';\nimport { createDynamicTools, createToolHooks } from './agents/tools.js';\nimport type { PostToolObserver, ToolLike } from './agents/tools.js';\n\nimport { getDynamicWorkspace, getGoalJudgeTools } from './agents/workspace.js';\nimport { isKimiCodingDeviceId } from './auth/providers/kimi-coding.js';\nimport { AuthStorage } from './auth/storage.js';\nimport { DEFAULT_CONFIG_DIR, validateConfigDirName } from './constants.js';\nimport { createOutcomeScorer, createEfficiencyScorer } from './evals/scorers/index.js';\nimport { HookManager } from './hooks/index.js';\nimport { createKnowledgeInspector as createScopedKnowledgeInspector } from './knowledge-inspector.js';\nimport { createMcpManager } from './mcp/index.js';\nimport type { McpServerConfig } from './mcp/index.js';\nimport { hasExplicitOMConfiguration } from './onboarding/om-settings.js';\nimport type { ProviderAccess } from './onboarding/packs.js';\nimport { getAvailableModePacks, getAvailableOmPacks, selectPreferredOMPack } from './onboarding/packs.js';\nimport {\n loadSettings,\n MASTRA_GATEWAY_PROVIDER,\n OBSERVABILITY_AUTH_PREFIX,\n resolveModelDefaults,\n resolveOmRoleModel,\n saveSettings,\n} from './onboarding/settings.js';\nimport { getToolCategory } from './permissions.js';\nimport { PluginManager } from './plugins/manager.js';\nimport { PluginSignalLane } from './plugins/signal-lane.js';\nimport type { PluginProcessorEntries } from './plugins/types.js';\nimport { PlanRejectionAbortProcessor } from './processors/plan-rejection-abort.js';\nimport { createAmazonBedrockGateway } from './providers/amazon-bedrock-gateway.js';\nimport { setAuthStorage } from './providers/claude-max.js';\nimport { setAuthStorage as setGitHubCopilotAuthStorage } from './providers/github-copilot.js';\nimport { setAuthStorage as setKimiCodingAuthStorage } from './providers/kimi-coding.js';\nimport { setAuthStorage as setOpenAIAuthStorage } from './providers/openai-codex.js';\nimport { setAuthStorage as setXAIAuthStorage } from './providers/xai.js';\n\nimport { stateSchema } from './schema.js';\nimport type { MastraCodeState } from './schema.js';\n\nimport { mastraBrand } from './theme-palette.js';\nimport { syncGateways } from './utils/gateway-sync.js';\nimport {\n detectProject,\n getObservabilityDatabasePath,\n getStorageConfig,\n getResourceIdOverride,\n} from './utils/project.js';\nimport type { StorageConfig } from './utils/project.js';\nimport { createSignalsPubSub } from './utils/signals-pubsub.js';\nimport { createStorage, createVectorStore } from './utils/storage-factory.js';\nimport type { StorageResult } from './utils/storage-factory.js';\nimport { createStorageMaintenance, DEFAULT_RETENTION, resolveLocalDbFiles } from './utils/storage-maintenance.js';\nimport type { StorageMaintenance } from './utils/storage-maintenance.js';\nimport { acquireThreadLock, releaseThreadLock } from './utils/thread-lock.js';\nimport { registerWorkflowBuilderPrimitives } from './workflows/register-primitives.js';\n\nconst CODE_AGENT_ID = 'code-agent';\n\n// Global retry policy for transient provider failures (e.g. dropped sockets and server errors).\n// Applied centrally to every model call via StreamErrorRetryProcessor, independent of model-pack\n// settings, so all modes/subagents benefit from a short wait before retrying a transient failure.\n// Delay uses exponential backoff: initialDelay * 2^retryCount, capped at maxDelay.\nconst MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES = 10;\nconst MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS = 500;\nconst MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS = 30000;\n\nconst TRANSIENT_CONNECTION_ERROR_CODES = new Set(['ECONNRESET', 'EPIPE']);\nconst TRANSIENT_CONNECTION_MESSAGE_PATTERN = /econnreset|socket hang up|write epipe|other side closed/i;\nconst TRANSIENT_SERVER_ERROR_STATUSES = new Set([500, 502, 503]);\nconst TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN = /internal server|server error|api may be experiencing issues/i;\n\n/**\n * Matcher for transient connection failures. Cause-chain traversal is handled\n * by `StreamErrorRetryProcessor.isRetryableStreamError`, which calls each\n * matcher at every level of the cause chain.\n */\n/**\n * Read the session state fields the AgentsMDInjector callbacks need from the\n * controller request context (set by hosts like the factory review flow).\n */\nfunction getInjectorSessionState(\n requestContext: { get: (key: string) => unknown } | undefined,\n): { untrustedCheckout?: boolean; baseRef?: string; projectPath?: string } | undefined {\n const agentControllerContext = requestContext?.get('controller') as\n | AgentControllerRequestContext<{ untrustedCheckout?: boolean; baseRef?: string; projectPath?: string }>\n | undefined;\n return agentControllerContext?.getState();\n}\n\nfunction isTransientConnectionError(error: unknown): boolean {\n if (!error) return false;\n\n const code = typeof error === 'object' && 'code' in error ? (error as { code?: unknown }).code : undefined;\n if (typeof code === 'string' && TRANSIENT_CONNECTION_ERROR_CODES.has(code.toUpperCase())) return true;\n\n const message = error instanceof Error ? error.message : undefined;\n if (typeof message === 'string' && TRANSIENT_CONNECTION_MESSAGE_PATTERN.test(message)) return true;\n\n return false;\n}\n\nfunction isTransientServerError(error: unknown): boolean {\n if (!error) return false;\n\n const errorObj = typeof error === 'object' ? (error as { status?: unknown; statusCode?: unknown }) : undefined;\n if (\n (typeof errorObj?.status === 'number' && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.status)) ||\n (typeof errorObj?.statusCode === 'number' && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.statusCode))\n ) {\n return true;\n }\n\n const message = error instanceof Error ? error.message : undefined;\n return typeof message === 'string' && TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN.test(message);\n}\n\nfunction getTransientRetryDelay(retryCount: number): number {\n return Math.min(\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS * Math.pow(2, retryCount),\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS,\n );\n}\n\nfunction emitTransientRetry(\n error: unknown,\n retryCount: number,\n delayMs: number,\n requestContext?: RequestContext,\n): void {\n const controllerContext = requestContext?.get('controller') as AgentControllerRequestContext | undefined;\n controllerContext?.emitEvent?.({\n type: 'error',\n error: error instanceof Error ? error : new Error(String(error)),\n retryable: true,\n retryDelay: delayMs,\n retryAttempt: retryCount + 1,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n });\n}\n\n/** Short deterministic hash (sha256, first 12 hex chars) matching project.ts shortHash style. */\nfunction shortHash(input: string): string {\n return createHash('sha256').update(input).digest('hex').slice(0, 12);\n}\n\nfunction applyEffectiveDefaultsToModes(\n modes: AgentControllerMode[],\n effectiveDefaults: Record<string, string>,\n): AgentControllerMode[] {\n return modes.map(mode => {\n const savedModel = effectiveDefaults[mode.id];\n if (!savedModel) {\n return mode;\n }\n return {\n ...mode,\n defaultModelId: savedModel,\n };\n });\n}\n\nfunction addPluginToolsToModeAllowlists(\n modes: AgentControllerMode[],\n pluginToolNames: string[],\n): AgentControllerMode[] {\n if (pluginToolNames.length === 0) return modes;\n return modes.map(mode => {\n if (!mode.availableTools) return mode;\n return {\n ...mode,\n availableTools: Array.from(new Set([...mode.availableTools, ...pluginToolNames])),\n };\n });\n}\n\nexport interface MastraCodeConfig {\n /** Working directory for project detection. Default: process.cwd() */\n cwd?: string;\n /** Home directory for global config discovery. Default: os.homedir() */\n homeDir?: string;\n /** Override modes (model IDs, colors, which modes exist). Default: build/plan/fast */\n modes?: AgentControllerMode[];\n /** Override or extend subagent definitions. Default: explore/plan/execute */\n subagents?: AgentControllerSubagent[];\n /** Extra tools merged into the dynamic tool set. Can be a static record or a (sync or async) function that receives requestContext. */\n extraTools?:\n | Record<string, ToolLike | undefined>\n | ((ctx: {\n requestContext: RequestContext;\n }) => Record<string, ToolLike | undefined> | Promise<Record<string, ToolLike | undefined>>);\n /** Observe completed tool calls without replacing or modifying the built-in tool implementation. */\n postToolObserver?: PostToolObserver;\n /**\n * Stateless input processor instances prepended before Mastra Code's mandatory processors.\n * Embedders may extend processing but cannot replace built-in safety and compatibility policy.\n */\n inputProcessors?: InputProcessor[];\n /** Tools removed from the dynamic tool set before exposure to the model */\n disabledTools?: string[];\n /**\n * Custom storage config instead of auto-detected default, or a pre-built\n * store instance. An instance is used as-is: no connection test and no\n * LibSQL fallback — if the injected store fails, that's a hard error.\n */\n storage?: StorageConfig | MastraCompositeStore;\n /** Backend for an injected custom storage instance. Inferred for LibSQLStore and PostgresStore. */\n storageBackend?: 'libsql' | 'pg';\n /** Pre-built vector store instance for recall search. Skips the default vector store creation. */\n vector?: MastraVector;\n /** Observational memory scope. Default: auto-detected from env/config files, falls back to 'thread' */\n omScope?: 'thread' | 'resource';\n /** Path to a custom settings.json file. Default: global settings */\n settingsPath?: string;\n /** Initial state overrides (yolo, thinkingLevel, etc.) */\n initialState?: Partial<MastraCodeState>;\n /** Override id generation for threads/messages. Primarily useful for deterministic tests. */\n idGenerator?: AgentControllerConfig<MastraCodeState>['idGenerator'];\n /** Override interval handlers. Default: gateway-sync */\n intervalHandlers?: IntervalHandler[];\n /** Override the workspace. Default: local filesystem + local sandbox based on detected project */\n workspace?: AgentControllerConfig<MastraCodeState>['workspace'];\n /** Override the config directory name. Default: '.mastracode'. Replaces '.mastracode' in all project-level and global config paths (MCP, hooks, commands, database, skills, agent instructions). */\n configDir?: string;\n /** Programmatic MCP server configurations, merged with (and overriding) file-based configs. */\n mcpServers?: Record<string, McpServerConfig>;\n /** Disable MCP server discovery. Default: false */\n disableMcp?: boolean;\n /** Disable hooks. Default: false */\n disableHooks?: boolean;\n /** Disable plugin discovery/loading. Default: false */\n disablePlugins?: boolean;\n /** Disable the polling-based GitHub signal provider even when enabled in global settings. Default: false */\n disableGithubSignals?: boolean;\n /**\n * Skip seeding observational-memory knobs (observer/reflector models,\n * thresholds, caveman mode, attachment observation) from settings.json.\n * Server deployments that persist memory settings in their own database\n * (the factory's `memory-settings` domain) set this so the host machine's\n * TUI settings file never leaks into server sessions. Default: false.\n */\n disableSettingsOmSeed?: boolean;\n /** Override the plugin manager. Primarily useful for tests or embedding. */\n pluginManager?: PluginManager;\n /**\n * Override the memory instance (or dynamic factory) passed to the AgentController.\n * When provided, this replaces the default `getDynamicMemory(storage, vector)` which\n * uses mastracode's built-in model gateway (Anthropic OAuth, OpenAI Codex,\n * custom providers, and models.dev fallback).\n *\n * Use this when you need to override memory model behavior completely.\n */\n memory?: AgentControllerConfig<MastraCodeState>['memory'] | false;\n /** Browser provider for browser automation tools. When set, the agent gains access to browser tools. */\n browser?: AgentControllerConfig<MastraCodeState>['browser'];\n /** PubSub for signal routing. When crossProcessPubSub is true, thread locks are disabled. */\n pubsub?: PubSub;\n /** Use Mastra Code's built-in Unix socket PubSub for local cross-process signal routing. */\n unixSocketPubSub?: boolean;\n /** Marks the configured PubSub as cross-process-safe, allowing Mastra Code to skip file thread locks. */\n crossProcessPubSub?: boolean;\n}\n\nexport function createAuthStorage() {\n const authStorage = new AuthStorage();\n setAuthStorage(authStorage);\n setOpenAIAuthStorage(authStorage);\n setGitHubCopilotAuthStorage(authStorage);\n setKimiCodingAuthStorage(authStorage);\n setXAIAuthStorage(authStorage);\n return authStorage;\n}\n\n/**\n * Resolve cloud observability credentials for the MastraPlatformExporter.\n * Priority: per-resource settings > environment variables > disabled.\n */\nfunction resolveCloudObservabilityConfig(\n settings: ReturnType<typeof loadSettings>,\n authStorage: AuthStorage,\n resourceId: string,\n): { accessToken?: string; projectId?: string } {\n const resourceConfig = settings.observability.resources[resourceId];\n if (resourceConfig) {\n const token = authStorage.getStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`);\n if (token) {\n return { accessToken: token, projectId: resourceConfig.projectId };\n }\n }\n // Fall back to environment variables for backwards compatibility\n return {\n accessToken: process.env.MASTRA_CLOUD_ACCESS_TOKEN,\n projectId: process.env.MASTRA_PROJECT_ID,\n };\n}\n\n/**\n * Base factory: builds every shared MastraCode resource (storage, observability,\n * memory, MCP, providers, gateways, agent, modes) and the {@link AgentController}, but\n * does NOT call `init()` or create a session. The controller is returned inert so\n * the composition layer can decide its Mastra ownership and session model.\n *\n * See {@link bootLocalAgentController} (Case 3) and `mountAgentControllerOnMastra` (Cases 1 & 2).\n */\n/**\n * `instanceof` checks against Mastra classes are unreliable here: published\n * packages pin exact `@mastra/core` versions, so a user's dependency graph can\n * contain multiple copies of core (and peer-keyed copies of `@mastra/libsql` /\n * `@mastra/pg`). A store built against one copy fails `instanceof` against\n * another — the injected instance then silently fell through to the\n * StorageConfig path and crashed on `config.url`. These structural checks work\n * across duplicated copies.\n */\nfunction isInjectedStorageInstance(storage: MastraCodeConfig['storage']): storage is MastraCompositeStore {\n if (!storage) return false;\n if (storage instanceof MastraCompositeStore) return true;\n // A StorageConfig is a plain data object with a string `backend`\n // discriminant; a store instance carries the MastraCompositeStore method\n // surface.\n const candidate = storage as Partial<MastraCompositeStore>;\n return typeof candidate.init === 'function' && typeof candidate.__registerMastra === 'function';\n}\n\n/** Cross-copy-safe class check: walks the prototype chain by constructor name. */\nfunction hasAncestorClassNamed(value: object, className: string): boolean {\n for (let proto = Object.getPrototypeOf(value); proto; proto = Object.getPrototypeOf(proto)) {\n if (proto.constructor?.name === className) return true;\n }\n return false;\n}\n\nfunction resolveInjectedStorageBackend(\n storage: MastraCompositeStore,\n configuredBackend?: 'libsql' | 'pg',\n): 'libsql' | 'pg' {\n if (configuredBackend) return configuredBackend;\n if (storage instanceof LibSQLStore || hasAncestorClassNamed(storage, 'LibSQLStore')) return 'libsql';\n if (storage instanceof PostgresStore || hasAncestorClassNamed(storage, 'PostgresStore')) return 'pg';\n throw new Error('storageBackend is required when injecting a custom storage instance.');\n}\n\nexport async function createMastraCodeAgentController(config?: MastraCodeConfig) {\n const cwd = config?.cwd ?? process.cwd();\n const homeDir = config?.homeDir ?? config?.initialState?.homeDir;\n const configDir = config?.configDir ?? DEFAULT_CONFIG_DIR;\n // The single session for this process, assigned once `createSession()` runs\n // below. Config callbacks defined before then (e.g. notification stream\n // options) read it lazily through this holder.\n let activeSession: Session<MastraCodeState> | undefined;\n // Same trick for the controller, which plugins reach through a lazy accessor.\n // Plugins load well before the controller is constructed, and a closure over\n // the `controller` binding itself would throw on early access rather than\n // reporting \"not ready yet\", so the accessor reads this holder instead.\n let pluginRuntimeController: AgentController<MastraCodeState> | undefined;\n if (configDir !== DEFAULT_CONFIG_DIR) {\n validateConfigDirName(configDir);\n }\n\n // Load .env file from cwd if present (for observability API keys, etc.)\n try {\n process.loadEnvFile(path.join(cwd, '.env'));\n } catch {\n // No .env file — that's fine, keys may be in shell environment\n }\n\n // Auth storage (shared with Claude Max / OpenAI providers and AgentController)\n const authStorage = createAuthStorage();\n const globalSettings = loadSettings(config?.settingsPath);\n const storedGatewayKey = authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER);\n const storedGatewayUrl = globalSettings.memoryGateway?.baseUrl;\n\n if (storedGatewayKey) {\n process.env['MASTRA_GATEWAY_API_KEY'] ??= storedGatewayKey;\n }\n\n if (storedGatewayUrl) {\n process.env['MASTRA_GATEWAY_URL'] ??= storedGatewayUrl;\n }\n\n // Load user-entered API keys from auth.json into process.env\n // (only sets env vars that aren't already present — env vars take precedence).\n // Skipped in deployed multi-tenant mode: when a per-tenant credential store\n // provider is registered, provider keys are resolved per request and must\n // never leak into process-global env vars.\n if (!hasCredentialStoreProvider()) {\n try {\n const registry = PROVIDER_REGISTRY as Record<string, ProviderConfig>;\n const providerEnvVars: Record<string, string | undefined> = {};\n for (const [provider, cfg] of Object.entries(registry)) {\n const envVars = cfg?.apiKeyEnvVar;\n providerEnvVars[provider] = Array.isArray(envVars) ? envVars[0] : envVars;\n }\n providerEnvVars[MASTRA_GATEWAY_PROVIDER] ??= 'MASTRA_GATEWAY_API_KEY';\n authStorage.loadStoredApiKeysIntoEnv(providerEnvVars);\n } catch {\n // Registry unavailable — load well-known provider keys so non-gateway flows still work\n authStorage.loadStoredApiKeysIntoEnv({\n [MASTRA_GATEWAY_PROVIDER]: 'MASTRA_GATEWAY_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n openai: 'OPENAI_API_KEY',\n google: 'GOOGLE_GENERATIVE_AI_API_KEY',\n cerebras: 'CEREBRAS_API_KEY',\n deepseek: 'DEEPSEEK_API_KEY',\n });\n }\n }\n\n const mgApiKey = process.env['MASTRA_GATEWAY_API_KEY'] ?? storedGatewayKey;\n const mastraGatewayBaseUrl = (\n process.env['MASTRA_GATEWAY_URL'] ??\n storedGatewayUrl ??\n 'https://gateway-api.mastra.ai'\n )\n .replace(/\\/+$/, '')\n .replace(/\\/v1$/, '');\n const mastraCodeGateway = createMastraCodeGateway({\n mastraGatewayBaseUrl,\n mastraGatewayApiKey: mgApiKey,\n routeThroughMastraGateway: false,\n settingsPath: config?.settingsPath,\n });\n const amazonBedrockGateway = createAmazonBedrockGateway();\n\n // Project detection\n const project = detectProject(cwd);\n\n const resourceIdOverride = getResourceIdOverride(project.rootPath, configDir);\n if (resourceIdOverride) {\n project.resourceId = resourceIdOverride;\n project.resourceIdOverride = true;\n }\n\n // Stable session id unique to this project/resource, and a machine-bound owner\n // id. resourceId encodes root path + git identity and honors overrides, so it\n // is the right input for scoping the session to the cwd/project.\n const sessionId = `mastracode-session-${shortHash(project.resourceId)}`;\n const ownerId = `mastracode-${shortHash(`${hostname()}\\0${project.rootPath}`)}`;\n\n const configuredPubSub = config?.pubsub;\n const useUnixSocketPubSub =\n (config?.unixSocketPubSub ?? globalSettings.signals?.unixSocketPubSub ?? false) && process.platform !== 'win32';\n const signalsPubSub = configuredPubSub ?? (useUnixSocketPubSub ? createSignalsPubSub(project.resourceId) : undefined);\n const crossProcessPubSub = config?.crossProcessPubSub ?? (!configuredPubSub && useUnixSocketPubSub);\n if (crossProcessPubSub && !signalsPubSub) {\n throw new Error('crossProcessPubSub requires a pubsub instance');\n }\n\n // Storage. An injected instance is used as-is — no connection test, no\n // LibSQL fallback: if the injected store fails, that's a hard error.\n const injectedStorage = isInjectedStorageInstance(config?.storage) ? config.storage : undefined;\n const storageConfig = injectedStorage\n ? undefined\n : ((config?.storage as StorageConfig | undefined) ??\n getStorageConfig(project.rootPath, globalSettings.storage, configDir));\n const storageResult: StorageResult = injectedStorage\n ? { storage: injectedStorage, backend: resolveInjectedStorageBackend(injectedStorage, config?.storageBackend) }\n : await createStorage(storageConfig!);\n const storageWarning = storageResult.warning;\n\n // Observability storage (DuckDB — separate file for OLAP-style trace/score/feedback queries).\n // Local tracing is opt-in via `/observability local on`. When disabled, the\n // MastraStorageExporter is omitted entirely so traces never fall through to\n // the default libsql backend.\n let observabilityDomain: DuckDBStore['observability'] | undefined;\n let observabilityWarning: string | undefined;\n if (globalSettings.observability.localTracing) {\n try {\n const observabilityDuckDB = new DuckDBStore({\n id: 'mastra-code-observability',\n path: getObservabilityDatabasePath(),\n });\n // Force an early connection attempt so the lock error surfaces now, not mid-session.\n await observabilityDuckDB.db.getConnection();\n observabilityDomain = observabilityDuckDB.observability;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const isLockError = /lock|locked|busy/i.test(message);\n if (isLockError) {\n observabilityWarning =\n 'Observability unavailable — another MastraCode instance holds the database lock. Traces, scores, and feedback will not be recorded in this session.';\n } else {\n observabilityWarning = `Observability unavailable — DuckDB initialization failed: ${message}`;\n }\n }\n }\n\n const harnessStorage = new InMemoryHarness();\n\n const storage = new MastraCompositeStore({\n id: 'mastra-code-storage',\n default: storageResult.storage,\n domains: {\n // When local tracing is off, disable the observability domain entirely so\n // trace/score/feedback writes never fall through to the default libsql store.\n observability: observabilityDomain ?? false,\n harness: harnessStorage,\n },\n });\n\n // Observability (tracing, scoring, feedback)\n const observability = new Observability({\n configs: {\n default: {\n serviceName: 'mastracode',\n // Only these requestContext keys are stored on spans — prevents leaking\n // large objects (controller state, workspace, env vars) into trace data.\n // Use dot-notation because these are nested inside the 'controller' key.\n //\n // Session identifiers:\n // threadId, resourceId, session.modeId, agentControllerId\n // Environment & project:\n // state.projectName, state.gitBranch\n // Model configuration:\n // session.modelId, state.subagentModelId\n // Agent settings:\n // state.yolo, state.thinkingLevel, state.smartEditing\n // Observational memory settings:\n // state.omScope, state.observerModelId, state.reflectorModelId,\n // state.observationThreshold, state.reflectionThreshold\n requestContextKeys: [\n // Session identifiers\n 'controller.threadId',\n 'controller.resourceId',\n 'controller.session.modeId',\n 'controller.controllerId',\n // Environment & project\n 'controller.state.projectName',\n 'controller.state.gitBranch',\n // Model configuration\n 'controller.session.modelId',\n 'controller.state.subagentModelId',\n // Agent settings\n 'controller.state.yolo',\n 'controller.state.thinkingLevel',\n 'controller.state.smartEditing',\n // Observational memory settings\n 'controller.state.omScope',\n 'controller.state.observerModelId',\n 'controller.state.reflectorModelId',\n 'controller.state.observationThreshold',\n 'controller.state.reflectionThreshold',\n ],\n exporters: [\n // Only persist traces locally when DuckDB observability is available\n // (via `/observability local on`). Without this guard the storage\n // exporter falls through to the default libsql backend and silently\n // fills the main database with gigabytes of span data.\n ...(observabilityDomain ? [new MastraStorageExporter({ strategy: 'event-sourced' })] : []),\n new MastraPlatformExporter(resolveCloudObservabilityConfig(globalSettings, authStorage, project.resourceId)),\n ],\n spanOutputProcessors: [new SensitiveDataFilter()],\n },\n },\n });\n\n // Vector store for recall search (separate DB file to avoid bloating main\n // storage). An injected instance is used as-is; with an injected storage\n // instance and no injected vector, recall search stays vector-less.\n const vector =\n config?.vector ?? (storageConfig ? await createVectorStore(storageConfig, storageResult.backend) : undefined);\n\n // Maintenance handle for /prune: prunes via the inner store (whose retention\n // config covers every domain, including legacy libsql observability spans)\n // and can compact local libsql files to reclaim disk. The vector store's\n // connection must close alongside storage — the compaction's file swap\n // refuses to run while any connection is open.\n const storageMaintenance: StorageMaintenance = createStorageMaintenance({\n storage: storageResult.storage,\n backend: storageResult.backend,\n retention: DEFAULT_RETENTION,\n localDbFiles: storageConfig ? resolveLocalDbFiles(storageConfig, storageResult.backend) : [],\n closeVector: vector instanceof LibSQLVector ? () => vector.close() : undefined,\n });\n\n const memory = config?.memory === false ? undefined : (config?.memory ?? getDynamicMemory(storage, vector));\n\n // MCP\n const mcpManager = config?.disableMcp\n ? undefined\n : createMcpManager(project.rootPath, configDir, config?.mcpServers, globalSettings.mcp);\n\n // Hooks\n const hookManager = config?.disableHooks\n ? undefined\n : new HookManager(\n project.rootPath,\n 'session-init',\n configDir,\n homeDir,\n project.isWorktree\n ? { path: project.rootPath, branch: project.gitBranch, mainRepoPath: project.mainRepoPath }\n : undefined,\n );\n\n const pluginManager = config?.disablePlugins\n ? undefined\n : (config?.pluginManager ??\n new PluginManager({\n projectRoot: project.rootPath,\n configDir,\n homeDir,\n }));\n // Publish the runtime accessors to whichever manager is in play — including an\n // injected one, which would otherwise hand plugins `undefined` for\n // `getController`/`getActiveSession`. Lazy closures: both locals are assigned\n // after the controller is constructed below.\n pluginManager?.setRuntime({\n getController: () => pluginRuntimeController,\n getActiveSession: () => activeSession,\n });\n const loadedPlugins = pluginManager ? await pluginManager.reload() : [];\n const pluginTools = pluginManager?.getPluginTools() ?? {};\n\n // Scorers (live evaluation with sampling)\n const outcomeScorer = createOutcomeScorer();\n const efficiencyScorer = createEfficiencyScorer();\n\n // Agent — githubSignals is created before `controller` but the closure below\n // captures `controller` by reference; it is only invoked at notification time,\n // well after controller is constructed (line ~692). Explicit type annotations\n // on githubSignals, codeAgent, modes, and controller break the circular\n // inference chain this forward reference would otherwise create.\n // Shared by GithubSignals (immediate sends) and the code agent's\n // notification config (deferred sends re-dispatched by the core notification\n // dispatch workflow) — both need the target session's request context, or a\n // woken idle thread has no model to run with (\"No model selected\").\n const getNotificationStreamOptions = async ({ resourceId, threadId }: { resourceId: string; threadId: string }) => {\n // Run the woken notification as the session that owns the target\n // resource so it uses that session's model/mode/state. Fall back to\n // the current session only when no session owns the resource yet.\n const session = (await controller.getSessionByResource(resourceId)) ?? activeSession;\n // No session owns the resource and none is active yet (e.g. a deferred\n // notification comes due before any session boots). Nothing to resolve a\n // model from; return undefined so the dispatcher sends a bare wake\n // instead of throwing mid-delivery.\n if (!session) return undefined;\n // A long-running system must be able to drive work unattended, so a\n // target session without an explicit model selection falls back to a\n // real model rather than failing the run: the current session's live\n // selection (what the user actually picked), then the mode's default.\n const modeId = session.mode.get();\n const defaultModeModelId = controller.listModes().find(mode => mode.id === modeId)?.defaultModelId;\n const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || '';\n const requestContext = new RequestContext();\n const agentControllerContext: AgentControllerRequestContext = {\n controllerId: controller.id,\n state: session.state.get(),\n getState: () => session.state.get(),\n setState: updates => session.state.set(updates),\n threadId,\n resourceId,\n session: {\n id: session.identity.getId(),\n ownerId: session.identity.getOwnerId(),\n modeId,\n modelId,\n state: {\n get: () => session.state.get(),\n set: updates => session.state.set(updates),\n update: updater => session.state.update(updater),\n },\n },\n workspace: session.getWorkspace(),\n getSubagentModelId: params => session.subagents.model.get(params ?? {}),\n };\n requestContext.set('controller', agentControllerContext);\n\n return {\n memory: { thread: threadId, resource: resourceId },\n requestContext,\n maxSteps: 1000,\n savePerStep: false,\n requireToolApproval: (session.state.get() as Record<string, unknown>).yolo !== true,\n modelSettings: { temperature: 1 },\n };\n };\n\n const githubSignals: GithubSignals | undefined =\n globalSettings.signals?.experimentalGithubSignals && !config?.disableGithubSignals\n ? new GithubSignals({\n cwd: project.rootPath,\n gitcrawlCommand:\n process.env.MASTRACODE_GITCRAWL_BIN ??\n process.env.GITCRAWL_BIN ??\n process.env.MASTRACODE_GITCRAWL_COMMAND ??\n process.env.GITCRAWL_COMMAND,\n getNotificationStreamOptions,\n })\n : undefined;\n // Mastra Code's own processors are constructed once, here, rather than inside\n // the resolver below: the resolver runs before every LLM call, and rebuilding\n // stateful processors per request would reset them.\n const mastraCodeInputProcessors: InputProcessor[] = [\n ...(config?.inputProcessors ?? []),\n new PlanRejectionAbortProcessor(),\n new AgentsMDInjector({\n // Untrusted checkouts (review sessions on PR branches) must not have\n // the working tree's instruction files injected as system reminders —\n // those files are attacker-writable content, not configuration. When\n // the session carries a trusted base ref, reminders are served from\n // that ref instead (see getReader); without one they are disabled.\n isEnabled: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n return state?.untrustedCheckout !== true || typeof state?.baseRef === 'string';\n },\n getReader: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n if (state?.untrustedCheckout !== true || typeof state?.baseRef !== 'string') return undefined;\n return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);\n },\n getIgnoredInstructionPaths: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n const projectPath = state?.projectPath ?? project.rootPath;\n // On untrusted checkouts the static prompt loads from the base ref,\n // so compute the statically-loaded paths through the same reader to\n // keep the dedup consistent.\n const projectReader =\n state?.untrustedCheckout === true && typeof state?.baseRef === 'string'\n ? createGitRefInstructionReader(projectPath, state.baseRef)\n : undefined;\n return getStaticallyLoadedInstructionPaths(projectPath, undefined, projectReader);\n },\n }),\n new ProviderHistoryCompat(),\n ];\n\n // TaskSignalProvider bundles the task tools + TaskStateProcessor (see the\n // `signals` array below); named here so the plugin lane can reserve its id.\n const taskSignalProvider = new TaskSignalProvider();\n\n const NO_PLUGIN_PROCESSORS: PluginProcessorEntries = { input: [], output: [] };\n let pluginProcessorReadWarned = false;\n\n // Providers contributed by plugins are driven from here rather than through\n // the agent's `signals` array: the Agent constructor harvests a provider's\n // processors into a closure it can never undo, so a provider wired there\n // could not be removed when its plugin is disabled, updated or uninstalled.\n // The built-in providers are seeded as reserved ids because they are wired\n // through the constructor and are therefore invisible to the lane.\n const pluginSignalLane = pluginManager\n ? new PluginSignalLane({\n reservedProviderIds: [taskSignalProvider.id, ...(githubSignals ? [githubSignals.id] : [])],\n })\n : undefined;\n let unsubscribePluginReload: (() => void) | undefined;\n\n /**\n * Plugin processors are read through a function so that enabling, disabling or\n * updating a plugin takes effect on the next request rather than requiring a\n * new agent. This runs before every LLM call, and also outside the request\n * path when the Agent catalogues its configured processors — where a throw is\n * swallowed into a debug log. So it only reads already-resolved state: no\n * filesystem, no network, no construction, and it never throws.\n */\n const readPluginProcessors = (): PluginProcessorEntries => {\n try {\n return pluginManager?.getPluginProcessors() ?? NO_PLUGIN_PROCESSORS;\n } catch (error) {\n // Warn once: this is on the hot path, and a broken read repeats.\n if (!pluginProcessorReadWarned) {\n pluginProcessorReadWarned = true;\n console.warn('Failed to read plugin processors:', error);\n }\n return NO_PLUGIN_PROCESSORS;\n }\n };\n\n const codeAgent: Agent = createCodingAgent({\n id: CODE_AGENT_ID,\n name: 'Code Agent',\n // Workspace is wired per-request at the AgentController level (see\n // `config.workspace` below), so opt out of the factory's default local\n // workspace. An explicit `undefined` is required: the factory only builds a\n // default when the `workspace` key is absent.\n workspace: undefined,\n instructions: getDynamicInstructions,\n // `settingsPath` matches the source `createMastraCode()` reads from so the\n // per-mode thinking defaults resolve against the same config file.\n model: ctx => getDynamicModel(ctx, config?.settingsPath),\n // Deferred notifications are re-dispatched by the core notification\n // dispatch workflow long after the originating send; the delivery policy\n // rebuilds the request context (model selection included) at delivery time\n // so waking an idle thread does not fail with \"No model selected\". The\n // default decision logic is kept as-is — the policy only attaches\n // streamOptions on top of it.\n notifications: {\n deliveryPolicy: {\n decide: async input => {\n const decision = defaultNotificationDeliveryDecision(input);\n // Without a resourceId there is no session to resolve options from —\n // don't fall through to the active session and wake it under an\n // empty resource binding.\n if (!input.record.resourceId) return decision;\n const streamOptions = await getNotificationStreamOptions({\n resourceId: input.record.resourceId,\n threadId: input.record.threadId,\n });\n return streamOptions ? { ...decision, streamOptions } : decision;\n },\n },\n },\n tools: createDynamicTools(mcpManager, config?.extraTools, config?.disabledTools, storage, pluginTools),\n hooks: createToolHooks(hookManager, config?.postToolObserver),\n scorers: {\n outcome: {\n scorer: outcomeScorer,\n sampling: { type: 'none' },\n },\n efficiency: {\n scorer: efficiencyScorer,\n sampling: { type: 'ratio', rate: 0.3 },\n },\n },\n // TaskSignalProvider bundles the task tools + TaskStateProcessor: it merges\n // the tools into the toolset and registers the task state-signal processor,\n // so the task list persists across turns and survives OM truncation.\n signals: [taskSignalProvider, ...(githubSignals ? [githubSignals] : [])],\n // Native goal mechanism: the in-loop goal step judges the thread's active\n // objective each qualifying iteration. The judge model is required for any\n // gating to occur; when unset the goal step is a complete no-op. A6 auto-wires\n // the GoalStateProcessor so the `<current-objective>` signal persists across\n // turns. Per-thread overrides live in the ThreadState `goal` record and win\n // over these defaults.\n goal: {\n // Resolve the judge model through mastracode's gateway (a model-resolver\n // function) so provider credentials are injected; returns undefined when no\n // judge model is configured, keeping the goal step a no-op. Bind the same\n // `settingsPath` used above so the judge model and `maxRuns` come from one\n // config (a custom settings file would otherwise diverge).\n judge: ctx => getGoalJudgeModel(ctx, config?.settingsPath),\n maxRuns: globalSettings.models.goalMaxTurns ?? 50,\n maxSteps: 1000,\n prompt: DEFAULT_GOAL_JUDGE_PROMPT,\n // Read-only workspace tools the default goal judge may call to verify the\n // agent's work against the actual filesystem (view, search_content,\n // find_files, file_stat, lsp_inspect) rather than grading prose alone —\n // restoring the original MastraCode judge's verification ability. Resolved\n // per-request from the active workspace (mirrors `judge`).\n tools: getGoalJudgeTools,\n },\n inputProcessors: () => [\n ...mastraCodeInputProcessors,\n ...readPluginProcessors().input.map(entry => entry.value),\n ...(pluginSignalLane?.getInputProcessors() ?? []),\n ],\n // Mastra Code contributes no output processors of its own; the lane exists\n // so plugins can. Like the input lane, plugin processors sit last — after\n // the layers they customize, before the channel and memory layers the\n // Agent appends.\n outputProcessors: () => [\n ...readPluginProcessors().output.map(entry => entry.value),\n ...(pluginSignalLane?.getOutputProcessors() ?? []),\n ],\n errorProcessors: [\n // ProviderHistoryCompat must run before StreamErrorRetryProcessor: both react to\n // HTTP 400s, but ProviderHistoryCompat repairs the incompatible history (e.g.\n // sanitizing tool-call IDs) before retrying, while StreamErrorRetryProcessor's\n // isBadRequestError matcher retries the identical request. Error processors\n // short-circuit on the first `retry: true`, so a blind retry first would resend\n // the broken history and fail again.\n new ProviderHistoryCompat(),\n new StreamErrorRetryProcessor({\n matchers: [\n { match: isBadRequestError, maxRetries: 1, delayMs: 2000 },\n {\n match: isTransientConnectionError,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),\n onRetry: ({ error, retryCount, delayMs, requestContext }) =>\n emitTransientRetry(error, retryCount, delayMs, requestContext),\n },\n {\n match: isTransientServerError,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),\n onRetry: ({ error, retryCount, delayMs, requestContext }) =>\n emitTransientRetry(error, retryCount, delayMs, requestContext),\n },\n ],\n }),\n new PrefillErrorHandler(),\n ],\n });\n\n // const defaultSubAgents: Array<AgentControllerSubagent> = [];\n // const defaultSubagents = [exploreSubagent, planSubagent, executeSubagent];\n\n const defaultModes: AgentControllerMode[] = [\n {\n ...buildMode,\n metadata: {\n ...buildMode.metadata,\n color: mastraBrand.green,\n },\n },\n {\n ...planMode,\n metadata: {\n ...planMode.metadata,\n color: mastraBrand.purple,\n },\n },\n {\n ...fastMode,\n metadata: {\n ...fastMode.metadata,\n color: mastraBrand.orange,\n },\n },\n ];\n\n const defaultIntervalHandlers: IntervalHandler[] = [\n {\n id: 'gateway-sync',\n intervalMs: 5 * 60 * 1000,\n immediate: false,\n handler: () => syncGateways(),\n },\n ];\n const intervalHandlers = config?.intervalHandlers ?? defaultIntervalHandlers;\n\n // Build lightweight provider access for resolving built-in packs at startup.\n // Anthropic/OpenAI use AuthStorage; other providers use env API keys.\n // Also scan the full provider registry so configured API keys satisfy access checks.\n const anthropicCred = authStorage.get('anthropic');\n const openaiCred = authStorage.get('openai-codex');\n const githubCopilotCred = authStorage.get('github-copilot');\n const kimiCodingCred = authStorage.get('kimi-for-coding');\n const startupAccess: ProviderAccess = {\n anthropic:\n anthropicCred?.type === 'oauth'\n ? 'oauth'\n : anthropicCred?.type === 'api_key' && anthropicCred.key.trim().length > 0\n ? 'apikey'\n : false,\n openai:\n openaiCred?.type === 'oauth'\n ? 'oauth'\n : openaiCred?.type === 'api_key' && openaiCred.key.trim().length > 0\n ? 'apikey'\n : false,\n cerebras: process.env.CEREBRAS_API_KEY ? 'apikey' : false,\n google: process.env.GOOGLE_GENERATIVE_AI_API_KEY ? 'apikey' : false,\n deepseek: process.env.DEEPSEEK_API_KEY ? 'apikey' : false,\n 'github-copilot': githubCopilotCred?.type === 'oauth' ? 'oauth' : false,\n 'kimi-for-coding':\n kimiCodingCred?.type === 'oauth' && isKimiCodingDeviceId(kimiCodingCred.deviceId)\n ? 'oauth'\n : (kimiCodingCred?.type === 'api_key' && kimiCodingCred.key.trim().length > 0) ||\n Boolean(process.env.KIMI_API_KEY?.trim())\n ? 'apikey'\n : false,\n };\n // Gateway covers all providers — ensure Anthropic/OpenAI packs are visible\n if (mgApiKey) {\n if (!startupAccess.anthropic) startupAccess.anthropic = 'apikey';\n if (!startupAccess.openai) startupAccess.openai = 'apikey';\n }\n // Check all providers in the registry for API keys\n try {\n const registry = PROVIDER_REGISTRY as Record<string, ProviderConfig>;\n for (const [provider, config] of Object.entries(registry)) {\n if (startupAccess[provider] === 'oauth' || startupAccess[provider] === 'apikey') continue; // Already enabled above\n if (provider === 'anthropic' || provider === 'openai') continue;\n const envVars = config?.apiKeyEnvVar;\n const envVarList = Array.isArray(envVars) ? envVars : envVars ? [envVars] : [];\n if (envVarList.some(envVar => process.env[envVar])) {\n startupAccess[provider] = 'apikey';\n }\n }\n } catch {\n // Registry may not be loaded yet; the 5 hardcoded providers are sufficient fallback\n }\n const builtinPacks = getAvailableModePacks(startupAccess);\n const builtinOmPacks = getAvailableOmPacks(startupAccess);\n const effectiveDefaults = resolveModelDefaults(globalSettings, builtinPacks);\n const activeProviderId = effectiveDefaults.build?.split('/')[0];\n const preferredOmModel = hasExplicitOMConfiguration(globalSettings)\n ? undefined\n : selectPreferredOMPack(startupAccess, activeProviderId)?.modelId;\n const effectiveObserverModel = resolveOmRoleModel(globalSettings, 'observer', builtinOmPacks) || preferredOmModel;\n const effectiveReflectorModel = resolveOmRoleModel(globalSettings, 'reflector', builtinOmPacks) || preferredOmModel;\n const effectiveObservationThreshold = globalSettings.models.omObservationThreshold ?? undefined;\n const effectiveReflectionThreshold = globalSettings.models.omReflectionThreshold ?? undefined;\n const effectiveCavemanObservations = globalSettings.models.omCavemanObservations ?? undefined;\n const effectiveObserveAttachments = globalSettings.models.omObserveAttachments ?? 'auto';\n\n const modes = addPluginToolsToModeAllowlists(\n applyEffectiveDefaultsToModes(config?.modes ? config.modes : defaultModes, effectiveDefaults),\n Object.keys(pluginTools),\n );\n const defaultModeId =\n modes.find(mode => mode.metadata?.default === true)?.id ??\n modes.find(mode => mode.id === 'build')?.id ??\n modes[0]?.id;\n if (!defaultModeId) {\n throw new Error('MastraCode requires at least one mode');\n }\n\n // Map subagent types to mode models: explore→fast, plan→plan, execute→build\n // const subagentModeMap: Record<string, string> = { explore: 'fast', plan: 'plan', execute: 'build' };\n // Subagents inherit workspace tools from the parent agent's workspace automatically.\n // Apply disabledTools filter to both default and custom subagents.\n // const subagents = [];\n\n // Build initial state with global preferences. OM knobs are skipped when the\n // host persists memory settings elsewhere (`disableSettingsOmSeed`) so the\n // machine-local settings.json never leaks into server sessions.\n const globalInitialState: Partial<MastraCodeState> = {};\n if (!config?.disableSettingsOmSeed) {\n if (effectiveObserverModel) {\n globalInitialState.observerModelId = effectiveObserverModel;\n }\n if (effectiveReflectorModel) {\n globalInitialState.reflectorModelId = effectiveReflectorModel;\n }\n if (effectiveObservationThreshold !== undefined) {\n globalInitialState.observationThreshold = effectiveObservationThreshold;\n }\n if (effectiveReflectionThreshold !== undefined) {\n globalInitialState.reflectionThreshold = effectiveReflectionThreshold;\n }\n if (effectiveCavemanObservations !== undefined) {\n globalInitialState.cavemanObservations = effectiveCavemanObservations;\n }\n if (effectiveObserveAttachments !== undefined) {\n globalInitialState.observeAttachments = effectiveObserveAttachments;\n }\n }\n if (globalSettings.preferences.yolo !== null) {\n globalInitialState.yolo = globalSettings.preferences.yolo;\n }\n // Note: `thinkingLevel` is intentionally NOT seeded into session state. The\n // state slot is a session-level override; the effective level is resolved at\n // request time (per-mode defaults → global preference) in getDynamicModel so\n // settings changes apply to the next request of every session.\n if (config?.omScope) {\n globalInitialState.omScope = config.omScope;\n }\n // Seed subagent models from global settings\n for (const [key, modelId] of Object.entries(globalSettings.models.subagentModels)) {\n if (key === 'default' || key === '_default') {\n globalInitialState.subagentModelId = modelId;\n } else {\n globalInitialState[`subagentModelId_${key}`] = modelId;\n }\n }\n\n const typedStateSchema = stateSchema as PublicSchema<MastraCodeState>;\n const controller: AgentController<MastraCodeState> = new AgentController<MastraCodeState>({\n id: 'mastra-code',\n resourceId: project.resourceId,\n storage,\n observability,\n memory,\n pubsub: signalsPubSub,\n stateSchema: typedStateSchema,\n agent: codeAgent,\n subagents: config?.subagents ?? [],\n gateways: [amazonBedrockGateway, mastraCodeGateway],\n workspace: config?.workspace ?? (args => getDynamicWorkspace(args)),\n browser: config?.browser,\n idGenerator: config?.idGenerator,\n toolCategoryResolver: getToolCategory,\n initialState: {\n projectPath: project.rootPath,\n projectName: project.name,\n gitBranch: project.gitBranch,\n pluginSkillPaths: loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : [])),\n pluginCommandPaths: loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' ? (plugin.commandPaths ?? []) : [],\n ),\n pluginInstructions: loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n ),\n yolo: true,\n ...globalInitialState,\n ...config?.initialState,\n // configDir must always win over initialState spreads to stay in sync\n // with MCP/hooks/storage which were already initialized with this value.\n configDir,\n },\n modes,\n intervalHandlers,\n modelUseCountProvider: () => loadSettings().modelUseCounts,\n modelUseCountTracker: modelId => {\n try {\n const settings = loadSettings();\n settings.modelUseCounts[modelId] = (settings.modelUseCounts[modelId] ?? 0) + 1;\n saveSettings(settings);\n } catch (error) {\n console.error('Failed to persist model usage count', error);\n }\n },\n threadLock: crossProcessPubSub\n ? undefined\n : {\n acquire: acquireThreadLock,\n release: releaseThreadLock,\n },\n });\n\n // Publish the controller to the plugin runtime accessors now that it exists.\n pluginRuntimeController = controller;\n\n if (pluginSignalLane && pluginManager) {\n // Register the plugins loaded at startup, and re-reconcile on every reload.\n // Providers are not started here: they need a Mastra instance for storage,\n // and Mastra does not exist until the composition layer boots the controller\n // (see `startPluginSignalProviders` on the returned object).\n pluginSignalLane.sync(pluginManager.getPluginSignalProviders());\n unsubscribePluginReload = pluginManager.onReload(() =>\n pluginSignalLane.sync(pluginManager.getPluginSignalProviders()),\n );\n }\n\n // The AgentController is fully constructed but intentionally NOT inited here. Init and\n // session creation are deferred to the composition layer (see below) so the\n // controller can be wired in three ways:\n //\n // 1. Server + Web — registered on a server Mastra, then inited; sessions\n // minted per browser client over HTTP.\n // 2. Server + TUI — same server composition; the TUI drives a session\n // (in-process today; remote transport is future work).\n // 3. Local + TUI — controller builds its own internal Mastra on init() and\n // mints one eager session for the whole process.\n //\n // Cases 1 & 2 use `mountAgentControllerOnMastra` (register-before-init, no eager\n // session). Case 3 uses `bootLocalAgentController` (init + one wired session).\n return {\n controller: controller,\n storage,\n storageMaintenance,\n createKnowledgeInspector: (session: Session<MastraCodeState>) =>\n createScopedKnowledgeInspector({ storage, session }),\n observability,\n memory,\n mcpManager,\n hookManager,\n pluginManager,\n loadedPlugins,\n pluginTools,\n signalsPubSub,\n authStorage,\n resolveModel,\n storageWarning,\n observabilityWarning,\n builtinPacks,\n builtinOmPacks,\n effectiveDefaults,\n githubSignals,\n // Identity for the single local session (Case 3). Servers ignore these and\n // mint per-request sessions with client-supplied resourceIds instead.\n sessionId,\n ownerId,\n // Surface the project root so boot/mount paths can wire workflow tools\n // against a workspace anchored at it without re-running detectProject().\n projectPath: project.rootPath,\n // Surface the Agent instance so registerWorkflowBuilderPrimitives can add\n // it as a plain agent on the Mastra registry. Workflows then compose it\n // as an agent step (agentId: 'code-agent') and delegate open-ended tool\n // orchestration to it — code-agent already has full workspace / MCP / web\n // access via its dynamic tool factory.\n codeAgent,\n // Lets the composition layer publish the created session back into the\n // config closures (e.g. notification stream options read it lazily).\n setActiveSession: (session: Session<MastraCodeState>) => {\n activeSession = session;\n },\n /**\n * Starts the signal providers contributed by plugins. Called by the\n * composition layer once the controller is inited, because that is when a\n * Mastra instance exists — a provider without one has no storage, and\n * nothing else will hand it one: the Agent propagates Mastra only to the\n * providers in its own `signals` array, which these deliberately are not in.\n */\n startPluginSignalProviders: () => {\n const mastra = controller.getMastra();\n if (!pluginSignalLane || !mastra) return;\n pluginSignalLane.setMastra(mastra, codeAgent);\n },\n /**\n * Stops every plugin-contributed signal provider and stops listening for\n * plugin reloads. The inverse of `startPluginSignalProviders`, for an\n * embedder that is done with this controller: a `pluginManager` shared\n * across controllers (`MastraCodeConfig.pluginManager`) outlives any one of\n * them, so without this its providers keep polling and its reload listener\n * keeps firing for a controller that is gone.\n */\n stopPluginSignalProviders: () => {\n unsubscribePluginReload?.();\n unsubscribePluginReload = undefined;\n pluginSignalLane?.stopAll();\n },\n /**\n * Hands Mastra to the statically configured input processors.\n *\n * The Agent does this itself, but only for processors configured as a\n * plain array (`Array.isArray` in `__registerMastra`). This lane is a\n * function so plugins can contribute to it, which takes those processors\n * out of that branch — including any an embedder passed as\n * `config.inputProcessors`, some of which need Mastra to work at all\n * (`CostGuardProcessor` reads observability storage there). Doing it here\n * keeps that unchanged.\n *\n * Plugin processors are deliberately not included: they come and go with\n * their plugin, and the registry keeps the first instance registered under\n * an id forever, which would leave a retired instance behind. Plugins\n * reach Mastra through `getController()` on the plugin context instead.\n */\n registerConfiguredProcessorsWithMastra: () => {\n const mastra = controller.getMastra();\n if (!mastra) return;\n for (const processor of mastraCodeInputProcessors) {\n mastra.addProcessor(processor as Processor);\n mastra.addProcessorConfiguration(processor as Processor, CODE_AGENT_ID, 'input');\n }\n },\n };\n}\n\n/**\n * Result of {@link createMastraCodeAgentController}: every shared resource plus the\n * inert AgentController, ready to be either booted locally or mounted on a server\n * Mastra.\n */\nexport type MastraCodeAgentController = Awaited<ReturnType<typeof createMastraCodeAgentController>>;\n\n/**\n * Wires the session-scoped concerns MastraCode layers on top of a Session:\n * hookManager thread-id sync, GitHub PR polling for the current thread, and\n * per-thread persistence of the mastracode-only `/om` settings.\n *\n * Used by {@link bootLocalAgentController} for the single local session. A server can\n * call this for any session it mints if it wants the same background wiring.\n */\nexport async function wireSessionConcerns(\n base: Pick<MastraCodeAgentController, 'hookManager' | 'githubSignals' | 'setActiveSession'>,\n session: Session<MastraCodeState>,\n): Promise<void> {\n const { hookManager, githubSignals } = base;\n base.setActiveSession(session);\n\n // Sync hookManager session ID on thread changes\n if (hookManager) {\n session.subscribe((event: AgentControllerEvent) => {\n if (event.type === 'thread_changed') {\n hookManager.setSessionId(event.threadId);\n } else if (event.type === 'thread_created') {\n hookManager.setSessionId(event.thread.id);\n }\n });\n }\n\n if (githubSignals) {\n const startGithubPollingForCurrentThread = async (threadId?: string | null) => {\n if (!threadId) return;\n githubSignals.stopAllPolling();\n try {\n const threads = await session.thread.list({ allResources: true });\n const thread = threads.find((item: { id: string }) => item.id === threadId);\n await githubSignals.startPollingForThread(\n {\n threadId,\n resourceId: thread?.resourceId ?? session.identity.getResourceId(),\n },\n { pollImmediately: true },\n );\n } catch (error) {\n console.warn('Failed to start GitHub PR polling:', error);\n }\n };\n\n session.subscribe((event: AgentControllerEvent) => {\n if (event.type === 'thread_changed') void startGithubPollingForCurrentThread(event.threadId);\n else if (event.type === 'thread_created') void startGithubPollingForCurrentThread(event.thread.id);\n });\n void startGithubPollingForCurrentThread(session.thread.getId());\n }\n\n // Persist MastraCode-owned /om settings per-thread (mastracode-only concern;\n // intentionally not in core's controller loadThreadMetadata).\n const omThreadStateSession = session as unknown as Session<Record<string, unknown>>;\n attachOMThreadStatePersistence(omThreadStateSession);\n await restoreOMThreadStateForCurrentThread(omThreadStateSession).catch(() => {\n // Persistence is best-effort; don't crash startup if storage hiccups.\n });\n}\n\n/**\n * Case 3 (AgentController local + TUI/headless): build the controller, let it stand up its\n * own internal Mastra via `init()`, and mint the single eager session that all\n * work in this process runs through. The AgentController owns no session of its own.\n */\nexport async function bootLocalAgentController(config?: MastraCodeConfig) {\n const base = await createMastraCodeAgentController(config);\n const { controller, sessionId, ownerId, projectPath, codeAgent, mcpManager } = base;\n\n await controller.init();\n // Register workflow primitives (sub-agent + workspace tools + code-agent\n // + web + notification_inbox + snapshot of MCP tools) on the controller's\n // Mastra so the dynamic-workflow loading in startWorkers() can rehydrate\n // saved workflows against the right tool/agent registry.\n const mastra = controller.getMastra();\n if (mastra) await registerWorkflowBuilderPrimitives(mastra, { projectPath, codeAgent, mcpManager });\n await mastra?.startWorkers();\n base.registerConfiguredProcessorsWithMastra();\n base.startPluginSignalProviders();\n const session = await controller.createSession({ id: sessionId, ownerId });\n await wireSessionConcerns(base, session);\n const knowledgeInspector = await base.createKnowledgeInspector(session);\n\n return {\n ...base,\n session,\n knowledgeInspector,\n knowledgeInspectorUnavailableReason: knowledgeInspector\n ? undefined\n : 'Knowledge inspection requires a configured knowledge storage domain.',\n };\n}\n\n/** Result of {@link mountAgentControllerOnMastra}: shared handles plus the owning Mastra. */\nexport type MountedMastraCode = MastraCodeAgentController & { mastra: Mastra };\n\n/**\n * Cases 1 & 2 (AgentController in Server + Web/TUI): build the controller, register it on a\n * server-owned Mastra, THEN init it. Registering before `init()` is what makes\n * the controller inherit the server's Mastra (storage, agents, gateways) instead of\n * spinning up its own internal one — there is a single shared Mastra.\n *\n * No eager session is minted: each client (browser or terminal) creates/resumes\n * its own isolated session via `controller.createSession({ resourceId })`, so one\n * server can drive many concurrent users.\n *\n * Pass an existing `mastra` to mount onto a Mastra that already hosts other\n * primitives; otherwise a Mastra is created that owns the controller's storage so\n * durability is configured in one place.\n */\nexport async function mountAgentControllerOnMastra(\n config?: MastraCodeConfig & {\n mastra?: Mastra;\n controllerId?: string;\n buildApiRoutes?: (deps: { controller: MountedMastraCode['controller']; authStorage: AuthStorage }) => ApiRoute[];\n /**\n * Additional `server` config to fold onto the constructed Mastra alongside\n * the assembled `apiRoutes` (e.g. `middleware`, `cors`). Used by the\n * platform entry (`src/mastra/index.ts`) to own the WorkOS gate + tenant\n * dispatcher + CORS on the instance the deployer generates its server from.\n * Ignored when `mastra` is provided (mounting onto a caller-owned instance).\n */\n buildServerConfig?: (deps: {\n controller: MountedMastraCode['controller'];\n authStorage: AuthStorage;\n }) => Omit<NonNullable<ConstructorParameters<typeof Mastra>[0]>['server'], 'apiRoutes'>;\n },\n): Promise<MountedMastraCode> {\n const prepared = await prepareAgentControllerMount(config);\n if (config?.mastra) {\n // Mounting onto a Mastra the caller already built. Ensure the controller's\n // back-reference points at it (idempotent — only sets #externalMastra).\n prepared.base.controller.__registerMastra(config.mastra);\n await prepared.finalize();\n return { ...prepared.base, mastra: config.mastra };\n }\n const mastra = new Mastra(prepared.mastraArgs);\n await prepared.finalize();\n return { ...prepared.base, mastra };\n}\n\n/**\n * Assemble everything needed to construct the server-owned Mastra WITHOUT\n * constructing it, so a caller (the platform entry `src/mastra/index.ts`) can\n * run the `new Mastra(...)` literal in its own module. The deployer's\n * `checkConfigExport` Babel plugin only marks the config valid when it finds a\n * top-level `new Mastra(...)` exported as `mastra` in the ENTRY file; hiding the\n * construction inside this helper would trip the \"Invalid Mastra config\" warning.\n *\n * Returns the constructor args plus a `finalize()` that runs the post-construct\n * boot (`controller.init()` + `startWorkers()`). The controller is registered on\n * the Mastra via the `agentControllers` arg at construction time.\n */\nexport async function prepareAgentControllerMount(\n config?: MastraCodeConfig & {\n mastra?: Mastra;\n controllerId?: string;\n buildApiRoutes?: (deps: { controller: MountedMastraCode['controller']; authStorage: AuthStorage }) => ApiRoute[];\n buildServerConfig?: (deps: {\n controller: MountedMastraCode['controller'];\n authStorage: AuthStorage;\n }) => Omit<NonNullable<ConstructorParameters<typeof Mastra>[0]>['server'], 'apiRoutes'>;\n },\n): Promise<{\n base: Awaited<ReturnType<typeof createMastraCodeAgentController>>;\n mastraArgs: NonNullable<ConstructorParameters<typeof Mastra>[0]>;\n finalize: () => Promise<void>;\n}> {\n const base = await createMastraCodeAgentController(config);\n const { controller, storage, authStorage, projectPath, codeAgent, mcpManager } = base;\n const controllerId = config?.controllerId ?? controller.id;\n const apiRoutes = config?.buildApiRoutes?.({ controller, authStorage });\n const extraServerConfig = config?.buildServerConfig?.({ controller, authStorage });\n // Only register workflow primitives when we own the Mastra. If the caller\n // brought their own, they're responsible for what's registered on it.\n const weOwnTheMastra = !config?.mastra;\n\n const serverConfig = {\n ...extraServerConfig,\n ...(apiRoutes?.length ? { apiRoutes } : {}),\n };\n const mastraArgs = {\n agentControllers: { [controllerId]: controller },\n storage,\n // Mirror the controller's internal-Mastra construction (which passes\n // `config.pubsub` through): the server-owned Mastra must run its event\n // bus on the same transport so streams/workflows/signals stay\n // cross-process when a distributed PubSub (e.g. Redis Streams) is\n // configured.\n ...(base.signalsPubSub ? { pubsub: base.signalsPubSub } : {}),\n ...(Object.keys(serverConfig).length ? { server: serverConfig } : {}),\n };\n\n const finalize = async () => {\n await controller.init();\n if (weOwnTheMastra) {\n const mastra = controller.getMastra();\n if (mastra) await registerWorkflowBuilderPrimitives(mastra, { projectPath, codeAgent, mcpManager });\n }\n await controller.getMastra()?.startWorkers();\n // Anchored here rather than at a `new Mastra(...)` call site: finalize runs\n // in every mount path (caller-supplied Mastra, SDK-constructed Mastra, and\n // the platform entry that constructs its own), so plugin providers start\n // exactly once regardless of how Mastra Code was mounted.\n base.registerConfiguredProcessorsWithMastra();\n base.startPluginSignalProviders();\n };\n\n return { base, mastraArgs, finalize };\n}\n\n/**\n * Back-compat alias. Historically `createMastraCode` built and booted a local\n * controller with a single session; that behavior now lives in\n * {@link bootLocalAgentController}. New code should call the explicit factory for its\n * case: `bootLocalAgentController` (local) or {@link mountAgentControllerOnMastra} (server).\n */\nexport const createMastraCode = bootLocalAgentController;\nexport * from './knowledge-inspector.js';\n\n/**\n * Programmatic headless API. `runMC` runs an already-built controller/session\n * (from {@link createMastraCode}) as an async-iterable run that also resolves to\n * a typed result. Also available via the `mastracode/headless` subpath.\n */\nexport {\n runMC,\n runMCCli,\n hasHeadlessFlag,\n autoApprovePolicy,\n denyPolicy,\n permissionModeToPolicy,\n formatHuman,\n formatJsonl,\n renderTextResult,\n renderJsonResult,\n} from './headless/index.js';\nexport type {\n RunMCOptions,\n RunMCResult,\n RunMCStatus,\n RunMCUsage,\n RunMCToolCall,\n RunMCToolResult,\n RunMCError,\n RunMCThreadOptions,\n MCRun,\n ResolutionPolicy,\n PermissionMode,\n} from './headless/index.js';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["createScopedKnowledgeInspector"],"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport path from 'node:path';\n\nimport type { Agent } from '@mastra/core/agent';\nimport { AgentController } from '@mastra/core/agent-controller';\nimport type {\n IntervalHandler,\n AgentControllerConfig,\n AgentControllerEvent,\n AgentControllerMode,\n AgentControllerSubagent,\n AgentControllerRequestContext,\n Session,\n} from '@mastra/core/agent-controller';\nimport { createCodingAgent } from '@mastra/core/coding-agent';\nimport type { PubSub } from '@mastra/core/events';\nimport { PROVIDER_REGISTRY } from '@mastra/core/llm';\nimport type { ProviderConfig } from '@mastra/core/llm';\nimport { Mastra } from '@mastra/core/mastra';\nimport { defaultNotificationDeliveryDecision } from '@mastra/core/notifications';\nimport {\n AgentsMDInjector,\n isBadRequestError,\n PrefillErrorHandler,\n ProviderHistoryCompat,\n StreamErrorRetryProcessor,\n} from '@mastra/core/processors';\nimport type { InputProcessor, Processor } from '@mastra/core/processors';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { PublicSchema } from '@mastra/core/schema';\nimport type { ApiRoute } from '@mastra/core/server';\nimport { TaskSignalProvider } from '@mastra/core/signals';\nimport { InMemoryHarness, MastraCompositeStore } from '@mastra/core/storage';\nimport { DEFAULT_GOAL_JUDGE_PROMPT } from '@mastra/core/tools';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { DuckDBStore } from '@mastra/duckdb';\n\nimport { GithubSignals } from '@mastra/github-signals';\nimport { LibSQLStore, LibSQLVector } from '@mastra/libsql';\nimport {\n Observability,\n MastraStorageExporter,\n MastraPlatformExporter,\n SensitiveDataFilter,\n} from '@mastra/observability';\nimport { PostgresStore } from '@mastra/pg';\n\nimport { hasCredentialStoreProvider } from './agents/credential-resolver.js';\nimport { getDynamicInstructions } from './agents/instructions.js';\nimport { getDynamicMemory } from './agents/memory.js';\nimport { createMastraCodeGateway, getDynamicModel, getGoalJudgeModel, resolveModel } from './agents/model.js';\nimport { buildMode } from './agents/modes/build.js';\nimport { fastMode } from './agents/modes/explore.js';\nimport { planMode } from './agents/modes/plan.js';\nimport {\n createGitRefInstructionReader,\n createGitRefReminderReader,\n getStaticallyLoadedInstructionPaths,\n} from './agents/prompts/agent-instructions.js';\n// import { executeSubagent } from './agents/subagents/execute.js';\n// import { exploreSubagent } from './agents/subagents/explore.js';\n// import { planSubagent } from './agents/subagents/plan.js';\nimport { attachOMThreadStatePersistence, restoreOMThreadStateForCurrentThread } from './agents/thread-caveman-state.js';\nimport { createDynamicTools, createToolHooks } from './agents/tools.js';\nimport type { PostToolObserver, ToolLike } from './agents/tools.js';\n\nimport { getDynamicWorkspace, getGoalJudgeTools } from './agents/workspace.js';\nimport { isKimiCodingDeviceId } from './auth/providers/kimi-coding.js';\nimport { AuthStorage } from './auth/storage.js';\nimport { DEFAULT_CONFIG_DIR, validateConfigDirName } from './constants.js';\nimport { createOutcomeScorer, createEfficiencyScorer } from './evals/scorers/index.js';\nimport { HookManager } from './hooks/index.js';\nimport { createKnowledgeInspector as createScopedKnowledgeInspector } from './knowledge-inspector.js';\nimport { createMcpManager } from './mcp/index.js';\nimport type { McpServerConfig } from './mcp/index.js';\nimport { hasExplicitOMConfiguration } from './onboarding/om-settings.js';\nimport type { ProviderAccess } from './onboarding/packs.js';\nimport { getAvailableModePacks, getAvailableOmPacks, selectPreferredOMPack } from './onboarding/packs.js';\nimport {\n loadSettings,\n MASTRA_GATEWAY_PROVIDER,\n OBSERVABILITY_AUTH_PREFIX,\n resolveModelDefaults,\n resolveOmRoleModel,\n saveSettings,\n} from './onboarding/settings.js';\nimport { getToolCategory } from './permissions.js';\nimport { PluginManager } from './plugins/manager.js';\nimport { PluginSignalLane } from './plugins/signal-lane.js';\nimport type { PluginProcessorEntries } from './plugins/types.js';\nimport { PlanRejectionAbortProcessor } from './processors/plan-rejection-abort.js';\nimport { createAmazonBedrockGateway } from './providers/amazon-bedrock-gateway.js';\nimport { setAuthStorage } from './providers/claude-max.js';\nimport { setAuthStorage as setGitHubCopilotAuthStorage } from './providers/github-copilot.js';\nimport { setAuthStorage as setKimiCodingAuthStorage } from './providers/kimi-coding.js';\nimport { setAuthStorage as setOpenAIAuthStorage } from './providers/openai-codex.js';\nimport { setAuthStorage as setXAIAuthStorage } from './providers/xai.js';\n\nimport { stateSchema } from './schema.js';\nimport type { MastraCodeState } from './schema.js';\n\nimport { mastraBrand } from './theme-palette.js';\nimport { syncGateways } from './utils/gateway-sync.js';\nimport {\n detectProject,\n getObservabilityDatabasePath,\n getStorageConfig,\n getResourceIdOverride,\n} from './utils/project.js';\nimport type { StorageConfig } from './utils/project.js';\nimport { createSignalsPubSub } from './utils/signals-pubsub.js';\nimport { createStorage, createVectorStore } from './utils/storage-factory.js';\nimport type { StorageResult } from './utils/storage-factory.js';\nimport { createStorageMaintenance, DEFAULT_RETENTION, resolveLocalDbFiles } from './utils/storage-maintenance.js';\nimport type { StorageMaintenance } from './utils/storage-maintenance.js';\nimport { acquireThreadLock, releaseThreadLock } from './utils/thread-lock.js';\nimport { registerWorkflowBuilderPrimitives } from './workflows/register-primitives.js';\n\nconst CODE_AGENT_ID = 'code-agent';\n\n// Global retry policy for transient provider failures (e.g. dropped sockets and server errors).\n// Applied centrally to every model call via StreamErrorRetryProcessor, independent of model-pack\n// settings, so all modes/subagents benefit from a short wait before retrying a transient failure.\n// Delay uses exponential backoff: initialDelay * 2^retryCount, capped at maxDelay.\nconst MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES = 10;\nconst MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS = 500;\nconst MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS = 30000;\n\nconst TRANSIENT_CONNECTION_ERROR_CODES = new Set(['ECONNRESET', 'EPIPE']);\nconst TRANSIENT_CONNECTION_MESSAGE_PATTERN = /econnreset|socket hang up|write epipe|other side closed/i;\nconst TRANSIENT_SERVER_ERROR_STATUSES = new Set([500, 502, 503]);\nconst TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN = /internal server|server error|api may be experiencing issues/i;\n\n/**\n * Matcher for transient connection failures. Cause-chain traversal is handled\n * by `StreamErrorRetryProcessor.isRetryableStreamError`, which calls each\n * matcher at every level of the cause chain.\n */\n/**\n * Read the session state fields the AgentsMDInjector callbacks need from the\n * controller request context (set by hosts like the factory review flow).\n */\nfunction getInjectorSessionState(\n requestContext: { get: (key: string) => unknown } | undefined,\n): { untrustedCheckout?: boolean; baseRef?: string; projectPath?: string } | undefined {\n const agentControllerContext = requestContext?.get('controller') as\n | AgentControllerRequestContext<{ untrustedCheckout?: boolean; baseRef?: string; projectPath?: string }>\n | undefined;\n return agentControllerContext?.getState();\n}\n\nfunction isTransientConnectionError(error: unknown): boolean {\n if (!error) return false;\n\n const code = typeof error === 'object' && 'code' in error ? (error as { code?: unknown }).code : undefined;\n if (typeof code === 'string' && TRANSIENT_CONNECTION_ERROR_CODES.has(code.toUpperCase())) return true;\n\n const message = error instanceof Error ? error.message : undefined;\n if (typeof message === 'string' && TRANSIENT_CONNECTION_MESSAGE_PATTERN.test(message)) return true;\n\n return false;\n}\n\nfunction isTransientServerError(error: unknown): boolean {\n if (!error) return false;\n\n const errorObj = typeof error === 'object' ? (error as { status?: unknown; statusCode?: unknown }) : undefined;\n if (\n (typeof errorObj?.status === 'number' && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.status)) ||\n (typeof errorObj?.statusCode === 'number' && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.statusCode))\n ) {\n return true;\n }\n\n const message = error instanceof Error ? error.message : undefined;\n return typeof message === 'string' && TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN.test(message);\n}\n\nfunction getTransientRetryDelay(retryCount: number): number {\n return Math.min(\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS * Math.pow(2, retryCount),\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS,\n );\n}\n\nfunction emitTransientRetry(\n error: unknown,\n retryCount: number,\n delayMs: number,\n requestContext?: RequestContext,\n): void {\n const controllerContext = requestContext?.get('controller') as AgentControllerRequestContext | undefined;\n controllerContext?.emitEvent?.({\n type: 'error',\n error: error instanceof Error ? error : new Error(String(error)),\n retryable: true,\n retryDelay: delayMs,\n retryAttempt: retryCount + 1,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n });\n}\n\n/** Short deterministic hash (sha256, first 12 hex chars) matching project.ts shortHash style. */\nfunction shortHash(input: string): string {\n return createHash('sha256').update(input).digest('hex').slice(0, 12);\n}\n\nfunction applyEffectiveDefaultsToModes(\n modes: AgentControllerMode[],\n effectiveDefaults: Record<string, string>,\n): AgentControllerMode[] {\n return modes.map(mode => {\n const savedModel = effectiveDefaults[mode.id];\n if (!savedModel) {\n return mode;\n }\n return {\n ...mode,\n defaultModelId: savedModel,\n };\n });\n}\n\nfunction addPluginToolsToModeAllowlists(\n modes: AgentControllerMode[],\n pluginToolNames: string[],\n): AgentControllerMode[] {\n if (pluginToolNames.length === 0) return modes;\n return modes.map(mode => {\n if (!mode.availableTools) return mode;\n return {\n ...mode,\n availableTools: Array.from(new Set([...mode.availableTools, ...pluginToolNames])),\n };\n });\n}\n\nexport interface MastraCodeConfig {\n /** Working directory for project detection. Default: process.cwd() */\n cwd?: string;\n /** Home directory for global config discovery. Default: os.homedir() */\n homeDir?: string;\n /** Override modes (model IDs, colors, which modes exist). Default: build/plan/fast */\n modes?: AgentControllerMode[];\n /** Override or extend subagent definitions. Default: explore/plan/execute */\n subagents?: AgentControllerSubagent[];\n /** Extra tools merged into the dynamic tool set. Can be a static record or a (sync or async) function that receives requestContext. */\n extraTools?:\n | Record<string, ToolLike | undefined>\n | ((ctx: {\n requestContext: RequestContext;\n }) => Record<string, ToolLike | undefined> | Promise<Record<string, ToolLike | undefined>>);\n /** Observe completed tool calls without replacing or modifying the built-in tool implementation. */\n postToolObserver?: PostToolObserver;\n /**\n * Stateless input processor instances prepended before Mastra Code's mandatory processors.\n * Embedders may extend processing but cannot replace built-in safety and compatibility policy.\n */\n inputProcessors?: InputProcessor[];\n /** Tools removed from the dynamic tool set before exposure to the model */\n disabledTools?: string[];\n /**\n * Custom storage config instead of auto-detected default, or a pre-built\n * store instance. An instance is used as-is: no connection test and no\n * LibSQL fallback — if the injected store fails, that's a hard error.\n */\n storage?: StorageConfig | MastraCompositeStore;\n /** Backend for an injected custom storage instance. Inferred for LibSQLStore and PostgresStore. */\n storageBackend?: 'libsql' | 'pg';\n /** Pre-built vector store instance for recall search. Skips the default vector store creation. */\n vector?: MastraVector;\n /** Observational memory scope. Default: auto-detected from env/config files, falls back to 'thread' */\n omScope?: 'thread' | 'resource';\n /** Path to a custom settings.json file. Default: global settings */\n settingsPath?: string;\n /** Initial state overrides (yolo, thinkingLevel, etc.) */\n initialState?: Partial<MastraCodeState>;\n /** Override id generation for threads/messages. Primarily useful for deterministic tests. */\n idGenerator?: AgentControllerConfig<MastraCodeState>['idGenerator'];\n /** Override interval handlers. Default: gateway-sync */\n intervalHandlers?: IntervalHandler[];\n /** Override the workspace. Default: local filesystem + local sandbox based on detected project */\n workspace?: AgentControllerConfig<MastraCodeState>['workspace'];\n /** Override the config directory name. Default: '.mastracode'. Replaces '.mastracode' in all project-level and global config paths (MCP, hooks, commands, database, skills, agent instructions). */\n configDir?: string;\n /** Programmatic MCP server configurations, merged with (and overriding) file-based configs. */\n mcpServers?: Record<string, McpServerConfig>;\n /** Disable MCP server discovery. Default: false */\n disableMcp?: boolean;\n /** Disable hooks. Default: false */\n disableHooks?: boolean;\n /** Disable plugin discovery/loading. Default: false */\n disablePlugins?: boolean;\n /** Disable the polling-based GitHub signal provider even when enabled in global settings. Default: false */\n disableGithubSignals?: boolean;\n /**\n * Skip seeding observational-memory knobs (observer/reflector models,\n * thresholds, caveman mode, attachment observation) from settings.json.\n * Server deployments that persist memory settings in their own database\n * (the factory's `memory-settings` domain) set this so the host machine's\n * TUI settings file never leaks into server sessions. Default: false.\n */\n disableSettingsOmSeed?: boolean;\n /** Override the plugin manager. Primarily useful for tests or embedding. */\n pluginManager?: PluginManager;\n /**\n * Override the memory instance (or dynamic factory) passed to the AgentController.\n * When provided, this replaces the default `getDynamicMemory(storage, vector)` which\n * uses mastracode's built-in model gateway (Anthropic OAuth, OpenAI Codex,\n * custom providers, and models.dev fallback).\n *\n * Use this when you need to override memory model behavior completely.\n */\n memory?: AgentControllerConfig<MastraCodeState>['memory'] | false;\n /** Browser provider for browser automation tools. When set, the agent gains access to browser tools. */\n browser?: AgentControllerConfig<MastraCodeState>['browser'];\n /** PubSub for signal routing. When crossProcessPubSub is true, thread locks are disabled. */\n pubsub?: PubSub;\n /** Use Mastra Code's built-in Unix socket PubSub for local cross-process signal routing. */\n unixSocketPubSub?: boolean;\n /** Marks the configured PubSub as cross-process-safe, allowing Mastra Code to skip file thread locks. */\n crossProcessPubSub?: boolean;\n}\n\nexport function createAuthStorage() {\n const authStorage = new AuthStorage();\n setAuthStorage(authStorage);\n setOpenAIAuthStorage(authStorage);\n setGitHubCopilotAuthStorage(authStorage);\n setKimiCodingAuthStorage(authStorage);\n setXAIAuthStorage(authStorage);\n return authStorage;\n}\n\n/**\n * Resolve cloud observability credentials for the MastraPlatformExporter.\n * Priority: per-resource settings > environment variables > disabled.\n */\nfunction resolveCloudObservabilityConfig(\n settings: ReturnType<typeof loadSettings>,\n authStorage: AuthStorage,\n resourceId: string,\n): { accessToken?: string; projectId?: string } {\n const resourceConfig = settings.observability.resources[resourceId];\n if (resourceConfig) {\n const token = authStorage.getStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`);\n if (token) {\n return { accessToken: token, projectId: resourceConfig.projectId };\n }\n }\n // Fall back to environment variables for backwards compatibility\n return {\n accessToken: process.env.MASTRA_CLOUD_ACCESS_TOKEN,\n projectId: process.env.MASTRA_PROJECT_ID,\n };\n}\n\n/**\n * Base factory: builds every shared MastraCode resource (storage, observability,\n * memory, MCP, providers, gateways, agent, modes) and the {@link AgentController}, but\n * does NOT call `init()` or create a session. The controller is returned inert so\n * the composition layer can decide its Mastra ownership and session model.\n *\n * See {@link bootLocalAgentController} (Case 3) and `mountAgentControllerOnMastra` (Cases 1 & 2).\n */\n/**\n * `instanceof` checks against Mastra classes are unreliable here: published\n * packages pin exact `@mastra/core` versions, so a user's dependency graph can\n * contain multiple copies of core (and peer-keyed copies of `@mastra/libsql` /\n * `@mastra/pg`). A store built against one copy fails `instanceof` against\n * another — the injected instance then silently fell through to the\n * StorageConfig path and crashed on `config.url`. These structural checks work\n * across duplicated copies.\n */\nfunction isInjectedStorageInstance(storage: MastraCodeConfig['storage']): storage is MastraCompositeStore {\n if (!storage) return false;\n if (storage instanceof MastraCompositeStore) return true;\n // A StorageConfig is a plain data object with a string `backend`\n // discriminant; a store instance carries the MastraCompositeStore method\n // surface.\n const candidate = storage as Partial<MastraCompositeStore>;\n return typeof candidate.init === 'function' && typeof candidate.__registerMastra === 'function';\n}\n\n/** Cross-copy-safe class check: walks the prototype chain by constructor name. */\nfunction hasAncestorClassNamed(value: object, className: string): boolean {\n for (let proto = Object.getPrototypeOf(value); proto; proto = Object.getPrototypeOf(proto)) {\n if (proto.constructor?.name === className) return true;\n }\n return false;\n}\n\nfunction resolveInjectedStorageBackend(\n storage: MastraCompositeStore,\n configuredBackend?: 'libsql' | 'pg',\n): 'libsql' | 'pg' {\n if (configuredBackend) return configuredBackend;\n if (storage instanceof LibSQLStore || hasAncestorClassNamed(storage, 'LibSQLStore')) return 'libsql';\n if (storage instanceof PostgresStore || hasAncestorClassNamed(storage, 'PostgresStore')) return 'pg';\n throw new Error('storageBackend is required when injecting a custom storage instance.');\n}\n\nexport async function createMastraCodeAgentController(config?: MastraCodeConfig) {\n const cwd = config?.cwd ?? process.cwd();\n const homeDir = config?.homeDir ?? config?.initialState?.homeDir;\n const configDir = config?.configDir ?? DEFAULT_CONFIG_DIR;\n // The single session for this process, assigned once `createSession()` runs\n // below. Config callbacks defined before then (e.g. notification stream\n // options) read it lazily through this holder.\n let activeSession: Session<MastraCodeState> | undefined;\n // Same trick for the controller, which plugins reach through a lazy accessor.\n // Plugins load well before the controller is constructed, and a closure over\n // the `controller` binding itself would throw on early access rather than\n // reporting \"not ready yet\", so the accessor reads this holder instead.\n let pluginRuntimeController: AgentController<MastraCodeState> | undefined;\n if (configDir !== DEFAULT_CONFIG_DIR) {\n validateConfigDirName(configDir);\n }\n\n // Load .env file from cwd if present (for observability API keys, etc.)\n try {\n process.loadEnvFile(path.join(cwd, '.env'));\n } catch {\n // No .env file — that's fine, keys may be in shell environment\n }\n\n // Auth storage (shared with Claude Max / OpenAI providers and AgentController)\n const authStorage = createAuthStorage();\n const globalSettings = loadSettings(config?.settingsPath);\n const storedGatewayKey = authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER);\n const storedGatewayUrl = globalSettings.memoryGateway?.baseUrl;\n\n if (storedGatewayKey) {\n process.env['MASTRA_GATEWAY_API_KEY'] ??= storedGatewayKey;\n }\n\n if (storedGatewayUrl) {\n process.env['MASTRA_GATEWAY_URL'] ??= storedGatewayUrl;\n }\n\n // Load user-entered API keys from auth.json into process.env\n // (only sets env vars that aren't already present — env vars take precedence).\n // Skipped in deployed multi-tenant mode: when a per-tenant credential store\n // provider is registered, provider keys are resolved per request and must\n // never leak into process-global env vars.\n if (!hasCredentialStoreProvider()) {\n try {\n const registry = PROVIDER_REGISTRY as Record<string, ProviderConfig>;\n const providerEnvVars: Record<string, string | undefined> = {};\n for (const [provider, cfg] of Object.entries(registry)) {\n const envVars = cfg?.apiKeyEnvVar;\n providerEnvVars[provider] = Array.isArray(envVars) ? envVars[0] : envVars;\n }\n providerEnvVars[MASTRA_GATEWAY_PROVIDER] ??= 'MASTRA_GATEWAY_API_KEY';\n authStorage.loadStoredApiKeysIntoEnv(providerEnvVars);\n } catch {\n // Registry unavailable — load well-known provider keys so non-gateway flows still work\n authStorage.loadStoredApiKeysIntoEnv({\n [MASTRA_GATEWAY_PROVIDER]: 'MASTRA_GATEWAY_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n openai: 'OPENAI_API_KEY',\n google: 'GOOGLE_GENERATIVE_AI_API_KEY',\n cerebras: 'CEREBRAS_API_KEY',\n deepseek: 'DEEPSEEK_API_KEY',\n });\n }\n }\n\n const mgApiKey = process.env['MASTRA_GATEWAY_API_KEY'] ?? storedGatewayKey;\n const mastraGatewayBaseUrl = (\n process.env['MASTRA_GATEWAY_URL'] ??\n storedGatewayUrl ??\n 'https://gateway-api.mastra.ai'\n )\n .replace(/\\/+$/, '')\n .replace(/\\/v1$/, '');\n const mastraCodeGateway = createMastraCodeGateway({\n mastraGatewayBaseUrl,\n mastraGatewayApiKey: mgApiKey,\n routeThroughMastraGateway: false,\n settingsPath: config?.settingsPath,\n });\n const amazonBedrockGateway = createAmazonBedrockGateway();\n\n // Project detection\n const project = detectProject(cwd);\n\n const resourceIdOverride = getResourceIdOverride(project.rootPath, configDir);\n if (resourceIdOverride) {\n project.resourceId = resourceIdOverride;\n project.resourceIdOverride = true;\n }\n\n // Stable session id unique to this project/resource, and a machine-bound owner\n // id. resourceId encodes root path + git identity and honors overrides, so it\n // is the right input for scoping the session to the cwd/project.\n const sessionId = `mastracode-session-${shortHash(project.resourceId)}`;\n const ownerId = `mastracode-${shortHash(`${hostname()}\\0${project.rootPath}`)}`;\n\n const configuredPubSub = config?.pubsub;\n const useUnixSocketPubSub =\n (config?.unixSocketPubSub ?? globalSettings.signals?.unixSocketPubSub ?? false) && process.platform !== 'win32';\n const signalsPubSub = configuredPubSub ?? (useUnixSocketPubSub ? createSignalsPubSub(project.resourceId) : undefined);\n const crossProcessPubSub = config?.crossProcessPubSub ?? (!configuredPubSub && useUnixSocketPubSub);\n if (crossProcessPubSub && !signalsPubSub) {\n throw new Error('crossProcessPubSub requires a pubsub instance');\n }\n\n // Storage. An injected instance is used as-is — no connection test, no\n // LibSQL fallback: if the injected store fails, that's a hard error.\n const injectedStorage = isInjectedStorageInstance(config?.storage) ? config.storage : undefined;\n const storageConfig = injectedStorage\n ? undefined\n : ((config?.storage as StorageConfig | undefined) ??\n getStorageConfig(project.rootPath, globalSettings.storage, configDir));\n const storageResult: StorageResult = injectedStorage\n ? { storage: injectedStorage, backend: resolveInjectedStorageBackend(injectedStorage, config?.storageBackend) }\n : await createStorage(storageConfig!);\n const storageWarning = storageResult.warning;\n\n // Observability storage (DuckDB — separate file for OLAP-style trace/score/feedback queries).\n // Local tracing is opt-in via `/observability local on`. When disabled, the\n // MastraStorageExporter is omitted entirely so traces never fall through to\n // the default libsql backend.\n let observabilityDomain: DuckDBStore['observability'] | undefined;\n let observabilityWarning: string | undefined;\n if (globalSettings.observability.localTracing) {\n try {\n const observabilityDuckDB = new DuckDBStore({\n id: 'mastra-code-observability',\n path: getObservabilityDatabasePath(),\n });\n // Force an early connection attempt so the lock error surfaces now, not mid-session.\n await observabilityDuckDB.db.getConnection();\n observabilityDomain = observabilityDuckDB.observability;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const isLockError = /lock|locked|busy/i.test(message);\n if (isLockError) {\n observabilityWarning =\n 'Observability unavailable — another MastraCode instance holds the database lock. Traces, scores, and feedback will not be recorded in this session.';\n } else {\n observabilityWarning = `Observability unavailable — DuckDB initialization failed: ${message}`;\n }\n }\n }\n\n const harnessStorage = new InMemoryHarness();\n\n const storage = new MastraCompositeStore({\n id: 'mastra-code-storage',\n default: storageResult.storage,\n domains: {\n // When local tracing is off, disable the observability domain entirely so\n // trace/score/feedback writes never fall through to the default libsql store.\n observability: observabilityDomain ?? false,\n harness: harnessStorage,\n },\n });\n\n // Observability (tracing, scoring, feedback)\n const observability = new Observability({\n configs: {\n default: {\n serviceName: 'mastracode',\n // Only these requestContext keys are stored on spans — prevents leaking\n // large objects (controller state, workspace, env vars) into trace data.\n // Use dot-notation because these are nested inside the 'controller' key.\n //\n // Session identifiers:\n // threadId, resourceId, session.modeId, agentControllerId\n // Environment & project:\n // state.projectName, state.gitBranch\n // Model configuration:\n // session.modelId, state.subagentModelId\n // Agent settings:\n // state.yolo, state.thinkingLevel, state.smartEditing\n // Observational memory settings:\n // state.omScope, state.observerModelId, state.reflectorModelId,\n // state.observationThreshold, state.reflectionThreshold\n requestContextKeys: [\n // Session identifiers\n 'controller.threadId',\n 'controller.resourceId',\n 'controller.session.modeId',\n 'controller.controllerId',\n // Environment & project\n 'controller.state.projectName',\n 'controller.state.gitBranch',\n // Model configuration\n 'controller.session.modelId',\n 'controller.state.subagentModelId',\n // Agent settings\n 'controller.state.yolo',\n 'controller.state.thinkingLevel',\n 'controller.state.smartEditing',\n // Observational memory settings\n 'controller.state.omScope',\n 'controller.state.observerModelId',\n 'controller.state.reflectorModelId',\n 'controller.state.observationThreshold',\n 'controller.state.reflectionThreshold',\n ],\n exporters: [\n // Only persist traces locally when DuckDB observability is available\n // (via `/observability local on`). Without this guard the storage\n // exporter falls through to the default libsql backend and silently\n // fills the main database with gigabytes of span data.\n ...(observabilityDomain ? [new MastraStorageExporter({ strategy: 'event-sourced' })] : []),\n new MastraPlatformExporter(resolveCloudObservabilityConfig(globalSettings, authStorage, project.resourceId)),\n ],\n spanOutputProcessors: [new SensitiveDataFilter()],\n },\n },\n });\n\n // Vector store for recall search (separate DB file to avoid bloating main\n // storage). An injected instance is used as-is; with an injected storage\n // instance and no injected vector, recall search stays vector-less.\n const vector =\n config?.vector ?? (storageConfig ? await createVectorStore(storageConfig, storageResult.backend) : undefined);\n\n // Maintenance handle for /prune: prunes via the inner store (whose retention\n // config covers every domain, including legacy libsql observability spans)\n // and can compact local libsql files to reclaim disk. The vector store's\n // connection must close alongside storage — the compaction's file swap\n // refuses to run while any connection is open.\n const storageMaintenance: StorageMaintenance = createStorageMaintenance({\n storage: storageResult.storage,\n backend: storageResult.backend,\n retention: DEFAULT_RETENTION,\n localDbFiles: storageConfig ? resolveLocalDbFiles(storageConfig, storageResult.backend) : [],\n closeVector: vector instanceof LibSQLVector ? () => vector.close() : undefined,\n });\n\n const memory = config?.memory === false ? undefined : (config?.memory ?? getDynamicMemory(storage, vector));\n\n // MCP\n const mcpManager = config?.disableMcp\n ? undefined\n : createMcpManager(project.rootPath, configDir, config?.mcpServers, globalSettings.mcp);\n\n // Hooks\n const hookManager = config?.disableHooks\n ? undefined\n : new HookManager(\n project.rootPath,\n 'session-init',\n configDir,\n homeDir,\n project.isWorktree\n ? { path: project.rootPath, branch: project.gitBranch, mainRepoPath: project.mainRepoPath }\n : undefined,\n );\n\n const pluginManager = config?.disablePlugins\n ? undefined\n : (config?.pluginManager ??\n new PluginManager({\n projectRoot: project.rootPath,\n configDir,\n homeDir,\n }));\n // Publish the runtime accessors to whichever manager is in play — including an\n // injected one, which would otherwise hand plugins `undefined` for\n // `getController`/`getActiveSession`. Lazy closures: both locals are assigned\n // after the controller is constructed below.\n pluginManager?.setRuntime({\n getController: () => pluginRuntimeController,\n getActiveSession: () => activeSession,\n });\n const loadedPlugins = pluginManager ? await pluginManager.reload() : [];\n const pluginTools = pluginManager?.getPluginTools() ?? {};\n\n // Scorers (live evaluation with sampling)\n const outcomeScorer = createOutcomeScorer();\n const efficiencyScorer = createEfficiencyScorer();\n\n // Agent — githubSignals is created before `controller` but the closure below\n // captures `controller` by reference; it is only invoked at notification time,\n // well after controller is constructed (line ~692). Explicit type annotations\n // on githubSignals, codeAgent, modes, and controller break the circular\n // inference chain this forward reference would otherwise create.\n // Shared by GithubSignals (immediate sends) and the code agent's\n // notification config (deferred sends re-dispatched by the core notification\n // dispatch workflow) — both need the target session's request context, or a\n // woken idle thread has no model to run with (\"No model selected\").\n const getNotificationStreamOptions = async ({ resourceId, threadId }: { resourceId: string; threadId: string }) => {\n // Run the woken notification as the session that owns the target\n // resource so it uses that session's model/mode/state. Fall back to\n // the current session only when no session owns the resource yet.\n const session = (await controller.getSessionByResource(resourceId)) ?? activeSession;\n // No session owns the resource and none is active yet (e.g. a deferred\n // notification comes due before any session boots). Nothing to resolve a\n // model from; return undefined so the dispatcher sends a bare wake\n // instead of throwing mid-delivery.\n if (!session) return undefined;\n // A long-running system must be able to drive work unattended, so a\n // target session without an explicit model selection falls back to a\n // real model rather than failing the run: the current session's live\n // selection (what the user actually picked), then the mode's default.\n const modeId = session.mode.get();\n const defaultModeModelId = controller.listModes().find(mode => mode.id === modeId)?.defaultModelId;\n const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || '';\n const requestContext = new RequestContext();\n const agentControllerContext: AgentControllerRequestContext = {\n controllerId: controller.id,\n state: session.state.get(),\n getState: () => session.state.get(),\n setState: updates => session.state.set(updates),\n threadId,\n resourceId,\n session: {\n id: session.identity.getId(),\n ownerId: session.identity.getOwnerId(),\n modeId,\n modelId,\n state: {\n get: () => session.state.get(),\n set: updates => session.state.set(updates),\n update: updater => session.state.update(updater),\n },\n },\n workspace: session.getWorkspace(),\n getSubagentModelId: params => session.subagents.model.get(params ?? {}),\n };\n requestContext.set('controller', agentControllerContext);\n\n return {\n memory: { thread: threadId, resource: resourceId },\n requestContext,\n maxSteps: 1000,\n savePerStep: false,\n requireToolApproval: (session.state.get() as Record<string, unknown>).yolo !== true,\n modelSettings: { temperature: 1 },\n };\n };\n\n const githubSignals: GithubSignals | undefined =\n globalSettings.signals?.experimentalGithubSignals && !config?.disableGithubSignals\n ? new GithubSignals({\n cwd: project.rootPath,\n pollIntervalMs: globalSettings.signals.githubPollIntervalMs,\n gitcrawlCommand:\n process.env.MASTRACODE_GITCRAWL_BIN ??\n process.env.GITCRAWL_BIN ??\n process.env.MASTRACODE_GITCRAWL_COMMAND ??\n process.env.GITCRAWL_COMMAND,\n getNotificationStreamOptions,\n })\n : undefined;\n // Mastra Code's own processors are constructed once, here, rather than inside\n // the resolver below: the resolver runs before every LLM call, and rebuilding\n // stateful processors per request would reset them.\n const mastraCodeInputProcessors: InputProcessor[] = [\n ...(config?.inputProcessors ?? []),\n new PlanRejectionAbortProcessor(),\n new AgentsMDInjector({\n // Untrusted checkouts (review sessions on PR branches) must not have\n // the working tree's instruction files injected as system reminders —\n // those files are attacker-writable content, not configuration. When\n // the session carries a trusted base ref, reminders are served from\n // that ref instead (see getReader); without one they are disabled.\n isEnabled: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n return state?.untrustedCheckout !== true || typeof state?.baseRef === 'string';\n },\n getReader: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n if (state?.untrustedCheckout !== true || typeof state?.baseRef !== 'string') return undefined;\n return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);\n },\n getIgnoredInstructionPaths: ({ requestContext }) => {\n const state = getInjectorSessionState(requestContext);\n const projectPath = state?.projectPath ?? project.rootPath;\n // On untrusted checkouts the static prompt loads from the base ref,\n // so compute the statically-loaded paths through the same reader to\n // keep the dedup consistent.\n const projectReader =\n state?.untrustedCheckout === true && typeof state?.baseRef === 'string'\n ? createGitRefInstructionReader(projectPath, state.baseRef)\n : undefined;\n return getStaticallyLoadedInstructionPaths(projectPath, undefined, projectReader);\n },\n }),\n new ProviderHistoryCompat(),\n ];\n\n // TaskSignalProvider bundles the task tools + TaskStateProcessor (see the\n // `signals` array below); named here so the plugin lane can reserve its id.\n const taskSignalProvider = new TaskSignalProvider();\n\n const NO_PLUGIN_PROCESSORS: PluginProcessorEntries = { input: [], output: [] };\n let pluginProcessorReadWarned = false;\n\n // Providers contributed by plugins are driven from here rather than through\n // the agent's `signals` array: the Agent constructor harvests a provider's\n // processors into a closure it can never undo, so a provider wired there\n // could not be removed when its plugin is disabled, updated or uninstalled.\n // The built-in providers are seeded as reserved ids because they are wired\n // through the constructor and are therefore invisible to the lane.\n const pluginSignalLane = pluginManager\n ? new PluginSignalLane({\n reservedProviderIds: [taskSignalProvider.id, ...(githubSignals ? [githubSignals.id] : [])],\n })\n : undefined;\n let unsubscribePluginReload: (() => void) | undefined;\n\n /**\n * Plugin processors are read through a function so that enabling, disabling or\n * updating a plugin takes effect on the next request rather than requiring a\n * new agent. This runs before every LLM call, and also outside the request\n * path when the Agent catalogues its configured processors — where a throw is\n * swallowed into a debug log. So it only reads already-resolved state: no\n * filesystem, no network, no construction, and it never throws.\n */\n const readPluginProcessors = (): PluginProcessorEntries => {\n try {\n return pluginManager?.getPluginProcessors() ?? NO_PLUGIN_PROCESSORS;\n } catch (error) {\n // Warn once: this is on the hot path, and a broken read repeats.\n if (!pluginProcessorReadWarned) {\n pluginProcessorReadWarned = true;\n console.warn('Failed to read plugin processors:', error);\n }\n return NO_PLUGIN_PROCESSORS;\n }\n };\n\n const codeAgent: Agent = createCodingAgent({\n id: CODE_AGENT_ID,\n name: 'Code Agent',\n // Workspace is wired per-request at the AgentController level (see\n // `config.workspace` below), so opt out of the factory's default local\n // workspace. An explicit `undefined` is required: the factory only builds a\n // default when the `workspace` key is absent.\n workspace: undefined,\n instructions: getDynamicInstructions,\n // `settingsPath` matches the source `createMastraCode()` reads from so the\n // per-mode thinking defaults resolve against the same config file.\n model: ctx => getDynamicModel(ctx, config?.settingsPath),\n // Deferred notifications are re-dispatched by the core notification\n // dispatch workflow long after the originating send; the delivery policy\n // rebuilds the request context (model selection included) at delivery time\n // so waking an idle thread does not fail with \"No model selected\". The\n // default decision logic is kept as-is — the policy only attaches\n // streamOptions on top of it.\n notifications: {\n deliveryPolicy: {\n decide: async input => {\n const decision = defaultNotificationDeliveryDecision(input);\n // Without a resourceId there is no session to resolve options from —\n // don't fall through to the active session and wake it under an\n // empty resource binding.\n if (!input.record.resourceId) return decision;\n const streamOptions = await getNotificationStreamOptions({\n resourceId: input.record.resourceId,\n threadId: input.record.threadId,\n });\n return streamOptions ? { ...decision, streamOptions } : decision;\n },\n },\n },\n tools: createDynamicTools(mcpManager, config?.extraTools, config?.disabledTools, storage, pluginTools),\n hooks: createToolHooks(hookManager, config?.postToolObserver),\n scorers: {\n outcome: {\n scorer: outcomeScorer,\n sampling: { type: 'none' },\n },\n efficiency: {\n scorer: efficiencyScorer,\n sampling: { type: 'ratio', rate: 0.3 },\n },\n },\n // TaskSignalProvider bundles the task tools + TaskStateProcessor: it merges\n // the tools into the toolset and registers the task state-signal processor,\n // so the task list persists across turns and survives OM truncation.\n signals: [taskSignalProvider, ...(githubSignals ? [githubSignals] : [])],\n // Native goal mechanism: the in-loop goal step judges the thread's active\n // objective each qualifying iteration. The judge model is required for any\n // gating to occur; when unset the goal step is a complete no-op. A6 auto-wires\n // the GoalStateProcessor so the `<current-objective>` signal persists across\n // turns. Per-thread overrides live in the ThreadState `goal` record and win\n // over these defaults.\n goal: {\n // Resolve the judge model through mastracode's gateway (a model-resolver\n // function) so provider credentials are injected; returns undefined when no\n // judge model is configured, keeping the goal step a no-op. Bind the same\n // `settingsPath` used above so the judge model and `maxRuns` come from one\n // config (a custom settings file would otherwise diverge).\n judge: ctx => getGoalJudgeModel(ctx, config?.settingsPath),\n maxRuns: globalSettings.models.goalMaxTurns ?? 50,\n maxSteps: 1000,\n prompt: DEFAULT_GOAL_JUDGE_PROMPT,\n // Read-only workspace tools the default goal judge may call to verify the\n // agent's work against the actual filesystem (view, search_content,\n // find_files, file_stat, lsp_inspect) rather than grading prose alone —\n // restoring the original MastraCode judge's verification ability. Resolved\n // per-request from the active workspace (mirrors `judge`).\n tools: getGoalJudgeTools,\n },\n inputProcessors: () => [\n ...mastraCodeInputProcessors,\n ...readPluginProcessors().input.map(entry => entry.value),\n ...(pluginSignalLane?.getInputProcessors() ?? []),\n ],\n // Mastra Code contributes no output processors of its own; the lane exists\n // so plugins can. Like the input lane, plugin processors sit last — after\n // the layers they customize, before the channel and memory layers the\n // Agent appends.\n outputProcessors: () => [\n ...readPluginProcessors().output.map(entry => entry.value),\n ...(pluginSignalLane?.getOutputProcessors() ?? []),\n ],\n errorProcessors: [\n // ProviderHistoryCompat must run before StreamErrorRetryProcessor: both react to\n // HTTP 400s, but ProviderHistoryCompat repairs the incompatible history (e.g.\n // sanitizing tool-call IDs) before retrying, while StreamErrorRetryProcessor's\n // isBadRequestError matcher retries the identical request. Error processors\n // short-circuit on the first `retry: true`, so a blind retry first would resend\n // the broken history and fail again.\n new ProviderHistoryCompat(),\n new StreamErrorRetryProcessor({\n matchers: [\n { match: isBadRequestError, maxRetries: 1, delayMs: 2000 },\n {\n match: isTransientConnectionError,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),\n onRetry: ({ error, retryCount, delayMs, requestContext }) =>\n emitTransientRetry(error, retryCount, delayMs, requestContext),\n },\n {\n match: isTransientServerError,\n maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,\n delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),\n onRetry: ({ error, retryCount, delayMs, requestContext }) =>\n emitTransientRetry(error, retryCount, delayMs, requestContext),\n },\n ],\n }),\n new PrefillErrorHandler(),\n ],\n });\n\n // const defaultSubAgents: Array<AgentControllerSubagent> = [];\n // const defaultSubagents = [exploreSubagent, planSubagent, executeSubagent];\n\n const defaultModes: AgentControllerMode[] = [\n {\n ...buildMode,\n metadata: {\n ...buildMode.metadata,\n color: mastraBrand.green,\n },\n },\n {\n ...planMode,\n metadata: {\n ...planMode.metadata,\n color: mastraBrand.purple,\n },\n },\n {\n ...fastMode,\n metadata: {\n ...fastMode.metadata,\n color: mastraBrand.orange,\n },\n },\n ];\n\n const defaultIntervalHandlers: IntervalHandler[] = [\n {\n id: 'gateway-sync',\n intervalMs: 5 * 60 * 1000,\n immediate: false,\n handler: () => syncGateways(),\n },\n ];\n const intervalHandlers = config?.intervalHandlers ?? defaultIntervalHandlers;\n\n // Build lightweight provider access for resolving built-in packs at startup.\n // Anthropic/OpenAI use AuthStorage; other providers use env API keys.\n // Also scan the full provider registry so configured API keys satisfy access checks.\n const anthropicCred = authStorage.get('anthropic');\n const openaiCred = authStorage.get('openai-codex');\n const githubCopilotCred = authStorage.get('github-copilot');\n const kimiCodingCred = authStorage.get('kimi-for-coding');\n const startupAccess: ProviderAccess = {\n anthropic:\n anthropicCred?.type === 'oauth'\n ? 'oauth'\n : anthropicCred?.type === 'api_key' && anthropicCred.key.trim().length > 0\n ? 'apikey'\n : false,\n openai:\n openaiCred?.type === 'oauth'\n ? 'oauth'\n : openaiCred?.type === 'api_key' && openaiCred.key.trim().length > 0\n ? 'apikey'\n : false,\n cerebras: process.env.CEREBRAS_API_KEY ? 'apikey' : false,\n google: process.env.GOOGLE_GENERATIVE_AI_API_KEY ? 'apikey' : false,\n deepseek: process.env.DEEPSEEK_API_KEY ? 'apikey' : false,\n 'github-copilot': githubCopilotCred?.type === 'oauth' ? 'oauth' : false,\n 'kimi-for-coding':\n kimiCodingCred?.type === 'oauth' && isKimiCodingDeviceId(kimiCodingCred.deviceId)\n ? 'oauth'\n : (kimiCodingCred?.type === 'api_key' && kimiCodingCred.key.trim().length > 0) ||\n Boolean(process.env.KIMI_API_KEY?.trim())\n ? 'apikey'\n : false,\n };\n // Gateway covers all providers — ensure Anthropic/OpenAI packs are visible\n if (mgApiKey) {\n if (!startupAccess.anthropic) startupAccess.anthropic = 'apikey';\n if (!startupAccess.openai) startupAccess.openai = 'apikey';\n }\n // Check all providers in the registry for API keys\n try {\n const registry = PROVIDER_REGISTRY as Record<string, ProviderConfig>;\n for (const [provider, config] of Object.entries(registry)) {\n if (startupAccess[provider] === 'oauth' || startupAccess[provider] === 'apikey') continue; // Already enabled above\n if (provider === 'anthropic' || provider === 'openai') continue;\n const envVars = config?.apiKeyEnvVar;\n const envVarList = Array.isArray(envVars) ? envVars : envVars ? [envVars] : [];\n if (envVarList.some(envVar => process.env[envVar])) {\n startupAccess[provider] = 'apikey';\n }\n }\n } catch {\n // Registry may not be loaded yet; the 5 hardcoded providers are sufficient fallback\n }\n const builtinPacks = getAvailableModePacks(startupAccess);\n const builtinOmPacks = getAvailableOmPacks(startupAccess);\n const effectiveDefaults = resolveModelDefaults(globalSettings, builtinPacks);\n const activeProviderId = effectiveDefaults.build?.split('/')[0];\n const preferredOmModel = hasExplicitOMConfiguration(globalSettings)\n ? undefined\n : selectPreferredOMPack(startupAccess, activeProviderId)?.modelId;\n const effectiveObserverModel = resolveOmRoleModel(globalSettings, 'observer', builtinOmPacks) || preferredOmModel;\n const effectiveReflectorModel = resolveOmRoleModel(globalSettings, 'reflector', builtinOmPacks) || preferredOmModel;\n const effectiveObservationThreshold = globalSettings.models.omObservationThreshold ?? undefined;\n const effectiveReflectionThreshold = globalSettings.models.omReflectionThreshold ?? undefined;\n const effectiveCavemanObservations = globalSettings.models.omCavemanObservations ?? undefined;\n const effectiveObserveAttachments = globalSettings.models.omObserveAttachments ?? 'auto';\n\n const modes = addPluginToolsToModeAllowlists(\n applyEffectiveDefaultsToModes(config?.modes ? config.modes : defaultModes, effectiveDefaults),\n Object.keys(pluginTools),\n );\n const defaultModeId =\n modes.find(mode => mode.metadata?.default === true)?.id ??\n modes.find(mode => mode.id === 'build')?.id ??\n modes[0]?.id;\n if (!defaultModeId) {\n throw new Error('MastraCode requires at least one mode');\n }\n\n // Map subagent types to mode models: explore→fast, plan→plan, execute→build\n // const subagentModeMap: Record<string, string> = { explore: 'fast', plan: 'plan', execute: 'build' };\n // Subagents inherit workspace tools from the parent agent's workspace automatically.\n // Apply disabledTools filter to both default and custom subagents.\n // const subagents = [];\n\n // Build initial state with global preferences. OM knobs are skipped when the\n // host persists memory settings elsewhere (`disableSettingsOmSeed`) so the\n // machine-local settings.json never leaks into server sessions.\n const globalInitialState: Partial<MastraCodeState> = {};\n if (!config?.disableSettingsOmSeed) {\n if (effectiveObserverModel) {\n globalInitialState.observerModelId = effectiveObserverModel;\n }\n if (effectiveReflectorModel) {\n globalInitialState.reflectorModelId = effectiveReflectorModel;\n }\n if (effectiveObservationThreshold !== undefined) {\n globalInitialState.observationThreshold = effectiveObservationThreshold;\n }\n if (effectiveReflectionThreshold !== undefined) {\n globalInitialState.reflectionThreshold = effectiveReflectionThreshold;\n }\n if (effectiveCavemanObservations !== undefined) {\n globalInitialState.cavemanObservations = effectiveCavemanObservations;\n }\n if (effectiveObserveAttachments !== undefined) {\n globalInitialState.observeAttachments = effectiveObserveAttachments;\n }\n }\n if (globalSettings.preferences.yolo !== null) {\n globalInitialState.yolo = globalSettings.preferences.yolo;\n }\n // Note: `thinkingLevel` is intentionally NOT seeded into session state. The\n // state slot is a session-level override; the effective level is resolved at\n // request time (per-mode defaults → global preference) in getDynamicModel so\n // settings changes apply to the next request of every session.\n if (config?.omScope) {\n globalInitialState.omScope = config.omScope;\n }\n // Seed subagent models from global settings\n for (const [key, modelId] of Object.entries(globalSettings.models.subagentModels)) {\n if (key === 'default' || key === '_default') {\n globalInitialState.subagentModelId = modelId;\n } else {\n globalInitialState[`subagentModelId_${key}`] = modelId;\n }\n }\n\n const typedStateSchema = stateSchema as PublicSchema<MastraCodeState>;\n const controller: AgentController<MastraCodeState> = new AgentController<MastraCodeState>({\n id: 'mastra-code',\n resourceId: project.resourceId,\n storage,\n observability,\n memory,\n pubsub: signalsPubSub,\n stateSchema: typedStateSchema,\n agent: codeAgent,\n subagents: config?.subagents ?? [],\n gateways: [amazonBedrockGateway, mastraCodeGateway],\n workspace: config?.workspace ?? (args => getDynamicWorkspace(args)),\n browser: config?.browser,\n idGenerator: config?.idGenerator,\n toolCategoryResolver: getToolCategory,\n initialState: {\n projectPath: project.rootPath,\n projectName: project.name,\n gitBranch: project.gitBranch,\n pluginSkillPaths: loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : [])),\n pluginCommandPaths: loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' ? (plugin.commandPaths ?? []) : [],\n ),\n pluginInstructions: loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n ),\n yolo: true,\n ...globalInitialState,\n ...config?.initialState,\n // configDir must always win over initialState spreads to stay in sync\n // with MCP/hooks/storage which were already initialized with this value.\n configDir,\n },\n modes,\n intervalHandlers,\n modelUseCountProvider: () => loadSettings().modelUseCounts,\n modelUseCountTracker: modelId => {\n try {\n const settings = loadSettings();\n settings.modelUseCounts[modelId] = (settings.modelUseCounts[modelId] ?? 0) + 1;\n saveSettings(settings);\n } catch (error) {\n console.error('Failed to persist model usage count', error);\n }\n },\n threadLock: crossProcessPubSub\n ? undefined\n : {\n acquire: acquireThreadLock,\n release: releaseThreadLock,\n },\n });\n\n // Publish the controller to the plugin runtime accessors now that it exists.\n pluginRuntimeController = controller;\n\n if (pluginSignalLane && pluginManager) {\n // Register the plugins loaded at startup, and re-reconcile on every reload.\n // Providers are not started here: they need a Mastra instance for storage,\n // and Mastra does not exist until the composition layer boots the controller\n // (see `startPluginSignalProviders` on the returned object).\n pluginSignalLane.sync(pluginManager.getPluginSignalProviders());\n unsubscribePluginReload = pluginManager.onReload(() =>\n pluginSignalLane.sync(pluginManager.getPluginSignalProviders()),\n );\n }\n\n // The AgentController is fully constructed but intentionally NOT inited here. Init and\n // session creation are deferred to the composition layer (see below) so the\n // controller can be wired in three ways:\n //\n // 1. Server + Web — registered on a server Mastra, then inited; sessions\n // minted per browser client over HTTP.\n // 2. Server + TUI — same server composition; the TUI drives a session\n // (in-process today; remote transport is future work).\n // 3. Local + TUI — controller builds its own internal Mastra on init() and\n // mints one eager session for the whole process.\n //\n // Cases 1 & 2 use `mountAgentControllerOnMastra` (register-before-init, no eager\n // session). Case 3 uses `bootLocalAgentController` (init + one wired session).\n return {\n controller: controller,\n storage,\n storageMaintenance,\n createKnowledgeInspector: (session: Session<MastraCodeState>) =>\n createScopedKnowledgeInspector({ storage, session }),\n observability,\n memory,\n mcpManager,\n hookManager,\n pluginManager,\n loadedPlugins,\n pluginTools,\n signalsPubSub,\n authStorage,\n resolveModel,\n storageWarning,\n observabilityWarning,\n builtinPacks,\n builtinOmPacks,\n effectiveDefaults,\n githubSignals,\n // Identity for the single local session (Case 3). Servers ignore these and\n // mint per-request sessions with client-supplied resourceIds instead.\n sessionId,\n ownerId,\n // Surface the project root so boot/mount paths can wire workflow tools\n // against a workspace anchored at it without re-running detectProject().\n projectPath: project.rootPath,\n // Surface the Agent instance so registerWorkflowBuilderPrimitives can add\n // it as a plain agent on the Mastra registry. Workflows then compose it\n // as an agent step (agentId: 'code-agent') and delegate open-ended tool\n // orchestration to it — code-agent already has full workspace / MCP / web\n // access via its dynamic tool factory.\n codeAgent,\n // Lets the composition layer publish the created session back into the\n // config closures (e.g. notification stream options read it lazily).\n setActiveSession: (session: Session<MastraCodeState>) => {\n activeSession = session;\n },\n /**\n * Starts the signal providers contributed by plugins. Called by the\n * composition layer once the controller is inited, because that is when a\n * Mastra instance exists — a provider without one has no storage, and\n * nothing else will hand it one: the Agent propagates Mastra only to the\n * providers in its own `signals` array, which these deliberately are not in.\n */\n startPluginSignalProviders: () => {\n const mastra = controller.getMastra();\n if (!pluginSignalLane || !mastra) return;\n pluginSignalLane.setMastra(mastra, codeAgent);\n },\n /**\n * Stops every plugin-contributed signal provider and stops listening for\n * plugin reloads. The inverse of `startPluginSignalProviders`, for an\n * embedder that is done with this controller: a `pluginManager` shared\n * across controllers (`MastraCodeConfig.pluginManager`) outlives any one of\n * them, so without this its providers keep polling and its reload listener\n * keeps firing for a controller that is gone.\n */\n stopPluginSignalProviders: () => {\n unsubscribePluginReload?.();\n unsubscribePluginReload = undefined;\n pluginSignalLane?.stopAll();\n },\n /**\n * Hands Mastra to the statically configured input processors.\n *\n * The Agent does this itself, but only for processors configured as a\n * plain array (`Array.isArray` in `__registerMastra`). This lane is a\n * function so plugins can contribute to it, which takes those processors\n * out of that branch — including any an embedder passed as\n * `config.inputProcessors`, some of which need Mastra to work at all\n * (`CostGuardProcessor` reads observability storage there). Doing it here\n * keeps that unchanged.\n *\n * Plugin processors are deliberately not included: they come and go with\n * their plugin, and the registry keeps the first instance registered under\n * an id forever, which would leave a retired instance behind. Plugins\n * reach Mastra through `getController()` on the plugin context instead.\n */\n registerConfiguredProcessorsWithMastra: () => {\n const mastra = controller.getMastra();\n if (!mastra) return;\n for (const processor of mastraCodeInputProcessors) {\n mastra.addProcessor(processor as Processor);\n mastra.addProcessorConfiguration(processor as Processor, CODE_AGENT_ID, 'input');\n }\n },\n };\n}\n\n/**\n * Result of {@link createMastraCodeAgentController}: every shared resource plus the\n * inert AgentController, ready to be either booted locally or mounted on a server\n * Mastra.\n */\nexport type MastraCodeAgentController = Awaited<ReturnType<typeof createMastraCodeAgentController>>;\n\n/**\n * Wires the session-scoped concerns MastraCode layers on top of a Session:\n * hookManager thread-id sync, GitHub PR polling for the current thread, and\n * per-thread persistence of the mastracode-only `/om` settings.\n *\n * Used by {@link bootLocalAgentController} for the single local session. A server can\n * call this for any session it mints if it wants the same background wiring.\n */\nexport async function wireSessionConcerns(\n base: Pick<MastraCodeAgentController, 'hookManager' | 'githubSignals' | 'setActiveSession'>,\n session: Session<MastraCodeState>,\n): Promise<void> {\n const { hookManager, githubSignals } = base;\n base.setActiveSession(session);\n\n // Sync hookManager session ID on thread changes\n if (hookManager) {\n session.subscribe((event: AgentControllerEvent) => {\n if (event.type === 'thread_changed') {\n hookManager.setSessionId(event.threadId);\n } else if (event.type === 'thread_created') {\n hookManager.setSessionId(event.thread.id);\n }\n });\n }\n\n if (githubSignals) {\n const startGithubPollingForCurrentThread = async (threadId?: string | null) => {\n if (!threadId) return;\n githubSignals.stopAllPolling();\n try {\n const threads = await session.thread.list({ allResources: true });\n const thread = threads.find((item: { id: string }) => item.id === threadId);\n await githubSignals.startPollingForThread(\n {\n threadId,\n resourceId: thread?.resourceId ?? session.identity.getResourceId(),\n },\n { pollImmediately: true },\n );\n } catch (error) {\n console.warn('Failed to start GitHub PR polling:', error);\n }\n };\n\n session.subscribe((event: AgentControllerEvent) => {\n if (event.type === 'thread_changed') void startGithubPollingForCurrentThread(event.threadId);\n else if (event.type === 'thread_created') void startGithubPollingForCurrentThread(event.thread.id);\n });\n void startGithubPollingForCurrentThread(session.thread.getId());\n }\n\n // Persist MastraCode-owned /om settings per-thread (mastracode-only concern;\n // intentionally not in core's controller loadThreadMetadata).\n const omThreadStateSession = session as unknown as Session<Record<string, unknown>>;\n attachOMThreadStatePersistence(omThreadStateSession);\n await restoreOMThreadStateForCurrentThread(omThreadStateSession).catch(() => {\n // Persistence is best-effort; don't crash startup if storage hiccups.\n });\n}\n\n/**\n * Case 3 (AgentController local + TUI/headless): build the controller, let it stand up its\n * own internal Mastra via `init()`, and mint the single eager session that all\n * work in this process runs through. The AgentController owns no session of its own.\n */\nexport async function bootLocalAgentController(config?: MastraCodeConfig) {\n const base = await createMastraCodeAgentController(config);\n const { controller, sessionId, ownerId, projectPath, codeAgent, mcpManager } = base;\n\n await controller.init();\n // Register workflow primitives (sub-agent + workspace tools + code-agent\n // + web + notification_inbox + snapshot of MCP tools) on the controller's\n // Mastra so the dynamic-workflow loading in startWorkers() can rehydrate\n // saved workflows against the right tool/agent registry.\n const mastra = controller.getMastra();\n if (mastra) await registerWorkflowBuilderPrimitives(mastra, { projectPath, codeAgent, mcpManager });\n await mastra?.startWorkers();\n base.registerConfiguredProcessorsWithMastra();\n base.startPluginSignalProviders();\n const session = await controller.createSession({ id: sessionId, ownerId });\n await wireSessionConcerns(base, session);\n const knowledgeInspector = await base.createKnowledgeInspector(session);\n\n return {\n ...base,\n session,\n knowledgeInspector,\n knowledgeInspectorUnavailableReason: knowledgeInspector\n ? undefined\n : 'Knowledge inspection requires a configured knowledge storage domain.',\n };\n}\n\n/** Result of {@link mountAgentControllerOnMastra}: shared handles plus the owning Mastra. */\nexport type MountedMastraCode = MastraCodeAgentController & { mastra: Mastra };\n\n/**\n * Cases 1 & 2 (AgentController in Server + Web/TUI): build the controller, register it on a\n * server-owned Mastra, THEN init it. Registering before `init()` is what makes\n * the controller inherit the server's Mastra (storage, agents, gateways) instead of\n * spinning up its own internal one — there is a single shared Mastra.\n *\n * No eager session is minted: each client (browser or terminal) creates/resumes\n * its own isolated session via `controller.createSession({ resourceId })`, so one\n * server can drive many concurrent users.\n *\n * Pass an existing `mastra` to mount onto a Mastra that already hosts other\n * primitives; otherwise a Mastra is created that owns the controller's storage so\n * durability is configured in one place.\n */\nexport async function mountAgentControllerOnMastra(\n config?: MastraCodeConfig & {\n mastra?: Mastra;\n controllerId?: string;\n buildApiRoutes?: (deps: { controller: MountedMastraCode['controller']; authStorage: AuthStorage }) => ApiRoute[];\n /**\n * Additional `server` config to fold onto the constructed Mastra alongside\n * the assembled `apiRoutes` (e.g. `middleware`, `cors`). Used by the\n * platform entry (`src/mastra/index.ts`) to own the WorkOS gate + tenant\n * dispatcher + CORS on the instance the deployer generates its server from.\n * Ignored when `mastra` is provided (mounting onto a caller-owned instance).\n */\n buildServerConfig?: (deps: {\n controller: MountedMastraCode['controller'];\n authStorage: AuthStorage;\n }) => Omit<NonNullable<ConstructorParameters<typeof Mastra>[0]>['server'], 'apiRoutes'>;\n },\n): Promise<MountedMastraCode> {\n const prepared = await prepareAgentControllerMount(config);\n if (config?.mastra) {\n // Mounting onto a Mastra the caller already built. Ensure the controller's\n // back-reference points at it (idempotent — only sets #externalMastra).\n prepared.base.controller.__registerMastra(config.mastra);\n await prepared.finalize();\n return { ...prepared.base, mastra: config.mastra };\n }\n const mastra = new Mastra(prepared.mastraArgs);\n await prepared.finalize();\n return { ...prepared.base, mastra };\n}\n\n/**\n * Assemble everything needed to construct the server-owned Mastra WITHOUT\n * constructing it, so a caller (the platform entry `src/mastra/index.ts`) can\n * run the `new Mastra(...)` literal in its own module. The deployer's\n * `checkConfigExport` Babel plugin only marks the config valid when it finds a\n * top-level `new Mastra(...)` exported as `mastra` in the ENTRY file; hiding the\n * construction inside this helper would trip the \"Invalid Mastra config\" warning.\n *\n * Returns the constructor args plus a `finalize()` that runs the post-construct\n * boot (`controller.init()` + `startWorkers()`). The controller is registered on\n * the Mastra via the `agentControllers` arg at construction time.\n */\nexport async function prepareAgentControllerMount(\n config?: MastraCodeConfig & {\n mastra?: Mastra;\n controllerId?: string;\n buildApiRoutes?: (deps: { controller: MountedMastraCode['controller']; authStorage: AuthStorage }) => ApiRoute[];\n buildServerConfig?: (deps: {\n controller: MountedMastraCode['controller'];\n authStorage: AuthStorage;\n }) => Omit<NonNullable<ConstructorParameters<typeof Mastra>[0]>['server'], 'apiRoutes'>;\n },\n): Promise<{\n base: Awaited<ReturnType<typeof createMastraCodeAgentController>>;\n mastraArgs: NonNullable<ConstructorParameters<typeof Mastra>[0]>;\n finalize: () => Promise<void>;\n}> {\n const base = await createMastraCodeAgentController(config);\n const { controller, storage, authStorage, projectPath, codeAgent, mcpManager } = base;\n const controllerId = config?.controllerId ?? controller.id;\n const apiRoutes = config?.buildApiRoutes?.({ controller, authStorage });\n const extraServerConfig = config?.buildServerConfig?.({ controller, authStorage });\n // Only register workflow primitives when we own the Mastra. If the caller\n // brought their own, they're responsible for what's registered on it.\n const weOwnTheMastra = !config?.mastra;\n\n const serverConfig = {\n ...extraServerConfig,\n ...(apiRoutes?.length ? { apiRoutes } : {}),\n };\n const mastraArgs = {\n agentControllers: { [controllerId]: controller },\n storage,\n // Mirror the controller's internal-Mastra construction (which passes\n // `config.pubsub` through): the server-owned Mastra must run its event\n // bus on the same transport so streams/workflows/signals stay\n // cross-process when a distributed PubSub (e.g. Redis Streams) is\n // configured.\n ...(base.signalsPubSub ? { pubsub: base.signalsPubSub } : {}),\n ...(Object.keys(serverConfig).length ? { server: serverConfig } : {}),\n };\n\n const finalize = async () => {\n await controller.init();\n if (weOwnTheMastra) {\n const mastra = controller.getMastra();\n if (mastra) await registerWorkflowBuilderPrimitives(mastra, { projectPath, codeAgent, mcpManager });\n }\n await controller.getMastra()?.startWorkers();\n // Anchored here rather than at a `new Mastra(...)` call site: finalize runs\n // in every mount path (caller-supplied Mastra, SDK-constructed Mastra, and\n // the platform entry that constructs its own), so plugin providers start\n // exactly once regardless of how Mastra Code was mounted.\n base.registerConfiguredProcessorsWithMastra();\n base.startPluginSignalProviders();\n };\n\n return { base, mastraArgs, finalize };\n}\n\n/**\n * Back-compat alias. Historically `createMastraCode` built and booted a local\n * controller with a single session; that behavior now lives in\n * {@link bootLocalAgentController}. New code should call the explicit factory for its\n * case: `bootLocalAgentController` (local) or {@link mountAgentControllerOnMastra} (server).\n */\nexport const createMastraCode = bootLocalAgentController;\nexport * from './knowledge-inspector.js';\n\n/**\n * Programmatic headless API. `runMC` runs an already-built controller/session\n * (from {@link createMastraCode}) as an async-iterable run that also resolves to\n * a typed result. Also available via the `mastracode/headless` subpath.\n */\nexport {\n runMC,\n runMCCli,\n hasHeadlessFlag,\n autoApprovePolicy,\n denyPolicy,\n permissionModeToPolicy,\n formatHuman,\n formatJsonl,\n renderTextResult,\n renderJsonResult,\n} from './headless/index.js';\nexport type {\n RunMCOptions,\n RunMCResult,\n RunMCStatus,\n RunMCUsage,\n RunMCToolCall,\n RunMCToolResult,\n RunMCError,\n RunMCThreadOptions,\n MCRun,\n ResolutionPolicy,\n PermissionMode,\n} from './headless/index.js';\n"],"mappings":"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"}
@@ -288,6 +288,8 @@ export interface SignalSettings {
288
288
  unixSocketPubSub: boolean;
289
289
  /** Experimental: enable GitHub PR subscription signals backed by gitcrawl. */
290
290
  experimentalGithubSignals: boolean;
291
+ /** Poll interval for GitHub PR subscriptions. */
292
+ githubPollIntervalMs: number;
291
293
  }
292
294
  export interface ObservabilityResourceConfig {
293
295
  /** Cloud project ID for this resource */
@@ -303,6 +305,9 @@ export interface ObservabilitySettings {
303
305
  }
304
306
  /** Auth key prefix for observability tokens stored per-resource in auth.json */
305
307
  export declare const OBSERVABILITY_AUTH_PREFIX = "observability:";
308
+ export declare const GITHUB_POLL_INTERVAL_DEFAULT_MS = 300000;
309
+ export declare const GITHUB_POLL_INTERVAL_MIN_MS = 10000;
310
+ export declare const GITHUB_POLL_INTERVAL_MAX_MS = 2147483647;
306
311
  export declare const STORAGE_DEFAULTS: StorageSettings;
307
312
  /** Default STT engine: on-device macOS recognizer where available, else cloud. */
308
313
  export declare function defaultVoiceEngine(): VoiceEngine;
@@ -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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"}
@@ -71,6 +71,9 @@ function parseViewportInput(input) {
71
71
  }
72
72
  /** Auth key prefix for observability tokens stored per-resource in auth.json */
73
73
  const OBSERVABILITY_AUTH_PREFIX = "observability:";
74
+ const GITHUB_POLL_INTERVAL_DEFAULT_MS = 3e5;
75
+ const GITHUB_POLL_INTERVAL_MIN_MS = 1e4;
76
+ const GITHUB_POLL_INTERVAL_MAX_MS = 2147483647;
74
77
  const STORAGE_DEFAULTS = {
75
78
  backend: "libsql",
76
79
  libsql: {},
@@ -136,7 +139,8 @@ const DEFAULTS = {
136
139
  },
137
140
  signals: {
138
141
  unixSocketPubSub: false,
139
- experimentalGithubSignals: false
142
+ experimentalGithubSignals: false,
143
+ githubPollIntervalMs: GITHUB_POLL_INTERVAL_DEFAULT_MS
140
144
  },
141
145
  mcp: {
142
146
  claudeCodeGlobal: false,
@@ -162,7 +166,7 @@ function rememberLoadedSettings(settings) {
162
166
  return settings;
163
167
  }
164
168
  function signalSettingsEqual(left, right) {
165
- return left.unixSocketPubSub === right.unixSocketPubSub && left.experimentalGithubSignals === right.experimentalGithubSignals;
169
+ return left.unixSocketPubSub === right.unixSocketPubSub && left.experimentalGithubSignals === right.experimentalGithubSignals && left.githubPollIntervalMs === right.githubPollIntervalMs;
166
170
  }
167
171
  function parseWebSearchProvider(value) {
168
172
  return typeof value === "string" && WEB_SEARCH_PROVIDER_VALUES.includes(value) ? value : DEFAULTS.preferences.webSearchProvider;
@@ -200,11 +204,18 @@ function parsePreferences(rawPreferences) {
200
204
  webSearchProvider: parseWebSearchProvider(raw.webSearchProvider)
201
205
  };
202
206
  }
207
+ function parseGithubPollIntervalMs(value) {
208
+ if (typeof value !== "number" || !Number.isFinite(value)) return DEFAULTS.signals.githubPollIntervalMs;
209
+ const intervalMs = Math.floor(value);
210
+ if (intervalMs < 1e4) return DEFAULTS.signals.githubPollIntervalMs;
211
+ return Math.min(intervalMs, GITHUB_POLL_INTERVAL_MAX_MS);
212
+ }
203
213
  function parseSignalSettings(rawSignals) {
204
214
  const raw = rawSignals && typeof rawSignals === "object" ? rawSignals : {};
205
215
  return {
206
216
  unixSocketPubSub: typeof raw.unixSocketPubSub === "boolean" ? raw.unixSocketPubSub : DEFAULTS.signals.unixSocketPubSub,
207
- experimentalGithubSignals: typeof raw.experimentalGithubSignals === "boolean" ? raw.experimentalGithubSignals : DEFAULTS.signals.experimentalGithubSignals
217
+ experimentalGithubSignals: typeof raw.experimentalGithubSignals === "boolean" ? raw.experimentalGithubSignals : DEFAULTS.signals.experimentalGithubSignals,
218
+ githubPollIntervalMs: parseGithubPollIntervalMs(raw.githubPollIntervalMs)
208
219
  };
209
220
  }
210
221
  function parseMcpDiscoverySettings(rawMcp) {
@@ -829,6 +840,6 @@ async function createBrowserFromSettings(settings) {
829
840
  throw new Error(`Unsupported browser provider: ${provider}`);
830
841
  }
831
842
  //#endregion
832
- export { MASTRA_GATEWAY_DEFAULT_URL, MASTRA_GATEWAY_PROVIDER, MEMORY_GATEWAY_DEFAULT_URL, MEMORY_GATEWAY_PROVIDER, OBSERVABILITY_AUTH_PREFIX, STORAGE_DEFAULTS, THINKING_LEVEL_VALUES, THREAD_ACTIVE_MODEL_PACK_ID_KEY, VIEWPORT_PRESETS, WEB_SEARCH_PROVIDER_VALUES, checkProfileProviderMismatch, createBrowserFromSettings, defaultVoiceEngine, getCustomProviderId, getProfileProvider, getSettingsPath, isThinkingLevelSetting, loadSettings, migrateLegacyVariedPack, parseCustomProviders, parseThreadSettings, parseViewportInput, resolveDefaultThinkingLevel, resolveLspSetting, resolveModePackModels, resolveModelDefaults, resolveOmModel, resolveOmRoleModel, resolveThreadActiveModelPackId, saveSettings, setProfileProvider, stripMastraCodeCustomProviderPrefix, toCustomProviderModelId };
843
+ export { GITHUB_POLL_INTERVAL_DEFAULT_MS, GITHUB_POLL_INTERVAL_MAX_MS, GITHUB_POLL_INTERVAL_MIN_MS, MASTRA_GATEWAY_DEFAULT_URL, MASTRA_GATEWAY_PROVIDER, MEMORY_GATEWAY_DEFAULT_URL, MEMORY_GATEWAY_PROVIDER, OBSERVABILITY_AUTH_PREFIX, STORAGE_DEFAULTS, THINKING_LEVEL_VALUES, THREAD_ACTIVE_MODEL_PACK_ID_KEY, VIEWPORT_PRESETS, WEB_SEARCH_PROVIDER_VALUES, checkProfileProviderMismatch, createBrowserFromSettings, defaultVoiceEngine, getCustomProviderId, getProfileProvider, getSettingsPath, isThinkingLevelSetting, loadSettings, migrateLegacyVariedPack, parseCustomProviders, parseThreadSettings, parseViewportInput, resolveDefaultThinkingLevel, resolveLspSetting, resolveModePackModels, resolveModelDefaults, resolveOmModel, resolveOmRoleModel, resolveThreadActiveModelPackId, saveSettings, setProfileProvider, stripMastraCodeCustomProviderPrefix, toCustomProviderModelId };
833
844
 
834
845
  //# sourceMappingURL=settings.js.map
@@ -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, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { AuthStorage } from '../auth/storage.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';\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/** 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 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 /** 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 /**\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 /** 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 /** 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 // 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 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}\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 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 modeDefaults: {},\n modeThinkingDefaults: {},\n activeOmPackId: null,\n omModelOverride: null,\n observerModelOverride: null,\n reflectorModelOverride: 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 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 signals: { unixSocketPubSub: false, experimentalGithubSignals: false },\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 );\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 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 quietModeMaxToolPreviewLines: parseQuietModeMaxToolPreviewLines(raw.quietModeMaxToolPreviewLines),\n webSearchProvider: parseWebSearchProvider(raw.webSearchProvider),\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 };\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 settings = {\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides: parseModePackOverrides(raw.models?.modePackOverrides),\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\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 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 writeFileSync(authPath, JSON.stringify(authData, null, 2), 'utf-8');\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 // 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: parseModePackOverrides(raw.models?.modePackOverrides),\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\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 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';\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\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 { activeOmPackId, omModelOverride, observerModelOverride, reflectorModelOverride } = settings.models;\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\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 writeFileSync(filePath, JSON.stringify(settings, null, 2), 'utf-8');\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 * 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(settings: BrowserSettings): 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 // When the user has an active OpenAI Codex (ChatGPT) subscription, route\n // Stagehand through the Codex endpoint. We use the AI SDK provider's\n // standard hooks (baseURL, headers, fetch, and middleware) instead of a\n // URL-rewriting fetch:\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 // Model is `gpt-5.4-mini`, the current ChatGPT-sign-in Codex whitelist\n // pick suited to Stagehand's vision + structured-output workload.\n //\n // An explicitly configured model wins: Codex is a fallback for users who\n // have no model of their own, not an override of one they chose. Stagehand\n // resolves the provider's API key from the environment for plain\n // `provider/model` strings, so no key plumbing is needed here.\n const authStorage = new AuthStorage();\n const cred = authStorage.get('openai-codex');\n if (stagehand?.model) {\n stagehandOpts.model = stagehand.model;\n } else if (cred?.type === 'oauth') {\n const accountId = (cred as any).accountId as string | undefined;\n stagehandOpts.model = {\n modelName: 'openai/gpt-5.4-mini',\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 }\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, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { MastraBrowser } from '@mastra/core/browser';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { AuthStorage } from '../auth/storage.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';\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/** 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 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 /** 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 /**\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 /** 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 /** 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 // 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 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 /** 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 modeDefaults: {},\n modeThinkingDefaults: {},\n activeOmPackId: null,\n omModelOverride: null,\n observerModelOverride: null,\n reflectorModelOverride: 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 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 signals: {\n unixSocketPubSub: false,\n experimentalGithubSignals: 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.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 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 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\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 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 settings = {\n onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },\n models: {\n ...DEFAULTS.models,\n ...raw.models,\n modePackOverrides: parseModePackOverrides(raw.models?.modePackOverrides),\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\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 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 writeFileSync(authPath, JSON.stringify(authData, null, 2), 'utf-8');\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 // 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: parseModePackOverrides(raw.models?.modePackOverrides),\n modeThinkingDefaults: parseModeThinkingDefaults(raw.models?.modeThinkingDefaults),\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 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';\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\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 { activeOmPackId, omModelOverride, observerModelOverride, reflectorModelOverride } = settings.models;\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\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 writeFileSync(filePath, JSON.stringify(settings, null, 2), 'utf-8');\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 * 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(settings: BrowserSettings): 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 // When the user has an active OpenAI Codex (ChatGPT) subscription, route\n // Stagehand through the Codex endpoint. We use the AI SDK provider's\n // standard hooks (baseURL, headers, fetch, and middleware) instead of a\n // URL-rewriting fetch:\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 // Model is `gpt-5.4-mini`, the current ChatGPT-sign-in Codex whitelist\n // pick suited to Stagehand's vision + structured-output workload.\n //\n // An explicitly configured model wins: Codex is a fallback for users who\n // have no model of their own, not an override of one they chose. Stagehand\n // resolves the provider's API key from the environment for plain\n // `provider/model` strings, so no key plumbing is needed here.\n const authStorage = new AuthStorage();\n const cred = authStorage.get('openai-codex');\n if (stagehand?.model) {\n stagehandOpts.model = stagehand.model;\n } else if (cred?.type === 'oauth') {\n const accountId = (cred as any).accountId as string | undefined;\n stagehandOpts.model = {\n modelName: 'openai/gpt-5.4-mini',\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 }\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "1.6.0-alpha.0",
3
+ "version": "1.6.0-alpha.2",
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": {
@@ -58,19 +58,19 @@
58
58
  "yaml": "^2.7.1",
59
59
  "zod": "^4.3.6",
60
60
  "@mastra/agent-browser": "0.5.1",
61
- "@mastra/fastembed": "1.3.0",
62
61
  "@mastra/duckdb": "1.6.3",
63
- "@mastra/core": "1.63.3-alpha.0",
62
+ "@mastra/core": "1.63.3-alpha.1",
64
63
  "@mastra/libsql": "1.22.2",
65
- "@mastra/github-signals": "0.3.0",
64
+ "@mastra/github-signals": "0.4.0-alpha.0",
66
65
  "@mastra/mcp": "1.17.2",
67
66
  "@mastra/observability": "1.17.4",
68
- "@mastra/memory": "1.28.1",
67
+ "@mastra/memory": "1.28.2-alpha.0",
69
68
  "@mastra/parallel": "0.1.0",
69
+ "@mastra/schema-compat": "1.3.7",
70
70
  "@mastra/pg": "1.22.2",
71
71
  "@mastra/stagehand": "0.3.3",
72
72
  "@mastra/tavily": "1.1.1",
73
- "@mastra/schema-compat": "1.3.7"
73
+ "@mastra/fastembed": "1.3.0"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@libsql/client": "^0.17.4",