@mastra/code-sdk 0.1.0-alpha.0 → 0.1.0-alpha.10

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/agents/mastracode-gateway.d.ts +4 -2
  3. package/dist/agents/mastracode-gateway.d.ts.map +1 -1
  4. package/dist/agents/mastracode-gateway.js +11 -7
  5. package/dist/agents/mastracode-gateway.js.map +1 -1
  6. package/dist/agents/model.js +1 -1
  7. package/dist/agents/model.js.map +1 -1
  8. package/dist/agents/tools.d.ts +3 -3
  9. package/dist/agents/tools.d.ts.map +1 -1
  10. package/dist/agents/tools.js +33 -22
  11. package/dist/agents/tools.js.map +1 -1
  12. package/dist/agents/workspace.d.ts.map +1 -1
  13. package/dist/agents/workspace.js +51 -19
  14. package/dist/agents/workspace.js.map +1 -1
  15. package/dist/index.d.ts +7 -9
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +17 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/onboarding/settings.d.ts +6 -2
  20. package/dist/onboarding/settings.d.ts.map +1 -1
  21. package/dist/onboarding/settings.js +6 -2
  22. package/dist/onboarding/settings.js.map +1 -1
  23. package/dist/plugins/dependencies.d.ts.map +1 -1
  24. package/dist/plugins/dependencies.js +28 -58
  25. package/dist/plugins/dependencies.js.map +1 -1
  26. package/dist/utils/path-security.d.ts +2 -0
  27. package/dist/utils/path-security.d.ts.map +1 -0
  28. package/dist/utils/path-security.js +9 -0
  29. package/dist/utils/path-security.js.map +1 -0
  30. package/dist/utils/project.d.ts +1 -2
  31. package/dist/utils/project.d.ts.map +1 -1
  32. package/dist/utils/project.js.map +1 -1
  33. package/dist/utils/slash-command-loader.d.ts +5 -1
  34. package/dist/utils/slash-command-loader.d.ts.map +1 -1
  35. package/dist/utils/slash-command-loader.js +30 -8
  36. package/dist/utils/slash-command-loader.js.map +1 -1
  37. package/dist/utils/storage-factory.d.ts +3 -3
  38. package/dist/utils/storage-factory.d.ts.map +1 -1
  39. package/dist/utils/storage-factory.js +5 -2
  40. package/dist/utils/storage-factory.js.map +1 -1
  41. package/dist/utils/storage-maintenance.d.ts +103 -0
  42. package/dist/utils/storage-maintenance.d.ts.map +1 -0
  43. package/dist/utils/storage-maintenance.js +236 -0
  44. package/dist/utils/storage-maintenance.js.map +1 -0
  45. package/package.json +17 -15
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
5
5
  import { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from "@mastra/core/workspace";
6
6
  import { DEFAULT_CONFIG_DIR } from "../constants.js";
7
7
  import { loadSettings } from "../onboarding/settings.js";
8
+ import { isPathWithinRoot } from "../utils/path-security.js";
8
9
  import { getPlansDir } from "../utils/plans.js";
9
10
  import { SandboxFilesystem } from "./sandbox-filesystem.js";
10
11
  import { reattachProjectSandbox } from "./sandbox-reattach.js";
@@ -21,29 +22,52 @@ function buildSandboxEnv() {
21
22
  DEBIAN_FRONTEND: "noninteractive"
22
23
  };
23
24
  }
