@mastra/code-sdk 1.1.1-alpha.2 → 1.1.1

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,43 @@
1
1
  # @mastra/code-sdk
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Extended Mastra Code's transient retry policy to cover provider server errors with up to 10 retries and exponential backoff starting at 500ms. ([#20393](https://github.com/mastra-ai/mastra/pull/20393))
8
+
9
+ - Improved Mastra Code connection recovery with up to 10 retries, exponential backoff starting at 500ms, and visible retry progress in the TUI. ([#19724](https://github.com/mastra-ai/mastra/pull/19724))
10
+
11
+ - Fixed the OpenAI pack to use its supported default model ID. ([#20423](https://github.com/mastra-ai/mastra/pull/20423))
12
+
13
+ - Review sessions now load project AGENTS.md/CLAUDE.md from the pull request's trusted base branch instead of skipping them entirely. The working-tree copies on an untrusted checkout remain excluded from the system prompt and reminder injection; content is served from the base ref via git, and sessions without a known base ref still skip project instruction files. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
14
+
15
+ - Fixed sandbox file tools (view, write, edit, list) failing with "Path not found" in Factory sessions when called with absolute paths inside the session working directory. File tools now also work on macOS-hosted local sandboxes, not just Linux VMs. ([#20325](https://github.com/mastra-ai/mastra/pull/20325))
16
+
17
+ - Sandbox filesystem operations now behave like local ones: missing files, existing destinations, and directory misuse raise typed errors instead of generic ones, reading a directory as a file fails instead of returning empty content, moving or copying a file into a new directory works, overwrite protection can no longer be raced by concurrent writers, and each filesystem reports a unique id and status. ([#20325](https://github.com/mastra-ai/mastra/pull/20325))
18
+
19
+ - Review sessions no longer ingest AGENTS.md or CLAUDE.md from the checked-out pull request branch. A PR branch is third-party content, so its instruction files are treated as content under review instead of trusted configuration — closing a prompt-injection path into the reviewer agent. The reviewer also runs the PR's install/build/test commands with GitHub tokens stripped from the environment. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
20
+
21
+ - Added an option to the instruction-file reminder processor that lets hosts disable injection entirely for a request, so instruction files from untrusted checkouts are never surfaced as reminders. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
22
+
23
+ - Updated dependencies [[`1288cba`](https://github.com/mastra-ai/mastra/commit/1288cba09b8ab906dba38270c7e2a75400344a98), [`3f472b4`](https://github.com/mastra-ai/mastra/commit/3f472b468892a1ff14ccb43cc0343b86f7d8fd7d), [`ba369f2`](https://github.com/mastra-ai/mastra/commit/ba369f2a0aaf998da0d6aa033d26f64f96bef8ac), [`35b929b`](https://github.com/mastra-ai/mastra/commit/35b929b7abc3d20d85c7985880960ac2d04a6c86), [`55c9e24`](https://github.com/mastra-ai/mastra/commit/55c9e248c27c1d72b5bb7e94ea6b8a3999eee49f), [`dcfed93`](https://github.com/mastra-ai/mastra/commit/dcfed93e1e256c6abfa792cbb7ca836f5d0e8638), [`2876e15`](https://github.com/mastra-ai/mastra/commit/2876e15b4d2f616a3bc1ed3af57d546c268384ce), [`9b3626a`](https://github.com/mastra-ai/mastra/commit/9b3626aeb1d16fcd34b0a8e94c114ddb80a3b240), [`4696963`](https://github.com/mastra-ai/mastra/commit/469696312ac4c618bc8475b0c5ed7949b8a3455e), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73), [`07f5b4b`](https://github.com/mastra-ai/mastra/commit/07f5b4ba9d608d88865030732e580298296adf99), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73), [`598080f`](https://github.com/mastra-ai/mastra/commit/598080f224edb3f0f5b801035b067fac50a56a03)]:
24
+ - @mastra/pg@1.18.1
25
+ - @mastra/core@1.55.0
26
+
27
+ ## 1.1.1-alpha.3
28
+
29
+ ### Patch Changes
30
+
31
+ - Review sessions now load project AGENTS.md/CLAUDE.md from the pull request's trusted base branch instead of skipping them entirely. The working-tree copies on an untrusted checkout remain excluded from the system prompt and reminder injection; content is served from the base ref via git, and sessions without a known base ref still skip project instruction files. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
32
+
33
+ - Review sessions no longer ingest AGENTS.md or CLAUDE.md from the checked-out pull request branch. A PR branch is third-party content, so its instruction files are treated as content under review instead of trusted configuration — closing a prompt-injection path into the reviewer agent. The reviewer also runs the PR's install/build/test commands with GitHub tokens stripped from the environment. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
34
+
35
+ - Added an option to the instruction-file reminder processor that lets hosts disable injection entirely for a request, so instruction files from untrusted checkouts are never surfaced as reminders. ([#20372](https://github.com/mastra-ai/mastra/pull/20372))
36
+
37
+ - Updated dependencies [[`1288cba`](https://github.com/mastra-ai/mastra/commit/1288cba09b8ab906dba38270c7e2a75400344a98), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73), [`723aa54`](https://github.com/mastra-ai/mastra/commit/723aa5437106bdb708ae03c0ef6b77aa11291e73)]:
38
+ - @mastra/pg@1.18.1-alpha.0
39
+ - @mastra/core@1.55.0-alpha.3
40
+
3
41
  ## 1.1.1-alpha.2
4
42
 
5
43
  ### Patch Changes
@@ -6,13 +6,52 @@ export interface InstructionSource {
6
6
  path: string;
7
7
  content: string;
8
8
  scope: 'global' | 'project';
9
+ /** Git ref the content was read from, when not read off the working tree. */
10
+ ref?: string;
9
11
  }
12
+ /**
13
+ * Reads project-scope instruction files. The default implementation reads the
14
+ * working tree via `fs`; alternative readers can serve content from another
15
+ * source (e.g. a trusted git ref) while keeping working-tree paths as the
16
+ * addressing scheme.
17
+ */
18
+ export interface InstructionFileReader {
19
+ exists(path: string): boolean;
20
+ read(path: string): string;
21
+ /** Git ref backing this reader, recorded on the loaded sources. */
22
+ ref?: string;
23
+ }
24
+ /**
25
+ * Create a reader that serves instruction files from a git ref instead of the
26
+ * working tree. Paths are still addressed as working-tree paths under
27
+ * `projectPath`; content comes from `git show <ref>:<relpath>` so an untrusted
28
+ * checkout (e.g. a PR branch under review) cannot influence what is loaded.
29
+ * Tries `origin/<ref>` first (remote truth), then the local ref. Any git
30
+ * failure (missing ref, missing file, no repo) reports the file as absent.
31
+ */
32
+ export declare function createGitRefInstructionReader(projectPath: string, ref: string): InstructionFileReader;
33
+ /**
34
+ * Reader for the reactive reminder channel (AgentsMDInjector) that serves
35
+ * paths under `projectPath` from a trusted git ref. Paths outside the project
36
+ * fall back to the operator machine's filesystem (those are trusted); paths
37
+ * inside the project are only ever resolved against the ref, never the
38
+ * working tree, so an untrusted checkout cannot feed content in.
39
+ */
40
+ export declare function createGitRefReminderReader(projectPath: string, ref: string): {
41
+ pathExists: (path: string) => boolean;
42
+ isDirectory: (path: string) => boolean;
43
+ readFile: (path: string) => string;
44
+ };
10
45
  /**
11
46
  * Load all agent instruction files from global and project locations.
12
47
  * Returns an array of instruction sources, with global ones first.
48
+ *
49
+ * `projectReader` controls where project-scope content comes from (defaults to
50
+ * the working tree). Global instructions always read the operator machine's
51
+ * filesystem.
13
52
  */
14
- export declare function loadAgentInstructions(projectPath: string, configDirName?: string): InstructionSource[];
15
- export declare function getStaticallyLoadedInstructionPaths(projectPath: string): string[];
53
+ export declare function loadAgentInstructions(projectPath: string, configDirName?: string, projectReader?: InstructionFileReader): InstructionSource[];
54
+ export declare function getStaticallyLoadedInstructionPaths(projectPath: string, configDirName?: string, projectReader?: InstructionFileReader): string[];
16
55
  /**
17
56
  * Format loaded instructions into a string for the system prompt.
18
57
  */
@@ -1 +1 @@
1
- {"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/agent-instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC7B;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,SAAqB,GAAG,iBAAiB,EAAE,CAiDlH;AAED,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAS5E"}
1
+ {"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/agent-instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAOD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB,CA+BrG;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACV;IACD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC,CA4CA;AAgBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,SAAqB,EAClC,aAAa,GAAE,qBAA2C,GACzD,iBAAiB,EAAE,CAsDrB;AAED,wBAAgB,mCAAmC,CACjD,WAAW,EAAE,MAAM,EACnB,aAAa,SAAqB,EAClC,aAAa,CAAC,EAAE,qBAAqB,GACpC,MAAM,EAAE,CAEV;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAU5E"}
@@ -1,7 +1,8 @@
1
1
  import { DEFAULT_CONFIG_DIR } from "../../constants.js";
2
- import { existsSync, readFileSync } from "fs";
2
+ import { existsSync, readFileSync, statSync } from "fs";
3
3
  import { homedir } from "os";
4
- import { join, normalize } from "path";
4
+ import { isAbsolute, join, normalize, relative, sep } from "path";
5
+ import { execFileSync } from "child_process";
5
6
  //#region src/agents/prompts/agent-instructions.ts
6
7
  /**
7
8
  * Load project and global agent instruction files (AGENTS.md, CLAUDE.md).
@@ -19,22 +20,130 @@ const GLOBAL_LOCATIONS = [
19
20
  ".config/claude",
20
21
  ".config/mastracode"
21
22
  ];
23
+ const fsInstructionReader = {
24
+ exists: (path) => existsSync(path),
25
+ read: (path) => readFileSync(path, "utf-8")
26
+ };
27
+ /**
28
+ * Create a reader that serves instruction files from a git ref instead of the
29
+ * working tree. Paths are still addressed as working-tree paths under
30
+ * `projectPath`; content comes from `git show <ref>:<relpath>` so an untrusted
31
+ * checkout (e.g. a PR branch under review) cannot influence what is loaded.
32
+ * Tries `origin/<ref>` first (remote truth), then the local ref. Any git
33
+ * failure (missing ref, missing file, no repo) reports the file as absent.
34
+ */
35
+ function createGitRefInstructionReader(projectPath, ref) {
36
+ const toRelative = (path) => {
37
+ const rel = relative(projectPath, path);
38
+ if (!rel || rel.startsWith("..") || isAbsolute(rel)) return null;
39
+ return rel.split(sep).join("/");
40
+ };
41
+ const show = (path) => {
42
+ const rel = toRelative(path);
43
+ if (rel === null) return null;
44
+ for (const candidate of [`origin/${ref}`, ref]) try {
45
+ return execFileSync("git", [
46
+ "-C",
47
+ projectPath,
48
+ "show",
49
+ `${candidate}:${rel}`
50
+ ], {
51
+ encoding: "utf-8",
52
+ stdio: [
53
+ "ignore",
54
+ "pipe",
55
+ "ignore"
56
+ ],
57
+ maxBuffer: 1024 * 1024
58
+ });
59
+ } catch {}
60
+ return null;
61
+ };
62
+ return {
63
+ ref,
64
+ exists: (path) => show(path) !== null,
65
+ read: (path) => {
66
+ const content = show(path);
67
+ if (content === null) throw new Error(`Not found at ref ${ref}: ${path}`);
68
+ return content;
69
+ }
70
+ };
71
+ }
72
+ /**
73
+ * Reader for the reactive reminder channel (AgentsMDInjector) that serves
74
+ * paths under `projectPath` from a trusted git ref. Paths outside the project
75
+ * fall back to the operator machine's filesystem (those are trusted); paths
76
+ * inside the project are only ever resolved against the ref, never the
77
+ * working tree, so an untrusted checkout cannot feed content in.
78
+ */
79
+ function createGitRefReminderReader(projectPath, ref) {
80
+ const gitReader = createGitRefInstructionReader(projectPath, ref);
81
+ const toRelative = (path) => {
82
+ const rel = relative(projectPath, normalize(path));
83
+ if (rel.startsWith("..") || isAbsolute(rel)) return null;
84
+ return rel.split(sep).join("/");
85
+ };
86
+ const objectType = (rel) => {
87
+ if (rel === "") return "tree";
88
+ for (const candidate of [`origin/${ref}`, ref]) try {
89
+ return execFileSync("git", [
90
+ "-C",
91
+ projectPath,
92
+ "cat-file",
93
+ "-t",
94
+ `${candidate}:${rel}`
95
+ ], {
96
+ encoding: "utf-8",
97
+ stdio: [
98
+ "ignore",
99
+ "pipe",
100
+ "ignore"
101
+ ]
102
+ }).trim();
103
+ } catch {}
104
+ return null;
105
+ };
106
+ return {
107
+ pathExists: (path) => {
108
+ const rel = toRelative(path);
109
+ if (rel === null) return existsSync(path);
110
+ return objectType(rel) !== null;
111
+ },
112
+ isDirectory: (path) => {
113
+ const rel = toRelative(path);
114
+ if (rel === null) try {
115
+ return statSync(path).isDirectory();
116
+ } catch {
117
+ return false;
118
+ }
119
+ return objectType(rel) === "tree";
120
+ },
121
+ readFile: (path) => {
122
+ if (toRelative(path) === null) return readFileSync(path, "utf-8");
123
+ return gitReader.read(path);
124
+ }
125
+ };
126
+ }
22
127
  /**
23
128
  * Find the first existing instruction file at a given base path.
24
129
  * Prefers AGENTS.md over CLAUDE.md.
25
130
  */
26
- function findInstructionFile(basePath) {
131
+ function findInstructionFile(basePath, reader = fsInstructionReader) {
27
132
  for (const filename of INSTRUCTION_FILES) {
28
133
  const fullPath = join(basePath, filename);
29
- if (existsSync(fullPath)) return fullPath;
134
+ if (reader.exists(fullPath)) return fullPath;
30
135
  }
31
136
  return null;
32
137
  }
33
138
  /**
34
139
  * Load all agent instruction files from global and project locations.
35
140
  * Returns an array of instruction sources, with global ones first.
141
+ *
142
+ * `projectReader` controls where project-scope content comes from (defaults to
143
+ * the working tree). Global instructions always read the operator machine's
144
+ * filesystem.
36
145
  */
37
- function loadAgentInstructions(projectPath, configDirName = DEFAULT_CONFIG_DIR) {
146
+ function loadAgentInstructions(projectPath, configDirName = DEFAULT_CONFIG_DIR, projectReader = fsInstructionReader) {
38
147
  const sources = [];
39
148
  const home = homedir();
40
149
  const projectLocations = PROJECT_LOCATIONS.map((loc) => loc === ".mastracode" ? configDirName : loc);
@@ -58,14 +167,15 @@ function loadAgentInstructions(projectPath, configDirName = DEFAULT_CONFIG_DIR)
58
167
  } catch {}
59
168
  }
60
169
  for (const location of projectLocations) {
61
- const filePath = findInstructionFile(location ? join(projectPath, location) : projectPath);
170
+ const filePath = findInstructionFile(location ? join(projectPath, location) : projectPath, projectReader);
62
171
  if (filePath) try {
63
- const content = readFileSync(filePath, "utf-8").trim();
172
+ const content = projectReader.read(filePath).trim();
64
173
  if (content) {
65
174
  sources.push({
66
175
  path: filePath,
67
176
  content,
68
- scope: "project"
177
+ scope: "project",
178
+ ...projectReader.ref ? { ref: projectReader.ref } : {}
69
179
  });
70
180
  break;
71
181
  }
@@ -73,8 +183,8 @@ function loadAgentInstructions(projectPath, configDirName = DEFAULT_CONFIG_DIR)
73
183
  }
74
184
  return sources;
75
185
  }
76
- function getStaticallyLoadedInstructionPaths(projectPath) {
77
- return loadAgentInstructions(projectPath).map((source) => normalize(source.path));
186
+ function getStaticallyLoadedInstructionPaths(projectPath, configDirName = DEFAULT_CONFIG_DIR, projectReader) {
187
+ return loadAgentInstructions(projectPath, configDirName, projectReader).map((source) => normalize(source.path));
78
188
  }
79
189
  /**
80
190
  * Format loaded instructions into a string for the system prompt.
@@ -82,10 +192,10 @@ function getStaticallyLoadedInstructionPaths(projectPath) {
82
192
  function formatAgentInstructions(sources) {
83
193
  if (sources.length === 0) return "";
84
194
  return `\n# Agent Instructions\n\n${sources.map((source) => {
85
- return `<!-- ${source.scope === "global" ? "Global" : "Project"} instructions from ${source.path} -->\n${source.content}`;
195
+ return `<!-- ${source.scope === "global" ? "Global" : "Project"} instructions from ${source.ref ? `${source.path} (at ref ${source.ref})` : source.path} -->\n${source.content}`;
86
196
  }).join("\n\n")}\n`;
87
197
  }
88
198
  //#endregion
89
- export { formatAgentInstructions, getStaticallyLoadedInstructionPaths, loadAgentInstructions };
199
+ export { createGitRefInstructionReader, createGitRefReminderReader, formatAgentInstructions, getStaticallyLoadedInstructionPaths, loadAgentInstructions };
90
200
 
91
201
  //# sourceMappingURL=agent-instructions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-instructions.js","names":[],"sources":["../../../src/agents/prompts/agent-instructions.ts"],"sourcesContent":["/**\n * Load project and global agent instruction files (AGENTS.md, CLAUDE.md).\n * Prefers AGENTS.md over CLAUDE.md when multiple exist at the same location.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, normalize } from 'node:path';\nimport { DEFAULT_CONFIG_DIR } from '../../constants.js';\n\n// Filenames to check, in order of preference\nconst INSTRUCTION_FILES = ['AGENTS.md', 'CLAUDE.md'];\n\n// Locations to scan (relative to project root or home)\nconst PROJECT_LOCATIONS = [\n '', // project root\n '.claude',\n '.mastracode',\n];\n\nconst GLOBAL_LOCATIONS = ['.claude', '.mastracode', '.config/claude', '.config/mastracode'];\n\nexport interface InstructionSource {\n path: string;\n content: string;\n scope: 'global' | 'project';\n}\n\n/**\n * Find the first existing instruction file at a given base path.\n * Prefers AGENTS.md over CLAUDE.md.\n */\nfunction findInstructionFile(basePath: string): string | null {\n for (const filename of INSTRUCTION_FILES) {\n const fullPath = join(basePath, filename);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Load all agent instruction files from global and project locations.\n * Returns an array of instruction sources, with global ones first.\n */\nexport function loadAgentInstructions(projectPath: string, configDirName = DEFAULT_CONFIG_DIR): InstructionSource[] {\n const sources: InstructionSource[] = [];\n const home = homedir();\n\n // Derive location arrays from the base constants, substituting the config dir name\n const projectLocations = PROJECT_LOCATIONS.map(loc => (loc === '.mastracode' ? configDirName : loc));\n const globalLocations = GLOBAL_LOCATIONS.map(loc => {\n if (loc === '.mastracode') return configDirName;\n // XDG-style path (~/.config/<name>): strip the leading dot since the\n // .config/ prefix already signals a hidden/config directory.\n if (loc === '.config/mastracode') return '.config/' + configDirName.replace(/^\\./, '');\n return loc;\n });\n\n // Load global instructions first\n for (const location of globalLocations) {\n const basePath = join(home, location);\n const filePath = findInstructionFile(basePath);\n if (filePath) {\n try {\n const content = readFileSync(filePath, 'utf-8').trim();\n if (content) {\n sources.push({ path: filePath, content, scope: 'global' });\n break; // Only use first found global instruction file\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n // Load project instructions\n for (const location of projectLocations) {\n const basePath = location ? join(projectPath, location) : projectPath;\n const filePath = findInstructionFile(basePath);\n if (filePath) {\n try {\n const content = readFileSync(filePath, 'utf-8').trim();\n if (content) {\n sources.push({ path: filePath, content, scope: 'project' });\n break; // Only use first found project instruction file\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return sources;\n}\n\nexport function getStaticallyLoadedInstructionPaths(projectPath: string): string[] {\n return loadAgentInstructions(projectPath).map(source => normalize(source.path));\n}\n\n/**\n * Format loaded instructions into a string for the system prompt.\n */\nexport function formatAgentInstructions(sources: InstructionSource[]): string {\n if (sources.length === 0) return '';\n\n const sections = sources.map(source => {\n const label = source.scope === 'global' ? 'Global' : 'Project';\n return `<!-- ${label} instructions from ${source.path} -->\\n${source.content}`;\n });\n\n return `\\n# Agent Instructions\\n\\n${sections.join('\\n\\n')}\\n`;\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,oBAAoB,CAAC,aAAa,WAAW;AAGnD,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;AAEA,MAAM,mBAAmB;CAAC;CAAW;CAAe;CAAkB;AAAoB;;;;;AAY1F,SAAS,oBAAoB,UAAiC;CAC5D,KAAK,MAAM,YAAY,mBAAmB;EACxC,MAAM,WAAW,KAAK,UAAU,QAAQ;EACxC,IAAI,WAAW,QAAQ,GACrB,OAAO;CAEX;CACA,OAAO;AACT;;;;;AAMA,SAAgB,sBAAsB,aAAqB,gBAAgB,oBAAyC;CAClH,MAAM,UAA+B,CAAC;CACtC,MAAM,OAAO,QAAQ;CAGrB,MAAM,mBAAmB,kBAAkB,KAAI,QAAQ,QAAQ,gBAAgB,gBAAgB,GAAI;CACnG,MAAM,kBAAkB,iBAAiB,KAAI,QAAO;EAClD,IAAI,QAAQ,eAAe,OAAO;EAGlC,IAAI,QAAQ,sBAAsB,OAAO,aAAa,cAAc,QAAQ,OAAO,EAAE;EACrF,OAAO;CACT,CAAC;CAGD,KAAK,MAAM,YAAY,iBAAiB;EAEtC,MAAM,WAAW,oBADA,KAAK,MAAM,QACgB,CAAC;EAC7C,IAAI,UACF,IAAI;GACF,MAAM,UAAU,aAAa,UAAU,OAAO,CAAC,CAAC,KAAK;GACrD,IAAI,SAAS;IACX,QAAQ,KAAK;KAAE,MAAM;KAAU;KAAS,OAAO;IAAS,CAAC;IACzD;GACF;EACF,QAAQ,CAER;CAEJ;CAGA,KAAK,MAAM,YAAY,kBAAkB;EAEvC,MAAM,WAAW,oBADA,WAAW,KAAK,aAAa,QAAQ,IAAI,WACb;EAC7C,IAAI,UACF,IAAI;GACF,MAAM,UAAU,aAAa,UAAU,OAAO,CAAC,CAAC,KAAK;GACrD,IAAI,SAAS;IACX,QAAQ,KAAK;KAAE,MAAM;KAAU;KAAS,OAAO;IAAU,CAAC;IAC1D;GACF;EACF,QAAQ,CAER;CAEJ;CAEA,OAAO;AACT;AAEA,SAAgB,oCAAoC,aAA+B;CACjF,OAAO,sBAAsB,WAAW,CAAC,CAAC,KAAI,WAAU,UAAU,OAAO,IAAI,CAAC;AAChF;;;;AAKA,SAAgB,wBAAwB,SAAsC;CAC5E,IAAI,QAAQ,WAAW,GAAG,OAAO;CAOjC,OAAO,6BALU,QAAQ,KAAI,WAAU;EAErC,OAAO,QADO,OAAO,UAAU,WAAW,WAAW,UAChC,qBAAqB,OAAO,KAAK,QAAQ,OAAO;CACvE,CAE2C,CAAC,CAAC,KAAK,MAAM,EAAE;AAC5D"}
1
+ {"version":3,"file":"agent-instructions.js","names":[],"sources":["../../../src/agents/prompts/agent-instructions.ts"],"sourcesContent":["/**\n * Load project and global agent instruction files (AGENTS.md, CLAUDE.md).\n * Prefers AGENTS.md over CLAUDE.md when multiple exist at the same location.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { isAbsolute, join, normalize, relative, sep } from 'node:path';\nimport { DEFAULT_CONFIG_DIR } from '../../constants.js';\n\n// Filenames to check, in order of preference\nconst INSTRUCTION_FILES = ['AGENTS.md', 'CLAUDE.md'];\n\n// Locations to scan (relative to project root or home)\nconst PROJECT_LOCATIONS = [\n '', // project root\n '.claude',\n '.mastracode',\n];\n\nconst GLOBAL_LOCATIONS = ['.claude', '.mastracode', '.config/claude', '.config/mastracode'];\n\nexport interface InstructionSource {\n path: string;\n content: string;\n scope: 'global' | 'project';\n /** Git ref the content was read from, when not read off the working tree. */\n ref?: string;\n}\n\n/**\n * Reads project-scope instruction files. The default implementation reads the\n * working tree via `fs`; alternative readers can serve content from another\n * source (e.g. a trusted git ref) while keeping working-tree paths as the\n * addressing scheme.\n */\nexport interface InstructionFileReader {\n exists(path: string): boolean;\n read(path: string): string;\n /** Git ref backing this reader, recorded on the loaded sources. */\n ref?: string;\n}\n\nconst fsInstructionReader: InstructionFileReader = {\n exists: path => existsSync(path),\n read: path => readFileSync(path, 'utf-8'),\n};\n\n/**\n * Create a reader that serves instruction files from a git ref instead of the\n * working tree. Paths are still addressed as working-tree paths under\n * `projectPath`; content comes from `git show <ref>:<relpath>` so an untrusted\n * checkout (e.g. a PR branch under review) cannot influence what is loaded.\n * Tries `origin/<ref>` first (remote truth), then the local ref. Any git\n * failure (missing ref, missing file, no repo) reports the file as absent.\n */\nexport function createGitRefInstructionReader(projectPath: string, ref: string): InstructionFileReader {\n const toRelative = (path: string): string | null => {\n const rel = relative(projectPath, path);\n if (!rel || rel.startsWith('..') || isAbsolute(rel)) return null;\n return rel.split(sep).join('/');\n };\n const show = (path: string): string | null => {\n const rel = toRelative(path);\n if (rel === null) return null;\n for (const candidate of [`origin/${ref}`, ref]) {\n try {\n return execFileSync('git', ['-C', projectPath, 'show', `${candidate}:${rel}`], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n maxBuffer: 1024 * 1024,\n });\n } catch {\n // Ref or file missing at this candidate — try the next one.\n }\n }\n return null;\n };\n return {\n ref,\n exists: path => show(path) !== null,\n read: path => {\n const content = show(path);\n if (content === null) throw new Error(`Not found at ref ${ref}: ${path}`);\n return content;\n },\n };\n}\n\n/**\n * Reader for the reactive reminder channel (AgentsMDInjector) that serves\n * paths under `projectPath` from a trusted git ref. Paths outside the project\n * fall back to the operator machine's filesystem (those are trusted); paths\n * inside the project are only ever resolved against the ref, never the\n * working tree, so an untrusted checkout cannot feed content in.\n */\nexport function createGitRefReminderReader(\n projectPath: string,\n ref: string,\n): {\n pathExists: (path: string) => boolean;\n isDirectory: (path: string) => boolean;\n readFile: (path: string) => string;\n} {\n const gitReader = createGitRefInstructionReader(projectPath, ref);\n const toRelative = (path: string): string | null => {\n const rel = relative(projectPath, normalize(path));\n if (rel.startsWith('..') || isAbsolute(rel)) return null;\n return rel.split(sep).join('/');\n };\n const objectType = (rel: string): string | null => {\n if (rel === '') return 'tree'; // project root\n for (const candidate of [`origin/${ref}`, ref]) {\n try {\n return execFileSync('git', ['-C', projectPath, 'cat-file', '-t', `${candidate}:${rel}`], {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim();\n } catch {\n // Ref or object missing at this candidate — try the next one.\n }\n }\n return null;\n };\n return {\n pathExists: path => {\n const rel = toRelative(path);\n if (rel === null) return existsSync(path);\n return objectType(rel) !== null;\n },\n isDirectory: path => {\n const rel = toRelative(path);\n if (rel === null) {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n }\n return objectType(rel) === 'tree';\n },\n readFile: path => {\n const rel = toRelative(path);\n if (rel === null) return readFileSync(path, 'utf-8');\n return gitReader.read(path);\n },\n };\n}\n\n/**\n * Find the first existing instruction file at a given base path.\n * Prefers AGENTS.md over CLAUDE.md.\n */\nfunction findInstructionFile(basePath: string, reader: InstructionFileReader = fsInstructionReader): string | null {\n for (const filename of INSTRUCTION_FILES) {\n const fullPath = join(basePath, filename);\n if (reader.exists(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Load all agent instruction files from global and project locations.\n * Returns an array of instruction sources, with global ones first.\n *\n * `projectReader` controls where project-scope content comes from (defaults to\n * the working tree). Global instructions always read the operator machine's\n * filesystem.\n */\nexport function loadAgentInstructions(\n projectPath: string,\n configDirName = DEFAULT_CONFIG_DIR,\n projectReader: InstructionFileReader = fsInstructionReader,\n): InstructionSource[] {\n const sources: InstructionSource[] = [];\n const home = homedir();\n\n // Derive location arrays from the base constants, substituting the config dir name\n const projectLocations = PROJECT_LOCATIONS.map(loc => (loc === '.mastracode' ? configDirName : loc));\n const globalLocations = GLOBAL_LOCATIONS.map(loc => {\n if (loc === '.mastracode') return configDirName;\n // XDG-style path (~/.config/<name>): strip the leading dot since the\n // .config/ prefix already signals a hidden/config directory.\n if (loc === '.config/mastracode') return '.config/' + configDirName.replace(/^\\./, '');\n return loc;\n });\n\n // Load global instructions first\n for (const location of globalLocations) {\n const basePath = join(home, location);\n const filePath = findInstructionFile(basePath);\n if (filePath) {\n try {\n const content = readFileSync(filePath, 'utf-8').trim();\n if (content) {\n sources.push({ path: filePath, content, scope: 'global' });\n break; // Only use first found global instruction file\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n // Load project instructions\n for (const location of projectLocations) {\n const basePath = location ? join(projectPath, location) : projectPath;\n const filePath = findInstructionFile(basePath, projectReader);\n if (filePath) {\n try {\n const content = projectReader.read(filePath).trim();\n if (content) {\n sources.push({\n path: filePath,\n content,\n scope: 'project',\n ...(projectReader.ref ? { ref: projectReader.ref } : {}),\n });\n break; // Only use first found project instruction file\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return sources;\n}\n\nexport function getStaticallyLoadedInstructionPaths(\n projectPath: string,\n configDirName = DEFAULT_CONFIG_DIR,\n projectReader?: InstructionFileReader,\n): string[] {\n return loadAgentInstructions(projectPath, configDirName, projectReader).map(source => normalize(source.path));\n}\n\n/**\n * Format loaded instructions into a string for the system prompt.\n */\nexport function formatAgentInstructions(sources: InstructionSource[]): string {\n if (sources.length === 0) return '';\n\n const sections = sources.map(source => {\n const label = source.scope === 'global' ? 'Global' : 'Project';\n const origin = source.ref ? `${source.path} (at ref ${source.ref})` : source.path;\n return `<!-- ${label} instructions from ${origin} -->\\n${source.content}`;\n });\n\n return `\\n# Agent Instructions\\n\\n${sections.join('\\n\\n')}\\n`;\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,oBAAoB,CAAC,aAAa,WAAW;AAGnD,MAAM,oBAAoB;CACxB;CACA;CACA;AACF;AAEA,MAAM,mBAAmB;CAAC;CAAW;CAAe;CAAkB;AAAoB;AAuB1F,MAAM,sBAA6C;CACjD,SAAQ,SAAQ,WAAW,IAAI;CAC/B,OAAM,SAAQ,aAAa,MAAM,OAAO;AAC1C;;;;;;;;;AAUA,SAAgB,8BAA8B,aAAqB,KAAoC;CACrG,MAAM,cAAc,SAAgC;EAClD,MAAM,MAAM,SAAS,aAAa,IAAI;EACtC,IAAI,CAAC,OAAO,IAAI,WAAW,IAAI,KAAK,WAAW,GAAG,GAAG,OAAO;EAC5D,OAAO,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;CAChC;CACA,MAAM,QAAQ,SAAgC;EAC5C,MAAM,MAAM,WAAW,IAAI;EAC3B,IAAI,QAAQ,MAAM,OAAO;EACzB,KAAK,MAAM,aAAa,CAAC,UAAU,OAAO,GAAG,GAC3C,IAAI;GACF,OAAO,aAAa,OAAO;IAAC;IAAM;IAAa;IAAQ,GAAG,UAAU,GAAG;GAAK,GAAG;IAC7E,UAAU;IACV,OAAO;KAAC;KAAU;KAAQ;IAAQ;IAClC,WAAW,OAAO;GACpB,CAAC;EACH,QAAQ,CAER;EAEF,OAAO;CACT;CACA,OAAO;EACL;EACA,SAAQ,SAAQ,KAAK,IAAI,MAAM;EAC/B,OAAM,SAAQ;GACZ,MAAM,UAAU,KAAK,IAAI;GACzB,IAAI,YAAY,MAAM,MAAM,IAAI,MAAM,oBAAoB,IAAI,IAAI,MAAM;GACxE,OAAO;EACT;CACF;AACF;;;;;;;;AASA,SAAgB,2BACd,aACA,KAKA;CACA,MAAM,YAAY,8BAA8B,aAAa,GAAG;CAChE,MAAM,cAAc,SAAgC;EAClD,MAAM,MAAM,SAAS,aAAa,UAAU,IAAI,CAAC;EACjD,IAAI,IAAI,WAAW,IAAI,KAAK,WAAW,GAAG,GAAG,OAAO;EACpD,OAAO,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;CAChC;CACA,MAAM,cAAc,QAA+B;EACjD,IAAI,QAAQ,IAAI,OAAO;EACvB,KAAK,MAAM,aAAa,CAAC,UAAU,OAAO,GAAG,GAC3C,IAAI;GACF,OAAO,aAAa,OAAO;IAAC;IAAM;IAAa;IAAY;IAAM,GAAG,UAAU,GAAG;GAAK,GAAG;IACvF,UAAU;IACV,OAAO;KAAC;KAAU;KAAQ;IAAQ;GACpC,CAAC,CAAC,CAAC,KAAK;EACV,QAAQ,CAER;EAEF,OAAO;CACT;CACA,OAAO;EACL,aAAY,SAAQ;GAClB,MAAM,MAAM,WAAW,IAAI;GAC3B,IAAI,QAAQ,MAAM,OAAO,WAAW,IAAI;GACxC,OAAO,WAAW,GAAG,MAAM;EAC7B;EACA,cAAa,SAAQ;GACnB,MAAM,MAAM,WAAW,IAAI;GAC3B,IAAI,QAAQ,MACV,IAAI;IACF,OAAO,SAAS,IAAI,CAAC,CAAC,YAAY;GACpC,QAAQ;IACN,OAAO;GACT;GAEF,OAAO,WAAW,GAAG,MAAM;EAC7B;EACA,WAAU,SAAQ;GAEhB,IADY,WAAW,IACjB,MAAM,MAAM,OAAO,aAAa,MAAM,OAAO;GACnD,OAAO,UAAU,KAAK,IAAI;EAC5B;CACF;AACF;;;;;AAMA,SAAS,oBAAoB,UAAkB,SAAgC,qBAAoC;CACjH,KAAK,MAAM,YAAY,mBAAmB;EACxC,MAAM,WAAW,KAAK,UAAU,QAAQ;EACxC,IAAI,OAAO,OAAO,QAAQ,GACxB,OAAO;CAEX;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,sBACd,aACA,gBAAgB,oBAChB,gBAAuC,qBAClB;CACrB,MAAM,UAA+B,CAAC;CACtC,MAAM,OAAO,QAAQ;CAGrB,MAAM,mBAAmB,kBAAkB,KAAI,QAAQ,QAAQ,gBAAgB,gBAAgB,GAAI;CACnG,MAAM,kBAAkB,iBAAiB,KAAI,QAAO;EAClD,IAAI,QAAQ,eAAe,OAAO;EAGlC,IAAI,QAAQ,sBAAsB,OAAO,aAAa,cAAc,QAAQ,OAAO,EAAE;EACrF,OAAO;CACT,CAAC;CAGD,KAAK,MAAM,YAAY,iBAAiB;EAEtC,MAAM,WAAW,oBADA,KAAK,MAAM,QACgB,CAAC;EAC7C,IAAI,UACF,IAAI;GACF,MAAM,UAAU,aAAa,UAAU,OAAO,CAAC,CAAC,KAAK;GACrD,IAAI,SAAS;IACX,QAAQ,KAAK;KAAE,MAAM;KAAU;KAAS,OAAO;IAAS,CAAC;IACzD;GACF;EACF,QAAQ,CAER;CAEJ;CAGA,KAAK,MAAM,YAAY,kBAAkB;EAEvC,MAAM,WAAW,oBADA,WAAW,KAAK,aAAa,QAAQ,IAAI,aACX,aAAa;EAC5D,IAAI,UACF,IAAI;GACF,MAAM,UAAU,cAAc,KAAK,QAAQ,CAAC,CAAC,KAAK;GAClD,IAAI,SAAS;IACX,QAAQ,KAAK;KACX,MAAM;KACN;KACA,OAAO;KACP,GAAI,cAAc,MAAM,EAAE,KAAK,cAAc,IAAI,IAAI,CAAC;IACxD,CAAC;IACD;GACF;EACF,QAAQ,CAER;CAEJ;CAEA,OAAO;AACT;AAEA,SAAgB,oCACd,aACA,gBAAgB,oBAChB,eACU;CACV,OAAO,sBAAsB,aAAa,eAAe,aAAa,CAAC,CAAC,KAAI,WAAU,UAAU,OAAO,IAAI,CAAC;AAC9G;;;;AAKA,SAAgB,wBAAwB,SAAsC;CAC5E,IAAI,QAAQ,WAAW,GAAG,OAAO;CAQjC,OAAO,6BANU,QAAQ,KAAI,WAAU;EAGrC,OAAO,QAFO,OAAO,UAAU,WAAW,WAAW,UAEhC,qBADN,OAAO,MAAM,GAAG,OAAO,KAAK,WAAW,OAAO,IAAI,KAAK,OAAO,KAC5B,QAAQ,OAAO;CAClE,CAE2C,CAAC,CAAC,KAAK,MAAM,EAAE;AAC5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAUpF,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAmD1D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAUpF,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAiE1D"}
@@ -3,7 +3,7 @@ import { planModePrompt } from "./plan.js";
3
3
  import { fastModePrompt } from "./fast.js";
4
4
  import { hasTavilyKey } from "../../tools/web-search.js";
5
5
  import "../../tools/index.js";
6
- import { formatAgentInstructions, loadAgentInstructions } from "./agent-instructions.js";
6
+ import { createGitRefInstructionReader, formatAgentInstructions, loadAgentInstructions } from "./agent-instructions.js";
7
7
  import { modelSpecificPrompts } from "./model.js";
8
8
  import { buildToolGuidance } from "./tool-guidance.js";
9
9
  import { buildBasePrompt } from "@mastra/core/coding-agent";
@@ -45,9 +45,15 @@ function buildFullPrompt(ctx) {
45
45
  const modeSpecific = (typeof entry === "function" ? entry(ctx) : entry) ?? "";
46
46
  const modelSpecific = ctx.modelId ? modelSpecificPrompts[ctx.modelId] ?? "" : "";
47
47
  const configDir = ctx.state?.configDir;
48
+ const untrustedCheckout = ctx.state?.untrustedCheckout === true;
49
+ const baseRef = typeof ctx.state?.baseRef === "string" ? ctx.state.baseRef : void 0;
50
+ const projectReader = untrustedCheckout ? baseRef ? createGitRefInstructionReader(ctx.workingDir, baseRef) : {
51
+ exists: () => false,
52
+ read: () => ""
53
+ } : void 0;
48
54
  return [
49
55
  base,
50
- formatAgentInstructions(loadAgentInstructions(ctx.workingDir, configDir)).trim(),
56
+ formatAgentInstructions(loadAgentInstructions(ctx.workingDir, configDir, projectReader)).trim(),
51
57
  modelSpecific.trim(),
52
58
  modeSpecific.trim()
53
59
  ].filter(Boolean).join("\n\n");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/prompts/index.ts"],"sourcesContent":["/**\n * Prompt system — exports the prompt builder and mode-specific prompts.\n */\n\nexport { buildModePrompt, buildModePromptFn } from './build.js';\nexport { planModePrompt } from './plan.js';\nexport { fastModePrompt } from './fast.js';\n\nimport { buildBasePrompt } from '@mastra/core/coding-agent';\nimport type { PromptContext as BasePromptContext } from '@mastra/core/coding-agent';\nimport { hasTavilyKey } from '../../tools/index.js';\nimport { loadAgentInstructions, formatAgentInstructions } from './agent-instructions.js';\nimport { buildModePromptFn } from './build.js';\nimport { fastModePrompt } from './fast.js';\nimport { modelSpecificPrompts } from './model.js';\nimport { planModePrompt } from './plan.js';\nimport { buildToolGuidance } from './tool-guidance.js';\n\n// Extended prompt context that includes runtime information\nexport interface PromptContext extends Omit<BasePromptContext, 'toolGuidance'> {\n modeId: string;\n state?: any;\n currentDate: string;\n workingDir: string;\n}\n\nconst modePrompts: Record<string, string | ((ctx: PromptContext) => string)> = {\n build: buildModePromptFn,\n plan: planModePrompt,\n fast: fastModePrompt,\n};\n\n/**\n * Build the full system prompt for a given mode and context.\n * Combines the base prompt with mode-specific instructions.\n */\nexport function buildFullPrompt(ctx: PromptContext): string {\n // Determine whether web search tools are available\n const modelId = ctx.modelId;\n const hasWebSearch = hasTavilyKey() || (!!modelId && modelId.startsWith('anthropic/'));\n\n // Collect per-tool deny rules so guidance omits denied tools\n const deniedTools = new Set<string>();\n const permRules = ctx.state?.permissionRules as { tools?: Record<string, string> } | undefined;\n if (permRules?.tools) {\n for (const [name, policy] of Object.entries(permRules.tools)) {\n if (policy === 'deny') deniedTools.add(name);\n }\n }\n\n // Build mode-aware tool guidance\n const toolGuidance = buildToolGuidance(ctx.modeId, { hasWebSearch, deniedTools });\n\n // Map new context to base context\n const baseCtx: BasePromptContext = {\n projectPath: ctx.workingDir,\n projectName: ctx.projectName || 'unknown',\n gitBranch: ctx.gitBranch,\n platform: process.platform,\n commonBinaries: ctx.commonBinaries,\n date: ctx.currentDate,\n mode: ctx.modeId,\n modelId: ctx.modelId,\n activePlan: ctx.state?.activePlan,\n toolGuidance,\n };\n\n const base = buildBasePrompt(baseCtx);\n const entry = modePrompts[ctx.modeId] || modePrompts.build;\n const modeSpecific = (typeof entry === 'function' ? entry(ctx) : entry) ?? '';\n const modelSpecific = ctx.modelId\n ? (modelSpecificPrompts[ctx.modelId as keyof typeof modelSpecificPrompts] ?? '')\n : '';\n\n // The current task list is carried on the agent state-signal lane (see\n // TaskStateProcessor) rather than injected into the cached system prompt. This\n // keeps the prompt prefix stable across task updates (preserving prompt cache)\n // while still surviving observational-memory truncation.\n\n // Load and inject agent instructions from AGENTS.md/CLAUDE.md files\n const configDir = ctx.state?.configDir as string | undefined;\n const instructionSources = loadAgentInstructions(ctx.workingDir, configDir);\n const instructionsSection = formatAgentInstructions(instructionSources);\n\n const sections = [base, instructionsSection.trim(), modelSpecific.trim(), modeSpecific.trim()].filter(Boolean);\n\n return sections.join('\\n\\n');\n}\n"],"mappings":";;;;;;;;;;AA0BA,MAAM,cAAyE;CAC7E,OAAO;CACP,MAAM;CACN,MAAM;AACR;;;;;AAMA,SAAgB,gBAAgB,KAA4B;CAE1D,MAAM,UAAU,IAAI;CACpB,MAAM,eAAe,aAAa,KAAM,CAAC,CAAC,WAAW,QAAQ,WAAW,YAAY;CAGpF,MAAM,8BAAc,IAAI,IAAY;CACpC,MAAM,YAAY,IAAI,OAAO;CAC7B,IAAI,WAAW,OACR;OAAA,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,UAAU,KAAK,GACzD,IAAI,WAAW,QAAQ,YAAY,IAAI,IAAI;CAAA;CAK/C,MAAM,eAAe,kBAAkB,IAAI,QAAQ;EAAE;EAAc;CAAY,CAAC;CAgBhF,MAAM,OAAO,gBAAgB;EAZ3B,aAAa,IAAI;EACjB,aAAa,IAAI,eAAe;EAChC,WAAW,IAAI;EACf,UAAU,QAAQ;EAClB,gBAAgB,IAAI;EACpB,MAAM,IAAI;EACV,MAAM,IAAI;EACV,SAAS,IAAI;EACb,YAAY,IAAI,OAAO;EACvB;CAGiC,CAAC;CACpC,MAAM,QAAQ,YAAY,IAAI,WAAW,YAAY;CACrD,MAAM,gBAAgB,OAAO,UAAU,aAAa,MAAM,GAAG,IAAI,UAAU;CAC3E,MAAM,gBAAgB,IAAI,UACrB,qBAAqB,IAAI,YAAiD,KAC3E;CAQJ,MAAM,YAAY,IAAI,OAAO;CAM7B,OAFiB;EAAC;EAFU,wBADD,sBAAsB,IAAI,YAAY,SACI,CAE3B,CAAC,CAAC,KAAK;EAAG,cAAc,KAAK;EAAG,aAAa,KAAK;CAAC,CAAC,CAAC,OAAO,OAExF,CAAC,CAAC,KAAK,MAAM;AAC7B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/prompts/index.ts"],"sourcesContent":["/**\n * Prompt system — exports the prompt builder and mode-specific prompts.\n */\n\nexport { buildModePrompt, buildModePromptFn } from './build.js';\nexport { planModePrompt } from './plan.js';\nexport { fastModePrompt } from './fast.js';\n\nimport { buildBasePrompt } from '@mastra/core/coding-agent';\nimport type { PromptContext as BasePromptContext } from '@mastra/core/coding-agent';\nimport { hasTavilyKey } from '../../tools/index.js';\nimport { loadAgentInstructions, formatAgentInstructions, createGitRefInstructionReader } from './agent-instructions.js';\nimport { buildModePromptFn } from './build.js';\nimport { fastModePrompt } from './fast.js';\nimport { modelSpecificPrompts } from './model.js';\nimport { planModePrompt } from './plan.js';\nimport { buildToolGuidance } from './tool-guidance.js';\n\n// Extended prompt context that includes runtime information\nexport interface PromptContext extends Omit<BasePromptContext, 'toolGuidance'> {\n modeId: string;\n state?: any;\n currentDate: string;\n workingDir: string;\n}\n\nconst modePrompts: Record<string, string | ((ctx: PromptContext) => string)> = {\n build: buildModePromptFn,\n plan: planModePrompt,\n fast: fastModePrompt,\n};\n\n/**\n * Build the full system prompt for a given mode and context.\n * Combines the base prompt with mode-specific instructions.\n */\nexport function buildFullPrompt(ctx: PromptContext): string {\n // Determine whether web search tools are available\n const modelId = ctx.modelId;\n const hasWebSearch = hasTavilyKey() || (!!modelId && modelId.startsWith('anthropic/'));\n\n // Collect per-tool deny rules so guidance omits denied tools\n const deniedTools = new Set<string>();\n const permRules = ctx.state?.permissionRules as { tools?: Record<string, string> } | undefined;\n if (permRules?.tools) {\n for (const [name, policy] of Object.entries(permRules.tools)) {\n if (policy === 'deny') deniedTools.add(name);\n }\n }\n\n // Build mode-aware tool guidance\n const toolGuidance = buildToolGuidance(ctx.modeId, { hasWebSearch, deniedTools });\n\n // Map new context to base context\n const baseCtx: BasePromptContext = {\n projectPath: ctx.workingDir,\n projectName: ctx.projectName || 'unknown',\n gitBranch: ctx.gitBranch,\n platform: process.platform,\n commonBinaries: ctx.commonBinaries,\n date: ctx.currentDate,\n mode: ctx.modeId,\n modelId: ctx.modelId,\n activePlan: ctx.state?.activePlan,\n toolGuidance,\n };\n\n const base = buildBasePrompt(baseCtx);\n const entry = modePrompts[ctx.modeId] || modePrompts.build;\n const modeSpecific = (typeof entry === 'function' ? entry(ctx) : entry) ?? '';\n const modelSpecific = ctx.modelId\n ? (modelSpecificPrompts[ctx.modelId as keyof typeof modelSpecificPrompts] ?? '')\n : '';\n\n // The current task list is carried on the agent state-signal lane (see\n // TaskStateProcessor) rather than injected into the cached system prompt. This\n // keeps the prompt prefix stable across task updates (preserving prompt cache)\n // while still surviving observational-memory truncation.\n\n // Load and inject agent instructions from AGENTS.md/CLAUDE.md files.\n // Untrusted checkouts (e.g. a PR branch under review) never read\n // project-scope files off the working tree: their AGENTS.md is\n // attacker-writable and would otherwise land in the system prompt as\n // trusted configuration. When the session carries a trusted base ref, the\n // project instructions are served from that ref instead (`git show`);\n // without one, project-scope files are skipped entirely. Global (operator\n // machine) instructions always load.\n const configDir = ctx.state?.configDir as string | undefined;\n const untrustedCheckout = ctx.state?.untrustedCheckout === true;\n const baseRef = typeof ctx.state?.baseRef === 'string' ? ctx.state.baseRef : undefined;\n const projectReader = untrustedCheckout\n ? baseRef\n ? createGitRefInstructionReader(ctx.workingDir, baseRef)\n : { exists: () => false, read: () => '' }\n : undefined;\n const instructionSources = loadAgentInstructions(ctx.workingDir, configDir, projectReader);\n const instructionsSection = formatAgentInstructions(instructionSources);\n\n const sections = [base, instructionsSection.trim(), modelSpecific.trim(), modeSpecific.trim()].filter(Boolean);\n\n return sections.join('\\n\\n');\n}\n"],"mappings":";;;;;;;;;;AA0BA,MAAM,cAAyE;CAC7E,OAAO;CACP,MAAM;CACN,MAAM;AACR;;;;;AAMA,SAAgB,gBAAgB,KAA4B;CAE1D,MAAM,UAAU,IAAI;CACpB,MAAM,eAAe,aAAa,KAAM,CAAC,CAAC,WAAW,QAAQ,WAAW,YAAY;CAGpF,MAAM,8BAAc,IAAI,IAAY;CACpC,MAAM,YAAY,IAAI,OAAO;CAC7B,IAAI,WAAW,OACR;OAAA,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,UAAU,KAAK,GACzD,IAAI,WAAW,QAAQ,YAAY,IAAI,IAAI;CAAA;CAK/C,MAAM,eAAe,kBAAkB,IAAI,QAAQ;EAAE;EAAc;CAAY,CAAC;CAgBhF,MAAM,OAAO,gBAAgB;EAZ3B,aAAa,IAAI;EACjB,aAAa,IAAI,eAAe;EAChC,WAAW,IAAI;EACf,UAAU,QAAQ;EAClB,gBAAgB,IAAI;EACpB,MAAM,IAAI;EACV,MAAM,IAAI;EACV,SAAS,IAAI;EACb,YAAY,IAAI,OAAO;EACvB;CAGiC,CAAC;CACpC,MAAM,QAAQ,YAAY,IAAI,WAAW,YAAY;CACrD,MAAM,gBAAgB,OAAO,UAAU,aAAa,MAAM,GAAG,IAAI,UAAU;CAC3E,MAAM,gBAAgB,IAAI,UACrB,qBAAqB,IAAI,YAAiD,KAC3E;CAeJ,MAAM,YAAY,IAAI,OAAO;CAC7B,MAAM,oBAAoB,IAAI,OAAO,sBAAsB;CAC3D,MAAM,UAAU,OAAO,IAAI,OAAO,YAAY,WAAW,IAAI,MAAM,UAAU,KAAA;CAC7E,MAAM,gBAAgB,oBAClB,UACE,8BAA8B,IAAI,YAAY,OAAO,IACrD;EAAE,cAAc;EAAO,YAAY;CAAG,IACxC,KAAA;CAMJ,OAFiB;EAAC;EAFU,wBADD,sBAAsB,IAAI,YAAY,WAAW,aACP,CAE3B,CAAC,CAAC,KAAK;EAAG,cAAc,KAAK;EAAG,aAAa,KAAK;CAAC,CAAC,CAAC,OAAO,OAExF,CAAC,CAAC,KAAK,MAAM;AAC7B"}
@@ -16,7 +16,7 @@ import { dirname, join } from "path";
16
16
  */
17
17
  const PROVIDER_DEFAULT_MODELS = {
18
18
  anthropic: "anthropic/claude-fable-5",
19
- "openai-codex": "openai/gpt-5.6",
19
+ "openai-codex": "openai/gpt-5.6-sol",
20
20
  "github-copilot": "github-copilot/gpt-4.1",
21
21
  xai: "xai/grok-4.5"
22
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","names":[],"sources":["../../src/auth/storage.ts"],"sourcesContent":["/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppDataDir } from '../utils/project.js';\nimport { anthropicOAuthProvider } from './providers/anthropic.js';\nimport { githubCopilotOAuthProvider } from './providers/github-copilot.js';\nimport { openaiCodexOAuthProvider } from './providers/openai-codex.js';\nimport { xaiOAuthProvider } from './providers/xai.js';\nimport type {\n AuthCredential,\n AuthStorageData,\n OAuthLoginCallbacks,\n OAuthProviderId,\n OAuthProviderInterface,\n} from './types.js';\n\n/**\n * Best/default models for each OAuth provider.\n * Used when auto-selecting a model after login.\n */\nexport const PROVIDER_DEFAULT_MODELS: Record<OAuthProviderId, string> = {\n anthropic: 'anthropic/claude-fable-5',\n 'openai-codex': 'openai/gpt-5.6',\n // gpt-4.1 routes through `/chat/completions` (which our OpenAI-compatible\n // adapter handles); Anthropic-shaped Copilot models (Claude on `/v1/messages`)\n // are not yet wired up, so picking one as the post-login default would error.\n 'github-copilot': 'github-copilot/gpt-4.1',\n xai: 'xai/grok-4.5',\n};\n\n// Provider registry\nconst oauthProviderRegistry = new Map<string, OAuthProviderInterface>([\n [anthropicOAuthProvider.id, anthropicOAuthProvider],\n [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider],\n [githubCopilotOAuthProvider.id, githubCopilotOAuthProvider],\n [xaiOAuthProvider.id, xaiOAuthProvider],\n]);\n\n/**\n * Get an OAuth provider by ID\n */\nexport function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined {\n return oauthProviderRegistry.get(id);\n}\n\n/**\n * Get all registered OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInterface[] {\n return Array.from(oauthProviderRegistry.values());\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n private data: AuthStorageData = {};\n\n constructor(private authPath: string = join(getAppDataDir(), 'auth.json')) {\n this.reload();\n }\n\n /**\n * Reload credentials from disk.\n */\n reload(): void {\n if (!existsSync(this.authPath)) {\n this.data = {};\n return;\n }\n try {\n this.data = JSON.parse(readFileSync(this.authPath, 'utf-8'));\n } catch {\n this.data = {};\n }\n }\n\n /**\n * Save credentials to disk.\n */\n private save(): void {\n const dir = dirname(this.authPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), 'utf-8');\n chmodSync(this.authPath, 0o600);\n }\n\n /**\n * Get credential for a provider.\n */\n get(provider: string): AuthCredential | undefined {\n return this.data[provider] ?? undefined;\n }\n\n /**\n * Set credential for a provider.\n */\n set(provider: string, credential: AuthCredential): void {\n this.data[provider] = credential;\n this.save();\n }\n\n /**\n * Remove credential for a provider.\n */\n remove(provider: string): void {\n delete this.data[provider];\n this.save();\n }\n\n /**\n * List all providers with credentials.\n */\n list(): string[] {\n return Object.keys(this.data);\n }\n\n /**\n * Check if credentials exist for a provider.\n */\n has(provider: string): boolean {\n return provider in this.data;\n }\n\n /**\n * Check if logged in via OAuth for a provider.\n */\n isLoggedIn(provider: string): boolean {\n const cred = this.data[provider];\n return cred?.type === 'oauth';\n }\n\n /**\n * Check if a stored API key exists for a provider.\n * Keys are stored under `apikey:<provider>` in auth.json.\n */\n hasStoredApiKey(provider: string): boolean {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0;\n }\n\n /**\n * Get a stored API key for a provider, if any.\n */\n getStoredApiKey(provider: string): string | undefined {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0 ? cred.key : undefined;\n }\n\n /**\n * Store an API key for a provider.\n * Also sets the corresponding environment variable so model resolution can find it.\n */\n setStoredApiKey(provider: string, key: string, envVar?: string): void {\n this.set(`apikey:${provider}`, { type: 'api_key', key });\n if (envVar) {\n process.env[envVar] = key;\n }\n }\n\n /**\n * Load all stored API keys into process.env.\n * Called at startup so model resolution can find stored keys.\n * Only sets env vars that aren't already set (env vars take precedence).\n */\n loadStoredApiKeysIntoEnv(providerEnvVars: Record<string, string | undefined>): void {\n for (const [key, cred] of Object.entries(this.data)) {\n if (!key.startsWith('apikey:') || cred.type !== 'api_key' || !cred.key) continue;\n const provider = key.substring('apikey:'.length);\n const envVar = providerEnvVars[provider];\n if (envVar && !process.env[envVar]) {\n process.env[envVar] = cred.key;\n }\n }\n }\n\n /**\n * Login to an OAuth provider.\n */\n async login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n throw new Error(`Unknown OAuth provider: ${providerId}`);\n }\n\n const credentials = await provider.login(callbacks);\n this.set(providerId, { type: 'oauth', ...credentials });\n }\n\n /**\n * Logout from a provider.\n */\n logout(provider: string): void {\n this.remove(provider);\n }\n\n /**\n * Get API key for a provider, auto-refreshing OAuth tokens if needed.\n */\n async getApiKey(providerId: string): Promise<string | undefined> {\n const cred = this.data[providerId];\n\n if (cred?.type === 'api_key') {\n return cred.key;\n }\n\n if (cred?.type === 'oauth') {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n return undefined;\n }\n\n // Check if token needs refresh\n if (Date.now() >= cred.expires) {\n try {\n const newCreds = await provider.refreshToken(cred);\n this.set(providerId, { type: 'oauth', ...newCreds });\n return provider.getApiKey(newCreds);\n } catch {\n // Refresh failed - user needs to re-login\n return undefined;\n }\n }\n\n return provider.getApiKey(cred);\n }\n\n return undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","names":[],"sources":["../../src/auth/storage.ts"],"sourcesContent":["/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppDataDir } from '../utils/project.js';\nimport { anthropicOAuthProvider } from './providers/anthropic.js';\nimport { githubCopilotOAuthProvider } from './providers/github-copilot.js';\nimport { openaiCodexOAuthProvider } from './providers/openai-codex.js';\nimport { xaiOAuthProvider } from './providers/xai.js';\nimport type {\n AuthCredential,\n AuthStorageData,\n OAuthLoginCallbacks,\n OAuthProviderId,\n OAuthProviderInterface,\n} from './types.js';\n\n/**\n * Best/default models for each OAuth provider.\n * Used when auto-selecting a model after login.\n */\nexport const PROVIDER_DEFAULT_MODELS: Record<OAuthProviderId, string> = {\n anthropic: 'anthropic/claude-fable-5',\n 'openai-codex': 'openai/gpt-5.6-sol',\n // gpt-4.1 routes through `/chat/completions` (which our OpenAI-compatible\n // adapter handles); Anthropic-shaped Copilot models (Claude on `/v1/messages`)\n // are not yet wired up, so picking one as the post-login default would error.\n 'github-copilot': 'github-copilot/gpt-4.1',\n xai: 'xai/grok-4.5',\n};\n\n// Provider registry\nconst oauthProviderRegistry = new Map<string, OAuthProviderInterface>([\n [anthropicOAuthProvider.id, anthropicOAuthProvider],\n [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider],\n [githubCopilotOAuthProvider.id, githubCopilotOAuthProvider],\n [xaiOAuthProvider.id, xaiOAuthProvider],\n]);\n\n/**\n * Get an OAuth provider by ID\n */\nexport function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined {\n return oauthProviderRegistry.get(id);\n}\n\n/**\n * Get all registered OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInterface[] {\n return Array.from(oauthProviderRegistry.values());\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n private data: AuthStorageData = {};\n\n constructor(private authPath: string = join(getAppDataDir(), 'auth.json')) {\n this.reload();\n }\n\n /**\n * Reload credentials from disk.\n */\n reload(): void {\n if (!existsSync(this.authPath)) {\n this.data = {};\n return;\n }\n try {\n this.data = JSON.parse(readFileSync(this.authPath, 'utf-8'));\n } catch {\n this.data = {};\n }\n }\n\n /**\n * Save credentials to disk.\n */\n private save(): void {\n const dir = dirname(this.authPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), 'utf-8');\n chmodSync(this.authPath, 0o600);\n }\n\n /**\n * Get credential for a provider.\n */\n get(provider: string): AuthCredential | undefined {\n return this.data[provider] ?? undefined;\n }\n\n /**\n * Set credential for a provider.\n */\n set(provider: string, credential: AuthCredential): void {\n this.data[provider] = credential;\n this.save();\n }\n\n /**\n * Remove credential for a provider.\n */\n remove(provider: string): void {\n delete this.data[provider];\n this.save();\n }\n\n /**\n * List all providers with credentials.\n */\n list(): string[] {\n return Object.keys(this.data);\n }\n\n /**\n * Check if credentials exist for a provider.\n */\n has(provider: string): boolean {\n return provider in this.data;\n }\n\n /**\n * Check if logged in via OAuth for a provider.\n */\n isLoggedIn(provider: string): boolean {\n const cred = this.data[provider];\n return cred?.type === 'oauth';\n }\n\n /**\n * Check if a stored API key exists for a provider.\n * Keys are stored under `apikey:<provider>` in auth.json.\n */\n hasStoredApiKey(provider: string): boolean {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0;\n }\n\n /**\n * Get a stored API key for a provider, if any.\n */\n getStoredApiKey(provider: string): string | undefined {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0 ? cred.key : undefined;\n }\n\n /**\n * Store an API key for a provider.\n * Also sets the corresponding environment variable so model resolution can find it.\n */\n setStoredApiKey(provider: string, key: string, envVar?: string): void {\n this.set(`apikey:${provider}`, { type: 'api_key', key });\n if (envVar) {\n process.env[envVar] = key;\n }\n }\n\n /**\n * Load all stored API keys into process.env.\n * Called at startup so model resolution can find stored keys.\n * Only sets env vars that aren't already set (env vars take precedence).\n */\n loadStoredApiKeysIntoEnv(providerEnvVars: Record<string, string | undefined>): void {\n for (const [key, cred] of Object.entries(this.data)) {\n if (!key.startsWith('apikey:') || cred.type !== 'api_key' || !cred.key) continue;\n const provider = key.substring('apikey:'.length);\n const envVar = providerEnvVars[provider];\n if (envVar && !process.env[envVar]) {\n process.env[envVar] = cred.key;\n }\n }\n }\n\n /**\n * Login to an OAuth provider.\n */\n async login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n throw new Error(`Unknown OAuth provider: ${providerId}`);\n }\n\n const credentials = await provider.login(callbacks);\n this.set(providerId, { type: 'oauth', ...credentials });\n }\n\n /**\n * Logout from a provider.\n */\n logout(provider: string): void {\n this.remove(provider);\n }\n\n /**\n * Get API key for a provider, auto-refreshing OAuth tokens if needed.\n */\n async getApiKey(providerId: string): Promise<string | undefined> {\n const cred = this.data[providerId];\n\n if (cred?.type === 'api_key') {\n return cred.key;\n }\n\n if (cred?.type === 'oauth') {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n return undefined;\n }\n\n // Check if token needs refresh\n if (Date.now() >= cred.expires) {\n try {\n const newCreds = await provider.refreshToken(cred);\n this.set(providerId, { type: 'oauth', ...newCreds });\n return provider.getApiKey(newCreds);\n } catch {\n // Refresh failed - user needs to re-login\n return undefined;\n }\n }\n\n return provider.getApiKey(cred);\n }\n\n return undefined;\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
@@ -5,7 +5,7 @@ import { setAuthStorage } from "./providers/openai-codex.js";
5
5
  import { MASTRA_GATEWAY_PROVIDER, OBSERVABILITY_AUTH_PREFIX, loadSettings, resolveModelDefaults, resolveOmRoleModel, saveSettings } from "./onboarding/settings.js";
6
6
  import { hasCredentialStoreProvider } from "./agents/credential-resolver.js";
7
7
  import { getDynamicWorkspace, getGoalJudgeTools } from "./agents/workspace.js";
8
- import { getStaticallyLoadedInstructionPaths } from "./agents/prompts/agent-instructions.js";
8
+ import { createGitRefInstructionReader, createGitRefReminderReader, getStaticallyLoadedInstructionPaths } from "./agents/prompts/agent-instructions.js";
9
9
  import { getDynamicInstructions } from "./agents/instructions.js";
10
10
  import { createAmazonBedrockGateway } from "./providers/amazon-bedrock-gateway.js";
11
11
  import { setAuthStorage as setAuthStorage$1 } from "./providers/claude-max.js";
@@ -77,6 +77,13 @@ const TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN = /internal server|server error|api
77
77
  * by `StreamErrorRetryProcessor.isRetryableStreamError`, which calls each
78
78
  * matcher at every level of the cause chain.
79
79
  */
80
+ /**
81
+ * Read the session state fields the AgentsMDInjector callbacks need from the
82
+ * controller request context (set by hosts like the factory review flow).
83
+ */
84
+ function getInjectorSessionState(requestContext) {
85
+ return (requestContext?.get("controller"))?.getState();
86
+ }
80
87
  function isTransientConnectionError(error) {
81
88
  if (!error) return false;
82
89
  const code = typeof error === "object" && "code" in error ? error.code : void 0;
@@ -393,10 +400,22 @@ async function createMastraCodeAgentController(config) {
393
400
  inputProcessors: [
394
401
  ...config?.inputProcessors ?? [],
395
402
  new PlanRejectionAbortProcessor(),
396
- new AgentsMDInjector({ getIgnoredInstructionPaths: ({ requestContext }) => {
397
- const state = (requestContext?.get("controller"))?.getState();
398
- return getStaticallyLoadedInstructionPaths(state?.projectPath ?? project.rootPath);
399
- } }),
403
+ new AgentsMDInjector({
404
+ isEnabled: ({ requestContext }) => {
405
+ const state = getInjectorSessionState(requestContext);
406
+ return state?.untrustedCheckout !== true || typeof state?.baseRef === "string";
407
+ },
408
+ getReader: ({ requestContext }) => {
409
+ const state = getInjectorSessionState(requestContext);
410
+ if (state?.untrustedCheckout !== true || typeof state?.baseRef !== "string") return void 0;
411
+ return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);
412
+ },
413
+ getIgnoredInstructionPaths: ({ requestContext }) => {
414
+ const state = getInjectorSessionState(requestContext);
415
+ const projectPath = state?.projectPath ?? project.rootPath;
416
+ return getStaticallyLoadedInstructionPaths(projectPath, void 0, state?.untrustedCheckout === true && typeof state?.baseRef === "string" ? createGitRefInstructionReader(projectPath, state.baseRef) : void 0);
417
+ }
418
+ }),
400
419
  new ProviderHistoryCompat()
401
420
  ],
402
421
  errorProcessors: [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"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 {\n AgentsMDInjector,\n isBadRequestError,\n PrefillErrorHandler,\n ProviderHistoryCompat,\n StreamErrorRetryProcessor,\n} from '@mastra/core/processors';\nimport type { InputProcessor } 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 { getStaticallyLoadedInstructionPaths } 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 { 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 { 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 { 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 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';\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 */\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 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 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 ? undefined : createMcpManager(project.rootPath, configDir, config?.mcpServers);\n\n // Hooks\n const hookManager = config?.disableHooks\n ? undefined\n : new HookManager(project.rootPath, 'session-init', configDir, homeDir);\n\n const pluginManager = config?.disablePlugins\n ? undefined\n : (config?.pluginManager ?? new PluginManager({ projectRoot: project.rootPath, configDir, homeDir }));\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 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: async ({ resourceId, threadId }) => {\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 // 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: controller.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 : undefined;\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 model: getDynamicModel,\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: [new 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 ...(config?.inputProcessors ?? []),\n new PlanRejectionAbortProcessor(),\n new AgentsMDInjector({\n getIgnoredInstructionPaths: ({ requestContext }) => {\n const agentControllerContext = requestContext?.get('controller') as\n | AgentControllerRequestContext<{ projectPath?: string }>\n | undefined;\n const state = agentControllerContext?.getState();\n return getStaticallyLoadedInstructionPaths(state?.projectPath ?? project.rootPath);\n },\n }),\n new ProviderHistoryCompat(),\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 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 };\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 globalInitialState.thinkingLevel = globalSettings.preferences.thinkingLevel;\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 // 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 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 // 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}\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 } = base;\n\n await controller.init();\n await controller.getMastra()?.startWorkers();\n const session = await controller.createSession({ id: sessionId, ownerId });\n await wireSessionConcerns(base, session);\n\n return { ...base, session };\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 } = base;\n const controllerId = config?.controllerId ?? controller.id;\n const apiRoutes = config?.buildApiRoutes?.({ controller, authStorage });\n const extraServerConfig = config?.buildServerConfig?.({ controller, authStorage });\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 await controller.getMastra()?.startWorkers();\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;\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":[],"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 {\n AgentsMDInjector,\n isBadRequestError,\n PrefillErrorHandler,\n ProviderHistoryCompat,\n StreamErrorRetryProcessor,\n} from '@mastra/core/processors';\nimport type { InputProcessor } 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 { 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 { 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 { 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 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';\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 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 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 ? undefined : createMcpManager(project.rootPath, configDir, config?.mcpServers);\n\n // Hooks\n const hookManager = config?.disableHooks\n ? undefined\n : new HookManager(project.rootPath, 'session-init', configDir, homeDir);\n\n const pluginManager = config?.disablePlugins\n ? undefined\n : (config?.pluginManager ?? new PluginManager({ projectRoot: project.rootPath, configDir, homeDir }));\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 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: async ({ resourceId, threadId }) => {\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 // 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: controller.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 : undefined;\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 model: getDynamicModel,\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: [new 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 ...(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 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 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 };\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 globalInitialState.thinkingLevel = globalSettings.preferences.thinkingLevel;\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 // 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 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 // 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}\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 } = base;\n\n await controller.init();\n await controller.getMastra()?.startWorkers();\n const session = await controller.createSession({ id: sessionId, ownerId });\n await wireSessionConcerns(base, session);\n\n return { ...base, session };\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 } = base;\n const controllerId = config?.controllerId ?? controller.id;\n const apiRoutes = config?.buildApiRoutes?.({ controller, authStorage });\n const extraServerConfig = config?.buildServerConfig?.({ controller, authStorage });\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 await controller.getMastra()?.startWorkers();\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;\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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"}
@@ -15,7 +15,7 @@ import { DEFAULT_OM_MODEL_ID } from "../constants.js";
15
15
  */
16
16
  function getAvailableModePacks(access, savedCustomPacks = []) {
17
17
  const packs = [];
18
- const openaiCodex = "openai/gpt-5.6";
18
+ const openaiCodex = "openai/gpt-5.6-sol";
19
19
  const openaiFast = "openai/gpt-5.4-mini";
20
20
  const anthropicBuild = "anthropic/claude-fable-5";
21
21
  if (access.anthropic) packs.push({
@@ -1 +1 @@
1
- {"version":3,"file":"packs.js","names":[],"sources":["../../src/onboarding/packs.ts"],"sourcesContent":["/**\n * Onboarding \"packs\" — predefined model configurations for each mode.\n *\n * Each pack assigns a default model to the build, plan, and fast modes,\n * plus an OM (observational memory) model.\n */\nimport { DEFAULT_OM_MODEL_ID } from '../constants.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ModePack {\n id: string;\n name: string;\n description: string;\n models: {\n build: string;\n plan: string;\n fast: string;\n };\n}\n\nexport interface OMPack {\n id: string;\n name: string;\n description: string;\n modelId: string;\n}\n\ninterface BuiltinOMPack {\n id: string;\n providerId: string;\n name: string;\n modelId: string;\n description: (access: Exclude<ProviderAccessLevel, false>) => string;\n}\n\n/** How a provider is accessed: OAuth subscription, API key, or not at all. */\nexport type ProviderAccessLevel = 'oauth' | 'apikey' | false;\n\n/** Which providers the user has access to and how. */\nexport interface ProviderAccess {\n anthropic: ProviderAccessLevel;\n openai: ProviderAccessLevel;\n cerebras: ProviderAccessLevel;\n google: ProviderAccessLevel;\n deepseek: ProviderAccessLevel;\n 'github-copilot': ProviderAccessLevel;\n [provider: string]: ProviderAccessLevel;\n}\n\n// ---------------------------------------------------------------------------\n// Mode Packs\n// ---------------------------------------------------------------------------\n\n/**\n * Build the list of available mode packs based on which providers the user\n * can actually reach (API key or OAuth login).\n *\n * @param savedCustomPacks Previously saved custom packs from settings.json.\n * These are inserted before the \"New Custom\" option.\n */\nexport function getAvailableModePacks(\n access: ProviderAccess,\n savedCustomPacks: Array<{ name: string; models: Record<string, string> }> = [],\n): ModePack[] {\n const packs: ModePack[] = [];\n\n const openaiCodex = 'openai/gpt-5.6';\n const openaiFast = 'openai/gpt-5.4-mini';\n const anthropicBuild = 'anthropic/claude-fable-5';\n\n if (access.anthropic) {\n packs.push({\n id: 'anthropic',\n name: 'Anthropic',\n description:\n access.anthropic === 'oauth' ? 'All Anthropic models via Max subscription' : 'All Anthropic models via API key',\n models: {\n build: anthropicBuild,\n plan: anthropicBuild,\n fast: 'anthropic/claude-haiku-4-5',\n },\n });\n }\n\n if (access.openai) {\n packs.push({\n id: 'openai',\n name: 'OpenAI',\n description:\n access.openai === 'oauth' ? 'All OpenAI models via Codex subscription' : 'All OpenAI models via API key',\n models: {\n build: openaiCodex,\n plan: openaiCodex,\n fast: openaiFast,\n },\n });\n }\n\n if (access['github-copilot']) {\n packs.push({\n id: 'github-copilot',\n name: 'GitHub Copilot',\n description: 'GitHub Copilot subscription',\n models: {\n build: 'github-copilot/gpt-4.1',\n plan: 'github-copilot/gemini-2.5-pro',\n fast: 'github-copilot/grok-code-fast-1',\n },\n });\n }\n\n // Saved custom packs — inserted before the \"New Custom\" option\n for (const cp of savedCustomPacks) {\n packs.push({\n id: `custom:${cp.name}`,\n name: cp.name,\n description: 'Saved custom pack',\n models: {\n build: cp.models.build ?? '',\n plan: cp.models.plan ?? '',\n fast: cp.models.fast ?? '',\n },\n });\n }\n\n // New Custom — always available; user picks each model individually\n const hasCustom = savedCustomPacks.length > 0;\n packs.push({\n id: 'custom',\n name: hasCustom ? 'New Custom' : 'Custom',\n description: 'Choose a model for each mode',\n models: { build: '', plan: '', fast: '' },\n });\n\n return packs;\n}\n\n// ---------------------------------------------------------------------------\n// OM Packs\n// ---------------------------------------------------------------------------\n\nconst BUILTIN_OM_PACKS: BuiltinOMPack[] = [\n {\n id: 'gemini',\n providerId: 'google',\n name: 'Gemini Flash',\n modelId: 'google/gemini-3.5-flash',\n description: access => (access === 'oauth' ? 'Via Google OAuth' : 'Via Google API key'),\n },\n {\n id: 'anthropic',\n providerId: 'anthropic',\n name: 'Claude Haiku',\n modelId: 'anthropic/claude-haiku-4-5',\n description: access => (access === 'oauth' ? 'Via Max subscription' : 'Via Anthropic API key'),\n },\n {\n id: 'openai',\n providerId: 'openai',\n name: 'OpenAI Mini',\n modelId: 'openai/gpt-5.4-mini',\n description: access => (access === 'oauth' ? 'Via Codex subscription' : 'Via OpenAI API key'),\n },\n {\n id: 'deepseek',\n providerId: 'deepseek',\n name: 'DeepSeek',\n modelId: 'deepseek/deepseek-v4-flash',\n description: () => 'Via DeepSeek API key',\n },\n];\n\nfunction normalizeOMProviderId(providerId: string): string {\n return providerId === 'openai-codex' ? 'openai' : providerId;\n}\n\n/** A provider's low-cost OM pack, or a custom pack on `fallbackModelId` when it has none. */\nexport function resolveProviderOMDefault(providerId: string, fallbackModelId = DEFAULT_OM_MODEL_ID): OMPack {\n const normalizedProviderId = normalizeOMProviderId(providerId);\n const builtin = BUILTIN_OM_PACKS.find(pack => pack.providerId === normalizedProviderId);\n if (builtin) {\n return {\n id: builtin.id,\n name: builtin.name,\n description: builtin.description('apikey'),\n modelId: builtin.modelId,\n };\n }\n\n return {\n id: 'custom',\n name: 'Custom',\n description: 'Uses the selected provider model',\n modelId: fallbackModelId || DEFAULT_OM_MODEL_ID,\n };\n}\n\nexport function getAvailableOmPacks(access: ProviderAccess): OMPack[] {\n const packs = BUILTIN_OM_PACKS.flatMap(pack => {\n const providerAccess = access[pack.providerId];\n if (!providerAccess) return [];\n return [\n {\n id: pack.id,\n name: pack.name,\n description: pack.description(providerAccess),\n modelId: pack.modelId,\n },\n ];\n });\n\n // Custom — always available; user picks any model\n packs.push({\n id: 'custom',\n name: 'Custom',\n description: 'Choose any available model',\n modelId: '',\n });\n\n return packs;\n}\n\n/** Best reachable built-in OM pack: preferred provider, then OAuth, then built-in order. */\nexport function selectPreferredOMPack(access: ProviderAccess, preferredProviderId?: string): OMPack | undefined {\n const available = getAvailableOmPacks(access).filter(pack => pack.id !== 'custom');\n\n if (preferredProviderId) {\n const preferredPackId = resolveProviderOMDefault(preferredProviderId).id;\n const preferred = available.find(pack => pack.id === preferredPackId);\n if (preferred) return preferred;\n }\n\n const oauth = available.find(pack => {\n const definition = BUILTIN_OM_PACKS.find(candidate => candidate.id === pack.id);\n return definition ? access[definition.providerId] === 'oauth' : false;\n });\n return oauth ?? available[0];\n}\n\n// ---------------------------------------------------------------------------\n// Current onboarding version — bump when adding new steps\n// ---------------------------------------------------------------------------\n\nexport const ONBOARDING_VERSION = 1;\n"],"mappings":"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"}
1
+ {"version":3,"file":"packs.js","names":[],"sources":["../../src/onboarding/packs.ts"],"sourcesContent":["/**\n * Onboarding \"packs\" — predefined model configurations for each mode.\n *\n * Each pack assigns a default model to the build, plan, and fast modes,\n * plus an OM (observational memory) model.\n */\nimport { DEFAULT_OM_MODEL_ID } from '../constants.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ModePack {\n id: string;\n name: string;\n description: string;\n models: {\n build: string;\n plan: string;\n fast: string;\n };\n}\n\nexport interface OMPack {\n id: string;\n name: string;\n description: string;\n modelId: string;\n}\n\ninterface BuiltinOMPack {\n id: string;\n providerId: string;\n name: string;\n modelId: string;\n description: (access: Exclude<ProviderAccessLevel, false>) => string;\n}\n\n/** How a provider is accessed: OAuth subscription, API key, or not at all. */\nexport type ProviderAccessLevel = 'oauth' | 'apikey' | false;\n\n/** Which providers the user has access to and how. */\nexport interface ProviderAccess {\n anthropic: ProviderAccessLevel;\n openai: ProviderAccessLevel;\n cerebras: ProviderAccessLevel;\n google: ProviderAccessLevel;\n deepseek: ProviderAccessLevel;\n 'github-copilot': ProviderAccessLevel;\n [provider: string]: ProviderAccessLevel;\n}\n\n// ---------------------------------------------------------------------------\n// Mode Packs\n// ---------------------------------------------------------------------------\n\n/**\n * Build the list of available mode packs based on which providers the user\n * can actually reach (API key or OAuth login).\n *\n * @param savedCustomPacks Previously saved custom packs from settings.json.\n * These are inserted before the \"New Custom\" option.\n */\nexport function getAvailableModePacks(\n access: ProviderAccess,\n savedCustomPacks: Array<{ name: string; models: Record<string, string> }> = [],\n): ModePack[] {\n const packs: ModePack[] = [];\n\n const openaiCodex = 'openai/gpt-5.6-sol';\n const openaiFast = 'openai/gpt-5.4-mini';\n const anthropicBuild = 'anthropic/claude-fable-5';\n\n if (access.anthropic) {\n packs.push({\n id: 'anthropic',\n name: 'Anthropic',\n description:\n access.anthropic === 'oauth' ? 'All Anthropic models via Max subscription' : 'All Anthropic models via API key',\n models: {\n build: anthropicBuild,\n plan: anthropicBuild,\n fast: 'anthropic/claude-haiku-4-5',\n },\n });\n }\n\n if (access.openai) {\n packs.push({\n id: 'openai',\n name: 'OpenAI',\n description:\n access.openai === 'oauth' ? 'All OpenAI models via Codex subscription' : 'All OpenAI models via API key',\n models: {\n build: openaiCodex,\n plan: openaiCodex,\n fast: openaiFast,\n },\n });\n }\n\n if (access['github-copilot']) {\n packs.push({\n id: 'github-copilot',\n name: 'GitHub Copilot',\n description: 'GitHub Copilot subscription',\n models: {\n build: 'github-copilot/gpt-4.1',\n plan: 'github-copilot/gemini-2.5-pro',\n fast: 'github-copilot/grok-code-fast-1',\n },\n });\n }\n\n // Saved custom packs — inserted before the \"New Custom\" option\n for (const cp of savedCustomPacks) {\n packs.push({\n id: `custom:${cp.name}`,\n name: cp.name,\n description: 'Saved custom pack',\n models: {\n build: cp.models.build ?? '',\n plan: cp.models.plan ?? '',\n fast: cp.models.fast ?? '',\n },\n });\n }\n\n // New Custom — always available; user picks each model individually\n const hasCustom = savedCustomPacks.length > 0;\n packs.push({\n id: 'custom',\n name: hasCustom ? 'New Custom' : 'Custom',\n description: 'Choose a model for each mode',\n models: { build: '', plan: '', fast: '' },\n });\n\n return packs;\n}\n\n// ---------------------------------------------------------------------------\n// OM Packs\n// ---------------------------------------------------------------------------\n\nconst BUILTIN_OM_PACKS: BuiltinOMPack[] = [\n {\n id: 'gemini',\n providerId: 'google',\n name: 'Gemini Flash',\n modelId: 'google/gemini-3.5-flash',\n description: access => (access === 'oauth' ? 'Via Google OAuth' : 'Via Google API key'),\n },\n {\n id: 'anthropic',\n providerId: 'anthropic',\n name: 'Claude Haiku',\n modelId: 'anthropic/claude-haiku-4-5',\n description: access => (access === 'oauth' ? 'Via Max subscription' : 'Via Anthropic API key'),\n },\n {\n id: 'openai',\n providerId: 'openai',\n name: 'OpenAI Mini',\n modelId: 'openai/gpt-5.4-mini',\n description: access => (access === 'oauth' ? 'Via Codex subscription' : 'Via OpenAI API key'),\n },\n {\n id: 'deepseek',\n providerId: 'deepseek',\n name: 'DeepSeek',\n modelId: 'deepseek/deepseek-v4-flash',\n description: () => 'Via DeepSeek API key',\n },\n];\n\nfunction normalizeOMProviderId(providerId: string): string {\n return providerId === 'openai-codex' ? 'openai' : providerId;\n}\n\n/** A provider's low-cost OM pack, or a custom pack on `fallbackModelId` when it has none. */\nexport function resolveProviderOMDefault(providerId: string, fallbackModelId = DEFAULT_OM_MODEL_ID): OMPack {\n const normalizedProviderId = normalizeOMProviderId(providerId);\n const builtin = BUILTIN_OM_PACKS.find(pack => pack.providerId === normalizedProviderId);\n if (builtin) {\n return {\n id: builtin.id,\n name: builtin.name,\n description: builtin.description('apikey'),\n modelId: builtin.modelId,\n };\n }\n\n return {\n id: 'custom',\n name: 'Custom',\n description: 'Uses the selected provider model',\n modelId: fallbackModelId || DEFAULT_OM_MODEL_ID,\n };\n}\n\nexport function getAvailableOmPacks(access: ProviderAccess): OMPack[] {\n const packs = BUILTIN_OM_PACKS.flatMap(pack => {\n const providerAccess = access[pack.providerId];\n if (!providerAccess) return [];\n return [\n {\n id: pack.id,\n name: pack.name,\n description: pack.description(providerAccess),\n modelId: pack.modelId,\n },\n ];\n });\n\n // Custom — always available; user picks any model\n packs.push({\n id: 'custom',\n name: 'Custom',\n description: 'Choose any available model',\n modelId: '',\n });\n\n return packs;\n}\n\n/** Best reachable built-in OM pack: preferred provider, then OAuth, then built-in order. */\nexport function selectPreferredOMPack(access: ProviderAccess, preferredProviderId?: string): OMPack | undefined {\n const available = getAvailableOmPacks(access).filter(pack => pack.id !== 'custom');\n\n if (preferredProviderId) {\n const preferredPackId = resolveProviderOMDefault(preferredProviderId).id;\n const preferred = available.find(pack => pack.id === preferredPackId);\n if (preferred) return preferred;\n }\n\n const oauth = available.find(pack => {\n const definition = BUILTIN_OM_PACKS.find(candidate => candidate.id === pack.id);\n return definition ? access[definition.providerId] === 'oauth' : false;\n });\n return oauth ?? available[0];\n}\n\n// ---------------------------------------------------------------------------\n// Current onboarding version — bump when adding new steps\n// ---------------------------------------------------------------------------\n\nexport const ONBOARDING_VERSION = 1;\n"],"mappings":"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"}
package/dist/schema.d.ts CHANGED
@@ -23,6 +23,19 @@ export interface MastraCodeState {
23
23
  worktreePath?: string;
24
24
  /** Active feature branch checked out in the worktree. */
25
25
  branch?: string;
26
+ /**
27
+ * The session's checkout contains third-party content (e.g. a PR branch
28
+ * under review). Project-level instruction files (AGENTS.md, CLAUDE.md)
29
+ * are attacker-writable there and must not be ingested into the system
30
+ * prompt or injected as reminders.
31
+ */
32
+ untrustedCheckout?: boolean;
33
+ /**
34
+ * Trusted git ref (typically the PR's base branch) to serve project
35
+ * instruction files from when the checkout is untrusted. Without it,
36
+ * project-scope instruction files are skipped entirely.
37
+ */
38
+ baseRef?: string;
26
39
  configDir: string;
27
40
  homeDir?: string;
28
41
  gitBranch?: string;
@@ -85,6 +98,8 @@ export declare const stateSchema: z.ZodObject<{
85
98
  sandboxWorkdir: z.ZodOptional<z.ZodString>;
86
99
  worktreePath: z.ZodOptional<z.ZodString>;
87
100
  branch: z.ZodOptional<z.ZodString>;
101
+ untrustedCheckout: z.ZodOptional<z.ZodBoolean>;
102
+ baseRef: z.ZodOptional<z.ZodString>;
88
103
  configDir: z.ZodDefault<z.ZodString>;
89
104
  homeDir: z.ZodOptional<z.ZodString>;
90
105
  gitBranch: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -13,6 +13,8 @@ const stateSchema = z.object({
13
13
  sandboxWorkdir: z.string().optional(),
14
14
  worktreePath: z.string().optional(),
15
15
  branch: z.string().optional(),
16
+ untrustedCheckout: z.boolean().optional(),
17
+ baseRef: z.string().optional(),
16
18
  configDir: z.string().default(DEFAULT_CONFIG_DIR),
17
19
  homeDir: z.string().optional(),
18
20
  gitBranch: z.string().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { z } from 'zod';\nimport { DEFAULT_CONFIG_DIR, DEFAULT_OM_MODEL_ID } from './constants.js';\n\nexport type PermissionPolicy = 'allow' | 'ask' | 'deny';\n\nexport type MastraCodeSessionState = {\n currentModelId: string;\n modeId: string;\n};\n\nexport type MastraCodeComposedState = MastraCodeState & MastraCodeSessionState;\n\nexport interface MastraCodeState {\n [key: string]: unknown;\n [key: `subagentModelId_${string}`]: string | undefined;\n subagentModelId?: string;\n projectPath?: string;\n projectName?: string;\n /** Factory project that owns this session. */\n factoryProjectId?: string;\n /** Linked repository used by this session when source-control execution is required. */\n projectRepositoryId?: string;\n /** Persisted sandbox id for reattaching the project's cloud workspace. */\n sandboxId?: string;\n /** Path inside the sandbox the repo is cloned into. */\n sandboxWorkdir?: string;\n /** Active git worktree path inside the sandbox for the current unit of work. */\n worktreePath?: string;\n /** Active feature branch checked out in the worktree. */\n branch?: string;\n configDir: string;\n homeDir?: string;\n gitBranch?: string;\n lastCommand?: string;\n observerModelId: string;\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n cavemanObservations: boolean;\n observeAttachments: 'auto' | boolean;\n omScope?: 'thread' | 'resource';\n thinkingLevel: 'off' | 'low' | 'medium' | 'high' | 'xhigh';\n yolo: boolean;\n permissionRules: {\n categories: Record<string, PermissionPolicy>;\n tools: Record<string, PermissionPolicy>;\n };\n smartEditing: boolean;\n notifications: 'bell' | 'system' | 'both' | 'off';\n tasks: Array<{\n id?: string;\n content: string;\n status: 'pending' | 'in_progress' | 'completed';\n activeForm: string;\n }>;\n sandboxAllowedPaths: string[];\n pluginSkillPaths: string[];\n pluginCommandPaths: string[];\n pluginInstructions: string[];\n activePlan: {\n title: string;\n plan: string;\n approvedAt: string;\n } | null;\n activeBrowserSettings?: {\n enabled: boolean;\n provider: 'stagehand' | 'agent-browser';\n headless?: boolean;\n viewport?: {\n width: number;\n height: number;\n };\n cdpUrl?: string;\n stagehand?: {\n env: 'LOCAL' | 'BROWSERBASE';\n apiKey?: string;\n projectId?: string;\n };\n };\n}\n\nexport const stateSchema = z.object({\n // Session-scoped selection.\n // validates state against this schema, so they MUST be declared here — Zod\n // strips unknown keys on parse, which would otherwise silently discard the\n // seeded model and leave the controller with no model selected.\n currentModelId: z.string().optional(),\n modeId: z.string().optional(),\n subagentModelId: z.string().optional(),\n projectPath: z.string().optional(),\n projectName: z.string().optional(),\n factoryProjectId: z.string().optional(),\n projectRepositoryId: z.string().optional(),\n sandboxId: z.string().optional(),\n sandboxWorkdir: z.string().optional(),\n worktreePath: z.string().optional(),\n branch: z.string().optional(),\n configDir: z.string().default(DEFAULT_CONFIG_DIR),\n homeDir: z.string().optional(),\n gitBranch: z.string().optional(),\n lastCommand: z.string().optional(),\n // Observational Memory model settings\n observerModelId: z.string().default(DEFAULT_OM_MODEL_ID),\n reflectorModelId: z.string().default(DEFAULT_OM_MODEL_ID),\n // Observational Memory threshold settings\n observationThreshold: z.number().default(30_000),\n reflectionThreshold: z.number().default(40_000),\n // Whether observations and reflections use the terse caveman-style instruction.\n // Off by default — caveman style is opt-in via `/om` settings; observers and\n // reflectors fall back to their built-in (prose) behavior unless enabled.\n cavemanObservations: z.boolean().default(false),\n // Whether OM forwards image/file attachment parts to the Observer LLM.\n // 'auto' (default) checks the provider capabilities registry to decide.\n // true/false forces the setting regardless of model capabilities.\n observeAttachments: z.union([z.literal('auto'), z.boolean()]).default('auto'),\n // Observational Memory scope — 'thread' (per-conversation) or 'resource' (shared across threads)\n omScope: z.enum(['thread', 'resource']).optional(),\n // Thinking level for model reasoning effort\n thinkingLevel: z.enum(['off', 'low', 'medium', 'high', 'xhigh']).default('off'),\n // YOLO mode — auto-approve all tool calls\n yolo: z.boolean().default(false),\n // Permission rules — per-category and per-tool approval policies\n permissionRules: z\n .object({\n categories: z.record(z.string(), z.enum(['allow', 'ask', 'deny'])).default({}),\n tools: z.record(z.string(), z.enum(['allow', 'ask', 'deny'])).default({}),\n })\n .default({ categories: {}, tools: {} }),\n // Smart editing mode — use AST-based analysis for code edits\n smartEditing: z.boolean().default(true),\n // Notification mode — alert when TUI needs user attention\n notifications: z.enum(['bell', 'system', 'both', 'off']).default('off'),\n // Task list (ephemeral per-thread, cleared on thread switch/creation)\n tasks: z\n .array(\n z.object({\n id: z.string().optional(),\n content: z.string(),\n status: z.enum(['pending', 'in_progress', 'completed']),\n activeForm: z.string(),\n }),\n )\n .default([]),\n // Sandbox allowed paths (per-thread, absolute paths allowed in addition to project root)\n sandboxAllowedPaths: z.array(z.string()).default([]),\n // Asset directories contributed by active plugins.\n pluginSkillPaths: z.array(z.string()).default([]),\n pluginCommandPaths: z.array(z.string()).default([]),\n pluginInstructions: z.array(z.string()).default([]),\n // Active plan (set when a plan is approved in Plan mode)\n activePlan: z\n .object({\n title: z.string(),\n plan: z.string(),\n approvedAt: z.string(),\n })\n .nullable()\n .default(null),\n // Active browser settings (tracks what's actually running vs. what's in the settings file)\n activeBrowserSettings: z\n .object({\n enabled: z.boolean(),\n provider: z.enum(['stagehand', 'agent-browser']),\n headless: z.boolean().optional(),\n viewport: z\n .object({\n width: z.number(),\n height: z.number(),\n })\n .optional(),\n cdpUrl: z.string().optional(),\n stagehand: z\n .object({\n env: z.enum(['LOCAL', 'BROWSERBASE']),\n apiKey: z.string().optional(),\n projectId: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { z } from 'zod';\nimport { DEFAULT_CONFIG_DIR, DEFAULT_OM_MODEL_ID } from './constants.js';\n\nexport type PermissionPolicy = 'allow' | 'ask' | 'deny';\n\nexport type MastraCodeSessionState = {\n currentModelId: string;\n modeId: string;\n};\n\nexport type MastraCodeComposedState = MastraCodeState & MastraCodeSessionState;\n\nexport interface MastraCodeState {\n [key: string]: unknown;\n [key: `subagentModelId_${string}`]: string | undefined;\n subagentModelId?: string;\n projectPath?: string;\n projectName?: string;\n /** Factory project that owns this session. */\n factoryProjectId?: string;\n /** Linked repository used by this session when source-control execution is required. */\n projectRepositoryId?: string;\n /** Persisted sandbox id for reattaching the project's cloud workspace. */\n sandboxId?: string;\n /** Path inside the sandbox the repo is cloned into. */\n sandboxWorkdir?: string;\n /** Active git worktree path inside the sandbox for the current unit of work. */\n worktreePath?: string;\n /** Active feature branch checked out in the worktree. */\n branch?: string;\n /**\n * The session's checkout contains third-party content (e.g. a PR branch\n * under review). Project-level instruction files (AGENTS.md, CLAUDE.md)\n * are attacker-writable there and must not be ingested into the system\n * prompt or injected as reminders.\n */\n untrustedCheckout?: boolean;\n /**\n * Trusted git ref (typically the PR's base branch) to serve project\n * instruction files from when the checkout is untrusted. Without it,\n * project-scope instruction files are skipped entirely.\n */\n baseRef?: string;\n configDir: string;\n homeDir?: string;\n gitBranch?: string;\n lastCommand?: string;\n observerModelId: string;\n reflectorModelId: string;\n observationThreshold: number;\n reflectionThreshold: number;\n cavemanObservations: boolean;\n observeAttachments: 'auto' | boolean;\n omScope?: 'thread' | 'resource';\n thinkingLevel: 'off' | 'low' | 'medium' | 'high' | 'xhigh';\n yolo: boolean;\n permissionRules: {\n categories: Record<string, PermissionPolicy>;\n tools: Record<string, PermissionPolicy>;\n };\n smartEditing: boolean;\n notifications: 'bell' | 'system' | 'both' | 'off';\n tasks: Array<{\n id?: string;\n content: string;\n status: 'pending' | 'in_progress' | 'completed';\n activeForm: string;\n }>;\n sandboxAllowedPaths: string[];\n pluginSkillPaths: string[];\n pluginCommandPaths: string[];\n pluginInstructions: string[];\n activePlan: {\n title: string;\n plan: string;\n approvedAt: string;\n } | null;\n activeBrowserSettings?: {\n enabled: boolean;\n provider: 'stagehand' | 'agent-browser';\n headless?: boolean;\n viewport?: {\n width: number;\n height: number;\n };\n cdpUrl?: string;\n stagehand?: {\n env: 'LOCAL' | 'BROWSERBASE';\n apiKey?: string;\n projectId?: string;\n };\n };\n}\n\nexport const stateSchema = z.object({\n // Session-scoped selection.\n // validates state against this schema, so they MUST be declared here — Zod\n // strips unknown keys on parse, which would otherwise silently discard the\n // seeded model and leave the controller with no model selected.\n currentModelId: z.string().optional(),\n modeId: z.string().optional(),\n subagentModelId: z.string().optional(),\n projectPath: z.string().optional(),\n projectName: z.string().optional(),\n factoryProjectId: z.string().optional(),\n projectRepositoryId: z.string().optional(),\n sandboxId: z.string().optional(),\n sandboxWorkdir: z.string().optional(),\n worktreePath: z.string().optional(),\n branch: z.string().optional(),\n // Session operates on an untrusted checkout — suppress AGENTS.md ingestion.\n untrustedCheckout: z.boolean().optional(),\n // Trusted ref to serve instruction files from on untrusted checkouts.\n baseRef: z.string().optional(),\n configDir: z.string().default(DEFAULT_CONFIG_DIR),\n homeDir: z.string().optional(),\n gitBranch: z.string().optional(),\n lastCommand: z.string().optional(),\n // Observational Memory model settings\n observerModelId: z.string().default(DEFAULT_OM_MODEL_ID),\n reflectorModelId: z.string().default(DEFAULT_OM_MODEL_ID),\n // Observational Memory threshold settings\n observationThreshold: z.number().default(30_000),\n reflectionThreshold: z.number().default(40_000),\n // Whether observations and reflections use the terse caveman-style instruction.\n // Off by default — caveman style is opt-in via `/om` settings; observers and\n // reflectors fall back to their built-in (prose) behavior unless enabled.\n cavemanObservations: z.boolean().default(false),\n // Whether OM forwards image/file attachment parts to the Observer LLM.\n // 'auto' (default) checks the provider capabilities registry to decide.\n // true/false forces the setting regardless of model capabilities.\n observeAttachments: z.union([z.literal('auto'), z.boolean()]).default('auto'),\n // Observational Memory scope — 'thread' (per-conversation) or 'resource' (shared across threads)\n omScope: z.enum(['thread', 'resource']).optional(),\n // Thinking level for model reasoning effort\n thinkingLevel: z.enum(['off', 'low', 'medium', 'high', 'xhigh']).default('off'),\n // YOLO mode — auto-approve all tool calls\n yolo: z.boolean().default(false),\n // Permission rules — per-category and per-tool approval policies\n permissionRules: z\n .object({\n categories: z.record(z.string(), z.enum(['allow', 'ask', 'deny'])).default({}),\n tools: z.record(z.string(), z.enum(['allow', 'ask', 'deny'])).default({}),\n })\n .default({ categories: {}, tools: {} }),\n // Smart editing mode — use AST-based analysis for code edits\n smartEditing: z.boolean().default(true),\n // Notification mode — alert when TUI needs user attention\n notifications: z.enum(['bell', 'system', 'both', 'off']).default('off'),\n // Task list (ephemeral per-thread, cleared on thread switch/creation)\n tasks: z\n .array(\n z.object({\n id: z.string().optional(),\n content: z.string(),\n status: z.enum(['pending', 'in_progress', 'completed']),\n activeForm: z.string(),\n }),\n )\n .default([]),\n // Sandbox allowed paths (per-thread, absolute paths allowed in addition to project root)\n sandboxAllowedPaths: z.array(z.string()).default([]),\n // Asset directories contributed by active plugins.\n pluginSkillPaths: z.array(z.string()).default([]),\n pluginCommandPaths: z.array(z.string()).default([]),\n pluginInstructions: z.array(z.string()).default([]),\n // Active plan (set when a plan is approved in Plan mode)\n activePlan: z\n .object({\n title: z.string(),\n plan: z.string(),\n approvedAt: z.string(),\n })\n .nullable()\n .default(null),\n // Active browser settings (tracks what's actually running vs. what's in the settings file)\n activeBrowserSettings: z\n .object({\n enabled: z.boolean(),\n provider: z.enum(['stagehand', 'agent-browser']),\n headless: z.boolean().optional(),\n viewport: z\n .object({\n width: z.number(),\n height: z.number(),\n })\n .optional(),\n cdpUrl: z.string().optional(),\n stagehand: z\n .object({\n env: z.enum(['LOCAL', 'BROWSERBASE']),\n apiKey: z.string().optional(),\n projectId: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\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.1.1-alpha.2",
3
+ "version": "1.1.1",
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": {
@@ -57,18 +57,18 @@
57
57
  "yaml": "^2.7.1",
58
58
  "zod": "^4.3.6",
59
59
  "@mastra/agent-browser": "0.4.1",
60
+ "@mastra/core": "1.55.0",
60
61
  "@mastra/fastembed": "1.2.0",
61
62
  "@mastra/duckdb": "1.5.2",
62
63
  "@mastra/github-signals": "0.2.2",
63
- "@mastra/core": "1.55.0-alpha.2",
64
64
  "@mastra/libsql": "1.18.0",
65
65
  "@mastra/mcp": "1.15.0",
66
66
  "@mastra/observability": "1.16.3",
67
- "@mastra/memory": "1.24.0",
68
- "@mastra/pg": "1.18.0",
69
- "@mastra/stagehand": "0.3.1",
70
67
  "@mastra/schema-compat": "1.3.4",
71
- "@mastra/tavily": "1.1.1"
68
+ "@mastra/tavily": "1.1.1",
69
+ "@mastra/stagehand": "0.3.1",
70
+ "@mastra/pg": "1.18.1",
71
+ "@mastra/memory": "1.24.0"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@libsql/client": "^0.17.4",
@@ -79,9 +79,9 @@
79
79
  "typescript": "^6.0.3",
80
80
  "typescript-eslint": "^8.57.0",
81
81
  "vitest": "4.1.10",
82
- "@internal/types-builder": "0.0.93",
83
- "@internal/lint": "0.0.118",
84
- "@internal/workspace-test-utils": "0.0.62"
82
+ "@internal/lint": "0.0.119",
83
+ "@internal/types-builder": "0.0.94",
84
+ "@internal/workspace-test-utils": "0.0.63"
85
85
  },
86
86
  "engines": {
87
87
  "node": ">=22.19.0"