Skip to content

feat: Upgrade to Typescript 5.8#643

Merged
kingston merged 7 commits into
mainfrom
kingston/eng-855-upgrade-to-typescript-58-and-enable-erasable-syntax-only
Aug 21, 2025
Merged

feat: Upgrade to Typescript 5.8#643
kingston merged 7 commits into
mainfrom
kingston/eng-855-upgrade-to-typescript-58-and-enable-erasable-syntax-only

Conversation

@kingston

@kingston kingston commented Aug 21, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Async combobox now refreshes options when initial values change.
    • Hash utility accepts Buffer input in addition to string and ArrayBuffer.
  • Chores

    • Upgraded TypeScript to 5.8 (erasable syntax mode), Node to 22.18, and PNPM to 10.15.
    • Updated toolchain/catalog entries, added Vite/SVGR type references, and added project config metadata.
  • Refactor

    • Class/constructor declaration style adjusted for compatibility with updated TypeScript.
  • Tests

    • Increased wait timing in a file-watch test for stability.

@vercel

vercel Bot commented Aug 21, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
baseplate-project-builder-web Ready Ready Preview Comment Aug 21, 2025 3:17am

@changeset-bot

changeset-bot Bot commented Aug 21, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a4eb456

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
@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
@baseplate-dev/project-builder-common Patch

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

@coderabbitai

coderabbitai Bot commented Aug 21, 2025

Copy link
Copy Markdown

Walkthrough

Repository-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