24
- function collectSkillPaths(skillsDirs) {
25
+ function collectSkillPaths(skillsDirs, allowedRoot) {
25
26
  const paths = [];
26
27
  const seen = /* @__PURE__ */ new Set();
28
+ let realAllowedRoot;
29
+ if (allowedRoot) {
30
+ try {
31
+ realAllowedRoot = fs.realpathSync(allowedRoot);
32
+ } catch {
33
+ return [];
34
+ }
35
+ }
27
36
  for (const skillsDir of skillsDirs) {
37
+ const skillsDirExists = fs.existsSync(skillsDir);
38
+ if (skillsDirExists && realAllowedRoot) {
39
+ try {
40
+ const realSkillsDir = fs.realpathSync(skillsDir);
41
+ if (!isPathWithinRoot(realSkillsDir, realAllowedRoot)) continue;
42
+ } catch {
43
+ continue;
44
+ }
45
+ }
28
46
  const resolved = path.resolve(skillsDir);
29
47
  if (!seen.has(resolved)) {
30
48
  seen.add(resolved);
31
49
  paths.push(skillsDir);
32
50
  }
33
- if (!fs.existsSync(skillsDir)) continue;
51
+ if (!skillsDirExists) continue;
34
52
  try {
35
53
  const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
36
54
  for (const entry of entries) {
37
55
  if (entry.isSymbolicLink()) {
38
- const linkPath = path.join(skillsDir, entry.name);
39
- const realPath = fs.realpathSync(linkPath);
40
- const stat = fs.statSync(realPath);
41
- if (stat.isDirectory()) {
42
- const realParent = path.dirname(realPath);
43
- if (!seen.has(realParent)) {
44
- seen.add(realParent);
45
- paths.push(realParent);
56
+ try {
57
+ const linkPath = path.join(skillsDir, entry.name);
58
+ const realPath = fs.realpathSync(linkPath);
59
+ if (realAllowedRoot && !isPathWithinRoot(realPath, realAllowedRoot)) continue;
60
+ const stat = fs.statSync(realPath);
61
+ if (stat.isDirectory()) {
62
+ const realParent = path.dirname(realPath);
63
+ if (realAllowedRoot && !isPathWithinRoot(realParent, realAllowedRoot)) continue;
64
+ if (!seen.has(realParent)) {
65
+ seen.add(realParent);
66
+ paths.push(realParent);
67
+ }
46
68
  }
69
+ } catch {
70
+ continue;
47
71
  }
48
72
  }
49
73
  }
@@ -59,15 +83,23 @@ function buildSkillPaths(projectPath, configDir, homeDir = os.homedir(), pluginS
59
83
  const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, "skills");
60
84
  const claudeGlobalSkillsPath = path.join(homeDir, ".claude", "skills");
61
85
  const agentSkillsGlobalPath = path.join(homeDir, ".agents", "skills");
62
- return collectSkillPaths([
63
- mastraCodeLocalSkillsPath,
64
- claudeLocalSkillsPath,
65
- agentSkillsLocalPath,
66
- mastraCodeGlobalSkillsPath,
67
- claudeGlobalSkillsPath,
68
- agentSkillsGlobalPath,
69
- ...pluginSkillPaths
70
- ]);
86
+ const paths = [
87
+ ...collectSkillPaths([mastraCodeLocalSkillsPath, claudeLocalSkillsPath, agentSkillsLocalPath], projectPath),
88
+ ...collectSkillPaths([mastraCodeGlobalSkillsPath, claudeGlobalSkillsPath, agentSkillsGlobalPath]),
89
+ ...pluginSkillPaths.flatMap((pluginSkillPath) => collectSkillPaths([pluginSkillPath], pluginSkillPath))
90
+ ];
91
+ const seenPaths = /* @__PURE__ */ new Set();
92
+ return paths.filter((skillPath) => {
93
+ let resolved;
94
+ try {
95
+ resolved = fs.realpathSync(skillPath);
96
+ } catch {
97
+ resolved = path.resolve(skillPath);
98
+ }
99
+ if (seenPaths.has(resolved)) return false;
100
+ seenPaths.add(resolved);
101
+ return true;
102
+ });
71
103
  }
72
104
  const DEFAULT_ALLOWED_PATHS = [os.tmpdir(), "/tmp", getPlansDir()].reduce((acc, p) => {
73
105
  const resolved = path.resolve(p);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agents/workspace.ts"],"sourcesContent":["import fs, { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path, { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from '@mastra/core/workspace';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getPlansDir } from '../utils/plans.js';\nimport { SandboxFilesystem } from './sandbox-filesystem.js';\nimport { reattachProjectSandbox } from './sandbox-reattach.js';\nimport { GOAL_JUDGE_READONLY_TOOLS, MASTRACODE_WORKSPACE_TOOLS } from './tool-availability.js';\n\n// =============================================================================\n// Sandbox Environment\n// =============================================================================\n\nfunction buildSandboxEnv(): NodeJS.ProcessEnv {\n return {\n ...process.env,\n // Explicit overrides for non-interactive subprocess execution\n FORCE_COLOR: '1',\n CLICOLOR_FORCE: '1',\n TERM: process.env.TERM || 'xterm-256color',\n CI: 'true',\n NONINTERACTIVE: '1',\n DEBIAN_FRONTEND: 'noninteractive',\n };\n}\n\n// =============================================================================\n// Create Workspace with Skills\n// =============================================================================\n\n// We support multiple skill locations for compatibility:\n// 1. Project-local: <configDir>/skills (project-specific mastracode skills)\n// 2. Project-local: .claude/skills (Claude Code compatible skills)\n// 3. Project-local: .agents/skills (Agent Skills spec compatible)\n// 4. Global: ~/<configDir>/skills (user-wide mastracode skills)\n// 5. Global: ~/.claude/skills (user-wide Claude Code skills)\n// 6. Global: ~/.agents/skills (user-wide Agent Skills spec compatible)\n\n// Mastra's LocalSkillSource.readdir uses Node's Dirent.isDirectory() which\n// returns false for symlinks. Tools like `npx skills add` install skills as\n// symlinks, so we need to resolve them. For each symlinked skill directory,\n// we add the real (resolved) parent path as an additional skill scan path.\nfunction collectSkillPaths(skillsDirs: string[]): string[] {\n const paths: string[] = [];\n const seen = new Set<string>();\n\n for (const skillsDir of skillsDirs) {\n const resolved = path.resolve(skillsDir);\n if (!seen.has(resolved)) {\n seen.add(resolved);\n paths.push(skillsDir);\n }\n\n if (!fs.existsSync(skillsDir)) continue;\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) {\n const linkPath = path.join(skillsDir, entry.name);\n const realPath = fs.realpathSync(linkPath);\n const stat = fs.statSync(realPath);\n if (stat.isDirectory()) {\n const realParent = path.dirname(realPath);\n if (!seen.has(realParent)) {\n seen.add(realParent);\n paths.push(realParent);\n }\n }\n }\n }\n } catch {\n // Ignore errors during symlink resolution\n }\n }\n\n return paths;\n}\n\n// Build skill paths dynamically based on configDir and projectPath\nexport function buildSkillPaths(\n projectPath: string,\n configDir: string,\n homeDir = os.homedir(),\n pluginSkillPaths: string[] = [],\n): string[] {\n const mastraCodeLocalSkillsPath = path.join(projectPath, configDir, 'skills');\n const claudeLocalSkillsPath = path.join(projectPath, '.claude', 'skills');\n const agentSkillsLocalPath = path.join(projectPath, '.agents', 'skills');\n const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, 'skills');\n const claudeGlobalSkillsPath = path.join(homeDir, '.claude', 'skills');\n const agentSkillsGlobalPath = path.join(homeDir, '.agents', 'skills');\n\n return collectSkillPaths([\n mastraCodeLocalSkillsPath,\n claudeLocalSkillsPath,\n agentSkillsLocalPath,\n mastraCodeGlobalSkillsPath,\n claudeGlobalSkillsPath,\n agentSkillsGlobalPath,\n ...pluginSkillPaths,\n ]);\n}\n\n/**\n * Paths the agent is always allowed to access (in addition to the project root\n * and any per-thread sandboxAllowedPaths). The OS temp directory is included\n * so the agent can use it as a scratchpad without requesting access every time.\n */\nconst DEFAULT_ALLOWED_PATHS: string[] = [os.tmpdir(), '/tmp', getPlansDir()].reduce<string[]>((acc, p) => {\n const resolved = path.resolve(p);\n if (!acc.includes(resolved)) acc.push(resolved);\n return acc;\n}, []);\n\nconst WORKSPACE_ID_PREFIX = 'mastra-code-workspace';\n\n/**\n * Detect the project's package runner from lock files.\n * Used as a fallback packageRunner for LSP when no binary is found locally or on PATH.\n */\nfunction detectPackageRunner(projectPath: string): string | undefined {\n if (existsSync(join(projectPath, 'pnpm-lock.yaml'))) return 'pnpm dlx';\n if (existsSync(join(projectPath, 'bun.lockb')) || existsSync(join(projectPath, 'bun.lock'))) return 'bunx';\n if (existsSync(join(projectPath, 'yarn.lock'))) return 'yarn dlx';\n if (existsSync(join(projectPath, 'package-lock.json'))) return 'npx --yes';\n return 'npx --yes';\n}\n\n/**\n * Build (or reuse) a sandbox-backed Workspace for a GitHub project. The sandbox\n * is reattached by its persisted provider id and a `SandboxFilesystem` is layered\n * over the in-sandbox checkout so file tools and command tools share one VM.\n */\nasync function getSandboxWorkspace({\n githubProjectId,\n sandboxId,\n workdir,\n worktreePath,\n mastra,\n}: {\n githubProjectId: string;\n sandboxId: string;\n workdir: string;\n worktreePath?: string;\n mastra?: Mastra;\n}): Promise<Workspace> {\n // Bind the workspace to the active worktree when one is set, so file tools and\n // command tools operate inside the feature branch's working tree rather than\n // the base checkout. Falls back to the repo root when no worktree is active.\n const boundWorkdir = worktreePath || workdir;\n\n // Include the sandbox id *and* worktree path in the reuse key: a new sandbox\n // (e.g. the previous one expired) or a different worktree must each get a\n // fresh Workspace/ProcessManager instead of reusing one bound to a stale\n // sandbox or the wrong working tree.\n const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}`;\n\n // Reuse the existing remote workspace if already registered (preserves the\n // reattached sandbox + ProcessManager state across re-opens).\n try {\n const existing = mastra?.getWorkspaceById(workspaceId) as Workspace | undefined;\n if (existing) {\n existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);\n return existing;\n }\n } catch {\n // Not registered yet.\n }\n\n const sandbox = await reattachProjectSandbox(sandboxId);\n const filesystem = new SandboxFilesystem({ sandbox, workdir: boundWorkdir });\n\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Sandbox Workspace',\n filesystem,\n sandbox: sandbox as unknown as ConstructorParameters<typeof Workspace>[0]['sandbox'],\n tools: MASTRACODE_WORKSPACE_TOOLS,\n });\n}\n\nexport async function getDynamicWorkspace({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}) {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = ctx?.getState();\n\n // GitHub/cloud-sandbox-backed project: the repo lives inside a remote sandbox,\n // not on the server host. Reattach to the already-provisioned + materialized\n // sandbox (the SPA called `.../ensure` first, persisting sandboxId/workdir on\n // controller state) and build a sandbox-backed Workspace. LSP/host skill paths\n // are skipped for these workspaces (follow-up).\n if (state?.githubProjectId && state.sandboxId && state.sandboxWorkdir) {\n return getSandboxWorkspace({\n githubProjectId: state.githubProjectId,\n sandboxId: state.sandboxId,\n workdir: state.sandboxWorkdir,\n worktreePath: state.worktreePath,\n mastra,\n });\n }\n\n const rawProjectPath = state?.projectPath;\n\n if (!rawProjectPath) {\n throw new Error('Project path is required');\n }\n\n const projectPath = path.resolve(rawProjectPath);\n const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;\n const skillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);\n const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;\n const sandboxPaths = state?.sandboxAllowedPaths ?? [];\n const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p: string) => path.resolve(p))];\n\n // All modes share the same workspace tool configuration. Per-mode tool\n // visibility is enforced at LLM-call time via `availableTools` /\n // `activeTools` on the AgentController, not by mutating workspace capabilities.\n const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;\n\n // Reuse existing workspace if already registered (preserves ProcessManager state)\n let existing: Workspace<LocalFilesystem, LocalSandbox> | undefined;\n try {\n existing = mastra?.getWorkspaceById(workspaceId) as Workspace<LocalFilesystem, LocalSandbox>;\n } catch {\n // Not registered yet\n }\n\n if (existing) {\n existing.filesystem.setAllowedPaths(allowedPaths);\n existing.setToolsConfig(workspaceTools);\n return existing;\n }\n\n const userLsp = loadSettings().lsp ?? {};\n const mcModulePath = join(dirname(fileURLToPath(import.meta.url)), '..');\n const lspConfig: LSPConfig = {\n ...userLsp,\n packageRunner: userLsp.packageRunner || detectPackageRunner(projectPath), // Detected runner is the fallback — user's packageRunner always wins\n searchPaths: [mcModulePath, ...(userLsp.searchPaths ?? [])],\n };\n\n // First call for this project — create the workspace\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Workspace',\n filesystem: new LocalFilesystem({\n basePath: projectPath,\n allowedPaths,\n }),\n sandbox: new LocalSandbox({\n workingDirectory: projectPath,\n env: buildSandboxEnv(),\n }),\n tools: workspaceTools,\n ...(skillPaths.length > 0 ? { skills: skillPaths } : {}),\n lsp: lspConfig,\n });\n}\n\n/**\n * Resolver for the agent's `goal.tools` config. Builds the request's workspace\n * (same per-request resolution as the agent's own tools) and returns only the\n * read-only verification subset, remapped to mastracode's tool names (`view`,\n * `search_content`, etc.). Returns `undefined` when no workspace can be resolved\n * (e.g. no project path), keeping the default judge text-only rather than\n * throwing inside the goal step.\n */\nexport async function getGoalJudgeTools({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}): Promise<ToolsInput | undefined> {\n let workspace: Workspace;\n try {\n workspace = await getDynamicWorkspace({ requestContext, mastra });\n } catch {\n return undefined;\n }\n\n const allTools = await createWorkspaceTools(workspace, { requestContext, workspace });\n const readonly: ToolsInput = {};\n for (const name of GOAL_JUDGE_READONLY_TOOLS) {\n if (allTools[name]) readonly[name] = allTools[name];\n }\n return Object.keys(readonly).length > 0 ? readonly : undefined;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/agents/workspace.ts"],"sourcesContent":["import fs, { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path, { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { Workspace, LocalFilesystem, LocalSandbox, createWorkspaceTools } from '@mastra/core/workspace';\nimport type { LSPConfig } from '@mastra/core/workspace';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { isPathWithinRoot } from '../utils/path-security.js';\nimport { getPlansDir } from '../utils/plans.js';\nimport { SandboxFilesystem } from './sandbox-filesystem.js';\nimport { reattachProjectSandbox } from './sandbox-reattach.js';\nimport { GOAL_JUDGE_READONLY_TOOLS, MASTRACODE_WORKSPACE_TOOLS } from './tool-availability.js';\n\n// =============================================================================\n// Sandbox Environment\n// =============================================================================\n\nfunction buildSandboxEnv(): NodeJS.ProcessEnv {\n return {\n ...process.env,\n // Explicit overrides for non-interactive subprocess execution\n FORCE_COLOR: '1',\n CLICOLOR_FORCE: '1',\n TERM: process.env.TERM || 'xterm-256color',\n CI: 'true',\n NONINTERACTIVE: '1',\n DEBIAN_FRONTEND: 'noninteractive',\n };\n}\n\n// =============================================================================\n// Create Workspace with Skills\n// =============================================================================\n\n// We support multiple skill locations for compatibility:\n// 1. Project-local: <configDir>/skills (project-specific mastracode skills)\n// 2. Project-local: .claude/skills (Claude Code compatible skills)\n// 3. Project-local: .agents/skills (Agent Skills spec compatible)\n// 4. Global: ~/<configDir>/skills (user-wide mastracode skills)\n// 5. Global: ~/.claude/skills (user-wide Claude Code skills)\n// 6. Global: ~/.agents/skills (user-wide Agent Skills spec compatible)\n\n// Mastra's LocalSkillSource.readdir uses Node's Dirent.isDirectory() which\n// returns false for symlinks. Tools like `npx skills add` install skills as\n// symlinks, so we need to resolve them. For each symlinked skill directory,\n// we add the real (resolved) parent path as an additional skill scan path.\nfunction collectSkillPaths(skillsDirs: string[], allowedRoot?: string): string[] {\n const paths: string[] = [];\n const seen = new Set<string>();\n let realAllowedRoot: string | undefined;\n\n if (allowedRoot) {\n try {\n realAllowedRoot = fs.realpathSync(allowedRoot);\n } catch {\n return [];\n }\n }\n\n for (const skillsDir of skillsDirs) {\n const skillsDirExists = fs.existsSync(skillsDir);\n if (skillsDirExists && realAllowedRoot) {\n try {\n const realSkillsDir = fs.realpathSync(skillsDir);\n if (!isPathWithinRoot(realSkillsDir, realAllowedRoot)) continue;\n } catch {\n continue;\n }\n }\n\n const resolved = path.resolve(skillsDir);\n if (!seen.has(resolved)) {\n seen.add(resolved);\n paths.push(skillsDir);\n }\n\n if (!skillsDirExists) continue;\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) {\n try {\n const linkPath = path.join(skillsDir, entry.name);\n const realPath = fs.realpathSync(linkPath);\n if (realAllowedRoot && !isPathWithinRoot(realPath, realAllowedRoot)) continue;\n const stat = fs.statSync(realPath);\n if (stat.isDirectory()) {\n const realParent = path.dirname(realPath);\n if (realAllowedRoot && !isPathWithinRoot(realParent, realAllowedRoot)) continue;\n if (!seen.has(realParent)) {\n seen.add(realParent);\n paths.push(realParent);\n }\n }\n } catch {\n continue;\n }\n }\n }\n } catch {\n // Ignore errors during symlink resolution\n }\n }\n\n return paths;\n}\n\n// Build skill paths dynamically based on configDir and projectPath\nexport function buildSkillPaths(\n projectPath: string,\n configDir: string,\n homeDir = os.homedir(),\n pluginSkillPaths: string[] = [],\n): string[] {\n const mastraCodeLocalSkillsPath = path.join(projectPath, configDir, 'skills');\n const claudeLocalSkillsPath = path.join(projectPath, '.claude', 'skills');\n const agentSkillsLocalPath = path.join(projectPath, '.agents', 'skills');\n const mastraCodeGlobalSkillsPath = path.join(homeDir, configDir, 'skills');\n const claudeGlobalSkillsPath = path.join(homeDir, '.claude', 'skills');\n const agentSkillsGlobalPath = path.join(homeDir, '.agents', 'skills');\n\n const paths = [\n ...collectSkillPaths([mastraCodeLocalSkillsPath, claudeLocalSkillsPath, agentSkillsLocalPath], projectPath),\n ...collectSkillPaths([mastraCodeGlobalSkillsPath, claudeGlobalSkillsPath, agentSkillsGlobalPath]),\n ...pluginSkillPaths.flatMap(pluginSkillPath => collectSkillPaths([pluginSkillPath], pluginSkillPath)),\n ];\n\n const seenPaths = new Set<string>();\n return paths.filter(skillPath => {\n let resolved: string;\n try {\n resolved = fs.realpathSync(skillPath);\n } catch {\n resolved = path.resolve(skillPath);\n }\n if (seenPaths.has(resolved)) return false;\n seenPaths.add(resolved);\n return true;\n });\n}\n\n/**\n * Paths the agent is always allowed to access (in addition to the project root\n * and any per-thread sandboxAllowedPaths). The OS temp directory is included\n * so the agent can use it as a scratchpad without requesting access every time.\n */\nconst DEFAULT_ALLOWED_PATHS: string[] = [os.tmpdir(), '/tmp', getPlansDir()].reduce<string[]>((acc, p) => {\n const resolved = path.resolve(p);\n if (!acc.includes(resolved)) acc.push(resolved);\n return acc;\n}, []);\n\nconst WORKSPACE_ID_PREFIX = 'mastra-code-workspace';\n\n/**\n * Detect the project's package runner from lock files.\n * Used as a fallback packageRunner for LSP when no binary is found locally or on PATH.\n */\nfunction detectPackageRunner(projectPath: string): string | undefined {\n if (existsSync(join(projectPath, 'pnpm-lock.yaml'))) return 'pnpm dlx';\n if (existsSync(join(projectPath, 'bun.lockb')) || existsSync(join(projectPath, 'bun.lock'))) return 'bunx';\n if (existsSync(join(projectPath, 'yarn.lock'))) return 'yarn dlx';\n if (existsSync(join(projectPath, 'package-lock.json'))) return 'npx --yes';\n return 'npx --yes';\n}\n\n/**\n * Build (or reuse) a sandbox-backed Workspace for a GitHub project. The sandbox\n * is reattached by its persisted provider id and a `SandboxFilesystem` is layered\n * over the in-sandbox checkout so file tools and command tools share one VM.\n */\nasync function getSandboxWorkspace({\n githubProjectId,\n sandboxId,\n workdir,\n worktreePath,\n mastra,\n}: {\n githubProjectId: string;\n sandboxId: string;\n workdir: string;\n worktreePath?: string;\n mastra?: Mastra;\n}): Promise<Workspace> {\n // Bind the workspace to the active worktree when one is set, so file tools and\n // command tools operate inside the feature branch's working tree rather than\n // the base checkout. Falls back to the repo root when no worktree is active.\n const boundWorkdir = worktreePath || workdir;\n\n // Include the sandbox id *and* worktree path in the reuse key: a new sandbox\n // (e.g. the previous one expired) or a different worktree must each get a\n // fresh Workspace/ProcessManager instead of reusing one bound to a stale\n // sandbox or the wrong working tree.\n const workspaceId = `${WORKSPACE_ID_PREFIX}-gh-${githubProjectId}-${sandboxId}-${boundWorkdir}`;\n\n // Reuse the existing remote workspace if already registered (preserves the\n // reattached sandbox + ProcessManager state across re-opens).\n try {\n const existing = mastra?.getWorkspaceById(workspaceId) as Workspace | undefined;\n if (existing) {\n existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);\n return existing;\n }\n } catch {\n // Not registered yet.\n }\n\n const sandbox = await reattachProjectSandbox(sandboxId);\n const filesystem = new SandboxFilesystem({ sandbox, workdir: boundWorkdir });\n\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Sandbox Workspace',\n filesystem,\n sandbox: sandbox as unknown as ConstructorParameters<typeof Workspace>[0]['sandbox'],\n tools: MASTRACODE_WORKSPACE_TOOLS,\n });\n}\n\nexport async function getDynamicWorkspace({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}) {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = ctx?.getState();\n\n // GitHub/cloud-sandbox-backed project: the repo lives inside a remote sandbox,\n // not on the server host. Reattach to the already-provisioned + materialized\n // sandbox (the SPA called `.../ensure` first, persisting sandboxId/workdir on\n // controller state) and build a sandbox-backed Workspace. LSP/host skill paths\n // are skipped for these workspaces (follow-up).\n if (state?.githubProjectId && state.sandboxId && state.sandboxWorkdir) {\n return getSandboxWorkspace({\n githubProjectId: state.githubProjectId,\n sandboxId: state.sandboxId,\n workdir: state.sandboxWorkdir,\n worktreePath: state.worktreePath,\n mastra,\n });\n }\n\n const rawProjectPath = state?.projectPath;\n\n if (!rawProjectPath) {\n throw new Error('Project path is required');\n }\n\n const projectPath = path.resolve(rawProjectPath);\n const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;\n const skillPaths = buildSkillPaths(projectPath, configDir, state?.homeDir, state?.pluginSkillPaths ?? []);\n const workspaceId = `${WORKSPACE_ID_PREFIX}-${projectPath}`;\n const sandboxPaths = state?.sandboxAllowedPaths ?? [];\n const allowedPaths = [...skillPaths, ...DEFAULT_ALLOWED_PATHS, ...sandboxPaths.map((p: string) => path.resolve(p))];\n\n // All modes share the same workspace tool configuration. Per-mode tool\n // visibility is enforced at LLM-call time via `availableTools` /\n // `activeTools` on the AgentController, not by mutating workspace capabilities.\n const workspaceTools = MASTRACODE_WORKSPACE_TOOLS;\n\n // Reuse existing workspace if already registered (preserves ProcessManager state)\n let existing: Workspace<LocalFilesystem, LocalSandbox> | undefined;\n try {\n existing = mastra?.getWorkspaceById(workspaceId) as Workspace<LocalFilesystem, LocalSandbox>;\n } catch {\n // Not registered yet\n }\n\n if (existing) {\n existing.filesystem.setAllowedPaths(allowedPaths);\n existing.setToolsConfig(workspaceTools);\n return existing;\n }\n\n const userLsp = loadSettings().lsp ?? {};\n const mcModulePath = join(dirname(fileURLToPath(import.meta.url)), '..');\n const lspConfig: LSPConfig = {\n ...userLsp,\n packageRunner: userLsp.packageRunner || detectPackageRunner(projectPath), // Detected runner is the fallback — user's packageRunner always wins\n searchPaths: [mcModulePath, ...(userLsp.searchPaths ?? [])],\n };\n\n // First call for this project — create the workspace\n return new Workspace({\n id: workspaceId,\n name: 'Mastra Code Workspace',\n filesystem: new LocalFilesystem({\n basePath: projectPath,\n allowedPaths,\n }),\n sandbox: new LocalSandbox({\n workingDirectory: projectPath,\n env: buildSandboxEnv(),\n }),\n tools: workspaceTools,\n ...(skillPaths.length > 0 ? { skills: skillPaths } : {}),\n lsp: lspConfig,\n });\n}\n\n/**\n * Resolver for the agent's `goal.tools` config. Builds the request's workspace\n * (same per-request resolution as the agent's own tools) and returns only the\n * read-only verification subset, remapped to mastracode's tool names (`view`,\n * `search_content`, etc.). Returns `undefined` when no workspace can be resolved\n * (e.g. no project path), keeping the default judge text-only rather than\n * throwing inside the goal step.\n */\nexport async function getGoalJudgeTools({\n requestContext,\n mastra,\n}: {\n requestContext: RequestContext;\n mastra?: Mastra;\n}): Promise<ToolsInput | undefined> {\n let workspace: Workspace;\n try {\n workspace = await getDynamicWorkspace({ requestContext, mastra });\n } catch {\n return undefined;\n }\n\n const allTools = await createWorkspaceTools(workspace, { requestContext, workspace });\n const readonly: ToolsInput = {};\n for (const name of GOAL_JUDGE_READONLY_TOOLS) {\n if (allTools[name]) readonly[name] = allTools[name];\n }\n return Object.keys(readonly).length > 0 ? readonly : undefined;\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -8,12 +8,14 @@ import { MastraCompositeStore } from '@mastra/core/storage';
8
8
  import { GithubSignals } from '@mastra/github-signals';
9
9
  import { Observability } from '@mastra/observability';
10
10
  import { resolveModel } from './agents/model.js';
11
+ import type { ToolLike } from './agents/tools.js';
11
12
  import { AuthStorage } from './auth/storage.js';
12
13
  import { HookManager } from './hooks/index.js';
13
14
  import type { McpServerConfig } from './mcp/index.js';
14
15
  import { PluginManager } from './plugins/manager.js';
15
16
  import type { MastraCodeState } from './schema.js';
16
17
  import type { StorageConfig } from './utils/project.js';
18
+ import type { StorageMaintenance } from './utils/storage-maintenance.js';
17
19
  export interface MastraCodeConfig {
18
20
  /** Working directory for project detection. Default: process.cwd() */
19
21
  cwd?: string;
@@ -23,16 +25,10 @@ export interface MastraCodeConfig {
23
25
  modes?: AgentControllerMode[];
24
26
  /** Override or extend subagent definitions. Default: explore/plan/execute */
25
27
  subagents?: AgentControllerSubagent[];
26
- /** Extra tools merged into the dynamic tool set. Can be a static record or a function that receives requestContext. */
27
- extraTools?: Record<string, {
28
- execute?: (input: unknown, context?: unknown) => Promise<unknown> | unknown;
29
- [key: string]: unknown;
30
- }> | ((ctx: {
28
+ /** Extra tools merged into the dynamic tool set. Can be a static record or a (sync or async) function that receives requestContext. */
29
+ extraTools?: Record<string, ToolLike> | ((ctx: {
31
30
  requestContext: RequestContext;
32
- }) => Record<string, {
33
- execute?: (input: unknown, context?: unknown) => Promise<unknown> | unknown;
34
- [key: string]: unknown;
35
- }>);
31
+ }) => Record<string, ToolLike> | Promise<Record<string, ToolLike>>);
36
32
  /** Tools removed from the dynamic tool set before exposure to the model */
37
33
  disabledTools?: string[];
38
34
  /** Custom storage config instead of auto-detected default */
@@ -91,6 +87,7 @@ export declare function createAuthStorage(): AuthStorage;
91
87
  export declare function createMastraCodeAgentController(config?: MastraCodeConfig): Promise<{
92
88
  controller: AgentController<MastraCodeState>;
93
89
  storage: MastraCompositeStore;
90
+ storageMaintenance: StorageMaintenance;
94
91
  observability: Observability;
95
92
  memory: import("@mastra/core/types").DynamicArgument<import("@mastra/core/memory").MastraMemory> | (({ requestContext }: {
96
93
  requestContext: RequestContext;
@@ -137,6 +134,7 @@ export declare function bootLocalAgentController(config?: MastraCodeConfig): Pro
137
134
  session: Session<MastraCodeState>;
138
135
  controller: AgentController<MastraCodeState>;
139
136
  storage: MastraCompositeStore;
137
+ storageMaintenance: StorageMaintenance;
140
138
  observability: Observability;
141
139
  memory: import("@mastra/core/types").DynamicArgument<import("@mastra/core/memory").MastraMemory> | (({ requestContext }: {
142
140
  requestContext: RequestContext;
@@ -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
@@ -18,6 +18,7 @@ import { InMemoryHarness, MastraCompositeStore } from "@mastra/core/storage";
18
18
  import { DEFAULT_GOAL_JUDGE_PROMPT } from "@mastra/core/tools";
19
19
  import { DuckDBStore } from "@mastra/duckdb";
20
20
  import { GithubSignals } from "@mastra/github-signals";
21
+ import { LibSQLVector } from "@mastra/libsql";
21
22
  import {
22
23
  Observability,
23
24
  MastraStorageExporter,
@@ -42,7 +43,7 @@ import { createMcpManager } from "./mcp/index.js";
42
43
  import { getAvailableModePacks, getAvailableOmPacks } from "./onboarding/packs.js";
43
44
  import {
44
45
  loadSettings,
45
- MEMORY_GATEWAY_PROVIDER,
46
+ MASTRA_GATEWAY_PROVIDER,
46
47
  OBSERVABILITY_AUTH_PREFIX,
47
48
  resolveModelDefaults,
48
49
  resolveOmRoleModel,
@@ -66,6 +67,7 @@ import {
66
67
  } from "./utils/project.js";
67
68
  import { createSignalsPubSub } from "./utils/signals-pubsub.js";
68
69
  import { createStorage, createVectorStore } from "./utils/storage-factory.js";
70
+ import { createStorageMaintenance, DEFAULT_RETENTION, resolveLocalDbFiles } from "./utils/storage-maintenance.js";
69
71
  import { acquireThreadLock, releaseThreadLock } from "./utils/thread-lock.js";
70
72
  const CODE_AGENT_ID = "code-agent";
71
73
  const MASTRACODE_ECONNRESET_MAX_RETRIES = 2;
@@ -139,7 +141,7 @@ async function createMastraCodeAgentController(config) {
139
141
  }
140
142
  const authStorage = createAuthStorage();
141
143
  const globalSettings = loadSettings(config?.settingsPath);
142
- const storedGatewayKey = authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER);
144
+ const storedGatewayKey = authStorage.getStoredApiKey(MASTRA_GATEWAY_PROVIDER);
143
145
  const storedGatewayUrl = globalSettings.memoryGateway?.baseUrl;
144
146
  if (storedGatewayKey) {
145
147
  process.env["MASTRA_GATEWAY_API_KEY"] ??= storedGatewayKey;
@@ -154,11 +156,11 @@ async function createMastraCodeAgentController(config) {
154
156
  const envVars = cfg?.apiKeyEnvVar;
155
157
  providerEnvVars[provider] = Array.isArray(envVars) ? envVars[0] : envVars;
156
158
  }
157
- providerEnvVars[MEMORY_GATEWAY_PROVIDER] ??= "MASTRA_GATEWAY_API_KEY";
159
+ providerEnvVars[MASTRA_GATEWAY_PROVIDER] ??= "MASTRA_GATEWAY_API_KEY";
158
160
  authStorage.loadStoredApiKeysIntoEnv(providerEnvVars);
159
161
  } catch {
160
162
  authStorage.loadStoredApiKeysIntoEnv({
161
- [MEMORY_GATEWAY_PROVIDER]: "MASTRA_GATEWAY_API_KEY",
163
+ [MASTRA_GATEWAY_PROVIDER]: "MASTRA_GATEWAY_API_KEY",
162
164
  anthropic: "ANTHROPIC_API_KEY",
163
165
  openai: "OPENAI_API_KEY",
164
166
  google: "GOOGLE_GENERATIVE_AI_API_KEY",
@@ -218,7 +220,9 @@ async function createMastraCodeAgentController(config) {
218
220
  id: "mastra-code-storage",
219
221
  default: storageResult.storage,
220
222
  domains: {
221
- ...observabilityDomain ? { observability: observabilityDomain } : {},
223
+ // When local tracing is off, disable the observability domain entirely so
224
+ // trace/score/feedback writes never fall through to the default libsql store.
225
+ observability: observabilityDomain ?? false,
222
226
  harness: harnessStorage
223
227
  }
224
228
  });
@@ -277,6 +281,13 @@ async function createMastraCodeAgentController(config) {
277
281
  }
278
282
  });
279
283
  const vectorStore = await createVectorStore(storageConfig, storageResult.backend);
284
+ const storageMaintenance = createStorageMaintenance({
285
+ storage: storageResult.storage,
286
+ backend: storageResult.backend,
287
+ retention: DEFAULT_RETENTION,
288
+ localDbFiles: resolveLocalDbFiles(storageConfig, storageResult.backend),
289
+ closeVector: vectorStore instanceof LibSQLVector ? () => vectorStore.close() : void 0
290
+ });
280
291
  const memory = config?.memory === false ? void 0 : config?.memory ?? getDynamicMemory(storage, vectorStore);
281
292
  const mcpManager = config?.disableMcp ? void 0 : createMcpManager(project.rootPath, configDir, config?.mcpServers);
282
293
  const hookManager = config?.disableHooks ? void 0 : new HookManager(project.rootPath, "session-init", configDir, homeDir);
@@ -568,6 +579,7 @@ async function createMastraCodeAgentController(config) {
568
579
  return {
569
580
  controller,
570
581
  storage,
582
+ storageMaintenance,
571
583
  observability,
572
584
  memory,
573
585
  mcpManager,