@mastra/code-sdk 0.2.0-alpha.3 → 0.2.0-alpha.8

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 (85) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/agents/credential-resolver.d.ts +51 -0
  3. package/dist/agents/credential-resolver.d.ts.map +1 -0
  4. package/dist/agents/credential-resolver.js +41 -0
  5. package/dist/agents/credential-resolver.js.map +1 -0
  6. package/dist/agents/instructions.d.ts.map +1 -1
  7. package/dist/agents/instructions.js.map +1 -1
  8. package/dist/agents/mastracode-gateway.d.ts +11 -4
  9. package/dist/agents/mastracode-gateway.d.ts.map +1 -1
  10. package/dist/agents/mastracode-gateway.js +51 -30
  11. package/dist/agents/mastracode-gateway.js.map +1 -1
  12. package/dist/agents/model.d.ts +2 -0
  13. package/dist/agents/model.d.ts.map +1 -1
  14. package/dist/agents/model.js +13 -2
  15. package/dist/agents/model.js.map +1 -1
  16. package/dist/agents/workspace.d.ts +11 -1
  17. package/dist/agents/workspace.d.ts.map +1 -1
  18. package/dist/agents/workspace.js +31 -13
  19. package/dist/agents/workspace.js.map +1 -1
  20. package/dist/auth/authorization-input.d.ts +16 -0
  21. package/dist/auth/authorization-input.d.ts.map +1 -0
  22. package/dist/auth/authorization-input.js +28 -0
  23. package/dist/auth/authorization-input.js.map +1 -0
  24. package/dist/auth/device-code.d.ts +93 -0
  25. package/dist/auth/device-code.d.ts.map +1 -0
  26. package/dist/auth/device-code.js +97 -0
  27. package/dist/auth/device-code.js.map +1 -0
  28. package/dist/auth/index.d.ts +1 -0
  29. package/dist/auth/index.d.ts.map +1 -1
  30. package/dist/auth/index.js +3 -1
  31. package/dist/auth/index.js.map +1 -1
  32. package/dist/auth/providers/anthropic.d.ts +24 -1
  33. package/dist/auth/providers/anthropic.d.ts.map +1 -1
  34. package/dist/auth/providers/anthropic.js +21 -8
  35. package/dist/auth/providers/anthropic.js.map +1 -1
  36. package/dist/auth/providers/github-copilot.d.ts +54 -0
  37. package/dist/auth/providers/github-copilot.d.ts.map +1 -1
  38. package/dist/auth/providers/github-copilot.js +88 -61
  39. package/dist/auth/providers/github-copilot.js.map +1 -1
  40. package/dist/auth/providers/openai-codex.d.ts +44 -0
  41. package/dist/auth/providers/openai-codex.d.ts.map +1 -1
  42. package/dist/auth/providers/openai-codex.js +79 -69
  43. package/dist/auth/providers/openai-codex.js.map +1 -1
  44. package/dist/auth/providers/xai.d.ts +64 -0
  45. package/dist/auth/providers/xai.d.ts.map +1 -0
  46. package/dist/auth/providers/xai.js +171 -0
  47. package/dist/auth/providers/xai.js.map +1 -0
  48. package/dist/auth/storage.d.ts.map +1 -1
  49. package/dist/auth/storage.js +5 -2
  50. package/dist/auth/storage.js.map +1 -1
  51. package/dist/auth/types.d.ts +21 -0
  52. package/dist/auth/types.d.ts.map +1 -1
  53. package/dist/hooks/types.d.ts.map +1 -1
  54. package/dist/hooks/types.js.map +1 -1
  55. package/dist/index.d.ts +12 -11
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +49 -35
  58. package/dist/index.js.map +1 -1
  59. package/dist/providers/amazon-bedrock-gateway.d.ts +7 -0
  60. package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -1
  61. package/dist/providers/amazon-bedrock-gateway.js +66 -2
  62. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  63. package/dist/providers/claude-max.d.ts +3 -1
  64. package/dist/providers/claude-max.d.ts.map +1 -1
  65. package/dist/providers/claude-max.js +1 -1
  66. package/dist/providers/claude-max.js.map +1 -1
  67. package/dist/providers/github-copilot.d.ts +3 -1
  68. package/dist/providers/github-copilot.d.ts.map +1 -1
  69. package/dist/providers/github-copilot.js +1 -1
  70. package/dist/providers/github-copilot.js.map +1 -1
  71. package/dist/providers/openai-codex.d.ts +3 -1
  72. package/dist/providers/openai-codex.d.ts.map +1 -1
  73. package/dist/providers/openai-codex.js +1 -1
  74. package/dist/providers/openai-codex.js.map +1 -1
  75. package/dist/providers/xai.d.ts +33 -0
  76. package/dist/providers/xai.d.ts.map +1 -0
  77. package/dist/providers/xai.js +63 -0
  78. package/dist/providers/xai.js.map +1 -0
  79. package/dist/tools/request-sandbox-access.d.ts.map +1 -1
  80. package/dist/tools/request-sandbox-access.js.map +1 -1
  81. package/dist/utils/update-check.d.ts +51 -2
  82. package/dist/utils/update-check.d.ts.map +1 -1
  83. package/dist/utils/update-check.js +131 -7
  84. package/dist/utils/update-check.js.map +1 -1
  85. package/package.json +12 -12
