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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @mastra/code-sdk
2
2
 
3
+ ## 1.1.1-alpha.2
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
+ - Updated dependencies [[`55c9e24`](https://github.com/mastra-ai/mastra/commit/55c9e248c27c1d72b5bb7e94ea6b8a3999eee49f), [`07f5b4b`](https://github.com/mastra-ai/mastra/commit/07f5b4ba9d608d88865030732e580298296adf99)]:
10
+ - @mastra/core@1.55.0-alpha.2
11
+
12
+ ## 1.1.1-alpha.1
13
+
14
+ ### Patch Changes
15
+
16
+ - 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))
17
+
18
+ - 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))
19
+
20
+ - Updated dependencies [[`ba369f2`](https://github.com/mastra-ai/mastra/commit/ba369f2a0aaf998da0d6aa033d26f64f96bef8ac), [`dcfed93`](https://github.com/mastra-ai/mastra/commit/dcfed93e1e256c6abfa792cbb7ca836f5d0e8638), [`2876e15`](https://github.com/mastra-ai/mastra/commit/2876e15b4d2f616a3bc1ed3af57d546c268384ce), [`598080f`](https://github.com/mastra-ai/mastra/commit/598080f224edb3f0f5b801035b067fac50a56a03)]:
21
+ - @mastra/core@1.55.0-alpha.1
22
+
3
23
  ## 1.1.1-alpha.0
4
24
 
5
25
  ### Patch Changes
@@ -45,6 +45,11 @@ export declare class SandboxFilesystem implements WorkspaceFilesystem {
45
45
  /**
46
46
  * Resolve a workspace path to an absolute path inside the sandbox, enforcing
47
47
  * that it stays within the workdir.
48
+ *
49
+ * Accepts both workspace-relative paths (`src/foo.ts`, `/src/foo.ts`) and
50
+ * absolute sandbox paths that already live under the workdir — the agent's
51
+ * prompt advertises the workdir as its working directory, so tools are
52
+ * routinely called with fully-qualified paths like `<workdir>/src/foo.ts`.
48
53
  */
49
54
  private resolve;
50
55
  resolveAbsolutePath(inputPath: string): string | undefined;
@@ -53,6 +58,11 @@ export declare class SandboxFilesystem implements WorkspaceFilesystem {
53
58
  * Lexical guard catches `..` traversal, but a symlink inside the workdir can
54
59
  * still point outside it. After resolving a path that refers to an existing
55
60
  * entry, verify its realpath is still contained in the workdir.
61
+ *
62
+ * Canonicalization tries `realpath`, then `readlink -f` (GNU/busybox), then
63
+ * `cd && pwd -P` for directories — covering GNU hosts, macOS/BSD, and
64
+ * busybox. If the path exists but cannot be canonicalized we fail CLOSED:
65
+ * returning without a check would let a symlink bypass containment.
56
66
  */
57
67
  private assertContainedRealpath;
58
68
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-filesystem.d.ts","sourceRoot":"","sources":["../../src/agents/sandbox-filesystem.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox-filesystem.d.ts","sourceRoot":"","sources":["../../src/agents/sandbox-filesystem.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { posix } from "path";
2
+ import { FileExistsError, FileNotFoundError, IsDirectoryError } from "@mastra/core/workspace";
2
3
  //#region src/agents/sandbox-filesystem.ts
3
4
  /**
4
5
  * SandboxFilesystem
@@ -14,6 +15,13 @@ import { posix } from "path";
14
15
  *
15
16
  * Reads/writes use base64 over the wire so binary content survives the shell.
16
17
  */
18
+ /**
19
+ * Sentinel exit codes used by guard clauses that run before the real command,
20
+ * so shell failures can be mapped to typed filesystem errors.
21
+ */
22
+ const EXIT_NOT_FOUND = 20;
23
+ const EXIT_IS_DIRECTORY = 21;
24
+ const EXIT_EXISTS = 22;
17
25
  /** Default per-command deadline so a hung sandbox can't block file tools forever. */
18
26
  const COMMAND_TIMEOUT_MS = 3e4;
19
27
  /** Single-quote a string for safe POSIX shell interpolation. */
@@ -37,14 +45,21 @@ var SandboxFilesystem = class {
37
45
  constructor(options) {
38
46
  this.sandbox = options.sandbox;
39
47
  this.basePath = options.workdir;
40
- this.id = options.id ?? `sandbox-fs:${options.sandbox.id}`;
48
+ this.id = options.id ?? `sandbox-fs:${options.sandbox.id}:${options.workdir}`;
41
49
  }
42
50
  /**
43
51
  * Resolve a workspace path to an absolute path inside the sandbox, enforcing
44
52
  * that it stays within the workdir.
53
+ *
54
+ * Accepts both workspace-relative paths (`src/foo.ts`, `/src/foo.ts`) and
55
+ * absolute sandbox paths that already live under the workdir — the agent's
56
+ * prompt advertises the workdir as its working directory, so tools are
57
+ * routinely called with fully-qualified paths like `<workdir>/src/foo.ts`.
45
58
  */
46
59
  resolve(inputPath) {
47
- const rel = inputPath.startsWith("/") ? inputPath.slice(1) : inputPath;
60
+ const base = posix.normalize(this.basePath);
61
+ const normalizedInput = posix.normalize(inputPath);
62
+ const rel = normalizedInput === base ? "" : normalizedInput.startsWith(`${base}/`) ? normalizedInput.slice(base.length + 1) : inputPath.startsWith("/") ? inputPath.slice(1) : inputPath;
48
63
  const resolved = posix.normalize(posix.join(this.basePath, rel));
49
64
  const root = posix.normalize(this.basePath);
50
65
  if (resolved !== root && !resolved.startsWith(`${root}/`)) throw new Error(`Path escapes workspace root: ${inputPath}`);
@@ -60,12 +75,25 @@ var SandboxFilesystem = class {
60
75
  * Lexical guard catches `..` traversal, but a symlink inside the workdir can
61
76
  * still point outside it. After resolving a path that refers to an existing
62
77
  * entry, verify its realpath is still contained in the workdir.
78
+ *
79
+ * Canonicalization tries `realpath`, then `readlink -f` (GNU/busybox), then
80
+ * `cd && pwd -P` for directories — covering GNU hosts, macOS/BSD, and
81
+ * busybox. If the path exists but cannot be canonicalized we fail CLOSED:
82
+ * returning without a check would let a symlink bypass containment.
63
83
  */
64
84
  async assertContainedRealpath(abs, inputPath) {
65
- const result = await this.exec(`readlink -f -- ${shellQuote(abs)} 2>/dev/null`);
66
- const real = result.stdout.trim();
67
- if (result.exitCode !== 0 || !real) return;
68
- const root = posix.normalize(this.basePath);
85
+ const result = await this.exec([
86
+ `p=${shellQuote(abs)}`,
87
+ `if [ ! -e "$p" ] && [ ! -L "$p" ]; then exit ${EXIT_NOT_FOUND}; fi`,
88
+ `root=$(cd ${shellQuote(this.basePath)} 2>/dev/null && pwd -P)`,
89
+ `[ -n "$root" ] || exit 1`,
90
+ `rp=$(realpath "$p" 2>/dev/null) || rp=$(readlink -f "$p" 2>/dev/null) || { [ -d "$p" ] && rp=$(cd "$p" 2>/dev/null && pwd -P); }`,
91
+ `[ -n "$rp" ] || exit 1`,
92
+ `printf '%s\\n%s' "$root" "$rp"`
93
+ ].join("\n"));
94
+ if (result.exitCode === EXIT_NOT_FOUND) return;
95
+ const [root, real] = result.stdout.split("\n").map((s) => s.trim());
96
+ if (result.exitCode !== 0 || !root || !real) throw new Error(`Unable to verify path stays within workspace root: ${inputPath}`);
69
97
  if (real !== root && !real.startsWith(`${root}/`)) throw new Error(`Path escapes workspace root (symlink): ${inputPath}`);
70
98
  }
71
99
  /**
@@ -88,8 +116,10 @@ var SandboxFilesystem = class {
88
116
  async readFile(path, options) {
89
117
  const abs = this.resolve(path);
90
118
  await this.assertContainedRealpath(abs, path);
91
- const result = await this.exec(`base64 < ${shellQuote(abs)}`);
92
- if (result.exitCode !== 0) throw new Error(`File not found: ${path}`);
119
+ const result = await this.exec(`if [ -d ${shellQuote(abs)} ]; then exit ${EXIT_IS_DIRECTORY}; elif [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; base64 < ${shellQuote(abs)}`);
120
+ if (result.exitCode === EXIT_IS_DIRECTORY) throw new IsDirectoryError(path);
121
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);
122
+ if (result.exitCode !== 0) throw new Error(`readFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
93
123
  const buffer = Buffer.from(result.stdout.replace(/\s/g, ""), "base64");
94
124
  if (options?.encoding) return buffer.toString(options.encoding);
95
125
  return buffer;
@@ -101,7 +131,10 @@ var SandboxFilesystem = class {
101
131
  const dir = posix.dirname(abs);
102
132
  const mkdir = options?.recursive === false ? "" : `mkdir -p ${shellQuote(dir)} && `;
103
133
  if (options?.overwrite === false) {
104
- if (await this.exists(path)) throw new Error(`File already exists: ${path}`);
134
+ const result = await this.exec(`${mkdir}{ (set -C; printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}) 2>/dev/null || { [ -e ${shellQuote(abs)} ] && exit ${EXIT_EXISTS} || exit 1; }; }`);
135
+ if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(path);
136
+ if (result.exitCode !== 0) throw new Error(`writeFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
137
+ return;
105
138
  }
106
139
  await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);
107
140
  }
@@ -113,8 +146,14 @@ var SandboxFilesystem = class {
113
146
  }
114
147
  async deleteFile(path, options) {
115
148
  const abs = this.resolve(path);
116
- const force = options?.force ? "-f " : "";
117
- if ((await this.exec(`rm ${force}${shellQuote(abs)}`)).exitCode !== 0 && !options?.force) throw new Error(`File not found: ${path}`);
149
+ await this.assertContainedRealpath(posix.dirname(abs), path);
150
+ if (options?.force) {
151
+ await this.execOk(`rm -f ${shellQuote(abs)}`, `deleteFile ${path}`);
152
+ return;
153
+ }
154
+ const result = await this.exec(`if [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; rm ${shellQuote(abs)}`);
155
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);
156
+ if (result.exitCode !== 0) throw new Error(`deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
118
157
  }
119
158
  async copyFile(src, dest, options) {
120
159
  const srcAbs = this.resolve(src);
@@ -123,9 +162,29 @@ var SandboxFilesystem = class {
123
162
  await this.assertContainedDest(destAbs, dest);
124
163
  const recursive = options?.recursive ? "-r " : "";
125
164
  if (options?.overwrite === false) {
126
- if (await this.exists(dest)) throw new Error(`Destination exists: ${dest}`);
165
+ const result = await this.exec([
166
+ `src=${shellQuote(srcAbs)}`,
167
+ `dest=${shellQuote(destAbs)}`,
168
+ `if [ ! -e "$src" ] && [ ! -L "$src" ]; then exit ${EXIT_NOT_FOUND}; fi`,
169
+ `mkdir -p ${shellQuote(posix.dirname(destAbs))} || exit 1`,
170
+ `if [ -d "$src" ]; then`,
171
+ ` mkdir "$dest" 2>/dev/null || exit ${EXIT_EXISTS}`,
172
+ ` cp -R "$src"/. "$dest"/`,
173
+ `else`,
174
+ ` tmp="$dest.__cptmp$$"`,
175
+ ` cp "$src" "$tmp" || exit 1`,
176
+ ` ln "$tmp" "$dest" 2>/dev/null || { rm -f "$tmp"; [ -e "$dest" ] && exit ${EXIT_EXISTS} || exit 1; }`,
177
+ ` rm -f "$tmp"`,
178
+ `fi`
179
+ ].join("\n"));
180
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
181
+ if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(dest);
182
+ if (result.exitCode !== 0) throw new Error(`copyFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
183
+ return;
127
184
  }
128
- await this.execOk(`cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `copyFile ${src} -> ${dest}`);
185
+ const result = await this.exec(`if [ ! -e ${shellQuote(srcAbs)} ]; then exit ${EXIT_NOT_FOUND}; fi; mkdir -p ${shellQuote(posix.dirname(destAbs))} && cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`);
186
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
187
+ if (result.exitCode !== 0) throw new Error(`copyFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
129
188
  }
130
189
  async moveFile(src, dest, options) {
131
190
  const srcAbs = this.resolve(src);
@@ -133,9 +192,22 @@ var SandboxFilesystem = class {
133
192
  await this.assertContainedRealpath(srcAbs, src);
134
193
  await this.assertContainedDest(destAbs, dest);
135
194
  if (options?.overwrite === false) {
136
- if (await this.exists(dest)) throw new Error(`Destination exists: ${dest}`);
195
+ const result = await this.exec([
196
+ `src=${shellQuote(srcAbs)}`,
197
+ `dest=${shellQuote(destAbs)}`,
198
+ `if [ ! -e "$src" ] && [ ! -L "$src" ]; then exit ${EXIT_NOT_FOUND}; fi`,
199
+ `mkdir -p ${shellQuote(posix.dirname(destAbs))} || exit 1`,
200
+ `mv -n "$src" "$dest" 2>/dev/null || exit 1`,
201
+ `if [ -e "$src" ] || [ -L "$src" ]; then exit ${EXIT_EXISTS}; fi`
202
+ ].join("\n"));
203
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
204
+ if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(dest);
205
+ if (result.exitCode !== 0) throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
206
+ return;
137
207
  }
138
- await this.execOk(`mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `moveFile ${src} -> ${dest}`);
208
+ const result = await this.exec(`if [ ! -e ${shellQuote(srcAbs)} ]; then exit ${EXIT_NOT_FOUND}; fi; mkdir -p ${shellQuote(posix.dirname(destAbs))} && mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`);
209
+ if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
210
+ if (result.exitCode !== 0) throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
139
211
  }
140
212
  async mkdir(path, options) {
141
213
  const abs = this.resolve(path);
@@ -145,6 +217,7 @@ var SandboxFilesystem = class {
145
217
  }
146
218
  async rmdir(path, options) {
147
219
  const abs = this.resolve(path);
220
+ await this.assertContainedRealpath(posix.dirname(abs), path);
148
221
  if (options?.recursive) {
149
222
  const force = options?.force ? "-f " : "";
150
223
  await this.execOk(`rm -r ${force}${shellQuote(abs)}`, `rmdir ${path}`);
@@ -156,11 +229,11 @@ var SandboxFilesystem = class {
156
229
  const abs = this.resolve(path);
157
230
  await this.assertContainedRealpath(abs, path);
158
231
  if (options?.recursive) {
159
- const result = await this.exec(`find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ""}-printf '%y\\t%p\\n' 2>/dev/null`);
232
+ const result = await this.exec(`test -d ${shellQuote(abs)} && find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ""}2>/dev/null | while IFS= read -r f; do if [ -d "$f" ]; then printf 'd\\t%s\\n' "$f"; else printf 'f\\t%s\\n' "$f"; fi; done`);
160
233
  if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);
161
234
  return this.parseFindOutput(result.stdout, abs, options);
162
235
  }
163
- const result = await this.exec(`cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e "$f" ] || continue; if [ -d "$f" ]; then echo "d\t$f"; else echo "f\t$f"; fi; done`);
236
+ const result = await this.exec(`cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e "$f" ] || continue; if [ -d "$f" ]; then printf 'd\\t%s\\n' "$f"; else printf 'f\\t%s\\n' "$f"; fi; done`);
164
237
  if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);
165
238
  return this.parseListOutput(result.stdout, options);
166
239
  }
@@ -210,10 +283,10 @@ var SandboxFilesystem = class {
210
283
  async stat(path) {
211
284
  const abs = this.resolve(path);
212
285
  await this.assertContainedRealpath(abs, path);
213
- const result = await this.exec(`stat -c '%F\\t%s\\t%Y\\t%W' ${shellQuote(abs)}`);
214
- if (result.exitCode !== 0) throw new Error(`Path not found: ${path}`);
215
- const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split(" ");
216
- const type = kind && kind.includes("directory") ? "directory" : "file";
286
+ const result = await this.exec(`stat -c '%F|%s|%Y|%W' ${shellQuote(abs)} 2>/dev/null || stat -f '%HT|%z|%m|%B' ${shellQuote(abs)}`);
287
+ if (result.exitCode !== 0) throw new FileNotFoundError(path);
288
+ const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split("|");
289
+ const type = kind && kind.toLowerCase().includes("directory") ? "directory" : "file";
217
290
  const size = Number(sizeStr) || 0;
218
291
  const mtime = Number(mtimeStr) || 0;
219
292
  const ctime = Number(ctimeStr);
@@ -238,6 +311,7 @@ var SandboxFilesystem = class {
238
311
  id: this.id,
239
312
  name: this.name,
240
313
  provider: this.provider,
314
+ status: this.status,
241
315
  metadata: {
242
316
  basePath: this.basePath,
243
317
  sandboxId: this.sandbox.id
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-filesystem.js","names":["posixPath"],"sources":["../../src/agents/sandbox-filesystem.ts"],"sourcesContent":["/**\n * SandboxFilesystem\n *\n * A `WorkspaceFilesystem` that stores files inside a remote `MastraSandbox`\n * (e.g. a Railway VM) rather than on the server host. File operations are\n * implemented by shelling out through the sandbox's `executeCommand`, so the\n * agent's file tools and command tools share one VM and one view of the repo.\n *\n * Paths are workspace-relative (`/src/foo.ts`) and resolve under the sandbox\n * working directory (`basePath`). A traversal guard rejects any path that\n * escapes the workdir, mirroring `LocalFilesystem`'s contained mode.\n *\n * Reads/writes use base64 over the wire so binary content survives the shell.\n */\n\nimport { posix as posixPath } from 'node:path';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n ListOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WorkspaceFilesystem,\n WriteOptions,\n} from '@mastra/core/workspace';\n\n/** Minimal command result shape we depend on. */\nexport interface SandboxCommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n/** Minimal sandbox surface the filesystem needs. */\nexport interface SandboxExec {\n readonly id: string;\n executeCommand(command: string, args?: string[], options?: { timeout?: number }): Promise<SandboxCommandResult>;\n}\n\nexport interface SandboxFilesystemOptions {\n /** Live sandbox to run commands in. */\n sandbox: SandboxExec;\n /** Absolute path inside the sandbox that is the workspace root. */\n workdir: string;\n /** Optional stable id; defaults to a sandbox-derived id. */\n id?: string;\n}\n\n/** Default per-command deadline so a hung sandbox can't block file tools forever. */\nconst COMMAND_TIMEOUT_MS = 30_000;\n\n/** Single-quote a string for safe POSIX shell interpolation. */\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction isFileContentString(content: FileContent): content is string {\n return typeof content === 'string';\n}\n\nfunction toBuffer(content: FileContent): Buffer {\n if (isFileContentString(content)) return Buffer.from(content, 'utf8');\n return Buffer.from(content);\n}\n\nexport class SandboxFilesystem implements WorkspaceFilesystem {\n readonly id: string;\n readonly name = 'SandboxFilesystem';\n readonly provider = 'sandbox';\n readonly basePath: string;\n status: ProviderStatus = 'ready';\n\n private readonly sandbox: SandboxExec;\n\n constructor(options: SandboxFilesystemOptions) {\n this.sandbox = options.sandbox;\n this.basePath = options.workdir;\n this.id = options.id ?? `sandbox-fs:${options.sandbox.id}`;\n }\n\n // ── Path handling ──────────────────────────────────────────────────────\n\n /**\n * Resolve a workspace path to an absolute path inside the sandbox, enforcing\n * that it stays within the workdir.\n */\n private resolve(inputPath: string): string {\n const rel = inputPath.startsWith('/') ? inputPath.slice(1) : inputPath;\n const resolved = posixPath.normalize(posixPath.join(this.basePath, rel));\n const root = posixPath.normalize(this.basePath);\n if (resolved !== root && !resolved.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root: ${inputPath}`);\n }\n return resolved;\n }\n\n resolveAbsolutePath(inputPath: string): string | undefined {\n return this.resolve(inputPath);\n }\n\n // ── Command helper ─────────────────────────────────────────────────────\n\n private async exec(script: string): Promise<SandboxCommandResult> {\n return this.sandbox.executeCommand('sh', ['-c', script], { timeout: COMMAND_TIMEOUT_MS });\n }\n\n /**\n * Lexical guard catches `..` traversal, but a symlink inside the workdir can\n * still point outside it. After resolving a path that refers to an existing\n * entry, verify its realpath is still contained in the workdir.\n */\n private async assertContainedRealpath(abs: string, inputPath: string): Promise<void> {\n const result = await this.exec(`readlink -f -- ${shellQuote(abs)} 2>/dev/null`);\n const real = result.stdout.trim();\n // If readlink couldn't resolve (path doesn't exist yet), nothing to check.\n if (result.exitCode !== 0 || !real) return;\n const root = posixPath.normalize(this.basePath);\n if (real !== root && !real.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root (symlink): ${inputPath}`);\n }\n }\n\n /**\n * Guard for write destinations. The lexical guard catches `..`, but a symlink\n * inside the workdir can redirect a write outside it. For an existing target\n * we check its realpath; for a not-yet-existing target we check the realpath\n * of its nearest existing ancestor directory, since a symlinked parent is the\n * escape vector (e.g. `link -> /etc` then writing `link/passwd`).\n */\n private async assertContainedDest(abs: string, inputPath: string): Promise<void> {\n // First check the target itself (covers overwriting an existing symlink).\n await this.assertContainedRealpath(abs, inputPath);\n // Then check the parent directory's realpath; readlink -f resolves the\n // nearest existing ancestor when the leaf doesn't exist yet.\n const parent = posixPath.dirname(abs);\n if (parent && parent !== abs) {\n await this.assertContainedRealpath(parent, inputPath);\n }\n }\n\n private async execOk(script: string, context: string): Promise<SandboxCommandResult> {\n const result = await this.exec(script);\n if (result.exitCode !== 0) {\n throw new Error(`${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);\n }\n return result;\n }\n\n // ── File operations ────────────────────────────────────────────────────\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n const result = await this.exec(`base64 < ${shellQuote(abs)}`);\n if (result.exitCode !== 0) {\n throw new Error(`File not found: ${path}`);\n }\n const buffer = Buffer.from(result.stdout.replace(/\\s/g, ''), 'base64');\n if (options?.encoding) {\n return buffer.toString(options.encoding);\n }\n return buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n const dir = posixPath.dirname(abs);\n const mkdir = options?.recursive === false ? '' : `mkdir -p ${shellQuote(dir)} && `;\n if (options?.overwrite === false) {\n const exists = await this.exists(path);\n if (exists) throw new Error(`File already exists: ${path}`);\n }\n await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n await this.execOk(\n `mkdir -p ${shellQuote(posixPath.dirname(abs))} && printf %s ${shellQuote(b64)} | base64 -d >> ${shellQuote(abs)}`,\n `appendFile ${path}`,\n );\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n const force = options?.force ? '-f ' : '';\n const result = await this.exec(`rm ${force}${shellQuote(abs)}`);\n if (result.exitCode !== 0 && !options?.force) {\n throw new Error(`File not found: ${path}`);\n }\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n const recursive = options?.recursive ? '-r ' : '';\n if (options?.overwrite === false) {\n const exists = await this.exists(dest);\n if (exists) throw new Error(`Destination exists: ${dest}`);\n }\n await this.execOk(`cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `copyFile ${src} -> ${dest}`);\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n if (options?.overwrite === false) {\n const exists = await this.exists(dest);\n if (exists) throw new Error(`Destination exists: ${dest}`);\n }\n await this.execOk(`mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `moveFile ${src} -> ${dest}`);\n }\n\n // ── Directory operations ───────────────────────────────────────────────\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const flag = options?.recursive === false ? '' : '-p ';\n await this.execOk(`mkdir ${flag}${shellQuote(abs)}`, `mkdir ${path}`);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n if (options?.recursive) {\n const force = options?.force ? '-f ' : '';\n await this.execOk(`rm -r ${force}${shellQuote(abs)}`, `rmdir ${path}`);\n return;\n }\n const result = await this.exec(`rmdir ${shellQuote(abs)}`);\n if (result.exitCode !== 0 && !options?.force) {\n throw new Error(`Directory not empty or not found: ${path}`);\n }\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n if (options?.recursive) {\n // Use find for recursive listings; emit \"type\\tpath\".\n const result = await this.exec(\n `find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ''}-printf '%y\\\\t%p\\\\n' 2>/dev/null`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseFindOutput(result.stdout, abs, options);\n }\n // Non-recursive: list with name + type via a portable loop.\n const result = await this.exec(\n `cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e \"$f\" ] || continue; if [ -d \"$f\" ]; then echo \"d\\t$f\"; else echo \"f\\t$f\"; fi; done`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseListOutput(result.stdout, options);\n }\n\n private parseListOutput(stdout: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const name = line.slice(tab + 1);\n if (!name || name === '.' || name === '..') continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private parseFindOutput(stdout: string, base: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const fullPath = line.slice(tab + 1);\n const name = posixPath.relative(base, fullPath);\n if (!name) continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private matchesExtension(name: string, extension?: string | string[]): boolean {\n if (!extension) return true;\n const exts = Array.isArray(extension) ? extension : [extension];\n return exts.some(ext => name.endsWith(ext));\n }\n\n // ── Path / metadata ────────────────────────────────────────────────────\n\n async exists(path: string): Promise<boolean> {\n const abs = this.resolve(path);\n const result = await this.exec(`test -e ${shellQuote(abs)}`);\n return result.exitCode === 0;\n }\n\n async stat(path: string): Promise<FileStat> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n // %F=type, %s=size, %X=atime, %Y=mtime (epoch seconds), %W=birth (or -1).\n const result = await this.exec(`stat -c '%F\\\\t%s\\\\t%Y\\\\t%W' ${shellQuote(abs)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Path not found: ${path}`);\n }\n const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split('\\t');\n const type = kind && kind.includes('directory') ? 'directory' : 'file';\n const size = Number(sizeStr) || 0;\n const mtime = Number(mtimeStr) || 0;\n const ctime = Number(ctimeStr);\n return {\n name: posixPath.basename(abs),\n path: `/${posixPath.relative(this.basePath, abs)}`,\n type,\n size: type === 'directory' ? 0 : size,\n modifiedAt: new Date(mtime * 1000),\n createdAt: new Date((ctime > 0 ? ctime : mtime) * 1000),\n };\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n async init(): Promise<void> {\n await this.execOk(`mkdir -p ${shellQuote(this.basePath)}`, 'init workdir');\n }\n\n async destroy(): Promise<void> {\n // The sandbox lifecycle is owned by the caller; nothing to tear down here.\n }\n\n async isReady(): Promise<boolean> {\n const result = await this.exec(`test -d ${shellQuote(this.basePath)}`);\n return result.exitCode === 0;\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n metadata: { basePath: this.basePath, sandboxId: this.sandbox.id },\n };\n }\n\n getInstructions(): string {\n return `Files are stored in a remote sandbox at ${this.basePath}. Use absolute workspace paths like /src/index.ts. All reads, writes and commands run inside the same sandbox.`;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sandbox-filesystem.js","names":["posixPath"],"sources":["../../src/agents/sandbox-filesystem.ts"],"sourcesContent":["/**\n * SandboxFilesystem\n *\n * A `WorkspaceFilesystem` that stores files inside a remote `MastraSandbox`\n * (e.g. a Railway VM) rather than on the server host. File operations are\n * implemented by shelling out through the sandbox's `executeCommand`, so the\n * agent's file tools and command tools share one VM and one view of the repo.\n *\n * Paths are workspace-relative (`/src/foo.ts`) and resolve under the sandbox\n * working directory (`basePath`). A traversal guard rejects any path that\n * escapes the workdir, mirroring `LocalFilesystem`'s contained mode.\n *\n * Reads/writes use base64 over the wire so binary content survives the shell.\n */\n\nimport { posix as posixPath } from 'node:path';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n ListOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WorkspaceFilesystem,\n WriteOptions,\n} from '@mastra/core/workspace';\nimport { FileExistsError, FileNotFoundError, IsDirectoryError } from '@mastra/core/workspace';\n\n/**\n * Sentinel exit codes used by guard clauses that run before the real command,\n * so shell failures can be mapped to typed filesystem errors.\n */\nconst EXIT_NOT_FOUND = 20;\nconst EXIT_IS_DIRECTORY = 21;\nconst EXIT_EXISTS = 22;\n\n/** Minimal command result shape we depend on. */\nexport interface SandboxCommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n/** Minimal sandbox surface the filesystem needs. */\nexport interface SandboxExec {\n readonly id: string;\n executeCommand(command: string, args?: string[], options?: { timeout?: number }): Promise<SandboxCommandResult>;\n}\n\nexport interface SandboxFilesystemOptions {\n /** Live sandbox to run commands in. */\n sandbox: SandboxExec;\n /** Absolute path inside the sandbox that is the workspace root. */\n workdir: string;\n /** Optional stable id; defaults to a sandbox-derived id. */\n id?: string;\n}\n\n/** Default per-command deadline so a hung sandbox can't block file tools forever. */\nconst COMMAND_TIMEOUT_MS = 30_000;\n\n/** Single-quote a string for safe POSIX shell interpolation. */\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction isFileContentString(content: FileContent): content is string {\n return typeof content === 'string';\n}\n\nfunction toBuffer(content: FileContent): Buffer {\n if (isFileContentString(content)) return Buffer.from(content, 'utf8');\n return Buffer.from(content);\n}\n\nexport class SandboxFilesystem implements WorkspaceFilesystem {\n readonly id: string;\n readonly name = 'SandboxFilesystem';\n readonly provider = 'sandbox';\n readonly basePath: string;\n status: ProviderStatus = 'ready';\n\n private readonly sandbox: SandboxExec;\n\n constructor(options: SandboxFilesystemOptions) {\n this.sandbox = options.sandbox;\n this.basePath = options.workdir;\n // Include the workdir: one sandbox can back several filesystems rooted at\n // different worktrees, and each needs a distinct id.\n this.id = options.id ?? `sandbox-fs:${options.sandbox.id}:${options.workdir}`;\n }\n\n // ── Path handling ──────────────────────────────────────────────────────\n\n /**\n * Resolve a workspace path to an absolute path inside the sandbox, enforcing\n * that it stays within the workdir.\n *\n * Accepts both workspace-relative paths (`src/foo.ts`, `/src/foo.ts`) and\n * absolute sandbox paths that already live under the workdir — the agent's\n * prompt advertises the workdir as its working directory, so tools are\n * routinely called with fully-qualified paths like `<workdir>/src/foo.ts`.\n */\n private resolve(inputPath: string): string {\n const base = posixPath.normalize(this.basePath);\n const normalizedInput = posixPath.normalize(inputPath);\n const rel =\n normalizedInput === base\n ? ''\n : normalizedInput.startsWith(`${base}/`)\n ? normalizedInput.slice(base.length + 1)\n : inputPath.startsWith('/')\n ? inputPath.slice(1)\n : inputPath;\n const resolved = posixPath.normalize(posixPath.join(this.basePath, rel));\n const root = posixPath.normalize(this.basePath);\n if (resolved !== root && !resolved.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root: ${inputPath}`);\n }\n return resolved;\n }\n\n resolveAbsolutePath(inputPath: string): string | undefined {\n return this.resolve(inputPath);\n }\n\n // ── Command helper ─────────────────────────────────────────────────────\n\n private async exec(script: string): Promise<SandboxCommandResult> {\n return this.sandbox.executeCommand('sh', ['-c', script], { timeout: COMMAND_TIMEOUT_MS });\n }\n\n /**\n * Lexical guard catches `..` traversal, but a symlink inside the workdir can\n * still point outside it. After resolving a path that refers to an existing\n * entry, verify its realpath is still contained in the workdir.\n *\n * Canonicalization tries `realpath`, then `readlink -f` (GNU/busybox), then\n * `cd && pwd -P` for directories — covering GNU hosts, macOS/BSD, and\n * busybox. If the path exists but cannot be canonicalized we fail CLOSED:\n * returning without a check would let a symlink bypass containment.\n */\n private async assertContainedRealpath(abs: string, inputPath: string): Promise<void> {\n const result = await this.exec(\n [\n `p=${shellQuote(abs)}`,\n `if [ ! -e \"$p\" ] && [ ! -L \"$p\" ]; then exit ${EXIT_NOT_FOUND}; fi`,\n // The workdir itself may contain symlinked components (/tmp on macOS),\n // so canonicalize it as the comparison root.\n `root=$(cd ${shellQuote(this.basePath)} 2>/dev/null && pwd -P)`,\n `[ -n \"$root\" ] || exit 1`,\n `rp=$(realpath \"$p\" 2>/dev/null) || rp=$(readlink -f \"$p\" 2>/dev/null) || { [ -d \"$p\" ] && rp=$(cd \"$p\" 2>/dev/null && pwd -P); }`,\n `[ -n \"$rp\" ] || exit 1`,\n `printf '%s\\\\n%s' \"$root\" \"$rp\"`,\n ].join('\\n'),\n );\n // Path doesn't exist yet: nothing to canonicalize (writes to a fresh leaf\n // are covered by assertContainedDest checking the parent directory).\n if (result.exitCode === EXIT_NOT_FOUND) return;\n const [root, real] = result.stdout.split('\\n').map(s => s.trim());\n if (result.exitCode !== 0 || !root || !real) {\n throw new Error(`Unable to verify path stays within workspace root: ${inputPath}`);\n }\n if (real !== root && !real.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root (symlink): ${inputPath}`);\n }\n }\n\n /**\n * Guard for write destinations. The lexical guard catches `..`, but a symlink\n * inside the workdir can redirect a write outside it. For an existing target\n * we check its realpath; for a not-yet-existing target we check the realpath\n * of its nearest existing ancestor directory, since a symlinked parent is the\n * escape vector (e.g. `link -> /etc` then writing `link/passwd`).\n */\n private async assertContainedDest(abs: string, inputPath: string): Promise<void> {\n // First check the target itself (covers overwriting an existing symlink).\n await this.assertContainedRealpath(abs, inputPath);\n // Then check the parent directory's realpath; readlink -f resolves the\n // nearest existing ancestor when the leaf doesn't exist yet.\n const parent = posixPath.dirname(abs);\n if (parent && parent !== abs) {\n await this.assertContainedRealpath(parent, inputPath);\n }\n }\n\n private async execOk(script: string, context: string): Promise<SandboxCommandResult> {\n const result = await this.exec(script);\n if (result.exitCode !== 0) {\n throw new Error(`${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);\n }\n return result;\n }\n\n // ── File operations ────────────────────────────────────────────────────\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n // Guard clauses first: redirecting from a directory \"succeeds\" with empty\n // output on some shells, so classify before reading.\n const result = await this.exec(\n `if [ -d ${shellQuote(abs)} ]; then exit ${EXIT_IS_DIRECTORY}; elif [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; base64 < ${shellQuote(abs)}`,\n );\n if (result.exitCode === EXIT_IS_DIRECTORY) throw new IsDirectoryError(path);\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);\n if (result.exitCode !== 0) {\n throw new Error(`readFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n const buffer = Buffer.from(result.stdout.replace(/\\s/g, ''), 'base64');\n if (options?.encoding) {\n return buffer.toString(options.encoding);\n }\n return buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n const dir = posixPath.dirname(abs);\n const mkdir = options?.recursive === false ? '' : `mkdir -p ${shellQuote(dir)} && `;\n if (options?.overwrite === false) {\n // `set -C` (noclobber) makes the redirect itself the exclusivity check —\n // no exists() pre-check that could race with a concurrent writer.\n const result = await this.exec(\n `${mkdir}{ (set -C; printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}) 2>/dev/null || { [ -e ${shellQuote(abs)} ] && exit ${EXIT_EXISTS} || exit 1; }; }`,\n );\n if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(path);\n if (result.exitCode !== 0) {\n throw new Error(`writeFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n return;\n }\n await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n await this.execOk(\n `mkdir -p ${shellQuote(posixPath.dirname(abs))} && printf %s ${shellQuote(b64)} | base64 -d >> ${shellQuote(abs)}`,\n `appendFile ${path}`,\n );\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n // Contain the parent's realpath: deleting `link/file` where `link` points\n // outside the workdir must fail, while deleting a symlink entry itself\n // (which lives inside the workdir) stays allowed.\n await this.assertContainedRealpath(posixPath.dirname(abs), path);\n if (options?.force) {\n // `rm -f` already succeeds for a missing file, but still fails for\n // directories and permission errors — surface those.\n await this.execOk(`rm -f ${shellQuote(abs)}`, `deleteFile ${path}`);\n return;\n }\n const result = await this.exec(\n `if [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; rm ${shellQuote(abs)}`,\n );\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);\n if (result.exitCode !== 0) {\n throw new Error(`deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n const recursive = options?.recursive ? '-r ' : '';\n if (options?.overwrite === false) {\n // Atomic no-clobber: directories claim the destination with an exclusive\n // mkdir; files copy to a temp name then hardlink into place (link(2)\n // fails if the destination exists). No racy exists() pre-check.\n const result = await this.exec(\n [\n `src=${shellQuote(srcAbs)}`,\n `dest=${shellQuote(destAbs)}`,\n `if [ ! -e \"$src\" ] && [ ! -L \"$src\" ]; then exit ${EXIT_NOT_FOUND}; fi`,\n `mkdir -p ${shellQuote(posixPath.dirname(destAbs))} || exit 1`,\n `if [ -d \"$src\" ]; then`,\n ` mkdir \"$dest\" 2>/dev/null || exit ${EXIT_EXISTS}`,\n ` cp -R \"$src\"/. \"$dest\"/`,\n `else`,\n ` tmp=\"$dest.__cptmp$$\"`,\n ` cp \"$src\" \"$tmp\" || exit 1`,\n ` ln \"$tmp\" \"$dest\" 2>/dev/null || { rm -f \"$tmp\"; [ -e \"$dest\" ] && exit ${EXIT_EXISTS} || exit 1; }`,\n ` rm -f \"$tmp\"`,\n `fi`,\n ].join('\\n'),\n );\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);\n if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(dest);\n if (result.exitCode !== 0) {\n throw new Error(`copyFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n return;\n }\n const result = await this.exec(\n `if [ ! -e ${shellQuote(srcAbs)} ]; then exit ${EXIT_NOT_FOUND}; fi; mkdir -p ${shellQuote(posixPath.dirname(destAbs))} && cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`,\n );\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);\n if (result.exitCode !== 0) {\n throw new Error(`copyFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n if (options?.overwrite === false) {\n // `mv -n` exits 0 even when it skips, so detect a skipped move by the\n // source surviving. The no-clobber rename itself is atomic; no racy\n // exists() pre-check.\n const result = await this.exec(\n [\n `src=${shellQuote(srcAbs)}`,\n `dest=${shellQuote(destAbs)}`,\n `if [ ! -e \"$src\" ] && [ ! -L \"$src\" ]; then exit ${EXIT_NOT_FOUND}; fi`,\n `mkdir -p ${shellQuote(posixPath.dirname(destAbs))} || exit 1`,\n `mv -n \"$src\" \"$dest\" 2>/dev/null || exit 1`,\n `if [ -e \"$src\" ] || [ -L \"$src\" ]; then exit ${EXIT_EXISTS}; fi`,\n ].join('\\n'),\n );\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);\n if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(dest);\n if (result.exitCode !== 0) {\n throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n return;\n }\n const result = await this.exec(\n `if [ ! -e ${shellQuote(srcAbs)} ]; then exit ${EXIT_NOT_FOUND}; fi; mkdir -p ${shellQuote(posixPath.dirname(destAbs))} && mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`,\n );\n if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);\n if (result.exitCode !== 0) {\n throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n }\n }\n\n // ── Directory operations ───────────────────────────────────────────────\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const flag = options?.recursive === false ? '' : '-p ';\n await this.execOk(`mkdir ${flag}${shellQuote(abs)}`, `mkdir ${path}`);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n // Same parent containment as deleteFile — `rm -r` through a symlinked\n // parent would otherwise delete outside the workspace.\n await this.assertContainedRealpath(posixPath.dirname(abs), path);\n if (options?.recursive) {\n const force = options?.force ? '-f ' : '';\n await this.execOk(`rm -r ${force}${shellQuote(abs)}`, `rmdir ${path}`);\n return;\n }\n const result = await this.exec(`rmdir ${shellQuote(abs)}`);\n if (result.exitCode !== 0 && !options?.force) {\n throw new Error(`Directory not empty or not found: ${path}`);\n }\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n if (options?.recursive) {\n // Recursive listing emitting \"type\\tpath\". `find -printf` is GNU-only\n // (fails on macOS/BSD hosts backing a local sandbox), so classify each\n // entry with a portable shell loop instead.\n const result = await this.exec(\n `test -d ${shellQuote(abs)} && find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ''}2>/dev/null | while IFS= read -r f; do if [ -d \"$f\" ]; then printf 'd\\\\t%s\\\\n' \"$f\"; else printf 'f\\\\t%s\\\\n' \"$f\"; fi; done`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseFindOutput(result.stdout, abs, options);\n }\n // Non-recursive: list with name + type via a portable loop. Use printf,\n // not echo — bash-as-/bin/sh (macOS local sandboxes) does not expand \\t\n // in echo arguments.\n const result = await this.exec(\n `cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e \"$f\" ] || continue; if [ -d \"$f\" ]; then printf 'd\\\\t%s\\\\n' \"$f\"; else printf 'f\\\\t%s\\\\n' \"$f\"; fi; done`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseListOutput(result.stdout, options);\n }\n\n private parseListOutput(stdout: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const name = line.slice(tab + 1);\n if (!name || name === '.' || name === '..') continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private parseFindOutput(stdout: string, base: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const fullPath = line.slice(tab + 1);\n const name = posixPath.relative(base, fullPath);\n if (!name) continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private matchesExtension(name: string, extension?: string | string[]): boolean {\n if (!extension) return true;\n const exts = Array.isArray(extension) ? extension : [extension];\n return exts.some(ext => name.endsWith(ext));\n }\n\n // ── Path / metadata ────────────────────────────────────────────────────\n\n async exists(path: string): Promise<boolean> {\n const abs = this.resolve(path);\n const result = await this.exec(`test -e ${shellQuote(abs)}`);\n return result.exitCode === 0;\n }\n\n async stat(path: string): Promise<FileStat> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n // GNU stat: %F=type, %s=size, %Y=mtime (epoch seconds), %W=birth (or -1).\n // BSD/macOS stat (local sandbox hosts) rejects `-c`; fall back to its\n // `-f` format with the same field order (%HT=type, %z=size, %m=mtime,\n // %B=birth). Delimit with `|` — neither stat interprets `\\t` escapes in\n // its format string.\n const result = await this.exec(\n `stat -c '%F|%s|%Y|%W' ${shellQuote(abs)} 2>/dev/null || stat -f '%HT|%z|%m|%B' ${shellQuote(abs)}`,\n );\n if (result.exitCode !== 0) {\n throw new FileNotFoundError(path);\n }\n const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split('|');\n const type = kind && kind.toLowerCase().includes('directory') ? 'directory' : 'file';\n const size = Number(sizeStr) || 0;\n const mtime = Number(mtimeStr) || 0;\n const ctime = Number(ctimeStr);\n return {\n name: posixPath.basename(abs),\n path: `/${posixPath.relative(this.basePath, abs)}`,\n type,\n size: type === 'directory' ? 0 : size,\n modifiedAt: new Date(mtime * 1000),\n createdAt: new Date((ctime > 0 ? ctime : mtime) * 1000),\n };\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n async init(): Promise<void> {\n await this.execOk(`mkdir -p ${shellQuote(this.basePath)}`, 'init workdir');\n }\n\n async destroy(): Promise<void> {\n // The sandbox lifecycle is owned by the caller; nothing to tear down here.\n }\n\n async isReady(): Promise<boolean> {\n const result = await this.exec(`test -d ${shellQuote(this.basePath)}`);\n return result.exitCode === 0;\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n metadata: { basePath: this.basePath, sandboxId: this.sandbox.id },\n };\n }\n\n getInstructions(): string {\n return `Files are stored in a remote sandbox at ${this.basePath}. Use absolute workspace paths like /src/index.ts. All reads, writes and commands run inside the same sandbox.`;\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
@@ -66,6 +66,12 @@ const MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS = 500;
66
66
  const MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS = 3e4;
67
67
  const TRANSIENT_CONNECTION_ERROR_CODES = /* @__PURE__ */ new Set(["ECONNRESET", "EPIPE"]);
68
68
  const TRANSIENT_CONNECTION_MESSAGE_PATTERN = /econnreset|socket hang up|write epipe|other side closed/i;
69
+ const TRANSIENT_SERVER_ERROR_STATUSES = /* @__PURE__ */ new Set([
70
+ 500,
71
+ 502,
72
+ 503
73
+ ]);
74
+ const TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN = /internal server|server error|api may be experiencing issues/i;
69
75
  /**
70
76
  * Matcher for transient connection failures. Cause-chain traversal is handled
71
77
  * by `StreamErrorRetryProcessor.isRetryableStreamError`, which calls each
@@ -79,7 +85,17 @@ function isTransientConnectionError(error) {
79
85
  if (typeof message === "string" && TRANSIENT_CONNECTION_MESSAGE_PATTERN.test(message)) return true;
80
86
  return false;
81
87
  }
82
- function emitTransientConnectionRetry(error, retryCount, delayMs, requestContext) {
88
+ function isTransientServerError(error) {
89
+ if (!error) return false;
90
+ const errorObj = typeof error === "object" ? error : void 0;
91
+ if (typeof errorObj?.status === "number" && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.status) || typeof errorObj?.statusCode === "number" && TRANSIENT_SERVER_ERROR_STATUSES.has(errorObj.statusCode)) return true;
92
+ const message = error instanceof Error ? error.message : void 0;
93
+ return typeof message === "string" && TRANSIENT_SERVER_ERROR_MESSAGE_PATTERN.test(message);
94
+ }
95
+ function getTransientRetryDelay(retryCount) {
96
+ return Math.min(MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS * Math.pow(2, retryCount), MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS);
97
+ }
98
+ function emitTransientRetry(error, retryCount, delayMs, requestContext) {
83
99
  (requestContext?.get("controller"))?.emitEvent?.({
84
100
  type: "error",
85
101
  error: error instanceof Error ? error : new Error(String(error)),
@@ -385,16 +401,25 @@ async function createMastraCodeAgentController(config) {
385
401
  ],
386
402
  errorProcessors: [
387
403
  new ProviderHistoryCompat(),
388
- new StreamErrorRetryProcessor({ matchers: [{
389
- match: isBadRequestError,
390
- maxRetries: 1,
391
- delayMs: 2e3
392
- }, {
393
- match: isTransientConnectionError,
394
- maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,
395
- delayMs: ({ retryCount }) => Math.min(MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS * Math.pow(2, retryCount), MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS),
396
- onRetry: ({ error, retryCount, delayMs, requestContext }) => emitTransientConnectionRetry(error, retryCount, delayMs, requestContext)
397
- }] }),
404
+ new StreamErrorRetryProcessor({ matchers: [
405
+ {
406
+ match: isBadRequestError,
407
+ maxRetries: 1,
408
+ delayMs: 2e3
409
+ },
410
+ {
411
+ match: isTransientConnectionError,
412
+ maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,
413
+ delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),
414
+ onRetry: ({ error, retryCount, delayMs, requestContext }) => emitTransientRetry(error, retryCount, delayMs, requestContext)
415
+ },
416
+ {
417
+ match: isTransientServerError,
418
+ maxRetries: MASTRACODE_TRANSIENT_CONNECTION_MAX_RETRIES,
419
+ delayMs: ({ retryCount }) => getTransientRetryDelay(retryCount),
420
+ onRetry: ({ error, retryCount, delayMs, requestContext }) => emitTransientRetry(error, retryCount, delayMs, requestContext)
421
+ }
422
+ ] }),
398
423
  new PrefillErrorHandler()
399
424
  ]
400
425
  });
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 connection failures (e.g. provider sockets dropping mid-stream).\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 dropped connection.\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;\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 emitTransientConnectionRetry(\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 }) =>\n Math.min(\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_INITIAL_DELAY_MS * Math.pow(2, retryCount),\n MASTRACODE_TRANSIENT_CONNECTION_RETRY_MAX_DELAY_MS,\n ),\n onRetry: ({ error, retryCount, delayMs, requestContext }) =>\n emitTransientConnectionRetry(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 { 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "1.1.1-alpha.0",
3
+ "version": "1.1.1-alpha.2",
4
4
  "description": "Mastra Code SDK: the agent core behind Mastra Code (everything except the TUI) — build your own UIs and surfaces on top of it",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -58,17 +58,17 @@
58
58
  "zod": "^4.3.6",
59
59
  "@mastra/agent-browser": "0.4.1",
60
60
  "@mastra/fastembed": "1.2.0",
61
- "@mastra/core": "1.55.0-alpha.0",
62
61
  "@mastra/duckdb": "1.5.2",
63
62
  "@mastra/github-signals": "0.2.2",
64
- "@mastra/mcp": "1.15.0",
63
+ "@mastra/core": "1.55.0-alpha.2",
65
64
  "@mastra/libsql": "1.18.0",
65
+ "@mastra/mcp": "1.15.0",
66
+ "@mastra/observability": "1.16.3",
66
67
  "@mastra/memory": "1.24.0",
67
- "@mastra/schema-compat": "1.3.4",
68
68
  "@mastra/pg": "1.18.0",
69
69
  "@mastra/stagehand": "0.3.1",
70
- "@mastra/tavily": "1.1.1",
71
- "@mastra/observability": "1.16.3"
70
+ "@mastra/schema-compat": "1.3.4",
71
+ "@mastra/tavily": "1.1.1"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@libsql/client": "^0.17.4",
@@ -79,8 +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",
82
83
  "@internal/lint": "0.0.118",
83
- "@internal/types-builder": "0.0.93"
84
+ "@internal/workspace-test-utils": "0.0.62"
84
85
  },
85
86
  "engines": {
86
87
  "node": ">=22.19.0"