feat: Upgrade to Typescript 5.8#643
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: a4eb456 The changes in this PR will be included in the next version bump. This PR includes changesets to release 18 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughRepository-wide toolchain updates (Node 22.18, PNPM 10.15, TypeScript 5.8) with catalog/manifests aligned. Introduces mise.toml. Refactors multiple TypeScript classes to avoid parameter properties. Adds Vite ambient types to UI/plugins. Adjusts async-combobox effect dependencies. Expands hash util to accept Buffer. Minor tests/expectations/timing updates. Adds a changeset. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Component as AsyncComboboxField
participant Effect as useEffect(loader)
participant API as OptionsLoader
User->>Component: Type/query or initialOptions changes
Component->>Effect: Trigger on [debouncedQuery, minSearchLength, initialOptions]
alt debouncedQuery.length < minSearchLength
Effect->>Component: setOptions(initialOptions)
else Load options
Effect->>API: loadOptions(debouncedQuery) [with abort on rerun]
API-->>Effect: options / error / aborted
alt success
Effect->>Component: setOptions(loaded)
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/project-builder-lib/src/definition/project-definition-container.ts (1)
4-6: Standardize on#src/Path Alias and Update GuidelinesThe audit shows 989 instances of
#src/imports versus a single occurrence of@src/in the entire repository. This indicates that#src/is the de facto alias. To align code and documentation:• Update the coding guidelines to specify
#src/as the official path alias (replacing any reference to@src/).
• Replace the lone@src/import (your audit’s one offender) with#src/so all imports are consistent.
♻️ Duplicate comments (1)
plugins/plugin-storage/src/vite-env.d.ts (1)
1-2: Same verification as plugin-auth (devDeps + scope).Replicating the ambient types here is consistent. Please apply the same dependency and tsconfig checks noted in plugins/plugin-auth/src/vite-env.d.ts.
If helpful, extend the previous script’s loop to include plugins/plugin-storage/package.json as well.
🧹 Nitpick comments (19)
packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx (3)
107-108: Remove unused ref initialOptionsRef.initialOptionsRef is written but never read; it’s dead code now that the effect depends directly on initialOptions.
Apply this diff:
- const initialOptionsRef = useRef(initialOptions); - initialOptionsRef.current = initialOptions;
141-152: Add cancellation guard around resolveValue to avoid stale state updates.If value changes quickly or the component unmounts, the resolveValue promise may resolve late and setSelectedOptionCache from an outdated closure. Guarding with a cancelled flag prevents that.
Apply this diff:
- // If we have a resolveValue function, try to resolve the option - if (resolveValue) { - resolveValue(value) - .then((resolvedOption) => { - if (resolvedOption && getOptionValue(resolvedOption) === value) { - setSelectedOptionCache(resolvedOption); - } - }) - .catch(() => { - // If resolution fails, we'll show the value as-is - }); - } + // If we have a resolveValue function, try to resolve the option (with cancellation guard) + if (resolveValue) { + let cancelled = false; + const currentValue = value; + Promise.resolve(resolveValue(currentValue)) + .then((resolvedOption) => { + if ( + !cancelled && + resolvedOption && + getOptionValue(resolvedOption) === currentValue + ) { + setSelectedOptionCache(resolvedOption); + } + }) + .catch(() => { + // If resolution fails, we'll show the value as-is + }); + return () => { + cancelled = true; + }; + }
278-287: Stabilize keys for options when value can be null.key={val} will be "null" for null values and can collide if multiple options share null. Derive a string key that incorporates the label to ensure uniqueness.
Apply this diff:
- {options.map((option) => { + {options.map((option) => { const val = getOptionValue(option); const label = getOptionLabel(option); - return ( - <ComboboxItem value={val} key={val} label={label}> + const itemKey = `${val ?? '__null__'}::${label}`; + return ( + <ComboboxItem value={val} key={itemKey} label={label}> {renderItemLabel ? renderItemLabel(option, { selected: val === value }) : label} </ComboboxItem> ); })}.node-version (1)
1-1: Add a trailing newline.Tiny nit to avoid needless diffs in some tools/editors.
-22.18.0 +22.18.0 +packages/project-builder-server/src/sync/conflict-file-monitor.test.ts (1)
153-154: Avoid fixed sleeps; use an explicit wait helper to remove test flakiness.Bumping the sleep from 10ms→20ms reduces flakes but keeps the test timing-sensitive. Prefer polling/waiting on the real condition or advancing fake timers.
- await new Promise((resolve) => { - setTimeout(resolve, 20); - }); + await waitForConflictResolution(syncMetadataController, 'test-package');Add this helper near the bottom of the file (outside the changed hunk):
async function waitForConflictResolution( controller: SyncMetadataController, pkg: string, timeoutMs = 500, intervalMs = 10, ): Promise<void> { const start = Date.now(); for (;;) { const md = await controller.getMetadata(); const info = md.packages[pkg]; if (info.status === 'success' && (info.result?.filesWithConflicts?.length ?? 0) === 0) return; if (Date.now() - start > timeoutMs) throw new Error('Timed out waiting for conflict resolution'); await new Promise((r) => setTimeout(r, intervalMs)); } }Optional alternative: switch to fake timers and
vi.advanceTimersByTimeAsync()to drive watcher debounce logic deterministically.Also consider applying the same pattern to other sleeps (Lines 206–208, 223–225, 274–276, 291–293) for consistency.
.nvmrc (1)
1-1: Add a trailing newline.Same nit as .node-version to keep editors/lint happy.
-22.18.0 +22.18.0 +.changeset/typescript-5-8-upgrade.md (1)
25-31: Call out the breaking Node requirement explicitly in the notes.Even if versions remain patch for private packages, help downstream readers by highlighting Node support changes.
Apply:
**Key Changes:** - Upgraded TypeScript to version 5.8 - Enabled `erasableSyntaxOnly` compiler option for improved build performance - Updated Node.js requirement to 22.18 - Updated PNPM requirement to 10.15 - Fixed parameter property syntax to be compatible with erasable syntax only mode + - BREAKING: Dropped support for Node.js < 22.18 (update your runtime/engines accordingly)packages/core-generators/src/constants/node.ts (1)
1-2: Approved: Node & PNPM version constants are fully alignedAll references to the Node 22 runtime and PNPM 10.15 versions are consistent across the repo:
packages/core-generators/src/constants/node.tsexportsNODE_VERSION = '22.18.0'andPNPM_VERSION = '10.15.0'.- Root tooling configs match exactly:
.nvmrccontains22.18.0.node-versioncontains22.18.0- The Create-Project templates and tests reference:
- Volta pin to Node
22.18.0- Engines field of
node: '^22.0.0'(covers 22.x) andpnpm: '^10.15.0'- No other conflicting runtime versions detected.
Consider an optional refactor to centralize these values into a single source of truth (e.g. import from the core constant or drive your template configs directly from
.nvmrc/Volta), to prevent future drift.packages/utils/src/crypto/hash.ts (1)
1-13: Review the buffer extraction logic for potential runtime issuesThe buffer extraction from
TextEncoder.encode()result introduces a runtime check that may be unnecessary. TheTextEncoder.encode()method returns aUint8Array, and accessing its.bufferproperty should always yield anArrayBuffer. The TypeError check seems overly defensive.Consider simplifying this logic:
function normalizeContent( content: string | ArrayBuffer | Buffer, ): ArrayBuffer | Buffer { if (typeof content === 'string') { const encoder = new TextEncoder(); - const { buffer } = encoder.encode(content); - if (!(buffer instanceof ArrayBuffer)) { - throw new TypeError('Buffer is not an ArrayBuffer'); - } - return buffer; + return encoder.encode(content).buffer; } return content; }packages/project-builder-web/src/utils/error.ts (3)
5-11: Refactor looks good; consider preserving subclass error namesSwitching away from parameter properties aligns with TS 5.8 erasable syntax. One small improvement: setting
this.name = 'UserVisibleError'forces all subclasses (e.g.,RefDeleteError,NotFoundError) to report the same name, which can hinder debugging and error discrimination. Prefer deriving the name from the actual constructor.Apply:
- this.title = title; - this.name = 'UserVisibleError'; + this.title = title; + this.name = new.target.name;
15-24: Explicit fields forRefDeleteErrorare correct; offer optional title for better UXThe explicit
issuesfield and assignment look good. Minor UX tweak:RefDeleteErrorcurrently doesn’t set a title, so consumers relying onUserVisibleError.titlewill seeundefined. Consider providing a consistent title.- super( + super( `Cannot delete because of references: ${issues .map((i) => i.ref.path.join('.')) .join(', ')}`, - ); + , 'Delete blocked by references');
33-41: Zod error formatter is fine; consider stable ordering for determinism
formatZodErrorreads clearly. If error path ordering from Zod isn’t stable across versions, deterministic sorting can help consistent snapshots/logs.- const errorMessages = error.issues.map((issue) => { + const errorMessages = [...error.issues] + .sort((a, b) => a.path.join('.').localeCompare(b.path.join('.'))) + .map((issue) => {packages/project-builder-lib/src/utils/definition-diff/definition-diff.ts (2)
54-65: Keyed array diff: solid refactor; consider freezingoptionsand guarding keysExplicit
getKey/optionsfields look good. Two optional hardening tweaks:
- Freeze
optionsto prevent accidental mutation after construction.- Guard against
getKeyreturning empty/duplicate keys to avoid surprising merges.constructor( name: string, getKey: (item: T[number]) => string, options: DefinitionDiffKeyedArrayFieldOptions = {}, ) { super(name); this.getKey = getKey; - this.options = options; + this.options = Object.freeze({ ...options }); }Optionally, add a duplication check inside
diff:// After building desiredByKey if (desiredByKey.size !== desiredValue.length) { console.warn('Duplicate keys detected in desired items for field "%s"', this.name); }Also applies to: 67-78, 101-109, 112-147
187-193: Array includes field: clean conversion; minor nit on key coercionThe private
getKeyfield and assignment are correct. Indiff, whengetKeyis not provided,String(item)is used for thekey. For objects/symbols, this may produce[object Object]/Symbol(...), leading to collisions. If you expect non-primitive arrays, consider requiringgetKey.- constructor(name: string, getKey?: (item: T[number]) => string) { + constructor(name: string, getKey?: (item: T[number]) => string) { super(name); this.getKey = getKey; }And optionally enforce:
if (!this.getKey && typeof desiredValue[0] === 'object') { throw new TypeError(`getKey is required for non-primitive arrays in "${this.name}"`); }Also applies to: 205-215, 227-235
packages/create-project/src/project-creator.ts (1)
17-24: Spinner lifecycle: succeed before side-effects; consider a second spinner or clearer phasesYou call
spinner.succeed()beforepnpm install. If install fails, users won’t see a failed spinner since it’s already completed. Optional: split into two spinners or update the text and succeed only after the entire flow completes.Example approach:
- const spinner = ora({ text: 'Creating project files...' }).start(); + const spinner = ora({ text: 'Creating project files...' }).start(); try { // ... file creation - spinner.succeed(); - await exec('pnpm install', directory); + spinner.succeed(); + const install = ora({ text: 'Installing dependencies...' }).start(); + await exec('pnpm install', directory); + install.succeed();Also applies to: 83-105
packages/project-builder-lib/src/plugins/schema/store.ts (2)
4-10: Prefer readonly field and (optionally) freeze input to prevent accidental mutation
implementationsappears to be immutable after construction. Marking it readonly (and optionally freezing a shallow copy) protects against accidental writes and external reference mutation.Apply within this hunk:
- public implementations: Partial<Record<string, PluginSpecImplementation>>; + public readonly implementations: Readonly< + Partial<Record<string, PluginSpecImplementation>> + >; - implementations: Partial<Record<string, PluginSpecImplementation>>, + implementations: Readonly< + Partial<Record<string, PluginSpecImplementation>> + >, ) { - this.implementations = implementations; + // Shallow freeze to guard against external mutation of the provided object + this.implementations = Object.freeze({ ...implementations }); }If runtime freezing is undesirable (hot paths), keep the spread copy without
Object.freeze.
15-19: Avoid generic “falsy” checks; test for undefined explicitlyA plugin implementation could theoretically be a falsy value. Checking
=== undefinedcommunicates intent and is safer with Partial records.Proposed change (outside this hunk for clarity):
getPluginSpec<TImplementation>( spec: PluginSpec<TImplementation>, ): TImplementation { const implementation = this.implementations[spec.name] as | TImplementation | undefined; if (implementation === undefined) { throw new Error(`Unable to find implementation for spec ${spec.name}`); } return implementation; }packages/project-builder-lib/src/definition/project-definition-container.ts (2)
37-50: Good migration away from parameter properties; consider making pluginStore readonlySwitching to an explicit field aligns with TS 5.8 “erasable syntax only.” Since
pluginStoreis effectively immutable post-construction, make itreadonlyto prevent accidental mutation.Apply within this hunk:
- pluginStore: PluginImplementationStore; + readonly pluginStore: PluginImplementationStore; constructor( config: ResolvedZodRefPayload<ProjectDefinition>, parserContext: SchemaParserContext, pluginStore: PluginImplementationStore, ) { @@ - this.pluginStore = pluginStore; + this.pluginStore = pluginStore;
123-160: Factory methods read cleanly; minor perf thought (optional)Both factories are cohesive and keep plugin wiring localized. If
nameFromId/safeNameFromIdbecome hot paths, consider building aMap<id, name>once in the constructor—but not required now.I can add a lazy
idToNamemap with negligible surface-area changes if you want.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (3)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamltests/simple/package.jsonis excluded by!tests/**tests/simple/packages/e2e/package.jsonis excluded by!tests/**
📒 Files selected for processing (28)
.changeset/typescript-5-8-upgrade.md(1 hunks).node-version(1 hunks).nvmrc(1 hunks)mise.toml(1 hunks)package.json(2 hunks)packages/code-morph/package.json(1 hunks)packages/core-generators/src/constants/core-packages.ts(1 hunks)packages/core-generators/src/constants/node.ts(1 hunks)packages/create-project/src/project-creator.ts(1 hunks)packages/create-project/src/project-creator.unit.test.ts(1 hunks)packages/project-builder-cli/package.json(1 hunks)packages/project-builder-lib/src/definition/project-definition-container.ts(1 hunks)packages/project-builder-lib/src/plugin-tools/plugin-loader.ts(1 hunks)packages/project-builder-lib/src/plugins/schema/store.ts(1 hunks)packages/project-builder-lib/src/references/markers.ts(1 hunks)packages/project-builder-lib/src/references/types.ts(2 hunks)packages/project-builder-lib/src/utils/definition-diff/definition-diff.ts(3 hunks)packages/project-builder-server/src/sync/conflict-file-monitor.test.ts(1 hunks)packages/project-builder-web/src/utils/error.ts(1 hunks)packages/tools/package.json(1 hunks)packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx(1 hunks)packages/ui-components/src/vite-env.d.ts(1 hunks)packages/ui-components/tsconfig.node.json(1 hunks)packages/utils/src/crypto/hash.ts(1 hunks)plugins/plugin-auth/src/vite-env.d.ts(1 hunks)plugins/plugin-queue/src/vite-env.d.ts(1 hunks)plugins/plugin-storage/src/vite-env.d.ts(1 hunks)pnpm-workspace.yaml(1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.{ts,tsx}: Import UI components from the@baseplate-dev/ui-componentspackage as shown in the provided examples.
Use both standalone and React Hook Form controller variants for form components from@baseplate-dev/ui-componentsas appropriate.
If a particular interface or type is not exported, change the file so it is exported.
**/*.{ts,tsx}: TypeScript with strict type checking
Always include return types on top-level functions including React components (React.ReactElement)
Include absolute paths in import statements via tsconfig paths (@src/is the alias forsrc/)
If a particular interface or type is not exported, change the file so it is exported
Files:
packages/project-builder-lib/src/definition/project-definition-container.tspackages/create-project/src/project-creator.unit.test.tspackages/create-project/src/project-creator.tspackages/ui-components/src/vite-env.d.tsplugins/plugin-storage/src/vite-env.d.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.tsplugins/plugin-queue/src/vite-env.d.tsplugins/plugin-auth/src/vite-env.d.tspackages/core-generators/src/constants/node.tspackages/utils/src/crypto/hash.tspackages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsxpackages/project-builder-lib/src/plugin-tools/plugin-loader.tspackages/project-builder-lib/src/references/markers.tspackages/project-builder-lib/src/plugins/schema/store.tspackages/core-generators/src/constants/core-packages.tspackages/project-builder-lib/src/references/types.tspackages/project-builder-web/src/utils/error.tspackages/project-builder-lib/src/utils/definition-diff/definition-diff.ts
**/*.{js,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Node 16 module resolution - include file extensions in imports (
.js)
Files:
packages/project-builder-lib/src/definition/project-definition-container.tspackages/create-project/src/project-creator.unit.test.tspackages/create-project/src/project-creator.tspackages/ui-components/src/vite-env.d.tsplugins/plugin-storage/src/vite-env.d.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.tsplugins/plugin-queue/src/vite-env.d.tsplugins/plugin-auth/src/vite-env.d.tspackages/core-generators/src/constants/node.tspackages/utils/src/crypto/hash.tspackages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsxpackages/project-builder-lib/src/plugin-tools/plugin-loader.tspackages/project-builder-lib/src/references/markers.tspackages/project-builder-lib/src/plugins/schema/store.tspackages/core-generators/src/constants/core-packages.tspackages/project-builder-lib/src/references/types.tspackages/project-builder-web/src/utils/error.tspackages/project-builder-lib/src/utils/definition-diff/definition-diff.ts
**/*.{ts,tsx,js}
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
**/*.{ts,tsx,js}: Sort imports by group: external libs first, then local imports
Use camelCase for variables/functions, PascalCase for types/classes
Order functions such that functions are placed below the variables/functions they use
We use the prefer using nullish coalescing operator (??) ESLint rule instead of a logical or (||), as it is a safer operator
Use console.info/warn/error instead of console.log
Files:
packages/project-builder-lib/src/definition/project-definition-container.tspackages/create-project/src/project-creator.unit.test.tspackages/create-project/src/project-creator.tspackages/ui-components/src/vite-env.d.tsplugins/plugin-storage/src/vite-env.d.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.tsplugins/plugin-queue/src/vite-env.d.tsplugins/plugin-auth/src/vite-env.d.tspackages/core-generators/src/constants/node.tspackages/utils/src/crypto/hash.tspackages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsxpackages/project-builder-lib/src/plugin-tools/plugin-loader.tspackages/project-builder-lib/src/references/markers.tspackages/project-builder-lib/src/plugins/schema/store.tspackages/core-generators/src/constants/core-packages.tspackages/project-builder-lib/src/references/types.tspackages/project-builder-web/src/utils/error.tspackages/project-builder-lib/src/utils/definition-diff/definition-diff.ts
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Use kebab-case for file names
Files:
packages/project-builder-lib/src/definition/project-definition-container.tspackages/create-project/src/project-creator.unit.test.tspackages/create-project/src/project-creator.tsmise.tomlpackages/ui-components/src/vite-env.d.tspackages/ui-components/tsconfig.node.jsonpackages/project-builder-cli/package.jsonplugins/plugin-storage/src/vite-env.d.tspackages/tools/package.jsonpackages/project-builder-server/src/sync/conflict-file-monitor.test.tspackage.jsonpackages/code-morph/package.jsonplugins/plugin-queue/src/vite-env.d.tsplugins/plugin-auth/src/vite-env.d.tspackages/core-generators/src/constants/node.tspackages/utils/src/crypto/hash.tspackages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsxpackages/project-builder-lib/src/plugin-tools/plugin-loader.tspackages/project-builder-lib/src/references/markers.tspackages/project-builder-lib/src/plugins/schema/store.tspackages/core-generators/src/constants/core-packages.tspackages/project-builder-lib/src/references/types.tspackages/project-builder-web/src/utils/error.tspackages/project-builder-lib/src/utils/definition-diff/definition-diff.tspnpm-workspace.yaml
**/*.{unit,int}.test.ts
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Unit tests use
.unit.test.tssuffix, integration tests use.int.test.ts
Files:
packages/create-project/src/project-creator.unit.test.ts
**/*.test.ts
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Always import vitest globals explicitly (describe, it, expect)
Files:
packages/create-project/src/project-creator.unit.test.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/testing.mdc)
**/*.test.{ts,tsx}: Use descriptive test names that explain what is being tested
Structure tests with clear setup, execution, and verification phases (Arrange-Act-Assert)
Always mock external API calls and file system operations in tests
Each test should be independent and not rely on others
Leverage TypeScript for type-safe mocking in tests
Focus on testing public methods and behaviors, not implementation details
Each test should verify one specific behavior to keep tests simple
For file system operations in tests, use memfs and mock 'node:fs' and 'node:fs/promises'
When using globby in tests, pass the mocked fs adapter
Files:
packages/create-project/src/project-creator.unit.test.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.ts
**/*.{test,test-helper}.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/testing.mdc)
Extract repeated logic into reusable helper functions
Files:
packages/create-project/src/project-creator.unit.test.tspackages/project-builder-server/src/sync/conflict-file-monitor.test.ts
**/*.unit.test.ts
📄 CodeRabbit Inference Engine (.cursor/rules/testing.mdc)
Unit tests are colocated with source files using
.unit.test.tssuffix
Files:
packages/create-project/src/project-creator.unit.test.ts
.changeset/*.md
📄 CodeRabbit Inference Engine (CLAUDE.md)
When adding a new feature or changing an existing feature, add a new Changeset in the
.changeset/directory in the specified markdown format.
Files:
.changeset/typescript-5-8-upgrade.md
**/*.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.tsx: When using form components, integrate them with React Hook Form by passing thecontrolprop fromuseForm().
Use layout components such asSidebarLayout,Card, andBreadcrumbfrom@baseplate-dev/ui-componentsto structure pages as shown in the example.
Use interactive dialog components likeDialog,ConfirmDialog, anduseConfirmDialogfrom@baseplate-dev/ui-componentsfor modal interactions.
Files:
packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
{packages/project-builder-web/**,packages/ui-components/**}/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/ui-rules.mdc)
{packages/project-builder-web/**,packages/ui-components/**}/*.tsx: Use ShadCN-based components from@baseplate-dev/ui-componentsand always prefer these components over creating custom ones
Use Tailwind CSS utilities exclusively for styling; avoid writing custom CSS classes and use Tailwind's utility classes for all styling needs
In plugins, prefix all Tailwind classes with the plugin name (e.g.,auth-,storage-)
Use icons fromreact-icons/md(Material Design icons) and import them likeimport { MdAdd, MdDelete } from 'react-icons/md'; avoid using other icon libraries
Files:
packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
🧠 Learnings (5)
📚 Learning: 2025-07-22T09:10:31.413Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-07-22T09:10:31.413Z
Learning: Applies to **/*.{ts,tsx} : Include absolute paths in import statements via tsconfig paths (`src/` is the alias for `src/`)
Applied to files:
packages/ui-components/tsconfig.node.json
📚 Learning: 2025-07-22T09:10:31.413Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-07-22T09:10:31.413Z
Learning: Applies to **/*.{js,ts,tsx} : Node 16 module resolution - include file extensions in imports (`.js`)
Applied to files:
packages/ui-components/tsconfig.node.json
📚 Learning: 2025-06-03T09:11:29.651Z
Learnt from: kingston
PR: halfdomelabs/baseplate#562
File: plugins/plugin-auth/package.json:32-36
Timestamp: 2025-06-03T09:11:29.651Z
Learning: With TypeScript project references, TypeScript compilation is watched from the root level using "watch:tsc:root" script, so individual packages no longer need to include their "tsc:watch" scripts in their local "watch" commands. The local "tsc:watch" scripts are renamed from "watch:tsc" but are not meant to be run as part of the package's watch command since TypeScript watching is handled centrally at the workspace root.
Applied to files:
package.json
📚 Learning: 2025-05-08T12:56:59.222Z
Learnt from: kingston
PR: halfdomelabs/baseplate#539
File: scripts/check-changesets.ts:10-13
Timestamp: 2025-05-08T12:56:59.222Z
Learning: Node.js 22.0.0 and later versions include both `glob` and `globSync` functionality in the core `node:fs` module, making `import { promises as fs, globSync } from 'node:fs';` valid syntax.
Applied to files:
packages/core-generators/src/constants/node.ts
📚 Learning: 2025-05-08T12:56:59.222Z
Learnt from: kingston
PR: halfdomelabs/baseplate#539
File: scripts/check-changesets.ts:10-13
Timestamp: 2025-05-08T12:56:59.222Z
Learning: Node.js 20.12.0 and above include `globSync` in the core `node:fs` module, so `import { promises as fs, globSync } from 'node:fs';` is valid syntax in projects using these Node.js versions.
Applied to files:
packages/core-generators/src/constants/node.ts
🧬 Code Graph Analysis (2)
packages/project-builder-lib/src/definition/project-definition-container.ts (3)
packages/project-builder-lib/src/plugins/schema/store.ts (1)
PluginImplementationStore(3-29)packages/project-builder-lib/src/references/types.ts (1)
ResolvedZodRefPayload(163-176)packages/project-builder-lib/src/parser/types.ts (1)
SchemaParserContext(6-8)
packages/project-builder-web/src/utils/error.ts (1)
packages/project-builder-lib/src/references/fix-ref-deletions.ts (1)
FixRefDeletionError(24-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Lint
- GitHub Check: Test E2E
- GitHub Check: test
🔇 Additional comments (29)
packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx (2)
209-209: LGTM: adding initialOptions to the effect deps is the right call.This keeps the async loader in sync with externally provided seeds and fixes stale results when parents replace initialOptions.
161-170: AsyncComboboxField: ensure a stable initialOptions to prevent needless effect churnThe early-return in the effect correctly resets state when
debouncedSearchQuery.length < minSearchLengthHowever, if consumers pass an inline array (or otherwise recreate
initialOptionson every render), theuseEffectdependency will see it change each time—causing unnecessary state resets and renders.• Verify in each usage of AsyncComboboxField that the
initialOptionsprop is a stable reference (e.g. memoized withuseMemo, lifted out of render, or stored in state).
• If you spot any inline literals like<AsyncComboboxField initialOptions={[…]} …/>, wrap them inuseMemo(() => […], […])or move them outside the component.
• Consider updating the docs to call out this requirement for passing stable option arrays..node-version (1)
1-1: All Node.js versions are unified at 22.18.0
- .node-version → 22.18.0
- .nvmrc → 22.18.0
- No
volta.nodeorengines.nodeentries in package.json- No hard-coded 22.19.0 (or other) references in templates/generators
No stragglers detected—everything is consistently set to 22.18.0.
packages/code-morph/package.json (2)
52-53: Validate ts-morph 26.0.0 upgrade before mergingI ran a full scan of ts-morph API surfaces and found widespread usage of:
- Project constructors (with and without
manipulationSettings) in core-generators renderers, extractors, and code-morph runner- Direct imports of
ManipulationSettings,SyntaxKind,ts,Node,SourceFile, etc.- Low-level calls like
getDescendants*,replaceWithText,insertStatementsacross multiple morphers and pluginsBefore accepting this major bump, please:
- Run a workspace-wide type check and full test suite to catch any renamed/deprecated helpers:
pnpm -w run typecheck pnpm -w run test- Manually verify that any custom manipulation settings (e.g.
TS_MORPH_MANIPULATION_SETTINGS) still apply as expected- Spot-check a few key flows—especially shebang/client-directive preservation and import reordering—to ensure no behavioral regressions
45-46: Review @inquirer/prompts bump: verify call-site APIsPlease confirm that upgrading to @inquirer/prompts 7.8.3 introduces no breaking changes to your usage of prompt functions. In particular, sanity-check option signatures, custom keymaps/validators, and any UI tweaks against these imports:
• packages/code-morph/src/scripts/run-morpher.ts
Imports: checkbox, input, search• packages/project-builder-cli/src/commands/snapshot.ts
Imports: confirmIf these prompt calls still accept the same parameters and behave as expected under 7.8.3, this bump is safe. Otherwise, adjust your call sites or pin a compatible minor version.
packages/project-builder-cli/package.json (1)
64-65: Verify interactive prompt flows remain intact after bump to @inquirer/prompts 7.8.3I’ve confirmed that all imports use the public API (no deep/internal paths), so the upgrade shouldn’t break import resolution:
• packages/project-builder-cli/src/commands/snapshot.ts imports
import { confirm } from '@inquirer/prompts';
• packages/code-morph/src/scripts/run-morpher.ts imports
import { checkbox, input, search } from '@inquirer/prompts';No occurrences of paths like
@inquirer/prompts/lib/...or similar were found.Please manually exercise each CLI flow that uses these prompts to ensure the UX is unchanged:
• Snapshot command (uses confirm)
• Morpher script (uses checkbox, input, search)Test both in a TTY (interactive shell) and in a non-TTY context (e.g. piped input or CI) to verify rendering and behavior (multiselect, confirmations, input with validation) remain identical.
Commands to run:
pnpm --filter @baseplate-dev/project-builder-cli start -- snapshot pnpm --filter @baseplate-dev/code-morph start -- [appropriate args]packages/tools/package.json (1)
60-62: Unify version sourcing for @tsconfig/ via catalog to reduce drift*We’ve confirmed that both presets are actively referenced in your tooling configs:
packages/tools/tsconfig.node.base.jsonextends@tsconfig/node22/tsconfig.jsonpackages/tools/tsconfig.vite.base.jsonextends@tsconfig/vite-react/tsconfig.jsonBecause our sandbox lacked a functioning
tscinstall, the automated compile check didn’t run. Please manually verify that switching tocatalog:doesn’t introduce any unexpected changes—especially around JSX or module settings when bumping from 3.x → 7.x.Steps to apply and verify:
Ensure both packages appear under a
catalog:entry in yourpnpm-workspace.yaml.Update
packages/tools/package.jsonversions:- "@tsconfig/node22": "22.0.2", - "@tsconfig/vite-react": "7.0.0", + "@tsconfig/node22": "catalog:", + "@tsconfig/vite-react": "catalog:",Run locally:
pnpm recursive exec -- tsc --noEmit -p packages/**/tsconfig*.json
to confirm no compilation errors or altered compiler behaviors.packages/ui-components/tsconfig.node.json (1)
9-9: Consider using compilerOptions.types for vite-env.d.tsThe
includearray inpackages/ui-components/tsconfig.node.jsoncurrently points atsrc/vite-env.d.ts, but pinning this file incompilerOptions.typesis less brittle and avoids path churn. Before making this change, please verify that your base preset doesn’t already declare atypesarray, since settingcompilerOptions.typeshere will override (not merge) any existing entries.Points to review:
- packages/ui-components/tsconfig.node.json
– currently includes".storybook/**/*", "vite.config.ts", "src/vite-env.d.ts"
– nocompilerOptions.typesdefined locally- packages/ui-components/tsconfig.json
– also has nocompilerOptions.typesdefined- The base config
@baseplate-dev/tools/tsconfig.vite.lib.json
– confirm it does not definecompilerOptions.types, or you’ll unintentionally drop those typesSuggested optional refactor (in
tsconfig.node.json):{ "extends": "@baseplate-dev/tools/tsconfig.vite.lib.json", "compilerOptions": { "noEmit": true, "sourceMap": false, "declaration": false, "declarationMap": false, + "types": ["vite/client", "vite-plugin-svgr/client"] }, - "include": [".storybook/**/*", "vite.config.ts", "src/vite-env.d.ts"] + "include": [".storybook/**/*", "vite.config.ts"] }If you decide to keep pointing at the file directly, confirm there are no duplicate environment declarations by checking that you aren’t loading
vite-env.d.tsboth viaincludeand via atypesarray.plugins/plugin-queue/src/vite-env.d.ts (1)
1-2: Ambient Vite/SVGR refs validated
- Verified that each plugin’s
tsconfig.jsonincludes"src/**/*", sovite-env.d.tsinsrc/is already picked up by TypeScript.- No further inclusion changes are required.
optional nit: if you find yourself copying this file across multiple plugins, you could centralize the SVGR/Vite types via a shared
compilerOptions.typesentry in a base tsconfig to reduce duplication.packages/ui-components/src/vite-env.d.ts (1)
1-2: Ambient Vite/SVGR types for UI package — LGTM.This is the right place and filename; keeps SVG ReactComponent typing and ImportMetaEnv available during builds.
package.json (5)
51-51: LGTM: Lint-staged configuration updated appropriatelyThe removal of
tomlfrom the glob pattern makes sense as the AI summary indicates TOML support was dropped. The remaining file types are comprehensive for code formatting.
54-54: LGTM: Changesets CLI version bumpUpdating
@changesets/clifrom 2.28.1 to 2.29.6 is a good maintenance update.
72-72: LGTM: PNPM version updateThe packageManager update to
pnpm@10.15.0aligns with the broader toolchain upgrade described in the PR.
75-75: LGTM: Engine requirement updated consistentlyThe PNPM engine requirement
^10.15.0matches the packageManager version, maintaining consistency.
78-78: LGTM: Volta Node version updatedThe Node version update to 22.18.0 aligns with the repository-wide Node.js upgrade mentioned in the AI summary.
packages/project-builder-lib/src/plugin-tools/plugin-loader.ts (1)
43-49: LGTM: Constructor parameter property refactored to explicit fieldThe refactoring from constructor parameter property to explicit class field follows the repository-wide pattern described in the AI summary. The functionality remains identical - the
innerErroris still properly assigned and accessible.packages/project-builder-lib/src/references/markers.ts (1)
14-23: LGTM: Constructor parameter properties converted to explicit fieldsThis change follows the consistent pattern across the codebase of replacing TypeScript constructor parameter properties with explicit class field declarations. The functionality is preserved - both
valueandreferenceare still properly assigned and accessible.packages/utils/src/crypto/hash.ts (1)
15-17: LGTM: Function signature expanded to accept BufferThe addition of
Bufferto the accepted input types enhances the utility of this function for Node.js environments where Buffer objects are common.packages/project-builder-lib/src/references/types.ts (2)
10-13: LGTM: Explicit field declarations addedThe explicit declarations of
nameandparentTypeas public readonly fields maintain the same access patterns as the previous constructor parameter properties.
22-30: LGTM: Constructor refactored consistentlyThe constructor parameter properties have been replaced with explicit assignments, following the repository-wide refactoring pattern. The functionality remains identical with proper assignment of
nameandparentType.pnpm-workspace.yaml (2)
26-34: Expanded ignoredBuiltDependencies: sanity-check impact on CI cachesAdding esbuild/protobufjs/ssh2/etc. to
ignoredBuiltDependenciescan speed up installs, but some packages expect postinstall binaries. If any subpackage invokes those CLIs during build/test, we may need explicit devDeps or prebuilt artifacts.Consider a CI dry run (install + build) to ensure no toolchain relies on these binaries at postinstall. If needed, we can document the rationale in the workspace README.
7-23: Node/TypeScript toolchain consistency confirmed– Root tooling files all target Node 22.18.0
• .nvmrc: 22.18.0
• .node-version: 22.18.0
• mise.toml [tools.node]: 22.18.0
• No .volta directory/config detected
– No packages or plugins pin custom TypeScript or @types/node versions outside the workspace catalog (TS 5.8.3, @types/node ^22.17.x)
– All TypeScript-using packages reference the workspace versions with no local overrides foundEverything aligns with the PR intent—no further changes needed.
packages/project-builder-lib/src/utils/definition-diff/definition-diff.ts (2)
16-25: Good move to explicit field; preserve readonly and constructor clarityReplacing the parameter property with
public readonly name: stringand assigning in the constructor is correct and TS 5.8–friendly. LGTM.
254-291: create/apply diff helpers remain type-safe and efficientNo regressions spotted; the helpers still lean on type-fest paths and es-toolkit. LGTM.
packages/create-project/src/project-creator.unit.test.ts (2)
108-116: Tests correctly capture expected template values; they will fail until generator alignsThe expectations for
packageManager,engines.pnpm, andvolta.nodematch the toolchain targets. Given the generator currently setsvolta.nodeto22.19.0, these tests provide the correct guard. No change needed in tests; update the generator as suggested.
225-245: Nice error-path test using memfs + read-only directoryGood use of memfs and spinner state to assert failure behavior. LGTM.
packages/project-builder-lib/src/plugins/schema/store.ts (1)
1-1: ESM import extension compliance looks goodLocal/aliased imports use “.js” extensions per Node 16/ESM resolution. No action needed.
packages/project-builder-lib/src/definition/project-definition-container.ts (2)
90-97: Immer usage: curried form is correct; LGTM
produce(setter)(this.definition)correctly uses the curried API. Passing{ plugins: this.pluginStore }intofixRefDeletionsis consistent with later usage in serialization.
104-114: Serialization path looks consistent
toSerializedContents()setsdefaultMode: 'strip'and threadsplugins: this.pluginStore. No issues spotted.
| '@baseplate-dev/project-builder-lib': patch | ||
| '@baseplate-dev/project-builder-web': patch | ||
| '@baseplate-dev/core-generators': patch | ||
| '@baseplate-dev/fastify-generators': patch | ||
| '@baseplate-dev/react-generators': patch | ||
| '@baseplate-dev/sync': patch | ||
| '@baseplate-dev/utils': patch | ||
| '@baseplate-dev/tools': patch | ||
| '@baseplate-dev/code-morph': patch | ||
| '@baseplate-dev/project-builder-server': patch | ||
| '@baseplate-dev/project-builder-cli': patch | ||
| '@baseplate-dev/project-builder-test': patch | ||
| '@baseplate-dev/ui-components': patch | ||
| '@baseplate-dev/create-project': patch | ||
| '@baseplate-dev/plugin-auth': patch | ||
| '@baseplate-dev/plugin-storage': patch | ||
| '@baseplate-dev/plugin-queue': patch |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Reassess semver: raising the Node runtime requirement is a breaking change for any published packages.
If any of these packages are published (not "private": true), bumping the minimum Node version to 22.18 should be released as a major. Otherwise consumers on older Node versions will receive a “patch” that breaks them.
Run to list non-private packages and their engines:
If any listed package is public, consider switching its entry below from patch to major:
- '@baseplate-dev/utils': patch
+ '@baseplate-dev/utils': major🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Non-private packages and their engines.node fields:"
jq -r '
.packages[]? // "packages/*" ' pnpm-workspace.yaml >/dev/null 2>&1 || true
fd -a package.json packages plugins | while read -r pkg; do
is_private=$(jq -r '.private // false' "$pkg")
name=$(jq -r '.name' "$pkg" 2>/dev/null || echo "$pkg")
engines=$(jq -r '.engines.node // "(none)"' "$pkg")
if [ "$is_private" != "true" ]; then
echo "- $name @ $pkg | engines.node: $engines"
fi
doneLength of output: 9056
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Re-running verification of non-private packages and their engines.node fields:"
find packages plugins -type f -name package.json | while read -r pkg; do
is_private=$(jq -r '.private // false' "$pkg")
name=$(jq -r '.name // "(unknown)"' "$pkg")
engines=$(jq -r '.engines.node // "(none)"' "$pkg")
if [[ "$is_private" != "true" ]]; then
echo "- $name @ $pkg | engines.node: $engines"
fi
doneLength of output: 9306
Update changelog entries to major for all public packages
Raising the minimum Node.js runtime to 22.18 is a breaking change. Any non-private (public) packages in this workspace must be released with a major bump rather than a patch to avoid publishing a “patch” that no longer supports older Node versions.
Please update .changeset/typescript-5-8-upgrade.md so that every non-private package uses major instead of patch. For example:
--- .changeset/typescript-5-8-upgrade.md
@@
- '@baseplate-dev/core-generators': patch
+ '@baseplate-dev/core-generators': major
- '@baseplate-dev/create-project': patch
+ '@baseplate-dev/create-project': major
- '@baseplate-dev/fastify-generators': patch
+ '@baseplate-dev/fastify-generators': major
- '@baseplate-dev/project-builder-cli': patch
+ '@baseplate-dev/project-builder-cli': major
- '@baseplate-dev/project-builder-common': patch
+ '@baseplate-dev/project-builder-common': major
- '@baseplate-dev/project-builder-lib': patch
+ '@baseplate-dev/project-builder-lib': major
- '@baseplate-dev/project-builder-server': patch
+ '@baseplate-dev/project-builder-server': major
- '@baseplate-dev/project-builder-web': patch
+ '@baseplate-dev/project-builder-web': major
- '@baseplate-dev/react-generators': patch
+ '@baseplate-dev/react-generators': major
- '@baseplate-dev/sync': patch
+ '@baseplate-dev/sync': major
- '@baseplate-dev/tools': patch
+ '@baseplate-dev/tools': major
- '@baseplate-dev/ui-components': patch
+ '@baseplate-dev/ui-components': major
- '@baseplate-dev/utils': patch
+ '@baseplate-dev/utils': major
- '@baseplate-dev/plugin-auth': patch
+ '@baseplate-dev/plugin-auth': major
- '@baseplate-dev/plugin-storage': patch
+ '@baseplate-dev/plugin-storage': major
- '@baseplate-dev/plugin-queue': patch
+ '@baseplate-dev/plugin-queue': majorFiles to update:
- .changeset/typescript-5-8-upgrade.md — convert
patch→majorfor each non-private package listed above.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In .changeset/typescript-5-8-upgrade.md around lines 2 to 18, the changelog
lists several packages with the release type set to "patch" but some of those
are public (non-private) packages and must be bumped to "major" because raising
the minimum Node runtime is a breaking change; update each listed non-private
package entry from "patch" to "major" (leave any private packages unchanged),
save the file, and verify the changeset now uses "major" for all public packages
listed.
| min_version = "2025.8.14" | ||
|
|
||
| [tools] | ||
| node = "22.18.0" |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Add pnpm to mise and align Node version across all templates/tooling.
- Given PNPM is standardized at 10.15.0 in this PR, add it to mise for reproducible local environments.
- Also verify no template (e.g., create-project) specifies a different Node (AI summary mentions Volta 22.19.0) to avoid user confusion.
Minimal addition:
[tools]
node = "22.18.0"
+pnpm = "10.15.0"Quick consistency sweep:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Root Node versions:"
echo -n ".node-version: "; cat .node-version
echo -n ".nvmrc: "; cat .nvmrc
rg -n "node = \"\K[0-9]+\.[0-9]+\.[0-9]+(?=\")" mise.toml -o || true
echo "Check Volta/tooling versions in templates and codegen:"
rg -nP '"volta"\s*:\s*\{[\s\S]*?"node"\s*:\s*"(?<ver>[^"]+)"' -oN packages | sed 's/^/ • /'
rg -nP 'pnpm@(?<ver>\d+\.\d+\.\d+)' packages/create-project || trueLength of output: 580
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for 22.19.0 in repo ==="
rg -n "22\.19\.0" -n . || true
echo "=== Search for 'volta' in repo ==="
rg -n "volta" -n . || true
echo "=== Inspect create-project package.json ==="
if [ -f packages/create-project/package.json ]; then
sed -n '1,50p' packages/create-project/package.json
else
echo "packages/create-project/package.json not found"
fi
echo "=== Find .toml files in packages/ ==="
find packages -type f -name '*.toml'
echo "=== Tools sections in toml files under packages/ ==="
rg -n "\[tools\]" -n packagesLength of output: 3796
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Extract volta config from create-project package.json ==="
grep -n '"volta"' -n packages/create-project/package.json -A10
echo "=== Show create-project src/project-creator.ts snippet ==="
sed -n '50,120p' packages/create-project/src/project-creator.ts
echo "=== Show core-generators volta config snippet ==="
sed -n '180,240p' packages/core-generators/src/generators/node/node/node.generator.tsLength of output: 3791
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Extract volta config from root package.json ==="
grep -n '"volta"' -n package.json -A10 || echo "No volta config in root package.json"Length of output: 226
Align Volta/Node versions and add pnpm to mise.toml
To ensure a consistent local environment and avoid confusion, please make the following updates:
• mise.toml
[tools]
node = "22.18.0"
+pnpm = "10.15.0"(Adds pnpm for reproducible installs.)
• packages/create-project/src/project-creator.ts (around line 70)
- volta: {
- node: '22.19.0',
- },
+ volta: {
+ node: '22.18.0',
+ },(Aligns the hard-coded Volta Node version with the root and mise.toml.)
No other templates hard-code a conflicting Node version—core-generators uses the shared descriptor.nodeVersion—so these two changes will restore full consistency across all tooling.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| min_version = "2025.8.14" | |
| [tools] | |
| node = "22.18.0" | |
| min_version = "2025.8.14" | |
| [tools] | |
| node = "22.18.0" | |
| pnpm = "10.15.0" |
🤖 Prompt for AI Agents
In mise.toml around lines 1–4 add pnpm to the [tools] section (e.g. pnpm =
"8.8.0") so the file contains node = "22.18.0" and pnpm = "8.8.0" for
reproducible installs, and in packages/create-project/src/project-creator.ts
around line 70 update the hard-coded Volta/Node version to "22.18.0" (matching
mise.toml/root) so all tooling uses the same Node version.
| export const CORE_PACKAGES = { | ||
| // Typescript | ||
| typescript: '5.7.3', | ||
| typescript: '5.8.3', |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
TS 5.8.3 bump looks good; verify workspace/catalog alignment and lint stack compatibility.
- Ensure pnpm-workspace.yaml’s catalog.typescript is also set to 5.8.3 and no package.json pins a divergent TS version (prefer "catalog:" everywhere to keep single-source-of-truth).
- typescript-eslint 8.38.0 + ESLint 9.32.0 should be compatible with TS 5.8.x; still, run a full lint + typecheck on a freshly generated project to catch config drift.
Run this quick audit from repo root:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "1) Check workspace catalog for TS 5.8.3"
rg -nP "catalog:\s*[\r\n]+(?:\s{2,}[\w-]+:.*[\r\n]+)*\s{2,}typescript:\s*['\"]?5\.8\.3['\"]?" pnpm-workspace.yaml || {
echo "Missing or mismatched catalog.typescript=5.8.3 in pnpm-workspace.yaml"; exit 1; }
echo "2) Ensure no packages pin a non-catalog TS"
rg -nP --glob '**/package.json' '"typescript":\s*"(?!catalog:)[^"]+"' || echo "OK: all packages use catalog for TS"
echo "3) Sanity lint/typecheck pass (no emit)"
pnpm -w -r exec bash -lc 'if [ -f package.json ] && jq -re ".scripts.typecheck" >/dev/null 2>&1; then pnpm run typecheck; fi'
pnpm -w -r exec bash -lc 'if [ -f package.json ] && jq -re ".scripts.lint" >/dev/null 2>&1; then pnpm run lint; fi'Length of output: 386
Align pnpm-workspace.yaml’s catalog.typescript with the TS 5.8.3 bump
The audit script reports that pnpm-workspace.yaml is still missing or has a mismatched catalog.typescript entry. Before merging:
-
Open
pnpm-workspace.yamlat the repository root. -
Under the top-level
catalog:section, add or update:catalog: typescript: '5.8.3' # …other catalog entries…
-
Commit that change so that every package can consume the bumped TS via
catalog:typescript.
After updating, re-run your verification script to confirm:
# from repo root
./scripts/verify-ts-bump.sh # or the audit snippet provided earlier
pnpm -w -r exec pnpm run typecheck
pnpm -w -r exec pnpm run lintThis will ensure a single source of truth for TS and that lint/typecheck pass across all workspaces.
🤖 Prompt for AI Agents
In packages/core-generators/src/constants/core-packages.ts around line 3, the
repo was bumped to TypeScript 5.8.3 but pnpm-workspace.yaml at the repository
root still lacks or has a mismatched catalog.typescript entry; open
pnpm-workspace.yaml and under the top-level catalog: section add or update the
typescript entry to '5.8.3', save and commit that change, then re-run
./scripts/verify-ts-bump.sh and the workspace typecheck/lint commands (pnpm -w
-r exec pnpm run typecheck and pnpm -w -r exec pnpm run lint) to confirm the
update.
| /// <reference types="vite/client" /> | ||
| /// <reference types="vite-plugin-svgr/client" /> |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Confirm local devDeps to avoid TS resolution errors.
Adding vite/client and vite-plugin-svgr/client ambient types is fine, but TypeScript will expect both packages to be resolvable from this workspace. Please verify the package (or workspace root) declares vite and vite-plugin-svgr in devDependencies, and that this file only applies to web code paths.
Run:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking devDeps for vite and vite-plugin-svgr in plugin-auth and at repo root"
for pkg in package.json plugins/plugin-auth/package.json; do
test -f "$pkg" || continue
echo "==> $pkg"
jq -r '
{
vite: (.devDependencies.vite // .dependencies.vite // "MISSING"),
vite_plugin_svgr: (.devDependencies["vite-plugin-svgr"] // .dependencies["vite-plugin-svgr"] // "MISSING")
}' "$pkg"
done
echo
echo "Sanity: ensure TS picks up vite-env.d.ts via tsconfig includes (usually automatic under src/)"
fd -a "tsconfig*.json" plugins/plugin-auth | xargs -I{} sh -c 'echo "==> {}"; rg -n "vite-env\.d\.ts" -n {} || echo "(not explicitly listed — OK if src/**/*.d.ts is included by default)"'Length of output: 1596
Add missing vite-plugin-svgr DevDependency to prevent TS resolution errors
TypeScript will fail to resolve /// <reference types="vite-plugin-svgr/client" /> because plugins/plugin-auth/package.json does not declare vite-plugin-svgr (and the workspace root is also missing it). Please add the missing package and verify your workspace configuration:
• plugins/plugin-auth/package.json
– Under devDependencies, add
"vite-plugin-svgr": "<appropriate-version>"• Alternatively, declare vite-plugin-svgr at the workspace root if you intend to hoist it.
• No changes are needed to tsconfig.json—ambient .d.ts files under src/ are picked up by default.
🤖 Prompt for AI Agents
In plugins/plugin-auth/src/vite-env.d.ts around lines 1 to 2, TypeScript cannot
resolve the reference to vite-plugin-svgr because the package is not declared in
the plugin package.json (nor at the workspace root); add "vite-plugin-svgr":
"<appropriate-version>" to plugins/plugin-auth/package.json devDependencies (or
add it to the workspace root package.json if you intend to hoist it), run
install to update lockfile, and verify the package is accessible to the plugin
so the triple-slash reference resolves without changing tsconfig.json.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/core-generators/package.json (1)
14-18: Repository.directory points to the wrong path for this package.The package lives under packages/core-generators, but repository.directory is set to packages/code-generators. This breaks the “view source” link on npm and tooling that relies on this metadata.
Apply this fix:
"repository": { "type": "git", "url": "https://github.com/halfdomelabs/baseplate", - "directory": "packages/code-generators" + "directory": "packages/core-generators" },
🧹 Nitpick comments (2)
packages/core-generators/package.json (2)
63-78: Consider moving ts-morph to the workspace catalog for consistency.Many deps here already use "catalog:" to centralize versions. Adding ts-morph to your pnpm catalog will prevent drift across packages and make future bumps (27.x) a one‑liner.
Example change (package-local side) once catalog is defined:
- "ts-morph": "26.0.0", + "ts-morph": "catalog:",Follow-up: add a catalog entry for ts-morph 26.0.0 in pnpm-workspace.yaml.
91-92: Optional: align engines.node with the repo’s pinned Node 22.18.0."^22.0.0" is acceptable, but if the rest of the workspace moved to 22.18.0 (mise/volta/tooling), tightening the minimum here can prevent accidental usage of older 22.x on CI or dev machines.
Proposed tweak:
- "engines": { - "node": "^22.0.0" - }, + "engines": { + "node": ">=22.18.0 <23" + },
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
packages/core-generators/package.json(1 hunks)packages/create-project/src/project-creator.ts(1 hunks)plugins/plugin-auth/src/vite-env.d.ts(1 hunks)plugins/plugin-queue/src/vite-env.d.ts(1 hunks)plugins/plugin-storage/src/vite-env.d.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- plugins/plugin-auth/src/vite-env.d.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- plugins/plugin-queue/src/vite-env.d.ts
- plugins/plugin-storage/src/vite-env.d.ts
- packages/create-project/src/project-creator.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Use kebab-case for file names
Files:
packages/core-generators/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test E2E
🔇 Additional comments (2)
packages/core-generators/package.json (2)
63-78: Heads-up: verify there are no transitive security/regression concerns with ts-morph 26.0.0.As of June–August 2025, public trackers list 26.0.0 as the latest and with no advisories. Still, run your org’s SCA to be sure. (security.snyk.io, socket.dev)
76-76: ts-morph 26.0.0 is consistently pinned and no direct TypeScript imports detectedAll workspace packages that declare
ts-morphare now locked to version26.0.0, and there are no stray imports of the underlyingtypescriptAPI:• packages/code-morph/package.json: ts-morph 26.0.0
• packages/core-generators/package.json: ts-morph 26.0.0No other
package.jsonfiles (excludingnode_modules) reference a differentts-morphversion, and no source file directly imports from"typescript"instead of usingimport { ts } from "ts-morph".Proceed with merging, and—as originally noted—make sure you’ve reviewed the ts-morph 25→26 breaking changes in the release notes before finalizing.
Summary by CodeRabbit
New Features
Chores
Refactor
Tests