@@ -0,0 +1,63 @@
1
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
2
+ import { AuthStorage } from "../auth/storage.js";
3
+ const XAI_PROVIDER_ID = "xai";
4
+ const XAI_BASE_URL = "https://api.x.ai/v1";
5
+ let authStorageInstance = null;
6
+ function getAuthStorage() {
7
+ if (!authStorageInstance) {
8
+ authStorageInstance = new AuthStorage();
9
+ }
10
+ return authStorageInstance;
11
+ }
12
+ function setAuthStorage(storage) {
13
+ authStorageInstance = storage ?? null;
14
+ }
15
+ function buildXAIOAuthFetch(opts = {}) {
16
+ return (async (url, init) => {
17
+ const storage = opts.authStorage ?? getAuthStorage();
18
+ storage.reload();
19
+ const cred = storage.get(XAI_PROVIDER_ID);
20
+ if (!cred || cred.type !== "oauth") {
21
+ throw new Error("Not logged in to xAI. Run /login first.");
22
+ }
23
+ const accessToken = await storage.getApiKey(XAI_PROVIDER_ID);
24
+ if (!accessToken) {
25
+ throw new Error("Failed to refresh xAI token. Please /login again.");
26
+ }
27
+ const headers = new Headers(url instanceof Request ? url.headers : void 0);
28
+ if (init?.headers) {
29
+ new Headers(init.headers).forEach((value, key) => headers.set(key, value));
30
+ }
31
+ headers.delete("authorization");
32
+ headers.delete("x-api-key");
33
+ headers.set("Authorization", `Bearer ${accessToken}`);
34
+ try {
35
+ return await fetch(url, { ...init, headers });
36
+ } catch (error) {
37
+ if (error && typeof error === "object") {
38
+ Object.assign(error, {
39
+ requestUrl: url instanceof URL ? url.toString() : typeof url === "string" ? url : url.url
40
+ });
41
+ }
42
+ throw error;
43
+ }
44
+ });
45
+ }
46
+ function xaiProvider(modelId, options) {
47
+ const provider = createOpenAICompatible({
48
+ name: XAI_PROVIDER_ID,
49
+ baseURL: XAI_BASE_URL,
50
+ apiKey: "oauth-placeholder",
51
+ // real auth injected by the custom fetch
52
+ headers: options?.headers,
53
+ fetch: buildXAIOAuthFetch({ authStorage: options?.authStorage })
54
+ });
55
+ return provider.chatModel(modelId);
56
+ }
57
+ export {
58
+ buildXAIOAuthFetch,
59
+ getAuthStorage,
60
+ setAuthStorage,
61
+ xaiProvider
62
+ };
63
+ //# sourceMappingURL=xai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/providers/xai.ts"],"sourcesContent":["/**\n * xAI (Grok) OAuth Provider\n *\n * Uses OAuth tokens from AuthStorage to authenticate with the xAI API.\n * The xAI API speaks an OpenAI-compatible chat format, and the OAuth access\n * token is accepted as a bearer API key, so we plug `@ai-sdk/openai-compatible`\n * into `https://api.x.ai/v1` with a custom fetch that injects the (auto-refreshed)\n * access token.\n */\n\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible';\nimport type { MastraModelConfig } from '@mastra/core/llm';\nimport { AuthStorage } from '../auth/storage.js';\nimport type { CredentialStore } from '../auth/types.js';\n\nconst XAI_PROVIDER_ID = 'xai';\nconst XAI_BASE_URL = 'https://api.x.ai/v1';\n\n// Singleton auth storage instance (shared with claude-max.ts / github-copilot.ts when not overridden).\nlet authStorageInstance: AuthStorage | null = null;\n\n/** Get or create the shared AuthStorage instance. */\nexport function getAuthStorage(): AuthStorage {\n if (!authStorageInstance) {\n authStorageInstance = new AuthStorage();\n }\n return authStorageInstance;\n}\n\n/** Set a custom AuthStorage instance (useful for tests / TUI integration). */\nexport function setAuthStorage(storage: AuthStorage | undefined): void {\n authStorageInstance = storage ?? null;\n}\n\n/**\n * Build a fetch wrapper that authenticates with xAI OAuth.\n * Injects the access token (auto-refreshed by AuthStorage) as a bearer token,\n * preserving non-auth headers from the caller.\n */\nexport function buildXAIOAuthFetch(opts: { authStorage?: CredentialStore } = {}): typeof fetch {\n return (async (url: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {\n const storage = opts.authStorage ?? getAuthStorage();\n storage.reload();\n\n const cred = storage.get(XAI_PROVIDER_ID);\n if (!cred || cred.type !== 'oauth') {\n throw new Error('Not logged in to xAI. Run /login first.');\n }\n\n // getApiKey() refreshes the access token if it has expired.\n const accessToken = await storage.getApiKey(XAI_PROVIDER_ID);\n if (!accessToken) {\n throw new Error('Failed to refresh xAI token. Please /login again.');\n }\n\n // Preserve existing headers, strip auth-related ones. Explicit init\n // headers override headers carried by an incoming Request.\n const headers = new Headers(url instanceof Request ? url.headers : undefined);\n if (init?.headers) {\n new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n }\n headers.delete('authorization');\n headers.delete('x-api-key');\n\n headers.set('Authorization', `Bearer ${accessToken}`);\n\n try {\n return await fetch(url, { ...init, headers });\n } catch (error) {\n if (error && typeof error === 'object') {\n Object.assign(error as Record<string, unknown>, {\n requestUrl: url instanceof URL ? url.toString() : typeof url === 'string' ? url : (url as Request).url,\n });\n }\n throw error;\n }\n }) as typeof fetch;\n}\n\n/**\n * Creates an xAI model using OAuth authentication.\n * Uses OAuth tokens from AuthStorage (auto-refreshes when needed).\n */\nexport function xaiProvider(\n modelId: string,\n options?: { headers?: Record<string, string>; authStorage?: CredentialStore },\n): MastraModelConfig {\n const provider = createOpenAICompatible({\n name: XAI_PROVIDER_ID,\n baseURL: XAI_BASE_URL,\n apiKey: 'oauth-placeholder', // real auth injected by the custom fetch\n headers: options?.headers,\n fetch: buildXAIOAuthFetch({ authStorage: options?.authStorage }),\n });\n return provider.chatModel(modelId);\n}\n"],"mappings":"AAUA,SAAS,8BAA8B;AAEvC,SAAS,mBAAmB;AAG5B,MAAM,kBAAkB;AACxB,MAAM,eAAe;AAGrB,IAAI,sBAA0C;AAGvC,SAAS,iBAA8B;AAC5C,MAAI,CAAC,qBAAqB;AACxB,0BAAsB,IAAI,YAAY;AAAA,EACxC;AACA,SAAO;AACT;AAGO,SAAS,eAAe,SAAwC;AACrE,wBAAsB,WAAW;AACnC;AAOO,SAAS,mBAAmB,OAA0C,CAAC,GAAiB;AAC7F,UAAQ,OAAO,KAA6B,SAAuC;AACjF,UAAM,UAAU,KAAK,eAAe,eAAe;AACnD,YAAQ,OAAO;AAEf,UAAM,OAAO,QAAQ,IAAI,eAAe;AACxC,QAAI,CAAC,QAAQ,KAAK,SAAS,SAAS;AAClC,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAGA,UAAM,cAAc,MAAM,QAAQ,UAAU,eAAe;AAC3D,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAIA,UAAM,UAAU,IAAI,QAAQ,eAAe,UAAU,IAAI,UAAU,MAAS;AAC5E,QAAI,MAAM,SAAS;AACjB,UAAI,QAAQ,KAAK,OAAO,EAAE,QAAQ,CAAC,OAAO,QAAQ,QAAQ,IAAI,KAAK,KAAK,CAAC;AAAA,IAC3E;AACA,YAAQ,OAAO,eAAe;AAC9B,YAAQ,OAAO,WAAW;AAE1B,YAAQ,IAAI,iBAAiB,UAAU,WAAW,EAAE;AAEpD,QAAI;AACF,aAAO,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC;AAAA,IAC9C,SAAS,OAAO;AACd,UAAI,SAAS,OAAO,UAAU,UAAU;AACtC,eAAO,OAAO,OAAkC;AAAA,UAC9C,YAAY,eAAe,MAAM,IAAI,SAAS,IAAI,OAAO,QAAQ,WAAW,MAAO,IAAgB;AAAA,QACrG,CAAC;AAAA,MACH;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAMO,SAAS,YACd,SACA,SACmB;AACnB,QAAM,WAAW,uBAAuB;AAAA,IACtC,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA;AAAA,IACR,SAAS,SAAS;AAAA,IAClB,OAAO,mBAAmB,EAAE,aAAa,SAAS,YAAY,CAAC;AAAA,EACjE,CAAC;AACD,SAAO,SAAS,UAAU,OAAO;AACnC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"request-sandbox-access.d.ts","sourceRoot":"","sources":["../../src/tools/request-sandbox-access.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH,eAAO,MAAM,wBAAwB,sKA6F5B,CAAC"}
1
+ {"version":3,"file":"request-sandbox-access.d.ts","sourceRoot":"","sources":["../../src/tools/request-sandbox-access.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH,eAAO,MAAM,wBAAwB,sKA4F5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tools/request-sandbox-access.ts"],"sourcesContent":["/**\n * request_access tool — requests permission to access a directory outside the project root.\n * The user can approve or deny the request via TUI dialog.\n */\n\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport { createTool } from '@mastra/core/tools';\nimport { LocalFilesystem } from '@mastra/core/workspace';\nimport { z } from 'zod';\nimport type { MastraCodeState } from '../schema.js';\nimport { isPathAllowed, getAllowedPathsFromContext } from './utils.js';\n\nfunction expandTilde(p: string): string {\n if (p === '~') return os.homedir();\n if (p.startsWith('~/') || p.startsWith('~\\\\')) return path.join(os.homedir(), p.slice(2));\n return p;\n}\n\ntype RequestSandboxAccessInput = {\n path: string;\n reason: string;\n};\n\nconst requestSandboxAccessInputSchema = z.object({\n path: z.string().min(1).describe('The absolute path to the directory you need access to.'),\n reason: z.string().min(1).describe('Brief explanation of why you need access to this directory.'),\n});\n\nexport const requestSandboxAccessTool = createTool({\n id: 'request_access',\n description: `Request permission to access a directory outside the current project. Use this when you need to read or write files in a directory that is not within the project root. The user will be prompted to approve or deny the request.`,\n inputSchema: requestSandboxAccessInputSchema,\n suspendSchema: z.object({\n kind: z.literal('sandbox_access_request'),\n path: z.string(),\n reason: z.string(),\n }),\n resumeSchema: z.union([z.string(), z.array(z.string())]),\n execute: async ({ path: requestedPath, reason }: RequestSandboxAccessInput, context: any) => {\n try {\n const agentControllerCtx = context?.requestContext?.get('controller') as\n | AgentControllerRequestContext<MastraCodeState>\n | undefined;\n\n // Resolve to absolute path (expand ~ first since Node path APIs don't handle it)\n const expanded = expandTilde(requestedPath);\n const absolutePath = path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);\n\n // Check if already allowed\n const projectRoot = process.cwd();\n const allowedPaths = getAllowedPathsFromContext(context);\n if (isPathAllowed(absolutePath, projectRoot, allowedPaths)) {\n return {\n content: `Access already granted: \"${absolutePath}\" is within the project root or allowed paths.`,\n isError: false,\n };\n }\n\n const suspend = context?.agent?.suspend ?? context?.suspend;\n const resumeData = context?.agent?.resumeData ?? context?.resumeData;\n\n // First pass: pause via the native tool-suspension primitive so the host can\n // prompt the user. The suspend payload carries the request details; the host\n // resumes with the user's answer as resume data.\n if (resumeData === undefined) {\n if (!suspend) {\n return {\n content: `Cannot request sandbox access: interactive context not available. The user should manually run /sandbox add ${absolutePath}`,\n isError: true,\n };\n }\n await suspend({ kind: 'sandbox_access_request', path: absolutePath, reason });\n return;\n }\n\n const answerText = Array.isArray(resumeData) ? resumeData.join(', ') : String(resumeData);\n const approved = answerText.toLowerCase().startsWith('y') || answerText.toLowerCase() === 'approve';\n if (approved) {\n // Persist to controller state first (and await it) so the value is\n // committed before the next tool call re-derives the workspace's\n // allowed paths from state. The workspace factory rebuilds the\n // filesystem allowlist from `sandboxAllowedPaths` on every call\n // (getDynamicWorkspace), so an unawaited setState would let that\n // rebuild clobber the in-turn widen below before the grant lands.\n const controllerState = agentControllerCtx?.getState();\n const currentAllowed = (controllerState?.sandboxAllowedPaths as string[] | undefined) ?? [];\n const nextAllowed = currentAllowed.includes(absolutePath) ? currentAllowed : [...currentAllowed, absolutePath];\n if (!currentAllowed.includes(absolutePath)) {\n await agentControllerCtx?.setState({\n sandboxAllowedPaths: nextAllowed,\n });\n }\n\n // Also update the live workspace filesystem immediately so tools in\n // the same turn (e.g. `view`) can access the path without waiting for\n // a fresh workspace build. The resolved workspace is carried on the\n // controller request context — the tool-execution context does not expose\n // it — so read the filesystem from there.\n const fs = agentControllerCtx?.workspace?.filesystem ?? context?.workspace?.filesystem;\n if (fs instanceof LocalFilesystem) {\n fs.setAllowedPaths((prev: readonly string[]) => [...prev, absolutePath]);\n }\n\n return {\n content: `Access granted: \"${absolutePath}\" has been added to allowed paths. You can now access files in this directory.`,\n isError: false,\n };\n } else {\n return {\n content: `Access denied: The user declined access to \"${absolutePath}\".`,\n isError: false,\n };\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : 'Unknown error';\n return {\n content: `Failed to request sandbox access: ${msg}`,\n isError: true,\n };\n }\n },\n} as any);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/tools/request-sandbox-access.ts"],"sourcesContent":["/**\n * request_access tool — requests permission to access a directory outside the project root.\n * The user can approve or deny the request via TUI dialog.\n */\n\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport { createTool } from '@mastra/core/tools';\nimport { LocalFilesystem } from '@mastra/core/workspace';\nimport { z } from 'zod';\nimport type { MastraCodeState } from '../schema.js';\nimport { isPathAllowed, getAllowedPathsFromContext } from './utils.js';\n\nfunction expandTilde(p: string): string {\n if (p === '~') return os.homedir();\n if (p.startsWith('~/') || p.startsWith('~\\\\')) return path.join(os.homedir(), p.slice(2));\n return p;\n}\n\ntype RequestSandboxAccessInput = {\n path: string;\n reason: string;\n};\n\nconst requestSandboxAccessInputSchema = z.object({\n path: z.string().min(1).describe('The absolute path to the directory you need access to.'),\n reason: z.string().min(1).describe('Brief explanation of why you need access to this directory.'),\n});\n\nexport const requestSandboxAccessTool = createTool({\n id: 'request_access',\n description: `Request permission to access a directory outside the current project. Use this when you need to read or write files in a directory that is not within the project root. The user will be prompted to approve or deny the request.`,\n inputSchema: requestSandboxAccessInputSchema,\n suspendSchema: z.object({\n kind: z.literal('sandbox_access_request'),\n path: z.string(),\n reason: z.string(),\n }),\n resumeSchema: z.union([z.string(), z.array(z.string())]),\n execute: async ({ path: requestedPath, reason }: RequestSandboxAccessInput, context: any) => {\n try {\n const agentControllerCtx = context?.requestContext?.get('controller') as\n AgentControllerRequestContext<MastraCodeState> | undefined;\n\n // Resolve to absolute path (expand ~ first since Node path APIs don't handle it)\n const expanded = expandTilde(requestedPath);\n const absolutePath = path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);\n\n // Check if already allowed\n const projectRoot = process.cwd();\n const allowedPaths = getAllowedPathsFromContext(context);\n if (isPathAllowed(absolutePath, projectRoot, allowedPaths)) {\n return {\n content: `Access already granted: \"${absolutePath}\" is within the project root or allowed paths.`,\n isError: false,\n };\n }\n\n const suspend = context?.agent?.suspend ?? context?.suspend;\n const resumeData = context?.agent?.resumeData ?? context?.resumeData;\n\n // First pass: pause via the native tool-suspension primitive so the host can\n // prompt the user. The suspend payload carries the request details; the host\n // resumes with the user's answer as resume data.\n if (resumeData === undefined) {\n if (!suspend) {\n return {\n content: `Cannot request sandbox access: interactive context not available. The user should manually run /sandbox add ${absolutePath}`,\n isError: true,\n };\n }\n await suspend({ kind: 'sandbox_access_request', path: absolutePath, reason });\n return;\n }\n\n const answerText = Array.isArray(resumeData) ? resumeData.join(', ') : String(resumeData);\n const approved = answerText.toLowerCase().startsWith('y') || answerText.toLowerCase() === 'approve';\n if (approved) {\n // Persist to controller state first (and await it) so the value is\n // committed before the next tool call re-derives the workspace's\n // allowed paths from state. The workspace factory rebuilds the\n // filesystem allowlist from `sandboxAllowedPaths` on every call\n // (getDynamicWorkspace), so an unawaited setState would let that\n // rebuild clobber the in-turn widen below before the grant lands.\n const controllerState = agentControllerCtx?.getState();\n const currentAllowed = (controllerState?.sandboxAllowedPaths as string[] | undefined) ?? [];\n const nextAllowed = currentAllowed.includes(absolutePath) ? currentAllowed : [...currentAllowed, absolutePath];\n if (!currentAllowed.includes(absolutePath)) {\n await agentControllerCtx?.setState({\n sandboxAllowedPaths: nextAllowed,\n });\n }\n\n // Also update the live workspace filesystem immediately so tools in\n // the same turn (e.g. `view`) can access the path without waiting for\n // a fresh workspace build. The resolved workspace is carried on the\n // controller request context — the tool-execution context does not expose\n // it — so read the filesystem from there.\n const fs = agentControllerCtx?.workspace?.filesystem ?? context?.workspace?.filesystem;\n if (fs instanceof LocalFilesystem) {\n fs.setAllowedPaths((prev: readonly string[]) => [...prev, absolutePath]);\n }\n\n return {\n content: `Access granted: \"${absolutePath}\" has been added to allowed paths. You can now access files in this directory.`,\n isError: false,\n };\n } else {\n return {\n content: `Access denied: The user declined access to \"${absolutePath}\".`,\n isError: false,\n };\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : 'Unknown error';\n return {\n content: `Failed to request sandbox access: ${msg}`,\n isError: true,\n };\n }\n },\n} as any);\n"],"mappings":"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","names":[]}
@@ -44,9 +44,58 @@ export declare function fetchChangelog(version: string): Promise<string | null>;
44
44
  * as a concise bullet list suitable for terminal display.