Cohort / File(s) Summary
Toolchain version alignment
/.node-version, /.nvmrc, /mise.toml, /package.json, /pnpm-workspace.yaml, /packages/core-generators/src/constants/node.ts, /packages/core-generators/src/constants/core-packages.ts
Bump Node to 22.18.0, PNPM to 10.15.x, TypeScript to 5.8.3; add mise.toml; update workspace catalog (deps and ignoredBuiltDependencies); update generator constants.
Changeset for TS 5.8
/.changeset/typescript-5-8-upgrade.md
Adds changeset documenting TS 5.8 upgrade, erasableSyntaxOnly enablement, and runtime/tooling requirements.
Package manifest updates
/packages/code-morph/package.json, /packages/project-builder-cli/package.json, /packages/tools/package.json, /package.json, /packages/core-generators/package.json
Bump dependencies (@inquirer/prompts, ts-morph, @tsconfig/*); update changesets CLI; update pnpm engine and packageManager; remove toml from lint-staged prettier glob.
Generator template and tests
/packages/create-project/src/project-creator.ts, /packages/create-project/src/project-creator.unit.test.ts
Update generated package.json pins (packageManager pnpm@10.15.0, engines.pnpm ^10.15.0, volta.node 22.18.0); adjust unit test expectations accordingly.
Parameter property refactors (erasableSyntaxOnly)
/packages/project-builder-lib/src/definition/project-definition-container.ts, /packages/project-builder-lib/src/plugin-tools/plugin-loader.ts, /packages/project-builder-lib/src/plugins/schema/store.ts, /packages/project-builder-lib/src/references/markers.ts, /packages/project-builder-lib/src/references/types.ts, /packages/project-builder-lib/src/utils/definition-diff/definition-diff.ts, /packages/project-builder-web/src/utils/error.ts
Replace constructor parameter properties with explicit class fields and assignments; adjust constructor signatures without changing runtime behavior.
UI: async combobox effect
/packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
Include initialOptions in useEffect deps; effect resets to initialOptions when query is too short; otherwise loads options; aborts in-flight loads on rerun.
Vite ambient typings
/packages/ui-components/src/vite-env.d.ts, /packages/ui-components/tsconfig.node.json, /plugins/plugin-auth/src/vite-env.d.ts, /plugins/plugin-queue/src/vite-env.d.ts, /plugins/plugin-storage/src/vite-env.d.ts
Add vite and vite-plugin-svgr triple-slash refs; include vite-env in UI tsconfig.
Hash util input widening
/packages/utils/src/crypto/hash.ts
Allow Buffer inputs; normalize returns ArrayBuffer
Test timing tweak
/packages/project-builder-server/src/sync/conflict-file-monitor.test.ts
Increase wait duration from 10ms to 20ms in test.

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
Loading

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 Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kingston/eng-855-upgrade-to-typescript-58-and-enable-erasable-syntax-only

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@socket-security

socket-security Bot commented Aug 21, 2025

Copy link
Copy Markdown

@socket-security

socket-security Bot commented Aug 21, 2025

Copy link
Copy Markdown

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.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
typescript@5.8.3 has a License Policy Violation.

License: CC-BY-4.0 (package/ThirdPartyNoticeText.txt)

License: MIT-Khronos-old (package/ThirdPartyNoticeText.txt)

From: package.jsonnpm/typescript@5.8.3

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/typescript@5.8.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Guidelines

The 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 aligned

All references to the Node 22 runtime and PNPM 10.15 versions are consistent across the repo:

  • packages/core-generators/src/constants/node.ts exports NODE_VERSION = '22.18.0' and PNPM_VERSION = '10.15.0'.
  • Root tooling configs match exactly:
    • .nvmrc contains 22.18.0
    • .node-version contains 22.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) and pnpm: '^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 issues

The buffer extraction from TextEncoder.encode() result introduces a runtime check that may be unnecessary. The TextEncoder.encode() method returns a Uint8Array, and accessing its .buffer property should always yield an ArrayBuffer. 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 names

Switching 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 for RefDeleteError are correct; offer optional title for better UX

The explicit issues field and assignment look good. Minor UX tweak: RefDeleteError currently doesn’t set a title, so consumers relying on UserVisibleError.title will see undefined. 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

formatZodError reads 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 freezing options and guarding keys

Explicit getKey/options fields look good. Two optional hardening tweaks:

  • Freeze options to prevent accidental mutation after construction.
  • Guard against getKey returning 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 coercion

The private getKey field and assignment are correct. In diff, when getKey is not provided, String(item) is used for the key. For objects/symbols, this may produce [object Object]/Symbol(...), leading to collisions. If you expect non-primitive arrays, consider requiring getKey.

-  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 phases

You call spinner.succeed() before pnpm 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

implementations appears 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 explicitly

A plugin implementation could theoretically be a falsy value. Checking === undefined communicates 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 readonly

Switching to an explicit field aligns with TS 5.8 “erasable syntax only.” Since pluginStore is effectively immutable post-construction, make it readonly to 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/safeNameFromId become hot paths, consider building a Map<id, name> once in the constructor—but not required now.

I can add a lazy idToName map 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 217de38 and fd46eed.

⛔ Files ignored due to path filters (3)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • tests/simple/package.json is excluded by !tests/**
  • tests/simple/packages/e2e/package.json is 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-components package as shown in the provided examples.
Use both standalone and React Hook Form controller variants for form components from @baseplate-dev/ui-components as 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 for src/)
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.ts
  • packages/create-project/src/project-creator.unit.test.ts
  • packages/create-project/src/project-creator.ts
  • packages/ui-components/src/vite-env.d.ts
  • plugins/plugin-storage/src/vite-env.d.ts
  • packages/project-builder-server/src/sync/conflict-file-monitor.test.ts
  • plugins/plugin-queue/src/vite-env.d.ts
  • plugins/plugin-auth/src/vite-env.d.ts
  • packages/core-generators/src/constants/node.ts
  • packages/utils/src/crypto/hash.ts
  • packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
  • packages/project-builder-lib/src/plugin-tools/plugin-loader.ts
  • packages/project-builder-lib/src/references/markers.ts
  • packages/project-builder-lib/src/plugins/schema/store.ts
  • packages/core-generators/src/constants/core-packages.ts
  • packages/project-builder-lib/src/references/types.ts
  • packages/project-builder-web/src/utils/error.ts
  • packages/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.ts
  • packages/create-project/src/project-creator.unit.test.ts
  • packages/create-project/src/project-creator.ts
  • packages/ui-components/src/vite-env.d.ts
  • plugins/plugin-storage/src/vite-env.d.ts
  • packages/project-builder-server/src/sync/conflict-file-monitor.test.ts
  • plugins/plugin-queue/src/vite-env.d.ts
  • plugins/plugin-auth/src/vite-env.d.ts
  • packages/core-generators/src/constants/node.ts
  • packages/utils/src/crypto/hash.ts
  • packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
  • packages/project-builder-lib/src/plugin-tools/plugin-loader.ts
  • packages/project-builder-lib/src/references/markers.ts
  • packages/project-builder-lib/src/plugins/schema/store.ts
  • packages/core-generators/src/constants/core-packages.ts
  • packages/project-builder-lib/src/references/types.ts
  • packages/project-builder-web/src/utils/error.ts
  • packages/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.ts
  • packages/create-project/src/project-creator.unit.test.ts
  • packages/create-project/src/project-creator.ts
  • packages/ui-components/src/vite-env.d.ts
  • plugins/plugin-storage/src/vite-env.d.ts
  • packages/project-builder-server/src/sync/conflict-file-monitor.test.ts
  • plugins/plugin-queue/src/vite-env.d.ts
  • plugins/plugin-auth/src/vite-env.d.ts
  • packages/core-generators/src/constants/node.ts
  • packages/utils/src/crypto/hash.ts
  • packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
  • packages/project-builder-lib/src/plugin-tools/plugin-loader.ts
  • packages/project-builder-lib/src/references/markers.ts
  • packages/project-builder-lib/src/plugins/schema/store.ts
  • packages/core-generators/src/constants/core-packages.ts
  • packages/project-builder-lib/src/references/types.ts
  • packages/project-builder-web/src/utils/error.ts
  • packages/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.ts
  • packages/create-project/src/project-creator.unit.test.ts
  • packages/create-project/src/project-creator.ts
  • mise.toml
  • packages/ui-components/src/vite-env.d.ts
  • packages/ui-components/tsconfig.node.json
  • packages/project-builder-cli/package.json
  • plugins/plugin-storage/src/vite-env.d.ts
  • packages/tools/package.json
  • packages/project-builder-server/src/sync/conflict-file-monitor.test.ts
  • package.json
  • packages/code-morph/package.json
  • plugins/plugin-queue/src/vite-env.d.ts
  • plugins/plugin-auth/src/vite-env.d.ts
  • packages/core-generators/src/constants/node.ts
  • packages/utils/src/crypto/hash.ts
  • packages/ui-components/src/components/ui/async-combobox-field/async-combobox-field.tsx
  • packages/project-builder-lib/src/plugin-tools/plugin-loader.ts
  • packages/project-builder-lib/src/references/markers.ts
  • packages/project-builder-lib/src/plugins/schema/store.ts
  • packages/core-generators/src/constants/core-packages.ts
  • packages/project-builder-lib/src/references/types.ts
  • packages/project-builder-web/src/utils/error.ts
  • packages/project-builder-lib/src/utils/definition-diff/definition-diff.ts
  • pnpm-workspace.yaml
**/*.{unit,int}.test.ts

📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)

