@mastra/code-sdk 1.0.3-alpha.0 → 1.1.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 +49 -0
- package/dist/acp/agent.js +155 -167
- package/dist/acp/agent.js.map +1 -1
- package/dist/acp/event-mapper.js +193 -168
- package/dist/acp/event-mapper.js.map +1 -1
- package/dist/acp/index.js +60 -49
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/server.js +31 -30
- package/dist/acp/server.js.map +1 -1
- package/dist/acp.js +1 -4
- package/dist/agents/credential-resolver.js +40 -29
- package/dist/agents/credential-resolver.js.map +1 -1
- package/dist/agents/custom-provider-source.js +16 -9
- package/dist/agents/custom-provider-source.js.map +1 -1
- package/dist/agents/instructions.js +27 -36
- package/dist/agents/instructions.js.map +1 -1
- package/dist/agents/mastracode-gateway.js +355 -428
- package/dist/agents/mastracode-gateway.js.map +1 -1
- package/dist/agents/memory.js +87 -78
- package/dist/agents/memory.js.map +1 -1
- package/dist/agents/model.js +114 -119
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/modes/build.js +12 -13
- package/dist/agents/modes/build.js.map +1 -1
- package/dist/agents/modes/explore.js +14 -13
- package/dist/agents/modes/explore.js.map +1 -1
- package/dist/agents/modes/plan.js +14 -15
- package/dist/agents/modes/plan.js.map +1 -1
- package/dist/agents/prompts/agent-instructions.js +78 -69
- package/dist/agents/prompts/agent-instructions.js.map +1 -1
- package/dist/agents/prompts/build.js +19 -16
- package/dist/agents/prompts/build.js.map +1 -1
- package/dist/agents/prompts/fast.js +8 -4
- package/dist/agents/prompts/fast.js.map +1 -1
- package/dist/agents/prompts/index.js +48 -47
- package/dist/agents/prompts/index.js.map +1 -1
- package/dist/agents/prompts/model.js +6 -5
- package/dist/agents/prompts/model.js.map +1 -1
- package/dist/agents/prompts/plan.js +20 -16
- package/dist/agents/prompts/plan.js.map +1 -1
- package/dist/agents/prompts/tool-guidance.js +77 -109
- package/dist/agents/prompts/tool-guidance.js.map +1 -1
- package/dist/agents/sandbox-filesystem.js +245 -259
- package/dist/agents/sandbox-filesystem.js.map +1 -1
- package/dist/agents/sandbox-reattach.js +9 -11
- package/dist/agents/sandbox-reattach.js.map +1 -1
- package/dist/agents/thread-caveman-state.js +92 -81
- package/dist/agents/thread-caveman-state.js.map +1 -1
- package/dist/agents/tool-availability.js +62 -80
- package/dist/agents/tool-availability.js.map +1 -1
- package/dist/agents/tools.js +99 -139
- package/dist/agents/tools.js.map +1 -1
- package/dist/agents/workspace.js +232 -225
- package/dist/agents/workspace.js.map +1 -1
- package/dist/analytics.js +139 -128
- package/dist/analytics.js.map +1 -1
- package/dist/auth/authorization-input.js +39 -25
- package/dist/auth/authorization-input.js.map +1 -1
- package/dist/auth/device-code.js +112 -80
- package/dist/auth/device-code.js.map +1 -1
- package/dist/auth/index.js +2 -9
- package/dist/auth/pkce.js +27 -16
- package/dist/auth/pkce.js.map +1 -1
- package/dist/auth/providers/anthropic.js +107 -93
- package/dist/auth/providers/anthropic.js.map +1 -1
- package/dist/auth/providers/github-copilot.js +304 -293
- package/dist/auth/providers/github-copilot.js.map +1 -1
- package/dist/auth/providers/openai-codex.js +442 -460
- package/dist/auth/providers/openai-codex.js.map +1 -1
- package/dist/auth/providers/xai.js +179 -145
- package/dist/auth/providers/xai.js.map +1 -1
- package/dist/auth/storage.js +182 -175
- package/dist/auth/storage.js.map +1 -1
- package/dist/auth/types.js +1 -1
- package/dist/clipboard/index.js +206 -172
- package/dist/clipboard/index.js.map +1 -1
- package/dist/constants.js +11 -16
- package/dist/constants.js.map +1 -1
- package/dist/error-classification.js +19 -11
- package/dist/error-classification.js.map +1 -1
- package/dist/evals/context-builder.js +145 -104
- package/dist/evals/context-builder.js.map +1 -1
- package/dist/evals/index.js +4 -7
- package/dist/evals/scorers/classify-command.js +62 -41
- package/dist/evals/scorers/classify-command.js.map +1 -1
- package/dist/evals/scorers/efficiency.js +239 -181
- package/dist/evals/scorers/efficiency.js.map +1 -1
- package/dist/evals/scorers/extract-tools.js +51 -47
- package/dist/evals/scorers/extract-tools.js.map +1 -1
- package/dist/evals/scorers/index.js +1 -5
- package/dist/evals/scorers/outcome.js +321 -212
- package/dist/evals/scorers/outcome.js.map +1 -1
- package/dist/goal-manager.js +266 -261
- package/dist/goal-manager.js.map +1 -1
- package/dist/goal-signal.js +14 -13
- package/dist/goal-signal.js.map +1 -1
- package/dist/headless/cli.js +153 -154
- package/dist/headless/cli.js.map +1 -1
- package/dist/headless/flags.js +180 -178
- package/dist/headless/flags.js.map +1 -1
- package/dist/headless/format.js +72 -71
- package/dist/headless/format.js.map +1 -1
- package/dist/headless/index.js +5 -31
- package/dist/headless/policy.js +35 -31
- package/dist/headless/policy.js.map +1 -1
- package/dist/headless/run-mc.js +332 -334
- package/dist/headless/run-mc.js.map +1 -1
- package/dist/headless/types.js +16 -7
- package/dist/headless/types.js.map +1 -1
- package/dist/hooks/config.js +56 -61
- package/dist/hooks/config.js.map +1 -1
- package/dist/hooks/executor.js +118 -116
- package/dist/hooks/executor.js.map +1 -1
- package/dist/hooks/index.js +4 -15
- package/dist/hooks/manager.js +221 -280
- package/dist/hooks/manager.js.map +1 -1
- package/dist/hooks/types.js +5 -4
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -712
- package/dist/index.js.map +1 -1
- package/dist/ipc/ipc-reporter.js +19 -22
- package/dist/ipc/ipc-reporter.js.map +1 -1
- package/dist/lsp/client.js +248 -306
- package/dist/lsp/client.js.map +1 -1
- package/dist/lsp/index.js +1 -6
- package/dist/lsp/language.js +39 -43
- package/dist/lsp/language.js.map +1 -1
- package/dist/lsp/manager.js +78 -93
- package/dist/lsp/manager.js.map +1 -1
- package/dist/lsp/server.js +151 -120
- package/dist/lsp/server.js.map +1 -1
- package/dist/lsp/workspace.js +50 -47
- package/dist/lsp/workspace.js.map +1 -1
- package/dist/mcp/config.js +210 -199
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/index.js +2 -9
- package/dist/mcp/manager.js +482 -475
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/types.js +1 -1
- package/dist/onboarding/custom-packs.js +14 -17
- package/dist/onboarding/custom-packs.js.map +1 -1
- package/dist/onboarding/custom-providers.js +22 -20
- package/dist/onboarding/custom-providers.js.map +1 -1
- package/dist/onboarding/index.d.ts +1 -1
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +3 -21
- package/dist/onboarding/om-settings.d.ts +5 -0
- package/dist/onboarding/om-settings.d.ts.map +1 -1
- package/dist/onboarding/om-settings.js +41 -20
- package/dist/onboarding/om-settings.js.map +1 -1
- package/dist/onboarding/packs.d.ts +4 -6
- package/dist/onboarding/packs.d.ts.map +1 -1
- package/dist/onboarding/packs.js +154 -105
- package/dist/onboarding/packs.js.map +1 -1
- package/dist/onboarding/settings.js +575 -517
- package/dist/onboarding/settings.js.map +1 -1
- package/dist/permissions.js +112 -99
- package/dist/permissions.js.map +1 -1
- package/dist/plugin.js +21 -23
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/dependencies.js +64 -87
- package/dist/plugins/dependencies.js.map +1 -1
- package/dist/plugins/install.js +159 -169
- package/dist/plugins/install.js.map +1 -1
- package/dist/plugins/loader.js +170 -185
- package/dist/plugins/loader.js.map +1 -1
- package/dist/plugins/manager.js +374 -380
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/manifest.js +38 -63
- package/dist/plugins/manifest.js.map +1 -1
- package/dist/plugins/package-link.js +48 -64
- package/dist/plugins/package-link.js.map +1 -1
- package/dist/plugins/paths.js +18 -19
- package/dist/plugins/paths.js.map +1 -1
- package/dist/plugins/registry.js +97 -81
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/scaffold.js +62 -98
- package/dist/plugins/scaffold.js.map +1 -1
- package/dist/plugins/types.js +1 -1
- package/dist/processors/plan-rejection-abort.js +45 -44
- package/dist/processors/plan-rejection-abort.js.map +1 -1
- package/dist/providers/amazon-bedrock-gateway.js +134 -125
- package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
- package/dist/providers/amazon-bedrock.js +68 -47
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/claude-max.js +153 -133
- package/dist/providers/claude-max.js.map +1 -1
- package/dist/providers/github-copilot.js +232 -230
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/openai-codex.js +271 -260
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/xai.js +57 -50
- package/dist/providers/xai.js.map +1 -1
- package/dist/schema.js +91 -89
- package/dist/schema.js.map +1 -1
- package/dist/theme-palette.js +18 -14
- package/dist/theme-palette.js.map +1 -1
- package/dist/tool-names.js +46 -37
- package/dist/tool-names.js.map +1 -1
- package/dist/tools/index.js +2 -8
- package/dist/tools/request-sandbox-access.js +71 -80
- package/dist/tools/request-sandbox-access.js.map +1 -1
- package/dist/tools/utils.js +26 -16
- package/dist/tools/utils.js.map +1 -1
- package/dist/tools/web-search.js +51 -55
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/binaries.js +65 -61
- package/dist/utils/binaries.js.map +1 -1
- package/dist/utils/debug-log.js +51 -47
- package/dist/utils/debug-log.js.map +1 -1
- package/dist/utils/errors.js +157 -192
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/gateway-sync.js +49 -37
- package/dist/utils/gateway-sync.js.map +1 -1
- package/dist/utils/path-security.js +7 -6
- package/dist/utils/path-security.js.map +1 -1
- package/dist/utils/plan-diff.js +58 -39
- package/dist/utils/plan-diff.js.map +1 -1
- package/dist/utils/plans.js +92 -74
- package/dist/utils/plans.js.map +1 -1
- package/dist/utils/project.js +318 -256
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/signals-pubsub.js +117 -99
- package/dist/utils/signals-pubsub.js.map +1 -1
- package/dist/utils/slash-command-loader.js +118 -154
- package/dist/utils/slash-command-loader.js.map +1 -1
- package/dist/utils/slash-command-processor.js +92 -83
- package/dist/utils/slash-command-processor.js.map +1 -1
- package/dist/utils/stdin-pipe.js +87 -63
- package/dist/utils/stdin-pipe.js.map +1 -1
- package/dist/utils/storage-factory.js +104 -84
- package/dist/utils/storage-factory.js.map +1 -1
- package/dist/utils/storage-maintenance.js +249 -211
- package/dist/utils/storage-maintenance.js.map +1 -1
- package/dist/utils/thread-lock.js +96 -92
- package/dist/utils/thread-lock.js.map +1 -1
- package/dist/utils/token-estimator.js +12 -12
- package/dist/utils/token-estimator.js.map +1 -1
- package/dist/utils/update-check.d.ts +1 -1
- package/dist/utils/update-check.js +341 -259
- package/dist/utils/update-check.js.map +1 -1
- package/dist/voice/stt-registry.js +131 -113
- package/dist/voice/stt-registry.js.map +1 -1
- package/package.json +11 -11
- package/dist/acp.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/evals/index.js.map +0 -1
- package/dist/evals/scorers/index.js.map +0 -1
- package/dist/headless/index.js.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/lsp/index.js.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/types.js.map +0 -1
- package/dist/onboarding/index.js.map +0 -1
- package/dist/plugins/types.js.map +0 -1
- package/dist/tools/index.js.map +0 -1
|
@@ -1,598 +1,656 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
1
|
+
import { getAppDataDir } from "../utils/project.js";
|
|
3
2
|
import { AuthStorage } from "../auth/storage.js";
|
|
4
3
|
import { buildCodexStagehandFetch, createCodexMiddleware } from "../providers/openai-codex.js";
|
|
5
|
-
import { getAppDataDir } from "../utils/project.js";
|
|
6
4
|
import { DEFAULT_STT_PROVIDER, resolveSTTModel } from "../voice/stt-registry.js";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6
|
+
import { dirname, join } from "path";
|
|
7
|
+
//#region src/onboarding/settings.ts
|
|
8
|
+
/**
|
|
9
|
+
* Persistent global settings stored in the app data directory as settings.json.
|
|
10
|
+
* This file persists onboarding state AND user preferences (model choices, yolo, etc.)
|
|
11
|
+
* so they carry across threads and restarts.
|
|
12
|
+
*/
|
|
13
|
+
/** Gateway provider key used in AuthStorage. */
|
|
7
14
|
const MASTRA_GATEWAY_PROVIDER = "mastra-gateway";
|
|
15
|
+
/** Default gateway URL. */
|
|
8
16
|
const MASTRA_GATEWAY_DEFAULT_URL = "https://gateway-api.mastra.ai";
|
|
17
|
+
/** @deprecated Renamed to {@link MASTRA_GATEWAY_PROVIDER}. */
|
|
9
18
|
const MEMORY_GATEWAY_PROVIDER = MASTRA_GATEWAY_PROVIDER;
|
|
19
|
+
/** @deprecated Renamed to {@link MASTRA_GATEWAY_DEFAULT_URL}. */
|
|
10
20
|
const MEMORY_GATEWAY_DEFAULT_URL = MASTRA_GATEWAY_DEFAULT_URL;
|
|
21
|
+
/** Auth key prefix for observability tokens stored per-resource in auth.json */
|
|
11
22
|
const OBSERVABILITY_AUTH_PREFIX = "observability:";
|
|
12
23
|
const STORAGE_DEFAULTS = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
backend: "libsql",
|
|
25
|
+
libsql: {},
|
|
26
|
+
pg: {}
|
|
16
27
|
};
|
|
28
|
+
/** Default STT engine: on-device macOS recognizer where available, else cloud. */
|
|
17
29
|
function defaultVoiceEngine() {
|
|
18
|
-
|
|
30
|
+
return process.platform === "darwin" ? "macos-native" : "cloud";
|
|
19
31
|
}
|
|
20
32
|
const DEFAULTS = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
33
|
+
onboarding: {
|
|
34
|
+
completedAt: null,
|
|
35
|
+
skippedAt: null,
|
|
36
|
+
version: 0,
|
|
37
|
+
modePackId: null,
|
|
38
|
+
omPackId: null,
|
|
39
|
+
quietModePreferenceSelected: true
|
|
40
|
+
},
|
|
41
|
+
models: {
|
|
42
|
+
activeModelPackId: null,
|
|
43
|
+
modeDefaults: {},
|
|
44
|
+
activeOmPackId: null,
|
|
45
|
+
omModelOverride: null,
|
|
46
|
+
observerModelOverride: null,
|
|
47
|
+
reflectorModelOverride: null,
|
|
48
|
+
omObservationThreshold: null,
|
|
49
|
+
omReflectionThreshold: null,
|
|
50
|
+
omCavemanObservations: null,
|
|
51
|
+
omObserveAttachments: null,
|
|
52
|
+
subagentModels: {},
|
|
53
|
+
goalJudgeModel: null,
|
|
54
|
+
goalMaxTurns: null
|
|
55
|
+
},
|
|
56
|
+
preferences: {
|
|
57
|
+
yolo: null,
|
|
58
|
+
theme: "auto",
|
|
59
|
+
thinkingLevel: "off",
|
|
60
|
+
quietMode: false,
|
|
61
|
+
quietModeMaxToolPreviewLines: 2
|
|
62
|
+
},
|
|
63
|
+
storage: { ...STORAGE_DEFAULTS },
|
|
64
|
+
customModelPacks: [],
|
|
65
|
+
customProviders: [],
|
|
66
|
+
modelUseCounts: {},
|
|
67
|
+
updateDismissedVersion: null,
|
|
68
|
+
memoryGateway: {},
|
|
69
|
+
lsp: {},
|
|
70
|
+
browser: {
|
|
71
|
+
enabled: false,
|
|
72
|
+
provider: "stagehand",
|
|
73
|
+
headless: false,
|
|
74
|
+
viewport: {
|
|
75
|
+
width: 1280,
|
|
76
|
+
height: 720
|
|
77
|
+
},
|
|
78
|
+
stagehand: { env: "LOCAL" }
|
|
79
|
+
},
|
|
80
|
+
shellPassthrough: { mode: "default" },
|
|
81
|
+
voice: {
|
|
82
|
+
enabled: false,
|
|
83
|
+
engine: defaultVoiceEngine(),
|
|
84
|
+
provider: DEFAULT_STT_PROVIDER
|
|
85
|
+
},
|
|
86
|
+
signals: {
|
|
87
|
+
unixSocketPubSub: false,
|
|
88
|
+
experimentalGithubSignals: false
|
|
89
|
+
},
|
|
90
|
+
observability: {
|
|
91
|
+
resources: {},
|
|
92
|
+
localTracing: false
|
|
93
|
+
}
|
|
69
94
|
};
|
|
70
|
-
const THINKING_LEVEL_VALUES = [
|
|
95
|
+
const THINKING_LEVEL_VALUES = [
|
|
96
|
+
"off",
|
|
97
|
+
"low",
|
|
98
|
+
"medium",
|
|
99
|
+
"high",
|
|
100
|
+
"xhigh"
|
|
101
|
+
];
|
|
71
102
|
const QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX = 8;
|
|
72
103
|
const loadedSignalSettings = /* @__PURE__ */ new WeakMap();
|
|
73
104
|
function cloneSignalSettings(signals) {
|
|
74
|
-
|
|
105
|
+
return { ...signals };
|
|
75
106
|
}
|
|
76
107
|
function rememberLoadedSettings(settings) {
|
|
77
|
-
|
|
78
|
-
|
|
108
|
+
loadedSignalSettings.set(settings, cloneSignalSettings(settings.signals));
|
|
109
|
+
return settings;
|
|
79
110
|
}
|
|
80
111
|
function signalSettingsEqual(left, right) {
|
|
81
|
-
|
|
112
|
+
return left.unixSocketPubSub === right.unixSocketPubSub && left.experimentalGithubSignals === right.experimentalGithubSignals;
|
|
82
113
|
}
|
|
83
114
|
function parseThinkingLevel(value) {
|
|
84
|
-
|
|
115
|
+
return typeof value === "string" && THINKING_LEVEL_VALUES.includes(value) ? value : DEFAULTS.preferences.thinkingLevel;
|
|
85
116
|
}
|
|
86
117
|
function parseQuietModeMaxToolPreviewLines(value) {
|
|
87
|
-
|
|
88
|
-
|
|
118
|
+
const rawValue = typeof value === "number" && Number.isFinite(value) ? value : DEFAULTS.preferences.quietModeMaxToolPreviewLines;
|
|
119
|
+
return Math.min(QUIET_MODE_MAX_TOOL_PREVIEW_LINES_MAX, Math.max(0, Math.floor(rawValue)));
|
|
89
120
|
}
|
|
90
121
|
function parsePreferences(rawPreferences) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
const raw = rawPreferences && typeof rawPreferences === "object" ? rawPreferences : {};
|
|
123
|
+
return {
|
|
124
|
+
...DEFAULTS.preferences,
|
|
125
|
+
...raw,
|
|
126
|
+
thinkingLevel: parseThinkingLevel(raw.thinkingLevel),
|
|
127
|
+
quietModeMaxToolPreviewLines: parseQuietModeMaxToolPreviewLines(raw.quietModeMaxToolPreviewLines)
|
|
128
|
+
};
|
|
98
129
|
}
|
|
99
130
|
function parseSignalSettings(rawSignals) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
const raw = rawSignals && typeof rawSignals === "object" ? rawSignals : {};
|
|
132
|
+
return {
|
|
133
|
+
unixSocketPubSub: typeof raw.unixSocketPubSub === "boolean" ? raw.unixSocketPubSub : DEFAULTS.signals.unixSocketPubSub,
|
|
134
|
+
experimentalGithubSignals: typeof raw.experimentalGithubSignals === "boolean" ? raw.experimentalGithubSignals : DEFAULTS.signals.experimentalGithubSignals
|
|
135
|
+
};
|
|
105
136
|
}
|
|
106
137
|
function hasQuietModePreferenceSelected(rawOnboarding) {
|
|
107
|
-
|
|
108
|
-
rawOnboarding && typeof rawOnboarding === "object" && Object.prototype.hasOwnProperty.call(rawOnboarding, "quietModePreferenceSelected")
|
|
109
|
-
);
|
|
138
|
+
return Boolean(rawOnboarding && typeof rawOnboarding === "object" && Object.prototype.hasOwnProperty.call(rawOnboarding, "quietModePreferenceSelected"));
|
|
110
139
|
}
|
|
111
140
|
function applyQuietModePreferenceRollout(settings, rawOnboarding) {
|
|
112
|
-
|
|
113
|
-
|
|
141
|
+
if (hasQuietModePreferenceSelected(rawOnboarding)) return;
|
|
142
|
+
settings.onboarding.quietModePreferenceSelected = settings.preferences.quietMode === true;
|
|
114
143
|
}
|
|
115
144
|
function getNewInstallDefaults() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
145
|
+
const settings = structuredClone(DEFAULTS);
|
|
146
|
+
settings.preferences.quietMode = true;
|
|
147
|
+
settings.onboarding.quietModePreferenceSelected = true;
|
|
148
|
+
return settings;
|
|
120
149
|
}
|
|
121
150
|
function getSettingsPath() {
|
|
122
|
-
|
|
151
|
+
return join(getAppDataDir(), "settings.json");
|
|
123
152
|
}
|
|
124
153
|
function getCustomProviderId(name) {
|
|
125
|
-
|
|
126
|
-
return slug || "provider";
|
|
154
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "provider";
|
|
127
155
|
}
|
|
128
156
|
function toCustomProviderModelId(providerName, modelName) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
return `${providerId}/${trimmedModelName}`;
|
|
157
|
+
const providerId = getCustomProviderId(providerName);
|
|
158
|
+
const trimmedModelName = modelName.trim();
|
|
159
|
+
const providerPrefix = `${providerId}/`;
|
|
160
|
+
if (trimmedModelName.startsWith(providerPrefix)) return trimmedModelName;
|
|
161
|
+
return `${providerId}/${trimmedModelName}`;
|
|
136
162
|
}
|
|
137
163
|
function parseCustomProviders(rawProviders) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
url,
|
|
162
|
-
...apiKey ? { apiKey } : {},
|
|
163
|
-
models
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
return parsedProviders;
|
|
164
|
+
if (!Array.isArray(rawProviders)) return [];
|
|
165
|
+
const parsedProviders = [];
|
|
166
|
+
for (const rawProvider of rawProviders) {
|
|
167
|
+
if (!rawProvider || typeof rawProvider !== "object") continue;
|
|
168
|
+
const candidate = rawProvider;
|
|
169
|
+
const name = typeof candidate.name === "string" ? candidate.name.trim() : "";
|
|
170
|
+
const url = typeof candidate.url === "string" ? candidate.url.trim() : "";
|
|
171
|
+
if (!name || !url) continue;
|
|
172
|
+
const providerId = getCustomProviderId(name);
|
|
173
|
+
const models = Array.isArray(candidate.models) ? [...new Set(candidate.models.filter((model) => typeof model === "string").map((model) => model.trim()).map((model) => {
|
|
174
|
+
const providerPrefix = `${providerId}/`;
|
|
175
|
+
if (model.startsWith(providerPrefix)) return model.slice(providerPrefix.length);
|
|
176
|
+
return model;
|
|
177
|
+
}))].filter((model) => model.length > 0) : [];
|
|
178
|
+
const apiKey = typeof candidate.apiKey === "string" && candidate.apiKey.trim().length > 0 ? candidate.apiKey.trim() : void 0;
|
|
179
|
+
parsedProviders.push({
|
|
180
|
+
name,
|
|
181
|
+
url,
|
|
182
|
+
...apiKey ? { apiKey } : {},
|
|
183
|
+
models
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return parsedProviders;
|
|
167
187
|
}
|
|
168
188
|
const BROWSER_PROVIDERS = /* @__PURE__ */ new Set(["stagehand", "agent-browser"]);
|
|
169
189
|
const STAGEHAND_ENVS = /* @__PURE__ */ new Set(["LOCAL", "BROWSERBASE"]);
|
|
190
|
+
/**
|
|
191
|
+
* Deep-merge and validate browser settings from JSON.
|
|
192
|
+
* Explicitly validates types to handle malformed settings.json gracefully.
|
|
193
|
+
*/
|
|
170
194
|
function parseBrowserSettings(rawBrowser) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
const raw = rawBrowser && typeof rawBrowser === "object" ? rawBrowser : {};
|
|
196
|
+
const rawViewport = raw.viewport && typeof raw.viewport === "object" ? raw.viewport : {};
|
|
197
|
+
const rawStagehand = raw.stagehand && typeof raw.stagehand === "object" ? raw.stagehand : {};
|
|
198
|
+
const rawAgentBrowser = raw.agentBrowser && typeof raw.agentBrowser === "object" ? raw.agentBrowser : {};
|
|
199
|
+
return {
|
|
200
|
+
enabled: typeof raw.enabled === "boolean" ? raw.enabled : DEFAULTS.browser.enabled,
|
|
201
|
+
provider: typeof raw.provider === "string" && BROWSER_PROVIDERS.has(raw.provider) ? raw.provider : DEFAULTS.browser.provider,
|
|
202
|
+
headless: typeof raw.headless === "boolean" ? raw.headless : DEFAULTS.browser.headless,
|
|
203
|
+
cdpUrl: typeof raw.cdpUrl === "string" && raw.cdpUrl.trim() ? raw.cdpUrl.trim() : void 0,
|
|
204
|
+
profile: typeof raw.profile === "string" && raw.profile.trim() ? raw.profile.trim() : void 0,
|
|
205
|
+
executablePath: typeof raw.executablePath === "string" && raw.executablePath.trim() ? raw.executablePath.trim() : void 0,
|
|
206
|
+
viewport: {
|
|
207
|
+
width: typeof rawViewport.width === "number" ? rawViewport.width : DEFAULTS.browser.viewport.width,
|
|
208
|
+
height: typeof rawViewport.height === "number" ? rawViewport.height : DEFAULTS.browser.viewport.height
|
|
209
|
+
},
|
|
210
|
+
scope: typeof raw.scope === "string" && (raw.scope === "shared" || raw.scope === "thread") ? raw.scope : void 0,
|
|
211
|
+
stagehand: {
|
|
212
|
+
env: typeof rawStagehand.env === "string" && STAGEHAND_ENVS.has(rawStagehand.env) ? rawStagehand.env : DEFAULTS.browser.stagehand.env,
|
|
213
|
+
...typeof rawStagehand.apiKey === "string" && rawStagehand.apiKey.trim() ? { apiKey: rawStagehand.apiKey.trim() } : {},
|
|
214
|
+
...typeof rawStagehand.projectId === "string" && rawStagehand.projectId.trim() ? { projectId: rawStagehand.projectId.trim() } : {},
|
|
215
|
+
...typeof rawStagehand.preserveUserDataDir === "boolean" ? { preserveUserDataDir: rawStagehand.preserveUserDataDir } : {}
|
|
216
|
+
},
|
|
217
|
+
agentBrowser: typeof rawAgentBrowser.storageState === "string" && rawAgentBrowser.storageState.trim() ? { storageState: rawAgentBrowser.storageState.trim() } : void 0
|
|
218
|
+
};
|
|
195
219
|
}
|
|
196
220
|
function parseShellPassthroughSettings(rawShellPassthrough) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
221
|
+
const raw = rawShellPassthrough && typeof rawShellPassthrough === "object" ? rawShellPassthrough : {};
|
|
222
|
+
const executable = typeof raw.executable === "string" && raw.executable.trim() ? raw.executable.trim() : void 0;
|
|
223
|
+
const family = typeof raw.family === "string" && raw.family.trim() ? raw.family.trim() : void 0;
|
|
224
|
+
const mode = typeof raw.mode === "string" && raw.mode.trim() ? raw.mode.trim() : void 0;
|
|
225
|
+
const defaultMode = executable ? void 0 : DEFAULTS.shellPassthrough.mode;
|
|
226
|
+
return {
|
|
227
|
+
...mode ?? defaultMode ? { mode: mode ?? defaultMode } : {},
|
|
228
|
+
...executable ? { executable } : {},
|
|
229
|
+
...family ? { family } : {}
|
|
230
|
+
};
|
|
207
231
|
}
|
|
208
232
|
function parseVoiceSettings(rawVoice) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
model: resolved.model
|
|
220
|
-
};
|
|
233
|
+
const raw = rawVoice && typeof rawVoice === "object" ? rawVoice : {};
|
|
234
|
+
const enabled = typeof raw.enabled === "boolean" ? raw.enabled : DEFAULTS.voice.enabled;
|
|
235
|
+
const engine = raw.engine === "macos-native" || raw.engine === "cloud" ? raw.engine : defaultVoiceEngine();
|
|
236
|
+
const resolved = resolveSTTModel(typeof raw.provider === "string" ? raw.provider : DEFAULTS.voice.provider, typeof raw.model === "string" ? raw.model : void 0);
|
|
237
|
+
return {
|
|
238
|
+
enabled,
|
|
239
|
+
engine,
|
|
240
|
+
provider: resolved.provider,
|
|
241
|
+
model: resolved.model
|
|
242
|
+
};
|
|
221
243
|
}
|
|
222
244
|
const VALID_PROJECT_ID = /^[a-zA-Z0-9_-]+$/;
|
|
223
245
|
function parseObservabilitySettings(raw) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
246
|
+
if (!raw || typeof raw !== "object") return {
|
|
247
|
+
resources: {},
|
|
248
|
+
localTracing: false
|
|
249
|
+
};
|
|
250
|
+
const obj = raw;
|
|
251
|
+
const localTracing = obj.localTracing === true;
|
|
252
|
+
const rawResources = obj.resources;
|
|
253
|
+
if (!rawResources || typeof rawResources !== "object") return {
|
|
254
|
+
resources: {},
|
|
255
|
+
localTracing
|
|
256
|
+
};
|
|
257
|
+
const resources = {};
|
|
258
|
+
for (const [key, val] of Object.entries(rawResources)) if (val && typeof val === "object") {
|
|
259
|
+
const v = val;
|
|
260
|
+
if (typeof v.projectId === "string" && VALID_PROJECT_ID.test(v.projectId)) resources[key] = {
|
|
261
|
+
projectId: v.projectId,
|
|
262
|
+
configuredAt: typeof v.configuredAt === "string" ? v.configuredAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
resources,
|
|
267
|
+
localTracing
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* One-time migration: move model-related data from auth.json to settings.json.
|
|
272
|
+
* Reads `_modelRanks`, `_modeModelId_*`, `_subagentModelId*` from auth.json,
|
|
273
|
+
* merges them into settings, removes them from auth.json, and writes both files.
|
|
274
|
+
* No-ops if auth.json has no _ prefixed model data.
|
|
275
|
+
*/
|
|
243
276
|
function migrateFromAuth(settingsPath) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
277
|
+
const authPath = join(getAppDataDir(), "auth.json");
|
|
278
|
+
if (!existsSync(authPath)) return false;
|
|
279
|
+
let authData;
|
|
280
|
+
try {
|
|
281
|
+
authData = JSON.parse(readFileSync(authPath, "utf-8"));
|
|
282
|
+
} catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const modelKeys = Object.keys(authData).filter((k) => k.startsWith("_"));
|
|
286
|
+
if (modelKeys.length === 0) return false;
|
|
287
|
+
let settings;
|
|
288
|
+
if (existsSync(settingsPath)) try {
|
|
289
|
+
const raw = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
290
|
+
settings = {
|
|
291
|
+
onboarding: {
|
|
292
|
+
...DEFAULTS.onboarding,
|
|
293
|
+
...raw.onboarding
|
|
294
|
+
},
|
|
295
|
+
models: {
|
|
296
|
+
...DEFAULTS.models,
|
|
297
|
+
...raw.models
|
|
298
|
+
},
|
|
299
|
+
preferences: parsePreferences(raw.preferences),
|
|
300
|
+
storage: {
|
|
301
|
+
...STORAGE_DEFAULTS,
|
|
302
|
+
...raw.storage,
|
|
303
|
+
libsql: {
|
|
304
|
+
...STORAGE_DEFAULTS.libsql,
|
|
305
|
+
...raw.storage?.libsql
|
|
306
|
+
},
|
|
307
|
+
pg: {
|
|
308
|
+
...STORAGE_DEFAULTS.pg,
|
|
309
|
+
...raw.storage?.pg
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],
|
|
313
|
+
customProviders: parseCustomProviders(raw.customProviders),
|
|
314
|
+
modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === "object" ? raw.modelUseCounts : {},
|
|
315
|
+
updateDismissedVersion: typeof raw.updateDismissedVersion === "string" ? raw.updateDismissedVersion : null,
|
|
316
|
+
memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === "object" ? raw.memoryGateway : {},
|
|
317
|
+
lsp: raw.lsp && typeof raw.lsp === "object" ? raw.lsp : void 0,
|
|
318
|
+
browser: parseBrowserSettings(raw.browser),
|
|
319
|
+
shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),
|
|
320
|
+
voice: parseVoiceSettings(raw.voice),
|
|
321
|
+
signals: parseSignalSettings(raw.signals),
|
|
322
|
+
observability: parseObservabilitySettings(raw.observability)
|
|
323
|
+
};
|
|
324
|
+
applyQuietModePreferenceRollout(settings, raw.onboarding);
|
|
325
|
+
} catch {
|
|
326
|
+
settings = structuredClone(DEFAULTS);
|
|
327
|
+
}
|
|
328
|
+
else settings = structuredClone(DEFAULTS);
|
|
329
|
+
if (authData._modelRanks && typeof authData._modelRanks === "object") settings.modelUseCounts = {
|
|
330
|
+
...authData._modelRanks,
|
|
331
|
+
...settings.modelUseCounts
|
|
332
|
+
};
|
|
333
|
+
for (const key of modelKeys) {
|
|
334
|
+
const modeMatch = key.match(/^_modeModelId_(.+)$/);
|
|
335
|
+
if (modeMatch?.[1] && typeof authData[key] === "string" && !settings.models.modeDefaults[modeMatch[1]]) settings.models.modeDefaults[modeMatch[1]] = authData[key];
|
|
336
|
+
}
|
|
337
|
+
for (const key of modelKeys) {
|
|
338
|
+
if (key === "_subagentModelId" && typeof authData[key] === "string" && !settings.models.subagentModels["default"]) settings.models.subagentModels["default"] = authData[key];
|
|
339
|
+
const saMatch = key.match(/^_subagentModelId_(.+)$/);
|
|
340
|
+
if (saMatch?.[1] && typeof authData[key] === "string" && !settings.models.subagentModels[saMatch[1]]) settings.models.subagentModels[saMatch[1]] = authData[key];
|
|
341
|
+
}
|
|
342
|
+
saveSettings(settings, settingsPath);
|
|
343
|
+
for (const key of modelKeys) delete authData[key];
|
|
344
|
+
try {
|
|
345
|
+
writeFileSync(authPath, JSON.stringify(authData, null, 2), "utf-8");
|
|
346
|
+
} catch {}
|
|
347
|
+
return true;
|
|
314
348
|
}
|
|
315
349
|
const LEGACY_VARIED_MODELS = {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
350
|
+
plan: "openai/gpt-5.4",
|
|
351
|
+
build: "anthropic/claude-sonnet-4-5",
|
|
352
|
+
fast: "anthropic/claude-haiku-4-5"
|
|
319
353
|
};
|
|
320
354
|
function migrateLegacyVariedPack(settings) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (settings.models.activeModelPackId === legacyPackId) {
|
|
340
|
-
settings.models.activeModelPackId = customPackId;
|
|
341
|
-
if (Object.keys(settings.models.modeDefaults).length === 0) {
|
|
342
|
-
settings.models.modeDefaults = { ...LEGACY_VARIED_MODELS };
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
if (settings.onboarding.modePackId === legacyPackId) {
|
|
346
|
-
settings.onboarding.modePackId = customPackId;
|
|
347
|
-
}
|
|
348
|
-
return true;
|
|
355
|
+
const legacyPackId = "varied";
|
|
356
|
+
const customPackId = "custom:varied";
|
|
357
|
+
if (!(settings.models.activeModelPackId === legacyPackId || settings.onboarding.modePackId === legacyPackId)) return false;
|
|
358
|
+
const existingIdx = settings.customModelPacks.findIndex((p) => p.name === "varied");
|
|
359
|
+
if (existingIdx >= 0) {
|
|
360
|
+
const existing = settings.customModelPacks[existingIdx];
|
|
361
|
+
if (!Object.entries(LEGACY_VARIED_MODELS).every(([k, v]) => existing.models[k] === v)) existing.models = { ...LEGACY_VARIED_MODELS };
|
|
362
|
+
} else settings.customModelPacks.push({
|
|
363
|
+
name: "varied",
|
|
364
|
+
models: { ...LEGACY_VARIED_MODELS },
|
|
365
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
366
|
+
});
|
|
367
|
+
if (settings.models.activeModelPackId === legacyPackId) {
|
|
368
|
+
settings.models.activeModelPackId = customPackId;
|
|
369
|
+
if (Object.keys(settings.models.modeDefaults).length === 0) settings.models.modeDefaults = { ...LEGACY_VARIED_MODELS };
|
|
370
|
+
}
|
|
371
|
+
if (settings.onboarding.modePackId === legacyPackId) settings.onboarding.modePackId = customPackId;
|
|
372
|
+
return true;
|
|
349
373
|
}
|
|
350
374
|
function loadSettings(filePath = getSettingsPath()) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
375
|
+
migrateFromAuth(filePath);
|
|
376
|
+
if (!existsSync(filePath)) return rememberLoadedSettings(getNewInstallDefaults());
|
|
377
|
+
try {
|
|
378
|
+
const raw = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
379
|
+
const settings = {
|
|
380
|
+
...raw,
|
|
381
|
+
onboarding: {
|
|
382
|
+
...DEFAULTS.onboarding,
|
|
383
|
+
...raw.onboarding
|
|
384
|
+
},
|
|
385
|
+
models: {
|
|
386
|
+
...DEFAULTS.models,
|
|
387
|
+
...raw.models
|
|
388
|
+
},
|
|
389
|
+
preferences: parsePreferences(raw.preferences),
|
|
390
|
+
storage: {
|
|
391
|
+
...STORAGE_DEFAULTS,
|
|
392
|
+
...raw.storage,
|
|
393
|
+
libsql: {
|
|
394
|
+
...STORAGE_DEFAULTS.libsql,
|
|
395
|
+
...raw.storage?.libsql
|
|
396
|
+
},
|
|
397
|
+
pg: {
|
|
398
|
+
...STORAGE_DEFAULTS.pg,
|
|
399
|
+
...raw.storage?.pg
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],
|
|
403
|
+
customProviders: parseCustomProviders(raw.customProviders),
|
|
404
|
+
modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === "object" ? raw.modelUseCounts : {},
|
|
405
|
+
updateDismissedVersion: typeof raw.updateDismissedVersion === "string" ? raw.updateDismissedVersion : null,
|
|
406
|
+
memoryGateway: raw.memoryGateway && typeof raw.memoryGateway === "object" ? raw.memoryGateway : {},
|
|
407
|
+
lsp: raw.lsp && typeof raw.lsp === "object" ? raw.lsp : void 0,
|
|
408
|
+
browser: parseBrowserSettings(raw.browser),
|
|
409
|
+
shellPassthrough: parseShellPassthroughSettings(raw.shellPassthrough),
|
|
410
|
+
voice: parseVoiceSettings(raw.voice),
|
|
411
|
+
signals: parseSignalSettings(raw.signals),
|
|
412
|
+
observability: parseObservabilitySettings(raw.observability)
|
|
413
|
+
};
|
|
414
|
+
let settingsChanged = false;
|
|
415
|
+
if (!hasQuietModePreferenceSelected(raw.onboarding)) {
|
|
416
|
+
applyQuietModePreferenceRollout(settings, raw.onboarding);
|
|
417
|
+
settingsChanged = true;
|
|
418
|
+
}
|
|
419
|
+
if (raw.models?.omModelId && !settings.models.omModelOverride) {
|
|
420
|
+
settings.models.omModelOverride = raw.models.omModelId;
|
|
421
|
+
settingsChanged = true;
|
|
422
|
+
}
|
|
423
|
+
if (migrateLegacyVariedPack(settings)) settingsChanged = true;
|
|
424
|
+
if (settingsChanged) saveSettings(settings, filePath);
|
|
425
|
+
return rememberLoadedSettings(settings);
|
|
426
|
+
} catch {
|
|
427
|
+
return rememberLoadedSettings(structuredClone(DEFAULTS));
|
|
428
|
+
}
|
|
397
429
|
}
|
|
398
430
|
const THREAD_ACTIVE_MODEL_PACK_ID_KEY = "activeModelPackId";
|
|
399
431
|
function parseThreadSettings(metadata) {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
432
|
+
const modeModelIds = {};
|
|
433
|
+
for (const [key, value] of Object.entries(metadata ?? {})) {
|
|
434
|
+
const modeMatch = key.match(/^modeModelId_(.+)$/);
|
|
435
|
+
if (modeMatch?.[1] && typeof value === "string" && value.length > 0) modeModelIds[modeMatch[1]] = value;
|
|
436
|
+
}
|
|
437
|
+
const rawPackId = metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY];
|
|
438
|
+
return {
|
|
439
|
+
activeModelPackId: typeof rawPackId === "string" && rawPackId.length > 0 ? rawPackId : null,
|
|
440
|
+
modeModelIds
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Resolve active model pack id for the current thread.
|
|
445
|
+
*
|
|
446
|
+
* Priority:
|
|
447
|
+
* 1) explicit thread metadata activeModelPackId
|
|
448
|
+
* 2) inferred from thread modeModelId_* values
|
|
449
|
+
* 3) global settings.models.activeModelPackId
|
|
450
|
+
*/
|
|
414
451
|
function resolveThreadActiveModelPackId(settings, builtinPacks, metadata) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
452
|
+
const threadSettings = parseThreadSettings(metadata);
|
|
453
|
+
const isKnownPack = (packId) => {
|
|
454
|
+
if (packId.startsWith("custom:")) {
|
|
455
|
+
const name = packId.slice(7);
|
|
456
|
+
return settings.customModelPacks.some((p) => p.name === name);
|
|
457
|
+
}
|
|
458
|
+
return builtinPacks.some((p) => p.id === packId);
|
|
459
|
+
};
|
|
460
|
+
if (threadSettings.activeModelPackId && isKnownPack(threadSettings.activeModelPackId)) return threadSettings.activeModelPackId;
|
|
461
|
+
const allPacks = [...builtinPacks, ...settings.customModelPacks.map((p) => ({
|
|
462
|
+
id: `custom:${p.name}`,
|
|
463
|
+
models: p.models
|
|
464
|
+
}))];
|
|
465
|
+
for (const pack of allPacks) {
|
|
466
|
+
const packEntries = Object.entries(pack.models);
|
|
467
|
+
const threadEntries = Object.keys(threadSettings.modeModelIds);
|
|
468
|
+
if (packEntries.length === threadEntries.length && packEntries.every(([modeId, modelId]) => threadSettings.modeModelIds[modeId] === modelId)) return pack.id;
|
|
469
|
+
}
|
|
470
|
+
if (settings.models.activeModelPackId && isKnownPack(settings.models.activeModelPackId)) return settings.models.activeModelPackId;
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Resolve effective per-mode model defaults.
|
|
475
|
+
*
|
|
476
|
+
* If `activeModelPackId` is set, looks up the pack (built-in or custom) and
|
|
477
|
+
* returns its models. Falls back to the explicit `modeDefaults` map.
|
|
478
|
+
*
|
|
479
|
+
* @param settings The loaded global settings.
|
|
480
|
+
* @param builtinPacks Built-in packs for the current provider access
|
|
481
|
+
* (from `getAvailableModePacks`). Pass `[]` if unavailable.
|
|
482
|
+
*/
|
|
441
483
|
function resolveModelDefaults(settings, builtinPacks) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
484
|
+
const { activeModelPackId, modeDefaults } = settings.models;
|
|
485
|
+
if (!activeModelPackId) return modeDefaults;
|
|
486
|
+
if (activeModelPackId.startsWith("custom:")) {
|
|
487
|
+
const name = activeModelPackId.slice(7);
|
|
488
|
+
const pack = settings.customModelPacks.find((p) => p.name === name);
|
|
489
|
+
if (pack) return pack.models;
|
|
490
|
+
return modeDefaults;
|
|
491
|
+
}
|
|
492
|
+
const builtin = builtinPacks.find((p) => p.id === activeModelPackId);
|
|
493
|
+
if (builtin) return builtin.models;
|
|
494
|
+
return modeDefaults;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Resolve the effective model ID for one of the two OM roles.
|
|
498
|
+
*
|
|
499
|
+
* Lookup order:
|
|
500
|
+
* 1. The role-specific override (`observerModelOverride` /
|
|
501
|
+
* `reflectorModelOverride`) if set.
|
|
502
|
+
* 2. If `activeOmPackId` points at a built-in pack, that pack's model.
|
|
503
|
+
* 3. The shared `omModelOverride` fallback.
|
|
504
|
+
*
|
|
505
|
+
* @param settings The loaded global settings.
|
|
506
|
+
* @param role Which OM role to resolve (`'observer'` or `'reflector'`).
|
|
507
|
+
* @param builtinOmPacks Built-in OM packs for the current provider access
|
|
508
|
+
* (from `getAvailableOmPacks`). Pass `[]` if unavailable.
|
|
509
|
+
*/
|
|
454
510
|
function resolveOmRoleModel(settings, role, builtinOmPacks) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
511
|
+
const { activeOmPackId, omModelOverride, observerModelOverride, reflectorModelOverride } = settings.models;
|
|
512
|
+
const roleOverride = role === "observer" ? observerModelOverride : reflectorModelOverride;
|
|
513
|
+
if (roleOverride) return roleOverride;
|
|
514
|
+
if (!activeOmPackId) return omModelOverride;
|
|
515
|
+
if (activeOmPackId === "custom") return omModelOverride;
|
|
516
|
+
const pack = builtinOmPacks.find((p) => p.id === activeOmPackId);
|
|
517
|
+
if (pack) return pack.modelId;
|
|
518
|
+
return omModelOverride;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* @deprecated Use `resolveOmRoleModel(settings, 'observer' | 'reflector', ...)`.
|
|
522
|
+
* Equivalent to resolving the observer role (existing callers set both observer
|
|
523
|
+
* and reflector to the same value).
|
|
524
|
+
*/
|
|
464
525
|
function resolveOmModel(settings, builtinOmPacks) {
|
|
465
|
-
|
|
526
|
+
return resolveOmRoleModel(settings, "observer", builtinOmPacks);
|
|
466
527
|
}
|
|
467
528
|
function getSignalSettingsForSave(settings, filePath) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
if (!signalSettingsEqual(currentSignals, loadedSignals)) {
|
|
476
|
-
return currentSignals;
|
|
477
|
-
}
|
|
478
|
-
} catch {
|
|
479
|
-
}
|
|
480
|
-
return settings.signals;
|
|
529
|
+
const loadedSignals = loadedSignalSettings.get(settings);
|
|
530
|
+
if (!loadedSignals || !signalSettingsEqual(settings.signals, loadedSignals) || !existsSync(filePath)) return settings.signals;
|
|
531
|
+
try {
|
|
532
|
+
const currentSignals = parseSignalSettings(JSON.parse(readFileSync(filePath, "utf-8")).signals);
|
|
533
|
+
if (!signalSettingsEqual(currentSignals, loadedSignals)) return currentSignals;
|
|
534
|
+
} catch {}
|
|
535
|
+
return settings.signals;
|
|
481
536
|
}
|
|
482
537
|
function saveSettings(settings, filePath = getSettingsPath()) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
538
|
+
const dir = dirname(filePath);
|
|
539
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
540
|
+
const signals = getSignalSettingsForSave(settings, filePath);
|
|
541
|
+
settings.signals = signals;
|
|
542
|
+
loadedSignalSettings.set(settings, cloneSignalSettings(signals));
|
|
543
|
+
writeFileSync(filePath, JSON.stringify(settings, null, 2), "utf-8");
|
|
544
|
+
}
|
|
545
|
+
/** Marker file name to track which provider last used a profile. */
|
|
492
546
|
const PROFILE_PROVIDER_MARKER = ".mastra-provider";
|
|
547
|
+
/**
|
|
548
|
+
* Check which provider last used a profile directory.
|
|
549
|
+
* Returns the provider name if the marker exists, undefined otherwise.
|
|
550
|
+
*/
|
|
493
551
|
function getProfileProvider(profilePath) {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
552
|
+
const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);
|
|
553
|
+
if (!existsSync(markerPath)) return;
|
|
554
|
+
try {
|
|
555
|
+
const content = readFileSync(markerPath, "utf-8").trim();
|
|
556
|
+
if (content === "stagehand" || content === "agent-browser") return content;
|
|
557
|
+
return;
|
|
558
|
+
} catch {
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Write the provider marker to a profile directory.
|
|
564
|
+
* Creates the directory if it doesn't exist.
|
|
565
|
+
*/
|
|
508
566
|
function setProfileProvider(profilePath, provider) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
567
|
+
const markerPath = join(profilePath, PROFILE_PROVIDER_MARKER);
|
|
568
|
+
if (!existsSync(profilePath)) mkdirSync(profilePath, { recursive: true });
|
|
569
|
+
writeFileSync(markerPath, provider, "utf-8");
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Check if a profile has a provider mismatch.
|
|
573
|
+
* Returns the existing provider if there's a mismatch, undefined otherwise.
|
|
574
|
+
*/
|
|
515
575
|
function checkProfileProviderMismatch(profilePath, targetProvider) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const existingProvider = getProfileProvider(profilePath);
|
|
520
|
-
if (existingProvider && existingProvider !== targetProvider) {
|
|
521
|
-
return existingProvider;
|
|
522
|
-
}
|
|
523
|
-
return void 0;
|
|
576
|
+
if (!profilePath) return;
|
|
577
|
+
const existingProvider = getProfileProvider(profilePath);
|
|
578
|
+
if (existingProvider && existingProvider !== targetProvider) return existingProvider;
|
|
524
579
|
}
|
|
525
580
|
function browserRecordingOptions() {
|
|
526
|
-
|
|
581
|
+
return { outputDir: join(getAppDataDir(), "browser-recordings") };
|
|
527
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Create a browser instance from settings.
|
|
585
|
+
* Shared by startup (main.ts) and live reconfiguration (/browser command).
|
|
586
|
+
* Returns undefined if browser is disabled.
|
|
587
|
+
*/
|
|
528
588
|
async function createBrowserFromSettings(settings) {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
toCustomProviderModelId
|
|
597
|
-
};
|
|
589
|
+
if (!settings.enabled) return;
|
|
590
|
+
const { provider, headless, viewport, cdpUrl, profile, executablePath, stagehand, agentBrowser } = settings;
|
|
591
|
+
const scope = profile ? "shared" : settings.scope;
|
|
592
|
+
const launchConfig = {
|
|
593
|
+
headless,
|
|
594
|
+
viewport,
|
|
595
|
+
profile,
|
|
596
|
+
executablePath,
|
|
597
|
+
scope
|
|
598
|
+
};
|
|
599
|
+
if (provider === "stagehand") {
|
|
600
|
+
const { StagehandBrowser } = await import("@mastra/stagehand");
|
|
601
|
+
const stagehandOpts = {
|
|
602
|
+
env: stagehand?.env ?? "LOCAL",
|
|
603
|
+
apiKey: stagehand?.apiKey ?? process.env.BROWSERBASE_API_KEY,
|
|
604
|
+
projectId: stagehand?.projectId ?? process.env.BROWSERBASE_PROJECT_ID,
|
|
605
|
+
preserveUserDataDir: stagehand?.preserveUserDataDir,
|
|
606
|
+
recording: browserRecordingOptions()
|
|
607
|
+
};
|
|
608
|
+
const authStorage = new AuthStorage();
|
|
609
|
+
const cred = authStorage.get("openai-codex");
|
|
610
|
+
if (cred?.type === "oauth") {
|
|
611
|
+
const accountId = cred.accountId;
|
|
612
|
+
stagehandOpts.model = {
|
|
613
|
+
modelName: "openai/gpt-5.4-mini",
|
|
614
|
+
apiKey: "codex-oauth",
|
|
615
|
+
baseURL: "https://chatgpt.com/backend-api/codex",
|
|
616
|
+
headers: {
|
|
617
|
+
originator: "mastracode",
|
|
618
|
+
"User-Agent": "mastracode",
|
|
619
|
+
...accountId ? { "ChatGPT-Account-ID": accountId } : {}
|
|
620
|
+
},
|
|
621
|
+
fetch: buildCodexStagehandFetch(authStorage),
|
|
622
|
+
middleware: createCodexMiddleware()
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
return cdpUrl ? new StagehandBrowser({
|
|
626
|
+
...launchConfig,
|
|
627
|
+
cdpUrl,
|
|
628
|
+
scope: "shared",
|
|
629
|
+
...stagehandOpts
|
|
630
|
+
}) : new StagehandBrowser({
|
|
631
|
+
...launchConfig,
|
|
632
|
+
...stagehandOpts
|
|
633
|
+
});
|
|
634
|
+
} else if (provider === "agent-browser") {
|
|
635
|
+
const { AgentBrowser } = await import("@mastra/agent-browser");
|
|
636
|
+
const agentBrowserOpts = {
|
|
637
|
+
storageState: agentBrowser?.storageState,
|
|
638
|
+
recording: browserRecordingOptions()
|
|
639
|
+
};
|
|
640
|
+
return cdpUrl ? new AgentBrowser({
|
|
641
|
+
...launchConfig,
|
|
642
|
+
cdpUrl,
|
|
643
|
+
scope: "shared",
|
|
644
|
+
...agentBrowserOpts
|
|
645
|
+
}) : new AgentBrowser({
|
|
646
|
+
...launchConfig,
|
|
647
|
+
...agentBrowserOpts,
|
|
648
|
+
scope
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
throw new Error(`Unsupported browser provider: ${provider}`);
|
|
652
|
+
}
|
|
653
|
+
//#endregion
|
|
654
|
+
export { MASTRA_GATEWAY_DEFAULT_URL, MASTRA_GATEWAY_PROVIDER, MEMORY_GATEWAY_DEFAULT_URL, MEMORY_GATEWAY_PROVIDER, OBSERVABILITY_AUTH_PREFIX, STORAGE_DEFAULTS, THREAD_ACTIVE_MODEL_PACK_ID_KEY, checkProfileProviderMismatch, createBrowserFromSettings, defaultVoiceEngine, getCustomProviderId, getProfileProvider, getSettingsPath, loadSettings, migrateLegacyVariedPack, parseCustomProviders, parseThreadSettings, resolveModelDefaults, resolveOmModel, resolveOmRoleModel, resolveThreadActiveModelPackId, saveSettings, setProfileProvider, toCustomProviderModelId };
|
|
655
|
+
|
|
598
656
|
//# sourceMappingURL=settings.js.map
|