45
45
  */
46
46
  export declare function parseChangelog(markdown: string, version: string): string | null;
47
+ /** Result of attempting an auto-update: exit status plus captured stderr. */
48
+ export interface UpdateResult {
49
+ ok: boolean;
50
+ stderr?: string;
51
+ }
47
52
  /**
48
53
  * Run the appropriate global install command to update mastracode.
49
- * Returns true on success, false on failure.
54
+ * Exit code 0 does not prove the running binary changed (the install may land
55
+ * in a location the PATH shim doesn't use) — verify with {@link locateOwnInstall}.
50
56
  */
51
- export declare function runUpdate(pm: PackageManager, targetVersion: string): Promise<boolean>;
57
+ export declare function runUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateResult>;
58
+ /**
59
+ * Find the installed mastracode package the running binary belongs to (walking
60
+ * up from `process.argv[1]`) and read its version fresh from disk. Returns
61
+ * null when it can't be determined, e.g. when running from source.
62
+ */
63
+ export declare function locateOwnInstall(): {
64
+ dir: string;
65
+ version: string | null;
66
+ } | null;
67
+ export type UpdateOutcome = {
68
+ status: 'updated';
69
+ message: string;
70
+ } | {
71
+ status: 'unchanged';
72
+ message: string;
73
+ } | {
74
+ status: 'failed';
75
+ message: string;
76
+ };
77
+ /**
78
+ * Decide what to tell the user after {@link runUpdate}: `updated` when the
79
+ * on-disk version matches the target (or can't be determined), `unchanged`
80
+ * when the package manager succeeded but the running install didn't change,
81
+ * `failed` on error (with the package manager's stderr).
82
+ */
83
+ export declare function resolveUpdateOutcome(opts: {
84
+ pm: PackageManager;
85
+ targetVersion: string;
86
+ result: UpdateResult;
87
+ install: {
88
+ dir: string;
89
+ version: string | null;
90
+ } | null;
91
+ /** Overrides the suggested manual command, e.g. when the update was delegated to the owning tool. */
92
+ manualCommand?: string;
93
+ }): UpdateOutcome;
94
+ /**
95
+ * Update mastracode and verify the result: delegates to the tool that owns the
96
+ * running install when we recognize it, skips the install when it isn't
97
+ * managed by `pm`, otherwise runs the package manager. Every executed update
98
+ * is verified against the on-disk version.
99
+ */
100
+ export declare function performUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateOutcome>;
52
101
  //# sourceMappingURL=update-check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAW7D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CA0CpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAY9E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAevE;AAKD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe5E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiD/E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrF"}
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAW7D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CA+CpE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAY9E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAevE;AAKD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe5E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiD/E;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE1F;AA0CD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CA6BjF;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,EAAE,EAAE,cAAc,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,qGAAqG;IACrG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,aAAa,CAsBhB;AAuDD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoCrG"}
@@ -1,10 +1,12 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { readFileSync, realpathSync } from "node:fs";
3
- import { dirname, resolve } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join, resolve, sep } from "node:path";
4
5
  import { fileURLToPath } from "node:url";