Unit tests use .unit.test.ts suffix, 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.ts
  • packages/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.ts
  • packages/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.ts
  • packages/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.ts suffix

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 the control prop from useForm().
Use layout components such as SidebarLayout, Card, and Breadcrumb from @baseplate-dev/ui-components to structure pages as shown in the example.
Use interactive dialog components like Dialog, ConfirmDialog, and useConfirmDialog from @baseplate-dev/ui-components for 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-components and 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 from react-icons/md (Material Design icons) and import them like import { 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 churn

The early-return in the effect correctly resets state when

debouncedSearchQuery.length < minSearchLength

However, if consumers pass an inline array (or otherwise recreate initialOptions on every render), the useEffect dependency will see it change each time—causing unnecessary state resets and renders.

• Verify in each usage of AsyncComboboxField that the initialOptions prop is a stable reference (e.g. memoized with useMemo, lifted out of render, or stored in state).
• If you spot any inline literals like <AsyncComboboxField initialOptions={[…]} …/>, wrap them in useMemo(() => […], […]) 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.node or engines.node entries 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 merging

I 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, insertStatements across multiple morphers and plugins

Before 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 APIs

Please 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: confirm

If 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.3

I’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.json extends @tsconfig/node22/tsconfig.json
  • packages/tools/tsconfig.vite.base.json extends @tsconfig/vite-react/tsconfig.json

Because our sandbox lacked a functioning tsc install, the automated compile check didn’t run. Please manually verify that switching to catalog: 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 your pnpm-workspace.yaml.

  • Update packages/tools/package.json versions:

    -    "@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.ts

The include array in packages/ui-components/tsconfig.node.json currently points at src/vite-env.d.ts, but pinning this file in compilerOptions.types is less brittle and avoids path churn. Before making this change, please verify that your base preset doesn’t already declare a types array, since setting compilerOptions.types here 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"
    – no compilerOptions.types defined locally
  • packages/ui-components/tsconfig.json
    – also has no compilerOptions.types defined
  • The base config @baseplate-dev/tools/tsconfig.vite.lib.json
    – confirm it does not define compilerOptions.types, or you’ll unintentionally drop those types

Suggested 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.ts both via include and via a types array.

plugins/plugin-queue/src/vite-env.d.ts (1)

1-2: Ambient Vite/SVGR refs validated

  • Verified that each plugin’s tsconfig.json includes "src/**/*", so vite-env.d.ts in src/ 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.types entry 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 appropriately

The removal of toml from 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 bump

Updating @changesets/cli from 2.28.1 to 2.29.6 is a good maintenance update.


72-72: LGTM: PNPM version update

The packageManager update to pnpm@10.15.0 aligns with the broader toolchain upgrade described in the PR.


75-75: LGTM: Engine requirement updated consistently

The PNPM engine requirement ^10.15.0 matches the packageManager version, maintaining consistency.


78-78: LGTM: Volta Node version updated

The 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 field

The refactoring from constructor parameter property to explicit class field follows the repository-wide pattern described in the AI summary. The functionality remains identical - the innerError is still properly assigned and accessible.

packages/project-builder-lib/src/references/markers.ts (1)

14-23: LGTM: Constructor parameter properties converted to explicit fields

This change follows the consistent pattern across the codebase of replacing TypeScript constructor parameter properties with explicit class field declarations. The functionality is preserved - both value and reference are still properly assigned and accessible.

packages/utils/src/crypto/hash.ts (1)

15-17: LGTM: Function signature expanded to accept Buffer

The addition of Buffer to 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 added

The explicit declarations of name and parentType as public readonly fields maintain the same access patterns as the previous constructor parameter properties.


22-30: LGTM: Constructor refactored consistently

The constructor parameter properties have been replaced with explicit assignments, following the repository-wide refactoring pattern. The functionality remains identical with proper assignment of name and parentType.

pnpm-workspace.yaml (2)

26-34: Expanded ignoredBuiltDependencies: sanity-check impact on CI caches

Adding esbuild/protobufjs/ssh2/etc. to ignoredBuiltDependencies can 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 found

Everything 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 clarity

Replacing the parameter property with public readonly name: string and assigning in the constructor is correct and TS 5.8–friendly. LGTM.


254-291: create/apply diff helpers remain type-safe and efficient

No 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 aligns

The expectations for packageManager, engines.pnpm, and volta.node match the toolchain targets. Given the generator currently sets volta.node to 22.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 directory

Good 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 good

Local/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 } into fixRefDeletions is consistent with later usage in serialization.


