-
Notifications
You must be signed in to change notification settings - Fork 1.5k
fix(deployer): auto-detect workspace packages for transpilation #11506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
@ftzi is attempting to deploy a commit to the Mastra Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis PR introduces workspace-aware bundling to the Mastra deployer. It adds workspace package detection and bundling logic by importing workspace utilities, updating function signatures to pass workspace information through the bundling pipeline, and modifying the node-modules-extension-resolver plugin to handle workspace packages as non-external bundles. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/deployer/src/build/utils/workspace-transpile.ts (1)
16-18: Consider simplifying the regex pattern to avoid potential ReDoS concerns.The static analysis tool flagged a potential ReDoS risk. While the input comes from a trusted source (workspace paths from
findWorkspaces), the pattern(?!.*node_modules).*$with nested quantifiers could theoretically cause backtracking issues.A safer alternative would exclude
node_modulesby checking path segments rather than using a negative lookahead with.*:🔎 Proposed simplification
- // Match files in workspace, excluding node_modules subdirectories - return new RegExp(`${path.isAbsolute(p) ? '^' : '/'}${escaped}/(?!.*node_modules).*$`); + // Match files in workspace, excluding node_modules subdirectories + return new RegExp(`${path.isAbsolute(p) ? '^' : '/'}${escaped}/(?!node_modules/).*$`);This change removes the
.*beforenode_modulesin the lookahead, which only checks if the path immediately after the workspace starts withnode_modules/. If you need to exclude nestednode_modulesanywhere in the path, you could instead use a pattern like/node_modules/check outside the regex or use a callback filter.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/deployer/src/build/analyze/analyzeEntry.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/utils/workspace-transpile.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm typecheckto validate TypeScript types across all packages
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
**/*.{ts,tsx,js,jsx,json,md}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm prettier:formatto format code andpnpm formatto run linting with auto-fix across all packages
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/**/*.{ts,tsx}: All packages must use TypeScript with strict type checking enabled
Use telemetry decorators for observability across components
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Include test cases for multiple occurrences of the transformation pattern, aliased imports, type imports, and mixed imports to verify the codemod works consistently
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/**/*.ts : Always optimize for minimal AST traversals: use shared utility functions from `src/codemods/lib/utils.ts`, combine multiple operations into single passes, add early returns when no changes needed, and track instances once and reuse the Set
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When transforming TypeScript type imports and usages, check the parent node type to skip transforming identifiers that are part of import declarations to avoid transforming imports from other packages with the same type name
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/**/*.ts : Always optimize for minimal AST traversals: use shared utility functions from `src/codemods/lib/utils.ts`, combine multiple operations into single passes, add early returns when no changes needed, and track instances once and reuse the Set
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Include test cases for multiple occurrences of the transformation pattern, aliased imports, type imports, and mixed imports to verify the codemod works consistently
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : Prefer using shared utility functions (`trackClassInstances()`, `renameMethod()`, `renameMethods()`, `transformMethodCalls()`, `renameImportAndUsages()`, `transformConstructorProperties()`, `transformObjectProperties()`) instead of writing custom AST transformation logic
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When transforming TypeScript type imports and usages, check the parent node type to skip transforming identifiers that are part of import declarations to avoid transforming imports from other packages with the same type name
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When renaming function/value imports and all their usages, use the `renameImportAndUsages()` utility which handles both the import declaration and usages in a single pass, and correctly handles aliased imports
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : Use `context.hasChanges = true` flag and `context.messages.push()` to track and report what transformations were made in the codemod
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When tracking which package an import came from, verify the import source before transforming usages to avoid transforming identifiers from other packages with the same name
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:40:41.785Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:41.785Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Use useMastraClient SDK for API calls instead of direct fetch() calls
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:41:10.784Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/.cursor/rules/frontend.mdc:0-0
Timestamp: 2025-11-24T16:41:10.784Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Use `useMastraClient` SDK for API calls in data-fetching hooks in `packages/playground-ui`
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:40:29.624Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/analyze/analyzeEntry.ts
📚 Learning: 2025-11-24T16:40:29.624Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,md} : Run `pnpm prettier:format` to format code and `pnpm format` to run linting with auto-fix across all packages
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
🧬 Code graph analysis (3)
packages/deployer/src/build/utils/workspace-transpile.ts (1)
packages/deployer/src/build/utils.ts (1)
slash(52-60)
packages/deployer/src/build/shared/extract-mastra-option.ts (1)
packages/deployer/src/build/utils/workspace-transpile.ts (1)
getWorkspaceTranspilePatterns(10-20)
packages/deployer/src/build/analyze/analyzeEntry.ts (3)
packages/deployer/src/build/utils.ts (1)
slash(52-60)packages/deployer/src/build/types.ts (1)
DependencyMetadata(4-17)packages/deployer/src/build/utils/workspace-transpile.ts (1)
getWorkspaceTranspilePatterns(10-20)
🪛 ast-grep (0.40.3)
packages/deployer/src/build/utils/workspace-transpile.ts
[warning] 17-17: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${path.isAbsolute(p) ? '^' : '/'}${escaped}/(?!.*node_modules).*$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🔇 Additional comments (7)
packages/deployer/src/build/utils/workspace-transpile.ts (1)
10-19: Implementation looks solid overall.The function correctly:
- Handles null/undefined workspaces with the nullish coalescing operator
- Escapes regex special characters in paths
- Uses the existing
slashutility for cross-platform path normalization- Differentiates between absolute and relative paths for the regex prefix
packages/deployer/src/build/shared/extract-mastra-option.ts (2)
17-27: Async conversion and auto-detection look good.The function is correctly made async to support the workspace detection. The conditional esbuildOpts construction ensures minimal overhead when no workspace patterns are found.
37-41: nodeResolve configuration is consistent with analyzeEntry.ts.The plugin configuration with
preferBuiltins: trueandexportConditions: ['node']matches the setup inanalyzeEntry.ts, ensuring consistent module resolution behavior across both code paths.packages/deployer/src/build/analyze/analyzeEntry.ts (4)
279-283: Pattern resolution logic is correct.The lazy evaluation ensures
getWorkspaceTranspilePatterns()is only called once at the top-level entry point, and the resolved patterns are propagated through all recursive calls. This avoids redundant filesystem operations during transitive dependency analysis.
173-180: Transitive dependency analysis correctly propagates transpilePatterns.The recursive call to
analyzeEntryincludes the resolved patterns, ensuring workspace packages discovered transitively also benefit from consistent transpilation settings.
48-51: nodeResolve plugin addition enhances module resolution.Adding
nodeResolvewithpreferBuiltins: trueandexportConditions: ['node']ensures proper resolution of Node.js built-in modules and ESM exports, which is important for monorepo workspace package analysis.
27-31: Consider usingconstwith a ternary for esbuildOpts.Minor style note: The pattern of building
esbuildOptsconditionally is fine, but ensure TypeScript correctly infers the type. The current approach works well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/deployer/src/build/bundler.ts (1)
76-78: Consider reusinggetPackageNameutility for consistency.The package name extraction logic here duplicates the existing
getPackageNamefunction from./utils. Using the shared utility would ensure consistent behavior across the codebase.🔎 Proposed refactor
import { slash } from './utils'; +import { getPackageName } from './utils';Then in the resolveId function:
if (isDev) { // Check if this is a workspace package using the workspaceMap - const pkgName = id.split('/').slice(0, id.startsWith('@') ? 2 : 1).join('/'); + const pkgName = getPackageName(id); const isWorkspacePackage = analyzedBundleInfo.workspaceMap?.has(pkgName);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
packages/deployer/src/build/analyze/analyzeEntry.tspackages/deployer/src/build/bundler.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/watcher.tspackages/deployer/src/bundler/workspaceDependencies.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/deployer/src/build/analyze/analyzeEntry.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm typecheckto validate TypeScript types across all packages
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/bundler.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/bundler/workspaceDependencies.tspackages/deployer/src/build/watcher.ts
**/*.{ts,tsx,js,jsx,json,md}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm prettier:formatto format code andpnpm formatto run linting with auto-fix across all packages
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/bundler.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/bundler/workspaceDependencies.tspackages/deployer/src/build/watcher.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/**/*.{ts,tsx}: All packages must use TypeScript with strict type checking enabled
Use telemetry decorators for observability across components
Files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/bundler.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/bundler/workspaceDependencies.tspackages/deployer/src/build/watcher.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/**/*.ts : Always optimize for minimal AST traversals: use shared utility functions from `src/codemods/lib/utils.ts`, combine multiple operations into single passes, add early returns when no changes needed, and track instances once and reuse the Set
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When transforming TypeScript type imports and usages, check the parent node type to skip transforming identifiers that are part of import declarations to avoid transforming imports from other packages with the same type name
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/watcher.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When tracking which package an import came from, verify the import source before transforming usages to avoid transforming identifiers from other packages with the same name
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/bundler.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/watcher.ts
📚 Learning: 2025-11-24T16:40:52.090Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground/CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:52.090Z
Learning: Applies to packages/playground/**/*.{ts,tsx} : Use named exports only in packages/playground; avoid default exports
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/plugins/node-modules-extension-resolver.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : Use `context.hasChanges = true` flag and `context.messages.push()` to track and report what transformations were made in the codemod
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/bundler/workspaceDependencies.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Include test cases for multiple occurrences of the transformation pattern, aliased imports, type imports, and mixed imports to verify the codemod works consistently
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : Prefer using shared utility functions (`trackClassInstances()`, `renameMethod()`, `renameMethods()`, `transformMethodCalls()`, `renameImportAndUsages()`, `transformConstructorProperties()`, `transformObjectProperties()`) instead of writing custom AST transformation logic
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When renaming function/value imports and all their usages, use the `renameImportAndUsages()` utility which handles both the import declaration and usages in a single pass, and correctly handles aliased imports
Applied to files:
packages/deployer/src/build/utils/workspace-transpile.tspackages/deployer/src/build/watcher.ts
📚 Learning: 2025-11-24T16:41:20.908Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground/.cursor/rules/frontend.mdc:0-0
Timestamp: 2025-11-24T16:41:20.908Z
Learning: Applies to packages/playground/src/**/*.{ts,tsx} : Use named exports only; avoid default exports
Applied to files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts
📚 Learning: 2025-11-24T16:40:41.785Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:41.785Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Use useMastraClient SDK for API calls instead of direct fetch() calls
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:40:29.624Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:40:29.624Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,md} : Run `pnpm prettier:format` to format code and `pnpm format` to run linting with auto-fix across all packages
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
🧬 Code graph analysis (4)
packages/deployer/src/build/bundler.ts (1)
packages/_types-builder/src/replace-types.js (1)
pkgName(94-94)
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
packages/deployer/src/build/utils.ts (1)
getPackageName(26-34)
packages/deployer/src/build/shared/extract-mastra-option.ts (1)
packages/deployer/src/build/utils/workspace-transpile.ts (1)
getWorkspaceTranspileOptions(7-36)
packages/deployer/src/build/watcher.ts (2)
packages/deployer/src/build/utils.ts (1)
getPackageName(26-34)packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
nodeModulesExtensionResolver(31-94)
🪛 ast-grep (0.40.3)
packages/deployer/src/build/utils/workspace-transpile.ts
[warning] 27-27: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(node_modules\\/(?!(?:${negativeLookahead})(?:\\/|$)))
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🔇 Additional comments (10)
packages/deployer/src/bundler/workspaceDependencies.ts (1)
64-74: LGTM! Debug logging is well-structured.The debug logging is properly gated behind the
MASTRA_BUNDLER_DEBUGenvironment variable and provides useful diagnostic information for troubleshooting workspace detection issues. The logged data (paths, counts, boolean flags) is appropriate for debugging without exposing sensitive information.packages/deployer/src/build/bundler.ts (1)
80-92: Workspace bundling logic is correct.The implementation correctly bundles workspace packages (to transpile TypeScript) while keeping non-workspace packages external for faster dev rebuilds. The control flow clearly separates the two cases.
packages/deployer/src/build/shared/extract-mastra-option.ts (3)
17-27: Good async refactor with clear documentation.The function is correctly made async to await
getWorkspaceTranspileOptions. The comment on line 25 clearly explains the chicken-and-egg problem this solves. The caller at line 81 already awaits this function, so the change is compatible.
36-40: Plugin ordering is correct.Adding
nodeResolvebeforeesbuildensures module resolution happens before transpilation. The configuration withpreferBuiltins: trueandexportConditions: ['node']is appropriate for Node.js target.
52-63: Consistent application of esbuildOpts across all esbuild calls.The
esbuildOptsare correctly passed to all threeesbuild()calls (lines 40, 52, 63), ensuring workspace packages are transpiled consistently throughout the pipeline.packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (2)
29-32: Clean API extension with proper defaults.The optional
workspacePackagesparameter with default empty array maintains backward compatibility while enabling workspace-aware behavior. Good use of the existinggetPackageNameutility for consistent package name extraction.
44-48: Workspace package check is correctly placed.The early-out for workspace packages is positioned correctly before other resolution logic. Returning
nullallows workspace packages to be handled by other plugins (like the workspace-resolver in watcher.ts) for bundling instead of externalization.packages/deployer/src/build/watcher.ts (2)
80-107: Workspace resolution logic is well-implemented.The
workspace-resolverplugin correctly:
- Checks if the imported package is a workspace package
- Uses
createRequirefrom the importer's context for proper resolution- Marks resolved modules as
external: falseto ensure bundling- Gracefully falls back by returning
nullon resolution failuresThe plugin is appropriately positioned before
nodeModulesExtensionResolver, which is now configured to skip workspace packages.
86-102: Robust error handling in workspace resolution.The try-catch block on lines 90-99 handles resolution failures gracefully. Using
require.resolvefromcreateRequire(importer)correctly resolves packages relative to the importing file's context, which is essential for monorepo workspace resolution.packages/deployer/src/build/utils/workspace-transpile.ts (1)
23-28: ReDoS risk is minimal with properly escaped trusted input.The static analysis warning about regex construction from variable input is overly cautious here. The risk is effectively mitigated:
- Package names come from workspace
package.jsonfiles (controlled, trusted source)- npm naming restrictions limit package names to lowercase letters, digits, hyphens, underscores, and periods—no dangerous regex metacharacters like
*,+,?,^, or$- Special regex characters are comprehensively escaped on line 24 with the pattern
/[.*+?^${}()|[\]\\]/g- The regex itself is straightforward (simple negative lookahead with literal alternation), with no nested quantifiers or exponential backtracking scenarios
The implementation is sound. No changes needed.
Workspace packages (monorepo dependencies with TypeScript source) were being kept as external imports in dev mode, causing runtime errors like: ERR_UNKNOWN_FILE_EXTENSION: Unknown file extension ".ts" This fix ensures workspace packages are bundled and transpiled: 1. node-modules-extension-resolver: Add workspacePackages option to resolve and bundle workspace imports (external: false) 2. extract-mastra-option: Add workspace-resolver plugin to bundle workspace packages during config extraction phase 3. watcher: Pass workspace package names to the resolver plugin Fixes mastra-ai#6852 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
f98bd70 to
fd0c64a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
49-62: Same type safety and duplication concerns as in extract-mastra-option.ts.This workspace package resolution logic (lines 55-62) duplicates the pattern in
packages/deployer/src/build/shared/extract-mastra-option.ts(lines 39-53), including the same@ts-expect-errorsuppressions (lines 56 and 79).Refer to the review comment on
extract-mastra-option.tslines 39-53 for the detailed concern about:
- Type safety with
@ts-expect-error- Code duplication
- Suggestion to extract shared utility
Also applies to: 79-79
🧹 Nitpick comments (1)
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
36-37: Consider type consistency across the codebase.This function accepts
workspacePackages?: string[]and converts it to aSet, whileextractMastraOptionBundlerinpackages/deployer/src/build/shared/extract-mastra-option.ts(line 25) acceptsworkspacePackages?: Set<string>directly.For consistency and to avoid unnecessary conversions, consider standardizing on
Set<string>in both function signatures since the internal representation is a Set in both cases.🔎 Proposed change for type consistency
export interface NodeModulesExtensionResolverOptions { - /** Workspace package names that should be bundled, not externalized */ - workspacePackages?: string[]; + /** Workspace package names that should be bundled, not externalized */ + workspacePackages?: Set<string>; } export function nodeModulesExtensionResolver(options?: NodeModulesExtensionResolverOptions): Plugin { - const workspacePackages = new Set(options?.workspacePackages ?? []); + const workspacePackages = options?.workspacePackages ?? new Set<string>();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.gitignorepackages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.tspackages/deployer/src/build/watcher.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/deployer/src/build/watcher.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm typecheckto validate TypeScript types across all packages
Files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.ts
**/*.{ts,tsx,js,jsx,json,md}
📄 CodeRabbit inference engine (CLAUDE.md)
Run
pnpm prettier:formatto format code andpnpm formatto run linting with auto-fix across all packages
Files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/**/*.{ts,tsx}: All packages must use TypeScript with strict type checking enabled
Use telemetry decorators for observability across components
Files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When transforming TypeScript type imports and usages, check the parent node type to skip transforming identifiers that are part of import declarations to avoid transforming imports from other packages with the same type name
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When tracking which package an import came from, verify the import source before transforming usages to avoid transforming identifiers from other packages with the same name
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When transforming TypeScript type imports and usages, check the parent node type to skip transforming identifiers that are part of import declarations to avoid transforming imports from other packages with the same type name
Applied to files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : When tracking which package an import came from, verify the import source before transforming usages to avoid transforming identifiers from other packages with the same name
Applied to files:
packages/deployer/src/build/plugins/node-modules-extension-resolver.tspackages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-12-30T15:02:58.132Z
Learnt from: taofeeq-deru
Repo: mastra-ai/mastra PR: 11486
File: packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts:643-678
Timestamp: 2025-12-30T15:02:58.132Z
Learning: In packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts, the code relies on the invariant that metadata.suspendedTools and metadata.pendingToolApprovals never contain resumed tools. Do not add filtering when using metadata directly. If this invariant could ever be violated, add an explicit defensive check; otherwise, avoid redundant filtering to preserve performance and rely on the established contract.
Applied to files:
.gitignore
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/**/*.ts : Always optimize for minimal AST traversals: use shared utility functions from `src/codemods/lib/utils.ts`, combine multiple operations into single passes, add early returns when no changes needed, and track instances once and reuse the Set
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:40:41.785Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:41.785Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Use useMastraClient SDK for API calls instead of direct fetch() calls
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:41:10.784Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/.cursor/rules/frontend.mdc:0-0
Timestamp: 2025-11-24T16:41:10.784Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Use `useMastraClient` SDK for API calls in data-fetching hooks in `packages/playground-ui`
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:41:10.784Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/playground-ui/.cursor/rules/frontend.mdc:0-0
Timestamp: 2025-11-24T16:41:10.784Z
Learning: Applies to packages/playground-ui/src/**/*.{ts,tsx} : Export explicit prop types separately from components in `packages/playground-ui`; keep type definitions alongside components
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/codemods/v1/**/*.ts : Use `context.hasChanges = true` flag and `context.messages.push()` to track and report what transformations were made in the codemod
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Include test cases for multiple occurrences of the transformation pattern, aliased imports, type imports, and mixed imports to verify the codemod works consistently
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
📚 Learning: 2025-11-24T16:40:29.624Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:40:29.624Z
Learning: Applies to **/*.{ts,tsx} : Run `pnpm typecheck` to validate TypeScript types across all packages
Applied to files:
packages/deployer/src/build/shared/extract-mastra-option.ts
🧬 Code graph analysis (2)
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
packages/deployer/src/build/utils.ts (1)
getPackageName(26-34)
packages/deployer/src/build/shared/extract-mastra-option.ts (2)
packages/_types-builder/src/replace-types.js (1)
pkgName(94-94)packages/deployer/src/build/utils.ts (1)
getPackageName(26-34)
🔇 Additional comments (4)
.gitignore (1)
51-51: LGTM! Appropriate ignore pattern for deployer artifacts.The addition correctly ignores generated tarball files in the deployer package, which aligns with the workspace-aware bundling changes introduced in this PR.
packages/deployer/src/build/shared/extract-mastra-option.ts (2)
98-102: Workspace detection logic looks correct.The workspace information retrieval and Set construction properly support the workspace-aware bundling feature. The
workspacePackagesSet is correctly passed to the bundler.
5-5: Imports are properly resolved and available.All three new imports are correctly exported from their source files and present in dependencies:
nodeResolvefrom@rollup/plugin-node-resolve(v16.0.3)getWorkspaceInformationfrom../../bundler/workspaceDependenciesgetPackageNamefrom../utilsEach is properly typed and used correctly in the code.
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts (1)
23-26: Well-documented interface for workspace package options.The
NodeModulesExtensionResolverOptionsinterface clearly documents the purpose of theworkspacePackagesoption.
| { | ||
| name: 'workspace-resolver', | ||
| async resolveId(id, importer, resolveOptions) { | ||
| if (!importer) return null; | ||
| const pkgName = getPackageName(id); | ||
| if (pkgName && workspacePackages.has(pkgName)) { | ||
| // @ts-expect-error - handler is part of resolveId signature | ||
| const resolved = await nodeResolvePlugin.resolveId?.handler?.call(this, id, importer, resolveOptions); | ||
| if (resolved?.id) { | ||
| return { id: resolved.id, external: false }; | ||
| } | ||
| } | ||
| return null; | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address type safety concern with @ts-expect-error and consider extracting duplicated workspace resolution logic.
The workspace-resolver plugin suppresses a type error when accessing nodeResolvePlugin.resolveId?.handler (line 45). This pattern is duplicated in node-modules-extension-resolver.ts (lines 56-57 and 79), suggesting a shared utility function could improve maintainability and type safety.
Concerns:
- Type safety: The
@ts-expect-errorindicates accessing an internal/undocumented API of the rollup plugin. This may break with future rollup updates. - Code duplication: Nearly identical workspace resolution logic exists in
packages/deployer/src/build/plugins/node-modules-extension-resolver.ts(lines 55-62).
Recommendations:
- Extract the workspace resolution pattern into a shared utility function that properly types the plugin handler access
- If accessing internal APIs is unavoidable, add a comment explaining why and document the rollup version dependency
- Consider using Rollup's public APIs if available
🔎 Suggested approach to extract shared workspace resolution logic
Create a new utility function in packages/deployer/src/build/utils.ts:
import nodeResolve from '@rollup/plugin-node-resolve';
import type { Plugin } from 'rollup';
export async function resolveWorkspacePackage(
id: string,
importer: string,
options: any,
context: Plugin,
): Promise<{ id: string; external: boolean } | null> {
const nodeResolvePlugin = nodeResolve({ preferBuiltins: true });
// Type assertion with explanation for why internal API access is needed
const resolveHandler = (nodeResolvePlugin.resolveId as any)?.handler;
if (!resolveHandler) {
return null;
}
const resolved = await resolveHandler.call(context, id, importer, options);
if (resolved?.id) {
return { id: resolved.id, external: false };
}
return null;
}Then use it in both files to reduce duplication.
🤖 Prompt for AI Agents
packages/deployer/src/build/shared/extract-mastra-option.ts lines 39-53: the
workspace-resolver currently uses an unchecked access pattern with
@ts-expect-error to call nodeResolvePlugin.resolveId?.handler and duplicates the
same logic in node-modules-extension-resolver.ts; extract this logic into a
shared utility (e.g., packages/deployer/src/build/utils.ts) that accepts (id,
importer, resolveOptions, pluginContext) and safely accesses the resolve handler
with a typed any/assertion, calls it with the proper context, returns {id,
external: false} when resolved or null otherwise, replace the duplicated blocks
in both files to call the new utility, and add a short comment documenting why
an internal handler is used and which Rollup version is required (or prefer
public API if available).
|
Hello, thanks for the PR! Can you please open a bug report (using the latest Mastra v1 beta) instead? We're pretty sure we solved most problems but if we missed something that will make it easier to fix it for you. Thanks! |
Hey, in my project, I kept having the error
I tried the latest versions, but without success. From #6852 I saw others still had issues even with the said fixes.
Note that my solution works both by specifying and by not specifying the transpilePackages, following @LekoArts's comment at #6852 (comment)
This solution is purely AI-coded with some aid from me, as I have no clue how Mastra's internals work.
Claude
Summary
find-workspaces(already a dependency)transpilePackagesfor workspace packagesProblem
When using Mastra in a monorepo with workspace packages (e.g.,
@myorg/shared), users had to manually list every workspace package intranspilePackagesconfig. This was a chicken-and-egg problem: the CLI needed to readtranspilePackagesfrom config, but the config file imports from workspace packages that need transpiling first.Solution
Use
find-workspacesto auto-detect all workspace packages and include them in esbuild'sincludepatterns during bundling. This happens before config extraction, solving the chicken-and-egg problem.Test plan
@stockapp/*workspace packagesnpm run devworks withouttranspilePackagesconfigFixes #6852
🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.