5
6
  const PACKAGE_NAME = "mastracode";
6
7
  const NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
7
8
  const FETCH_TIMEOUT_MS = 5e3;
9
+ const USE_SHELL = process.platform === "win32";
8
10
  function matchPM(str) {
9
11
  if (/pnpm/i.test(str)) return "pnpm";
10
12
  if (/\byarn\b/i.test(str)) return "yarn";
@@ -37,9 +39,14 @@ async function detectPackageManager() {
37
39
  } catch {
38
40
  }
39
41
  const pnpmResult = await new Promise((resolve2) => {
40
- execFile("pnpm", ["list", "-g", "--depth=0", PACKAGE_NAME], { timeout: 3e3 }, (error, stdout) => {
41
- resolve2(!error && stdout.includes(PACKAGE_NAME));
42
- });
42
+ execFile(
43
+ "pnpm",
44
+ ["list", "-g", "--depth=0", PACKAGE_NAME],
45
+ { timeout: 3e3, shell: USE_SHELL },
46
+ (error, stdout) => {
47
+ resolve2(!error && stdout.includes(PACKAGE_NAME));
48
+ }
49
+ );
43
50
  });
44
51
  if (pnpmResult) return "pnpm";
45
52
  return "npm";
@@ -144,10 +151,17 @@ function parseChangelog(markdown, version) {
144
151
  return entries.map((e) => ` \u2022 ${e}`).join("\n");
145
152
  }
146
153
  function runUpdate(pm, targetVersion) {
147
- const args = buildInstallArgs(pm, targetVersion);
154
+ return execUpdate(pm, buildInstallArgs(pm, targetVersion));
155
+ }
156
+ function execUpdate(cmd, args) {
148
157
  return new Promise((resolve2) => {
149
- execFile(pm, args, { timeout: 6e4 }, (error) => {
150
- resolve2(!error);
158
+ execFile(cmd, args, { timeout: 6e4, shell: USE_SHELL }, (error, _stdout, stderr) => {
159
+ const captured = (stderr ?? "").trim();
160
+ if (error) {
161
+ resolve2({ ok: false, stderr: captured || error.message });
162
+ } else {
163
+ resolve2({ ok: true, stderr: captured || void 0 });
164
+ }
151
165
  });
152
166
  });
153
167
  }
@@ -164,6 +178,113 @@ function buildInstallArgs(pm, version) {
164
178
  return ["install", "-g", pkg];
165
179
  }
166
180
  }
181
+ const MAX_UPDATE_ERROR_LINES = 5;
182
+ function formatUpdaterError(stderr) {
183
+ if (!stderr) return null;
184
+ const lines = stderr.split("\n").map((line) => line.trimEnd()).filter((line) => line.trim().length > 0);
185
+ if (lines.length === 0) return null;
186
+ return lines.slice(-MAX_UPDATE_ERROR_LINES).join("\n");
187
+ }
188
+ function locateOwnInstall() {
189
+ const entry = process.argv[1];
190
+ if (!entry) return null;
191
+ let dir;
192
+ try {
193
+ dir = dirname(realpathSync(entry));
194
+ } catch {
195
+ return null;
196
+ }
197
+ let previous = "";
198
+ while (dir && dir !== previous) {
199
+ try {
200
+ const pkg = JSON.parse(readFileSync(resolve(dir, "package.json"), "utf-8"));
201
+ if (pkg.name === PACKAGE_NAME) {
202
+ return { dir, version: typeof pkg.version === "string" ? pkg.version : null };
203
+ }
204
+ } catch {
205
+ }
206
+ previous = dir;
207
+ dir = dirname(dir);
208
+ }
209
+ return null;
210
+ }
211
+ function resolveUpdateOutcome(opts) {
212
+ const { pm, targetVersion, result, install } = opts;
213
+ const cmd = opts.manualCommand ?? getInstallCommand(pm, targetVersion);
214
+ if (!result.ok) {
215
+ const details = formatUpdaterError(result.stderr);
216
+ let message = `Auto-update failed. Run \`${cmd}\` manually.`;
217
+ if (details) message += `
218
+
219
+ ${details}`;
220
+ return { status: "failed", message };
221
+ }
222
+ if (install?.version != null && install.version !== targetVersion) {
223
+ const message = opts.manualCommand ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still v${install.version}. Try \`${cmd}\` manually.` : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still v${install.version} \u2014 it looks like it is managed by another tool. Update it with that tool, or try \`${cmd}\`.`;
224
+ return { status: "unchanged", message };
225
+ }
226
+ return { status: "updated", message: `Updated to v${targetVersion}. Please restart Mastra Code.` };
227
+ }
228
+ function getGlobalRoot(pm) {
229
+ const args = pm === "yarn" ? ["global", "dir"] : ["root", "-g"];
230
+ return new Promise((res) => {
231
+ execFile(pm, args, { timeout: 1e4, shell: USE_SHELL }, (error, stdout) => {
232
+ const out = (stdout ?? "").trim().split("\n").pop()?.trim();
233
+ if (error || !out) return res(null);
234
+ res(pm === "yarn" ? resolve(out, "node_modules") : out);
235
+ });
236
+ });
237
+ }
238
+ async function isOwnInstallManagedBy(pm, install) {
239
+ if (!install) return true;
240
+ const root = await getGlobalRoot(pm);
241
+ if (!root) return true;
242
+ try {
243
+ return realpathSync(resolve(root, PACKAGE_NAME)) === install.dir;
244
+ } catch {
245
+ return false;
246
+ }
247
+ }
248
+ function findInstallOwner(dir, version) {
249
+ if (dir.startsWith(join(homedir(), ".vite-plus") + sep)) {
250
+ return {
251
+ name: "vite-plus",
252
+ exec: { cmd: "vp", args: ["install", "-g", `${PACKAGE_NAME}@${version}`] },
253
+ command: `vp install -g ${PACKAGE_NAME}@${version}`
254
+ };
255
+ }
256
+ if (dir.split(sep).includes("Cellar")) {
257
+ return { name: "Homebrew", command: `brew upgrade ${PACKAGE_NAME}` };
258
+ }
259
+ return null;
260
+ }
261
+ async function performUpdate(pm, targetVersion) {
262
+ if (!/^[\w.+-]+$/.test(targetVersion)) {
263
+ return { status: "failed", message: `Auto-update aborted: unexpected version "${targetVersion}".` };
264
+ }
265
+ const install = locateOwnInstall();
266
+ const owner = install ? findInstallOwner(install.dir, targetVersion) : null;
267
+ if (owner) {
268
+ if (!owner.exec) {
269
+ const message = `Your Mastra Code install (at ${install.dir}) is managed by ${owner.name}. Update it with \`${owner.command}\`.`;
270
+ return { status: "unchanged", message };
271
+ }
272
+ const result2 = await execUpdate(owner.exec.cmd, owner.exec.args);
273
+ return resolveUpdateOutcome({
274
+ pm,
275
+ targetVersion,
276
+ result: result2,
277
+ install: locateOwnInstall(),
278
+ manualCommand: owner.command
279
+ });
280
+ }
281
+ if (!await isOwnInstallManagedBy(pm, install)) {
282
+ const message = `Your Mastra Code install (at ${install.dir}) is not managed by ${pm} \u2014 it looks like it was installed by another tool. Update it with that tool, or try \`${getInstallCommand(pm, targetVersion)}\`.`;
283
+ return { status: "unchanged", message };
284
+ }
285
+ const result = await runUpdate(pm, targetVersion);
286
+ return resolveUpdateOutcome({ pm, targetVersion, result, install: locateOwnInstall() });
287
+ }
167
288
  export {
168
289
  detectPackageManager,
169
290
  fetchChangelog,
@@ -171,7 +292,10 @@ export {
171
292
  getCurrentVersion,
172
293
  getInstallCommand,
173
294
  isNewerVersion,
295
+ locateOwnInstall,
174
296
  parseChangelog,
297
+ performUpdate,
298
+ resolveUpdateOutcome,
175
299
  runUpdate
176
300
  };
177
301
  //# sourceMappingURL=update-check.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/update-check.ts"],"sourcesContent":["/**\n * Check for newer versions of mastracode on npm.\n */\n\nimport { execFile } from 'node:child_process';\nimport { readFileSync, realpathSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nconst PACKAGE_NAME = 'mastracode';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\n/** Timeout for the npm registry fetch (ms). */\nconst FETCH_TIMEOUT_MS = 5_000;\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nfunction matchPM(str: string): PackageManager | null {\n // Order matters: check pnpm before npm since \"npm\" is a substring of some paths\n if (/pnpm/i.test(str)) return 'pnpm';\n if (/\\byarn\\b/i.test(str)) return 'yarn';\n if (/\\bbun\\b/i.test(str)) return 'bun';\n if (/\\bnpm\\b/i.test(str)) return 'npm';\n return null;\n}\n\n/**\n * Detect which package manager was used to install mastracode globally.\n *\n * Uses a multi-tier approach:\n * 1. npm_config_user_agent env var (set when run via `pnpm run`, `npm run`, etc.)\n * 2. npm_execpath env var (fallback for script-based invocation)\n * 3. NODE_PATH env var (set by pnpm global bin stubs)\n * 4. Resolved path of the running script (process.argv[1])\n * 5. Shell-out to `pnpm list -g` to check if pnpm manages the package\n * 6. Falls back to 'npm'\n */\nexport async function detectPackageManager(): Promise<PackageManager> {\n // Tier 1: npm_config_user_agent (most reliable when available)\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n const pm = matchPM(userAgent);\n if (pm) return pm;\n }\n\n // Tier 2: npm_execpath\n const execPath = process.env.npm_execpath;\n if (execPath) {\n const pm = matchPM(execPath);\n if (pm) return pm;\n }\n\n // Tier 3: NODE_PATH (pnpm global stubs set this to paths containing .pnpm)\n const nodePath = process.env.NODE_PATH;\n if (nodePath) {\n if (/[/\\\\]\\.pnpm[/\\\\]/.test(nodePath) || /[/\\\\]pnpm[/\\\\]/.test(nodePath)) return 'pnpm';\n if (/[/\\\\]\\.yarn[/\\\\]/.test(nodePath)) return 'yarn';\n if (/[/\\\\]\\.bun[/\\\\]/.test(nodePath)) return 'bun';\n }\n\n // Tier 4: Resolved script path\n try {\n const scriptPath = realpathSync(process.argv[1] ?? '');\n if (/[/\\\\]\\.?pnpm[/\\\\]/.test(scriptPath)) return 'pnpm';\n if (/[/\\\\]\\.?yarn[/\\\\]/.test(scriptPath)) return 'yarn';\n if (/[/\\\\]\\.?bun[/\\\\]/.test(scriptPath)) return 'bun';\n } catch {\n // realpathSync can fail if argv[1] is missing/broken — fall through\n }\n\n // Tier 5: Check if the package is in pnpm's global store (non-blocking)\n const pnpmResult = await new Promise<boolean>(resolve => {\n execFile('pnpm', ['list', '-g', '--depth=0', PACKAGE_NAME], { timeout: 3_000 }, (error, stdout) => {\n resolve(!error && stdout.includes(PACKAGE_NAME));\n });\n });\n if (pnpmResult) return 'pnpm';\n\n return 'npm';\n}\n\n/**\n * Build the shell command string a user would run to install/update globally.\n */\nexport function getInstallCommand(pm: PackageManager, version?: string): string {\n const pkg = version ? `${PACKAGE_NAME}@${version}` : `${PACKAGE_NAME}@latest`;\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g ${pkg}`;\n case 'yarn':\n return `yarn global add ${pkg}`;\n case 'bun':\n return `bun add -g ${pkg}`;\n default:\n return `npm install -g ${pkg}`;\n }\n}\n\n/**\n * Read the current version, injected at build time by tsup's `define` option.\n * Falls back to reading package.json at runtime (e.g. when running from source with tsx).\n */\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n // Fallback for running from source (e.g. pnpx tsx mastracode/src/main.ts)\n const dir = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(dir, '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version;\n}\n\n/**\n * Fetch the latest published version from npm.\n * Returns null if the fetch fails (network error, timeout, etc.).\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_LATEST_VERSION) return process.env.MASTRACODE_UPDATE_LATEST_VERSION;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(NPM_REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Simple semver comparison: returns true if `latest` is newer than `current`.\n * Handles standard x.y.z versions. Ignores pre-release tags.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const parse = (v: string) =>\n v\n .replace(/^v/, '')\n .split('-')[0]!\n .split('.')\n .map(s => {\n const n = Number(s);\n return Number.isFinite(n) ? n : 0;\n });\n const [cMajor = 0, cMinor = 0, cPatch = 0] = parse(current);\n const [lMajor = 0, lMinor = 0, lPatch = 0] = parse(latest);\n if (lMajor !== cMajor) return lMajor > cMajor;\n if (lMinor !== cMinor) return lMinor > cMinor;\n return lPatch > cPatch;\n}\n\n/** Max entries to show in the changelog summary. */\nconst MAX_CHANGELOG_ENTRIES = 20;\n\n/**\n * Fetch the CHANGELOG.md for a specific published version from the npm CDN\n * and extract a human-readable summary of changes.\n * Returns null if the fetch fails or the changelog can't be parsed.\n */\nexport async function fetchChangelog(version: string): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_CHANGELOG) return process.env.MASTRACODE_UPDATE_CHANGELOG;\n\n try {\n const url = `https://unpkg.com/${PACKAGE_NAME}@${version}/CHANGELOG.md`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const text = await res.text();\n return parseChangelog(text, version);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract the changelog section for a specific version and format it\n * as a concise bullet list suitable for terminal display.\n */\nexport function parseChangelog(markdown: string, version: string): string | null {\n const versionHeader = `## ${version}`;\n const startIdx = markdown.indexOf(versionHeader);\n if (startIdx === -1) return null;\n\n const afterHeader = startIdx + versionHeader.length;\n const nextHeaderIdx = markdown.indexOf('\\n## ', afterHeader);\n const section = nextHeaderIdx === -1 ? markdown.slice(afterHeader) : markdown.slice(afterHeader, nextHeaderIdx);\n\n const lines = section.split('\\n');\n const entries: string[] = [];\n let skipIndented = false;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!;\n const trimmed = raw.trim();\n\n // Only match top-level entries (no leading whitespace before \"- \")\n const isTopLevel = raw === trimmed && trimmed.startsWith('- ');\n if (!isTopLevel) {\n // Skip indented sub-items (e.g. dependency list entries)\n if (skipIndented && /^\\s+-\\s/.test(raw)) continue;\n skipIndented = false;\n continue;\n }\n\n // Skip dependency update entries and their sub-items\n if (/^- Updated dependenc/i.test(trimmed)) {\n skipIndented = true;\n continue;\n }\n skipIndented = false;\n\n let entry = trimmed.slice(2);\n // Strip markdown links: [text](url) → text\n entry = entry.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n // Strip PR references like (#15760)\n entry = entry.replace(/\\s*\\(#\\d+\\)\\s*/g, ' ');\n // Strip commit SHA references like (`abc123`)\n entry = entry.replace(/\\s*\\(`[a-f0-9]+`\\)\\s*/g, ' ');\n // Trim trailing periods for cleaner bullet display\n entry = entry.replace(/\\.\\s*$/, '');\n entry = entry.trim();\n if (entry) entries.push(entry);\n if (entries.length >= MAX_CHANGELOG_ENTRIES) break;\n }\n\n if (entries.length === 0) return null;\n return entries.map(e => ` • ${e}`).join('\\n');\n}\n\n/**\n * Run the appropriate global install command to update mastracode.\n * Returns true on success, false on failure.\n */\nexport function runUpdate(pm: PackageManager, targetVersion: string): Promise<boolean> {\n const args = buildInstallArgs(pm, targetVersion);\n return new Promise(resolve => {\n execFile(pm, args, { timeout: 60_000 }, error => {\n resolve(!error);\n });\n });\n}\n\nfunction buildInstallArgs(pm: PackageManager, version: string): string[] {\n const pkg = `${PACKAGE_NAME}@${version}`;\n switch (pm) {\n case 'pnpm':\n return ['add', '-g', pkg];\n case 'yarn':\n return ['global', 'add', pkg];\n case 'bun':\n return ['add', '-g', pkg];\n default:\n return ['install', '-g', pkg];\n }\n}\n"],"mappings":"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","names":["resolve"]}
1
+ {"version":3,"sources":["../../src/utils/update-check.ts"],"sourcesContent":["/**\n * Check for newer versions of mastracode on npm.\n */\n\nimport { execFile } from 'node:child_process';\nimport { readFileSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve, sep } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\ndeclare const MASTRACODE_VERSION: string | undefined;\n\nconst PACKAGE_NAME = 'mastracode';\nconst NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n\n/** Timeout for the npm registry fetch (ms). */\nconst FETCH_TIMEOUT_MS = 5_000;\n\n// Package managers and vp are .cmd shims on Windows; execFile can't spawn those without a shell (EINVAL).\nconst USE_SHELL = process.platform === 'win32';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nfunction matchPM(str: string): PackageManager | null {\n // Order matters: check pnpm before npm since \"npm\" is a substring of some paths\n if (/pnpm/i.test(str)) return 'pnpm';\n if (/\\byarn\\b/i.test(str)) return 'yarn';\n if (/\\bbun\\b/i.test(str)) return 'bun';\n if (/\\bnpm\\b/i.test(str)) return 'npm';\n return null;\n}\n\n/**\n * Detect which package manager was used to install mastracode globally.\n *\n * Uses a multi-tier approach:\n * 1. npm_config_user_agent env var (set when run via `pnpm run`, `npm run`, etc.)\n * 2. npm_execpath env var (fallback for script-based invocation)\n * 3. NODE_PATH env var (set by pnpm global bin stubs)\n * 4. Resolved path of the running script (process.argv[1])\n * 5. Shell-out to `pnpm list -g` to check if pnpm manages the package\n * 6. Falls back to 'npm'\n */\nexport async function detectPackageManager(): Promise<PackageManager> {\n // Tier 1: npm_config_user_agent (most reliable when available)\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n const pm = matchPM(userAgent);\n if (pm) return pm;\n }\n\n // Tier 2: npm_execpath\n const execPath = process.env.npm_execpath;\n if (execPath) {\n const pm = matchPM(execPath);\n if (pm) return pm;\n }\n\n // Tier 3: NODE_PATH (pnpm global stubs set this to paths containing .pnpm)\n const nodePath = process.env.NODE_PATH;\n if (nodePath) {\n if (/[/\\\\]\\.pnpm[/\\\\]/.test(nodePath) || /[/\\\\]pnpm[/\\\\]/.test(nodePath)) return 'pnpm';\n if (/[/\\\\]\\.yarn[/\\\\]/.test(nodePath)) return 'yarn';\n if (/[/\\\\]\\.bun[/\\\\]/.test(nodePath)) return 'bun';\n }\n\n // Tier 4: Resolved script path\n try {\n const scriptPath = realpathSync(process.argv[1] ?? '');\n if (/[/\\\\]\\.?pnpm[/\\\\]/.test(scriptPath)) return 'pnpm';\n if (/[/\\\\]\\.?yarn[/\\\\]/.test(scriptPath)) return 'yarn';\n if (/[/\\\\]\\.?bun[/\\\\]/.test(scriptPath)) return 'bun';\n } catch {\n // realpathSync can fail if argv[1] is missing/broken — fall through\n }\n\n // Tier 5: Check if the package is in pnpm's global store (non-blocking)\n const pnpmResult = await new Promise<boolean>(resolve => {\n execFile(\n 'pnpm',\n ['list', '-g', '--depth=0', PACKAGE_NAME],\n { timeout: 3_000, shell: USE_SHELL },\n (error, stdout) => {\n resolve(!error && stdout.includes(PACKAGE_NAME));\n },\n );\n });\n if (pnpmResult) return 'pnpm';\n\n return 'npm';\n}\n\n/**\n * Build the shell command string a user would run to install/update globally.\n */\nexport function getInstallCommand(pm: PackageManager, version?: string): string {\n const pkg = version ? `${PACKAGE_NAME}@${version}` : `${PACKAGE_NAME}@latest`;\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g ${pkg}`;\n case 'yarn':\n return `yarn global add ${pkg}`;\n case 'bun':\n return `bun add -g ${pkg}`;\n default:\n return `npm install -g ${pkg}`;\n }\n}\n\n/**\n * Read the current version, injected at build time by tsup's `define` option.\n * Falls back to reading package.json at runtime (e.g. when running from source with tsx).\n */\nexport function getCurrentVersion(): string {\n if (typeof MASTRACODE_VERSION !== 'undefined') {\n return MASTRACODE_VERSION;\n }\n // Fallback for running from source (e.g. pnpx tsx mastracode/src/main.ts)\n const dir = dirname(fileURLToPath(import.meta.url));\n const pkgPath = resolve(dir, '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return pkg.version;\n}\n\n/**\n * Fetch the latest published version from npm.\n * Returns null if the fetch fails (network error, timeout, etc.).\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_LATEST_VERSION) return process.env.MASTRACODE_UPDATE_LATEST_VERSION;\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(NPM_REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const data = (await res.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Simple semver comparison: returns true if `latest` is newer than `current`.\n * Handles standard x.y.z versions. Ignores pre-release tags.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const parse = (v: string) =>\n v\n .replace(/^v/, '')\n .split('-')[0]!\n .split('.')\n .map(s => {\n const n = Number(s);\n return Number.isFinite(n) ? n : 0;\n });\n const [cMajor = 0, cMinor = 0, cPatch = 0] = parse(current);\n const [lMajor = 0, lMinor = 0, lPatch = 0] = parse(latest);\n if (lMajor !== cMajor) return lMajor > cMajor;\n if (lMinor !== cMinor) return lMinor > cMinor;\n return lPatch > cPatch;\n}\n\n/** Max entries to show in the changelog summary. */\nconst MAX_CHANGELOG_ENTRIES = 20;\n\n/**\n * Fetch the CHANGELOG.md for a specific published version from the npm CDN\n * and extract a human-readable summary of changes.\n * Returns null if the fetch fails or the changelog can't be parsed.\n */\nexport async function fetchChangelog(version: string): Promise<string | null> {\n if (process.env.MASTRACODE_UPDATE_CHANGELOG) return process.env.MASTRACODE_UPDATE_CHANGELOG;\n\n try {\n const url = `https://unpkg.com/${PACKAGE_NAME}@${version}/CHANGELOG.md`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!res.ok) return null;\n const text = await res.text();\n return parseChangelog(text, version);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract the changelog section for a specific version and format it\n * as a concise bullet list suitable for terminal display.\n */\nexport function parseChangelog(markdown: string, version: string): string | null {\n const versionHeader = `## ${version}`;\n const startIdx = markdown.indexOf(versionHeader);\n if (startIdx === -1) return null;\n\n const afterHeader = startIdx + versionHeader.length;\n const nextHeaderIdx = markdown.indexOf('\\n## ', afterHeader);\n const section = nextHeaderIdx === -1 ? markdown.slice(afterHeader) : markdown.slice(afterHeader, nextHeaderIdx);\n\n const lines = section.split('\\n');\n const entries: string[] = [];\n let skipIndented = false;\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!;\n const trimmed = raw.trim();\n\n // Only match top-level entries (no leading whitespace before \"- \")\n const isTopLevel = raw === trimmed && trimmed.startsWith('- ');\n if (!isTopLevel) {\n // Skip indented sub-items (e.g. dependency list entries)\n if (skipIndented && /^\\s+-\\s/.test(raw)) continue;\n skipIndented = false;\n continue;\n }\n\n // Skip dependency update entries and their sub-items\n if (/^- Updated dependenc/i.test(trimmed)) {\n skipIndented = true;\n continue;\n }\n skipIndented = false;\n\n let entry = trimmed.slice(2);\n // Strip markdown links: [text](url) → text\n entry = entry.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n // Strip PR references like (#15760)\n entry = entry.replace(/\\s*\\(#\\d+\\)\\s*/g, ' ');\n // Strip commit SHA references like (`abc123`)\n entry = entry.replace(/\\s*\\(`[a-f0-9]+`\\)\\s*/g, ' ');\n // Trim trailing periods for cleaner bullet display\n entry = entry.replace(/\\.\\s*$/, '');\n entry = entry.trim();\n if (entry) entries.push(entry);\n if (entries.length >= MAX_CHANGELOG_ENTRIES) break;\n }\n\n if (entries.length === 0) return null;\n return entries.map(e => ` • ${e}`).join('\\n');\n}\n\n/** Result of attempting an auto-update: exit status plus captured stderr. */\nexport interface UpdateResult {\n ok: boolean;\n stderr?: string;\n}\n\n/**\n * Run the appropriate global install command to update mastracode.\n * Exit code 0 does not prove the running binary changed (the install may land\n * in a location the PATH shim doesn't use) — verify with {@link locateOwnInstall}.\n */\nexport function runUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateResult> {\n return execUpdate(pm, buildInstallArgs(pm, targetVersion));\n}\n\nfunction execUpdate(cmd: string, args: string[]): Promise<UpdateResult> {\n return new Promise(resolve => {\n execFile(cmd, args, { timeout: 60_000, shell: USE_SHELL }, (error, _stdout, stderr) => {\n const captured = (stderr ?? '').trim();\n if (error) {\n resolve({ ok: false, stderr: captured || error.message });\n } else {\n resolve({ ok: true, stderr: captured || undefined });\n }\n });\n });\n}\n\nfunction buildInstallArgs(pm: PackageManager, version: string): string[] {\n const pkg = `${PACKAGE_NAME}@${version}`;\n switch (pm) {\n case 'pnpm':\n return ['add', '-g', pkg];\n case 'yarn':\n return ['global', 'add', pkg];\n case 'bun':\n return ['add', '-g', pkg];\n default:\n return ['install', '-g', pkg];\n }\n}\n\n/** Max stderr lines to surface when an update fails. */\nconst MAX_UPDATE_ERROR_LINES = 5;\n\nfunction formatUpdaterError(stderr: string | undefined): string | null {\n if (!stderr) return null;\n const lines = stderr\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(line => line.trim().length > 0);\n if (lines.length === 0) return null;\n return lines.slice(-MAX_UPDATE_ERROR_LINES).join('\\n');\n}\n\n/**\n * Find the installed mastracode package the running binary belongs to (walking\n * up from `process.argv[1]`) and read its version fresh from disk. Returns\n * null when it can't be determined, e.g. when running from source.\n */\nexport function locateOwnInstall(): { dir: string; version: string | null } | null {\n const entry = process.argv[1];\n if (!entry) return null;\n\n let dir: string;\n try {\n dir = dirname(realpathSync(entry));\n } catch {\n return null;\n }\n\n let previous = '';\n while (dir && dir !== previous) {\n try {\n const pkg = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8')) as {\n name?: string;\n version?: string;\n };\n if (pkg.name === PACKAGE_NAME) {\n return { dir, version: typeof pkg.version === 'string' ? pkg.version : null };\n }\n } catch {\n // Not a readable manifest — keep walking up.\n }\n previous = dir;\n dir = dirname(dir);\n }\n\n return null;\n}\n\nexport type UpdateOutcome =\n | { status: 'updated'; message: string }\n | { status: 'unchanged'; message: string }\n | { status: 'failed'; message: string };\n\n/**\n * Decide what to tell the user after {@link runUpdate}: `updated` when the\n * on-disk version matches the target (or can't be determined), `unchanged`\n * when the package manager succeeded but the running install didn't change,\n * `failed` on error (with the package manager's stderr).\n */\nexport function resolveUpdateOutcome(opts: {\n pm: PackageManager;\n targetVersion: string;\n result: UpdateResult;\n install: { dir: string; version: string | null } | null;\n /** Overrides the suggested manual command, e.g. when the update was delegated to the owning tool. */\n manualCommand?: string;\n}): UpdateOutcome {\n const { pm, targetVersion, result, install } = opts;\n const cmd = opts.manualCommand ?? getInstallCommand(pm, targetVersion);\n\n if (!result.ok) {\n const details = formatUpdaterError(result.stderr);\n let message = `Auto-update failed. Run \\`${cmd}\\` manually.`;\n if (details) message += `\\n\\n${details}`;\n return { status: 'failed', message };\n }\n\n if (install?.version != null && install.version !== targetVersion) {\n const message = opts.manualCommand\n ? `The update ran, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version}. Try \\`${cmd}\\` manually.`\n : `The update installed, but the Mastra Code you are running (at ${install.dir}) is still ` +\n `v${install.version} — it looks like it is managed by another tool. Update it with that tool, ` +\n `or try \\`${cmd}\\`.`;\n return { status: 'unchanged', message };\n }\n\n return { status: 'updated', message: `Updated to v${targetVersion}. Please restart Mastra Code.` };\n}\n\n/** Global node_modules directory the package manager installs into, or null when unknown. */\nfunction getGlobalRoot(pm: PackageManager): Promise<string | null> {\n const args = pm === 'yarn' ? ['global', 'dir'] : ['root', '-g'];\n return new Promise(res => {\n execFile(pm, args, { timeout: 10_000, shell: USE_SHELL }, (error, stdout) => {\n const out = (stdout ?? '').trim().split('\\n').pop()?.trim();\n if (error || !out) return res(null);\n res(pm === 'yarn' ? resolve(out, 'node_modules') : out);\n });\n });\n}\n\n/**\n * Whether updating via `pm` would touch the install the running binary uses.\n * Fail-open: returns true when either side can't be determined, so the update\n * proceeds and the post-install verification has the final word.\n */\nasync function isOwnInstallManagedBy(pm: PackageManager, install: { dir: string } | null): Promise<boolean> {\n if (!install) return true;\n const root = await getGlobalRoot(pm);\n if (!root) return true;\n try {\n return realpathSync(resolve(root, PACKAGE_NAME)) === install.dir;\n } catch {\n // Package absent from the pm's global root: installing there can't affect the running binary.\n return false;\n }\n}\n\n/** A tool other than a package manager that owns the running install, matched by path. */\ninterface InstallOwner {\n name: string;\n /** Command to run to delegate the update; omitted when we only suggest `command` to the user. */\n exec?: { cmd: string; args: string[] };\n command: string;\n}\n\nfunction findInstallOwner(dir: string, version: string): InstallOwner | null {\n if (dir.startsWith(join(homedir(), '.vite-plus') + sep)) {\n return {\n name: 'vite-plus',\n exec: { cmd: 'vp', args: ['install', '-g', `${PACKAGE_NAME}@${version}`] },\n command: `vp install -g ${PACKAGE_NAME}@${version}`,\n };\n }\n // Homebrew keeps formulas under <prefix>/Cellar/ whatever the prefix, so match the path segment.\n if (dir.split(sep).includes('Cellar')) {\n // Suggest-only: brew formulas lag npm, and `brew upgrade` can pull unrelated updates.\n return { name: 'Homebrew', command: `brew upgrade ${PACKAGE_NAME}` };\n }\n return null;\n}\n\n/**\n * Update mastracode and verify the result: delegates to the tool that owns the\n * running install when we recognize it, skips the install when it isn't\n * managed by `pm`, otherwise runs the package manager. Every executed update\n * is verified against the on-disk version.\n */\nexport async function performUpdate(pm: PackageManager, targetVersion: string): Promise<UpdateOutcome> {\n // The registry-provided version reaches shell commands on Windows — accept only version tokens.\n if (!/^[\\w.+-]+$/.test(targetVersion)) {\n return { status: 'failed', message: `Auto-update aborted: unexpected version \"${targetVersion}\".` };\n }\n\n const install = locateOwnInstall();\n\n const owner = install ? findInstallOwner(install.dir, targetVersion) : null;\n if (owner) {\n if (!owner.exec) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is managed by ${owner.name}. ` +\n `Update it with \\`${owner.command}\\`.`;\n return { status: 'unchanged', message };\n }\n const result = await execUpdate(owner.exec.cmd, owner.exec.args);\n return resolveUpdateOutcome({\n pm,\n targetVersion,\n result,\n install: locateOwnInstall(),\n manualCommand: owner.command,\n });\n }\n\n if (!(await isOwnInstallManagedBy(pm, install))) {\n const message =\n `Your Mastra Code install (at ${install!.dir}) is not managed by ${pm} — it looks like it was ` +\n `installed by another tool. Update it with that tool, or try \\`${getInstallCommand(pm, targetVersion)}\\`.`;\n return { status: 'unchanged', message };\n }\n\n const result = await runUpdate(pm, targetVersion);\n // Re-locate so the version reflects what the install just wrote to disk.\n return resolveUpdateOutcome({ pm, targetVersion, result, install: locateOwnInstall() });\n}\n"],"mappings":"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","names":["resolve","result"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.0-alpha.8",
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": {
@@ -47,7 +47,7 @@
47
47
  "@ai-sdk/openai-compatible": "^2.0.59",
48
48
  "@ast-grep/napi": "^0.42.0",
49
49
  "@aws-sdk/credential-providers": "^3.864.0",
50
- "ai": "^6.0.224",
50
+ "ai": "^6.0.225",
51
51
  "execa": "^9.6.1",
52
52
  "libsql": "^0.5.29",
53
53
  "posthog-node": "^5.37.0",
@@ -59,28 +59,28 @@
59
59
  "@mastra/agent-browser": "0.4.1",
60
60
  "@mastra/duckdb": "1.5.1",
61
61
  "@mastra/fastembed": "1.2.0",
62
- "@mastra/core": "1.52.0-alpha.3",
63
- "@mastra/libsql": "1.16.0",
64
- "@mastra/github-signals": "0.2.2",
62
+ "@mastra/libsql": "1.17.0-alpha.1",
65
63
  "@mastra/mcp": "1.15.0-alpha.0",
66
- "@mastra/observability": "1.16.1",
67
- "@mastra/memory": "1.23.1-alpha.0",
68
- "@mastra/pg": "1.16.1-alpha.0",
64
+ "@mastra/github-signals": "0.2.2",
65
+ "@mastra/observability": "1.16.2-alpha.0",
66
+ "@mastra/memory": "1.23.1-alpha.1",
67
+ "@mastra/pg": "1.17.0-alpha.1",
69
68
  "@mastra/schema-compat": "1.3.4",
69
+ "@mastra/core": "1.52.0-alpha.8",
70
70
  "@mastra/stagehand": "0.3.1-alpha.0",
71
- "@mastra/tavily": "1.1.0"
71
+ "@mastra/tavily": "1.1.1-alpha.0"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@libsql/client": "^0.17.4",
75
75
  "@types/node": "22.20.1",
76
- "eslint": "^10.4.1",
76
+ "eslint": "^10.7.0",
77
77
  "tsup": "^8.5.1",
78
78
  "tsx": "^4.22.4",
79
79
  "typescript": "^6.0.3",
80
80
  "typescript-eslint": "^8.57.0",
81
81
  "vitest": "4.1.10",
82
- "@internal/lint": "0.0.114",
83
- "@internal/types-builder": "0.0.89"
82
+ "@internal/types-builder": "0.0.89",
83
+ "@internal/lint": "0.0.114"
84
84
  },
85
85
  "engines": {
86
86
  "node": ">=22.19.0"