104-114: Serialization path looks consistent

toSerializedContents() sets defaultMode: 'strip' and threads plugins: this.pluginStore. No issues spotted.

Comment on lines +2 to +18
'@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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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
done

Length 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
done

Length 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': major

Files to update:

  • .changeset/typescript-5-8-upgrade.md — convert patchmajor for 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.

Comment thread mise.toml
Comment on lines +1 to +4
min_version = "2025.8.14"

[tools]
node = "22.18.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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 || true

Length 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 packages

Length 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.ts

Length 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.

Suggested change
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',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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.yaml at 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 lint

This 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.

Comment thread packages/create-project/src/project-creator.ts
Comment thread plugins/plugin-auth/src/vite-env.d.ts Outdated
Comment on lines +1 to +2
/// <reference types="vite/client" />
/// <reference types="vite-plugin-svgr/client" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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.

@kingston kingston merged commit 7d9e6d0 into main Aug 21, 2025
9 checks passed
@kingston kingston deleted the kingston/eng-855-upgrade-to-typescript-58-and-enable-erasable-syntax-only branch August 21, 2025 03:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

📥 Commits

Reviewing files that changed from the base of the PR and between fd46eed and a4eb456.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is 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 detected

All workspace packages that declare ts-morph are now locked to version 26.0.0, and there are no stray imports of the underlying typescript API:

• packages/code-morph/package.json: ts-morph 26.0.0
• packages/core-generators/package.json: ts-morph 26.0.0

No other package.json files (excluding node_modules) reference a different ts-morph version, and no source file directly imports from "typescript" instead of using import { 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant