feat: Separate dev commands to project-builder-dev#782
Conversation
🦋 Changeset detectedLatest commit: a6ad042 The changes in this PR will be included in the next version bump. This PR includes changesets to release 21 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 |
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughExtracts developer tooling into a new Changes
Sequence Diagram(s)mermaid mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/project-builder-cli/src/utils/project-resolver.ts (1)
171-175:⚠️ Potential issue | 🟡 MinorIncorrect error message references
package.jsoninstead ofproject-definition.json.Line 173 says "No package.json found" but
loadProjectInforeadsbaseplate/project-definition.json(line 138-142). The ENOENT error would occur when the project definition file is missing, notpackage.json.Fix error message
} catch (error) { if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { - throw new Error(`No package.json found in ${directory}`); + throw new Error(`No project definition found at ${path.join(directory, 'baseplate', 'project-definition.json')}`); } throw error; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-cli/src/utils/project-resolver.ts` around lines 171 - 175, The catch block in loadProjectInfo incorrectly reports "No package.json found" when handling ENOENT; update the thrown Error message in the catch of loadProjectInfo (in project-resolver.ts) to reference the actual file path used (baseplate/project-definition.json) or a clearer message like "No project-definition.json found in baseplate for <directory>" so the error matches the file being read; keep the same ENOENT check (error instanceof Error && 'code' in error && error.code === 'ENOENT') and only change the string passed to new Error(...) to mention project-definition.json/baseplate.packages/project-builder-dev/src/runner/generate.ts (1)
22-32:⚠️ Potential issue | 🔴 CriticalHardcoded
id,name, andisInternalExamplebreak the generated project.The hardcoded values passed to
createNodeSchemaParserContextare test-specific and incorrect for production use:
id: 'test-project'— All projects get the same ID instead of a unique identifier (should usegenerateProjectId(directory))name: 'Test Project'— All projects get the same name instead of reading from the actual project'sproject-definition.json(should useprojectDef.settings.general.name)isInternalExample: true— Excludes@baseplate-dev/project-builder-clifrom dev dependencies (confirmed inroot-package-compiler.ts: the CLI package is only included whenisInternalExampleisfalse)The correct pattern is already established in
project-discovery.tsandcreate-project/project-generator.ts: load these values from the actual project directory and definition. Apply the same approach here by reading the project definition and usingisExampleProject(directory)to determine the internal example flag.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/runner/generate.ts` around lines 22 - 32, The call to createNodeSchemaParserContext is using test-only hardcoded values (id, name, isInternalExample); replace them by deriving the real values from the project directory: call generateProjectId(projectDirectory) for the id, read the project's definition to use projectDef.settings.general.name for the name, and use isExampleProject(projectDirectory) for isInternalExample; pass these computed values (alongside the existing logger, plugins, and version) into createNodeSchemaParserContext so the generated project gets correct ID, name, and dev-dependency behavior.
🧹 Nitpick comments (8)
examples/blog-with-auth/docker/.env (1)
2-4: Optional: reorder Postgres keys to satisfy dotenv-linter ordering.This is only for lint cleanliness.
Suggested reordering
COMPOSE_PROJECT_NAME=blog-with-auth-dev -POSTGRES_PORT=5432 -POSTGRES_PASSWORD=blog-with-auth-password POSTGRES_DB=blog-with-auth +POSTGRES_PASSWORD=blog-with-auth-password +POSTGRES_PORT=5432🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/blog-with-auth/docker/.env` around lines 2 - 4, Reorder the Postgres environment keys in the .env to satisfy dotenv-linter ordering: change the sequence of POSTGRES_PORT, POSTGRES_PASSWORD, POSTGRES_DB to alphabetical order (POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_PORT); update the file where those three keys are defined so the linter passes.examples/todo-with-auth0/docker/.env (1)
2-6: Optional: reorder keys to clear dotenv-linterUnorderedKeywarnings.No runtime issue, but reordering avoids noisy lint output.
Suggested reordering
COMPOSE_PROJECT_NAME=todo-with-auth0-dev -POSTGRES_PORT=6432 -POSTGRES_PASSWORD=todo-with-auth0-password POSTGRES_DB=todo-with-auth0 -REDIS_PORT=6379 +POSTGRES_PASSWORD=todo-with-auth0-password +POSTGRES_PORT=6432 REDIS_PASSWORD=todo-with-auth0-password +REDIS_PORT=6379🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/todo-with-auth0/docker/.env` around lines 2 - 6, Reorder the environment variable lines in the .env file to satisfy dotenv-linter's UnorderedKey rule by sorting the keys alphabetically; specifically arrange the POSTGRES_* and REDIS_* entries so the keys are in alphabetical order (e.g., POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_PORT, REDIS_PASSWORD, REDIS_PORT) to remove the lint warnings.packages/project-builder-dev/src/commands/templates.ts (1)
146-151: RepeateddiscoverPlugins(process.cwd(), logger)calls across handlers.
discoverPluginsis invoked identically inhandleListTemplates,handleDeleteTemplate,handleExtractTemplates, andhandleGenerateTemplates. Since each handler runs independently per CLI invocation, this is functionally fine — but if plugin discovery becomes expensive, consider extracting it to a shared lazy-initialized helper within this module.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/commands/templates.ts` around lines 146 - 151, Multiple handlers (handleListTemplates, handleDeleteTemplate, handleExtractTemplates, handleGenerateTemplates) each call discoverPlugins(process.cwd(), logger) redundantly; extract this into a module-scoped lazy helper (e.g., getPlugins or cachedDiscoverPlugins) that caches the Promise/result on first call and returns it thereafter so subsequent handler calls reuse the discovered plugins; update each handler to call the new helper instead of calling discoverPlugins directly to avoid repeating expensive discovery.packages/project-builder-cli/src/utils/project-resolver.ts (1)
102-126: Different path-detection heuristic than the dev package'sresolveProject.The CLI's
resolveProjectusesincludes('/')orincludes('\\')to detect paths, whilepackages/project-builder-dev/src/utils/list-projects.tsusesstartsWith('.'),path.isAbsolute(), andstartsWith('~'). This meansmy-projectwould be a name lookup in both, butsubfolder/projectwould be treated as a path in the CLI but a name lookup in the dev package.This may be intentional since the two packages serve different audiences, but it's worth noting the inconsistency if users might expect uniform behavior.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-cli/src/utils/project-resolver.ts` around lines 102 - 126, The CLI's resolveProject uses includes('/') or includes('\\') to detect paths which differs from the dev package heuristic; update resolveProject to use the same checks as packages/project-builder-dev (use path.isAbsolute(nameOrPath) || nameOrPath.startsWith('.') || nameOrPath.startsWith('~')) before calling expandPathWithTilde/loadProjectInfo so path detection is consistent; locate resolveProject and replace the includes-based branch with those predicates (you can still call expandPathWithTilde and loadProjectInfo as before).packages/project-builder-dev/src/utils/list-projects.ts (1)
15-15: Module-levelgetEnvConfig()call runs at import time.
getEnvConfig()parsesprocess.envwith a Zod schema synchronously at module load. If the schema has any required fields or strict validation, this will throw before any function in this module is called, which could produce confusing errors. Ensure this is intentional and that the schema is permissive enough for all import contexts (e.g., tests).Consider lazy initialization if needed
-const config = getEnvConfig(); +let _config: ReturnType<typeof getEnvConfig> | undefined; +function config(): ReturnType<typeof getEnvConfig> { + if (!_config) { + _config = getEnvConfig(); + } + return _config; +}Then replace
config.Xwithconfig().Xthroughout.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/utils/list-projects.ts` at line 15, The module-level call to getEnvConfig() (assigned to config) runs at import time and can throw; change to lazy initialization by replacing the top-level const config = getEnvConfig() with a function (e.g., getConfig() that calls getEnvConfig() when invoked) and update all usages in this file to call getConfig().X (or call getConfig() where needed) so parsing happens at runtime inside functions like listProjects (or other exported functions) rather than at module import; ensure getConfig() returns the same shaped object and keep getEnvConfig() unchanged.packages/project-builder-dev/src/index.ts (1)
2-2: Consider usingnew Command()instead of the globalprogramsingleton.Importing the
programsingleton fromcommanderand mutating it insiderunDevCli()makes the function non-idempotent. CallingparseAsyncmultiple times on the sameCommandinstance is a known gotcha, because internally all parsed options are cached. While this is fine for a binary that runs once per process, the fact thatrunDevCli()is a named export in the public API (used bycli.tsand potentially tests) means a future caller could accidentally invoke it twice, leading to duplicate command registration and stale cached state.♻️ Suggested refactor
-import { program } from 'commander'; +import { Command } from 'commander'; export async function runDevCli(): Promise<void> { const version = (await getPackageVersion(import.meta.dirname)) ?? '0.0.0'; + const program = new Command(); program.version(version, '-v, --version'); // ... rest unchangedAlso applies to: 20-31
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/index.ts` at line 2, The code uses the global singleton `program` from commander which makes `runDevCli()` non-idempotent; change `import { program } from 'commander'` to create a fresh instance via `new Command()` inside `runDevCli()` (or a helper that returns it) so each invocation gets a clean `Command` instance, move all command/registering logic (the registrations currently applied to `program`) to use that local `Command` instance, and call `parseAsync` on the new instance; ensure exported `runDevCli()` returns or awaits the parse result as before and remove any reliance on the global `program` so multiple calls won’t share cached parsed state.packages/project-builder-dev/src/utils/create-service-action-context.ts (1)
34-38: Include the caught error in plugin-discovery warnings.The current warning drops the underlying exception, which makes triage harder when plugin roots are misconfigured.
Suggested improvement
...extraPluginDirs.map(async (dir) => { try { return await discoverPlugins(dir, logger); - } catch { - logger.warn(`Could not discover plugins from ${dir}`); + } catch (error) { + logger.warn( + { dir, error }, + 'Could not discover plugins from configured plugin root', + ); return [] as PluginMetadataWithPaths[]; } }),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/utils/create-service-action-context.ts` around lines 34 - 38, The catch block swallowing errors when calling discoverPlugins(dir, logger) should capture the thrown error (e.g., catch (err)) and include it in the logger warning so the exception details are preserved; update the catch for discoverPlugins to log a descriptive message and the caught error via logger.warn (referencing discoverPlugins and logger.warn) before returning the empty PluginMetadataWithPaths[].packages/project-builder-dev/src/commands/diff.ts (1)
41-46: Avoid spreading CLI-only flags into action input.
failOnDifferencesis a command-level behavior, not action input. Keep the action payload explicit to avoid leaking command-only options into the service-action contract.Suggested refactor
const result = await invokeServiceActionAsCli( diffProjectAction, { project: resolvedProject.name, - ...options, + compact: options.compact, + packages: options.packages, + include: options.include, }, context, );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/commands/diff.ts` around lines 41 - 46, The current call to invokeServiceActionAsCli(diffProjectAction, { project: resolvedProject.name, ...options }) is leaking CLI-only flags (e.g., failOnDifferences) into the action payload; change it to pass an explicit payload object containing only the action inputs required (start with { project: resolvedProject.name } and add only service-relevant fields) or destructure options to omit failOnDifferences before spreading, so diffProjectAction receives only its intended inputs while the command retains failOnDifferences as a local behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gitignore:
- Line 58: The .gitignore change narrowed ignoring to "/.env", which only
ignores the repo-root file and risks committing nested .env files; revert to a
global ignore by restoring ".env" instead of "/.env" and, if you need a
checked-in template, explicitly unignore that template (e.g., add an allow rule
like "!<template-name>.env" or ".env.example") so only the safe template is
tracked; update the .gitignore entry accordingly.
In `@AGENTS.md`:
- Line 34: The documentation lists for the package
`@baseplate-dev/project-builder-common` are inconsistent: the summary mentions
plugin-email as part of the default bundle exposed by getDefaultPlugins(), but
the Plugins section omits it; update the Plugins section to include plugin-email
(or remove plugin-email from the summary if it is not actually returned by
getDefaultPlugins()) so both lists match and reflect the real output of
getDefaultPlugins().
In `@packages/create-project/src/version.ts`:
- Around line 6-7: getPackageVersion expects a package directory but the code
passes the resolved entry file path from require.resolve(...) into
getPackageVersion (cliPackagePath); fix by converting the resolved path to the
package directory (use path.dirname on the require.resolve result) before
calling getPackageVersion so that getPackageVersion receives the package folder
rather than a file path.
In `@packages/project-builder-dev/.env`:
- Line 2: Document or fix resolution of relative paths for
PLUGIN_ROOT_DIRECTORIES: either update README to state that environment-variable
relative paths (e.g., PLUGIN_ROOT_DIRECTORIES) are resolved against the launch
directory (process.cwd()), or change expandPathWithTilde to resolve relative
paths against the .env file location by deriving the .env file directory and
using that as the base instead of process.cwd() when calling path.resolve;
reference the PLUGIN_ROOT_DIRECTORIES env var and the expandPathWithTilde helper
to implement the chosen approach.
In `@packages/project-builder-dev/LICENSE`:
- Around line 275-315: The LICENSE file has Sections 6 and 7 mangled into
hyphen-prefixed/escaped lines; restore the canonical MPL-2.0 text for "6.
Disclaimer of Warranty" and "7. Limitation of Liability" (or replace the entire
LICENSE with the exact upstream MPL-2.0 text plus your explicit exception
addendum) so the clauses are normal, intact paragraphs rather than
hyphen-escaped lines; locate the malformed blocks by the headers "Disclaimer of
Warranty" and "Limitation of Liability" and update the text to match the
official MPL-2.0 wording verbatim (or drop in the full upstream license file and
then append the project-specific exception) to remove legal ambiguity.
In `@packages/project-builder-dev/src/commands/serve.ts`:
- Around line 55-58: The code computes portOffset and effectivePort without
validating numeric parsing, which can produce NaN and pass an invalid port to
startWebServer; update the logic around portOffset, port (the CLI --port value),
and effectivePort to validate parsed integers (use Number.isFinite or
Number.isNaN checks) and fall back to DEFAULT_SERVER_PORT or 0 when parsing
fails, and ensure you validate both process.env.PORT_OFFSET and the incoming
port before calling startWebServer so only a safe numeric port is passed.
In `@packages/project-builder-dev/src/commands/sync.ts`:
- Around line 24-27: The CLI currently allows --snapshot without requiring
--overwrite but still forwards snapshotDirectory; update the option validation
so that when snapshotDirectory (the '--snapshot' option) is provided the
overwrite flag (the '--overwrite' option / overwrite variable) must be true: add
a check after parsing options in sync.ts that throws or exits with a clear error
if snapshotDirectory is set and overwrite is false, and only forward
snapshotDirectory to downstream calls (e.g., where snapshotDirectory is passed
into the sync function or syncProject) when overwrite is true; reference the
snapshotDirectory and overwrite variables and the place where snapshotDirectory
is forwarded to ensure the dependency is enforced.
In `@packages/project-builder-dev/src/utils/config.ts`:
- Line 5: The EXCLUDE_EXAMPLES schema entry currently uses
z.coerce.boolean().optional(), which will treat non-empty strings like "false"
as true; update the EXCLUDE_EXAMPLES definition to use the string-to-boolean
codec (z.stringbool().optional()) so that common env string values
("true"/"false", "1"/"0") are parsed correctly and preserve optionality; locate
the EXCLUDE_EXAMPLES symbol in the config.ts and replace the z.coerce.boolean()
usage with z.stringbool() (keeping .optional()) throughout any related parsing
logic.
In `@packages/project-builder-dev/src/utils/find-examples-directories.ts`:
- Around line 9-10: The code promises an EXAMPLES_DIRECTORIES env override but
never uses it—update the findExamplesDirectories function to check
process.env.EXAMPLES_DIRECTORIES at the top and if present parse it as a
comma-separated list (trim entries, filter out empties), resolve/normalize paths
as needed, and immediately return that array instead of performing the
filesystem walk-up; keep the existing discovery logic unchanged for the no-env
case and ensure the early-return prevents further directory discovery.
In `@packages/project-builder-dev/src/utils/list-projects.ts`:
- Around line 70-90: The resolveProject function misclassifies bare relative
paths like "subfolder/project" as project names; update its path-detection logic
(in resolveProject) to treat any input containing a path separator as a
directory path (e.g., check for path.sep or '/' in projectNameOrDirectory) in
addition to the existing startsWith('.') / path.isAbsolute / startsWith('~')
checks, then expand via expandPathWithTilde and call loadProjectFromDirectory;
keep the existing fallback to listProjects and name/id lookup (listProjects and
the project find logic) unchanged.
In `@packages/utils/src/fs/get-package-version.ts`:
- Around line 17-18: The function that parses package.json (in
get-package-version.ts) currently casts JSON to { version?: string } and returns
packageJson.version directly; instead validate at runtime that
packageJson.version is a string before returning it. Update the return logic in
the function (e.g., in getPackageVersion / the packageJson variable handling) to
check typeof packageJson.version === 'string' and return that string, otherwise
return null, ensuring non-string values (numbers, objects, etc.) don't violate
the function contract.
---
Outside diff comments:
In `@packages/project-builder-cli/src/utils/project-resolver.ts`:
- Around line 171-175: The catch block in loadProjectInfo incorrectly reports
"No package.json found" when handling ENOENT; update the thrown Error message in
the catch of loadProjectInfo (in project-resolver.ts) to reference the actual
file path used (baseplate/project-definition.json) or a clearer message like "No
project-definition.json found in baseplate for <directory>" so the error matches
the file being read; keep the same ENOENT check (error instanceof Error &&
'code' in error && error.code === 'ENOENT') and only change the string passed to
new Error(...) to mention project-definition.json/baseplate.
In `@packages/project-builder-dev/src/runner/generate.ts`:
- Around line 22-32: The call to createNodeSchemaParserContext is using
test-only hardcoded values (id, name, isInternalExample); replace them by
deriving the real values from the project directory: call
generateProjectId(projectDirectory) for the id, read the project's definition to
use projectDef.settings.general.name for the name, and use
isExampleProject(projectDirectory) for isInternalExample; pass these computed
values (alongside the existing logger, plugins, and version) into
createNodeSchemaParserContext so the generated project gets correct ID, name,
and dev-dependency behavior.
---
Nitpick comments:
In `@examples/blog-with-auth/docker/.env`:
- Around line 2-4: Reorder the Postgres environment keys in the .env to satisfy
dotenv-linter ordering: change the sequence of POSTGRES_PORT, POSTGRES_PASSWORD,
POSTGRES_DB to alphabetical order (POSTGRES_DB, POSTGRES_PASSWORD,
POSTGRES_PORT); update the file where those three keys are defined so the linter
passes.
In `@examples/todo-with-auth0/docker/.env`:
- Around line 2-6: Reorder the environment variable lines in the .env file to
satisfy dotenv-linter's UnorderedKey rule by sorting the keys alphabetically;
specifically arrange the POSTGRES_* and REDIS_* entries so the keys are in
alphabetical order (e.g., POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_PORT,
REDIS_PASSWORD, REDIS_PORT) to remove the lint warnings.
In `@packages/project-builder-cli/src/utils/project-resolver.ts`:
- Around line 102-126: The CLI's resolveProject uses includes('/') or
includes('\\') to detect paths which differs from the dev package heuristic;
update resolveProject to use the same checks as packages/project-builder-dev
(use path.isAbsolute(nameOrPath) || nameOrPath.startsWith('.') ||
nameOrPath.startsWith('~')) before calling expandPathWithTilde/loadProjectInfo
so path detection is consistent; locate resolveProject and replace the
includes-based branch with those predicates (you can still call
expandPathWithTilde and loadProjectInfo as before).
In `@packages/project-builder-dev/src/commands/diff.ts`:
- Around line 41-46: The current call to
invokeServiceActionAsCli(diffProjectAction, { project: resolvedProject.name,
...options }) is leaking CLI-only flags (e.g., failOnDifferences) into the
action payload; change it to pass an explicit payload object containing only the
action inputs required (start with { project: resolvedProject.name } and add
only service-relevant fields) or destructure options to omit failOnDifferences
before spreading, so diffProjectAction receives only its intended inputs while
the command retains failOnDifferences as a local behavior.
In `@packages/project-builder-dev/src/commands/templates.ts`:
- Around line 146-151: Multiple handlers (handleListTemplates,
handleDeleteTemplate, handleExtractTemplates, handleGenerateTemplates) each call
discoverPlugins(process.cwd(), logger) redundantly; extract this into a
module-scoped lazy helper (e.g., getPlugins or cachedDiscoverPlugins) that
caches the Promise/result on first call and returns it thereafter so subsequent
handler calls reuse the discovered plugins; update each handler to call the new
helper instead of calling discoverPlugins directly to avoid repeating expensive
discovery.
In `@packages/project-builder-dev/src/index.ts`:
- Line 2: The code uses the global singleton `program` from commander which
makes `runDevCli()` non-idempotent; change `import { program } from 'commander'`
to create a fresh instance via `new Command()` inside `runDevCli()` (or a helper
that returns it) so each invocation gets a clean `Command` instance, move all
command/registering logic (the registrations currently applied to `program`) to
use that local `Command` instance, and call `parseAsync` on the new instance;
ensure exported `runDevCli()` returns or awaits the parse result as before and
remove any reliance on the global `program` so multiple calls won’t share cached
parsed state.
In `@packages/project-builder-dev/src/utils/create-service-action-context.ts`:
- Around line 34-38: The catch block swallowing errors when calling
discoverPlugins(dir, logger) should capture the thrown error (e.g., catch (err))
and include it in the logger warning so the exception details are preserved;
update the catch for discoverPlugins to log a descriptive message and the caught
error via logger.warn (referencing discoverPlugins and logger.warn) before
returning the empty PluginMetadataWithPaths[].
In `@packages/project-builder-dev/src/utils/list-projects.ts`:
- Line 15: The module-level call to getEnvConfig() (assigned to config) runs at
import time and can throw; change to lazy initialization by replacing the
top-level const config = getEnvConfig() with a function (e.g., getConfig() that
calls getEnvConfig() when invoked) and update all usages in this file to call
getConfig().X (or call getConfig() where needed) so parsing happens at runtime
inside functions like listProjects (or other exported functions) rather than at
module import; ensure getConfig() returns the same shaped object and keep
getEnvConfig() unchanged.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (5)
examples/blog-with-auth/baseplate/generated/docker/.envis excluded by!**/generated/**,!**/generated/**examples/todo-with-auth0/baseplate/generated/docker/.envis excluded by!**/generated/**,!**/generated/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yamltests/simple/baseplate/generated/docker/.envis excluded by!**/generated/**,!tests/**,!**/generated/**tests/simple/docker/.envis excluded by!tests/**
📒 Files selected for processing (64)
.changeset/add-project-builder-dev.md.github/workflows/verify-examples-sync.yml.gitignoreAGENTS.mdexamples/blog-with-auth/docker/.envexamples/todo-with-auth0/docker/.envpackage.jsonpackages/create-project/src/create-baseplate-project.tspackages/create-project/src/version.tspackages/project-builder-cli/package.jsonpackages/project-builder-cli/src/commands/config.tspackages/project-builder-cli/src/commands/mcp.tspackages/project-builder-cli/src/commands/projects.tspackages/project-builder-cli/src/commands/server.tspackages/project-builder-cli/src/index.tspackages/project-builder-cli/src/services/user-config.tspackages/project-builder-cli/src/utils/config.tspackages/project-builder-cli/src/utils/create-service-action-context.tspackages/project-builder-cli/src/utils/list-projects.tspackages/project-builder-cli/src/utils/project-resolver.tspackages/project-builder-cli/src/utils/project-resolver.unit.test.tspackages/project-builder-cli/src/utils/version.tspackages/project-builder-dev/.envpackages/project-builder-dev/.gitignorepackages/project-builder-dev/.prettierignorepackages/project-builder-dev/LICENSEpackages/project-builder-dev/README.mdpackages/project-builder-dev/bin/baseplate-dev.jspackages/project-builder-dev/eslint.config.jspackages/project-builder-dev/package.jsonpackages/project-builder-dev/prettier.config.jspackages/project-builder-dev/src/cli.tspackages/project-builder-dev/src/commands/dev-server.tspackages/project-builder-dev/src/commands/diff.tspackages/project-builder-dev/src/commands/mcp.tspackages/project-builder-dev/src/commands/serve.tspackages/project-builder-dev/src/commands/snapshot.tspackages/project-builder-dev/src/commands/sync-examples.tspackages/project-builder-dev/src/commands/sync.tspackages/project-builder-dev/src/commands/templates.tspackages/project-builder-dev/src/index.tspackages/project-builder-dev/src/runner/generate.tspackages/project-builder-dev/src/services/logger.tspackages/project-builder-dev/src/utils/config.tspackages/project-builder-dev/src/utils/create-service-action-context.tspackages/project-builder-dev/src/utils/find-examples-directories.tspackages/project-builder-dev/src/utils/list-projects.tspackages/project-builder-dev/src/utils/resolve.tspackages/project-builder-dev/tsconfig.app.jsonpackages/project-builder-dev/tsconfig.build.jsonpackages/project-builder-dev/tsconfig.jsonpackages/project-builder-server/src/actions/index.tspackages/project-builder-server/src/actions/registry.tspackages/project-builder-server/src/dev-server/mcp/stdio.tspackages/project-builder-server/src/user-config/user-config-schema.tspackages/project-builder-test/package.jsonpackages/project-builder-test/src/commands/generate.tspackages/project-builder-test/src/commands/serve.tspackages/project-builder-test/src/runner/runner.tspackages/utils/src/fs/get-package-version.tspackages/utils/src/fs/index.tspackages/utils/src/paths/expand-path-with-tilde.tspackages/utils/src/paths/index.tstsconfig.build.json
💤 Files with no reviewable changes (5)
- packages/project-builder-cli/src/utils/version.ts
- packages/project-builder-cli/package.json
- packages/project-builder-cli/src/services/user-config.ts
- packages/project-builder-cli/src/utils/config.ts
- packages/project-builder-cli/src/utils/project-resolver.unit.test.ts
|
|
||
| # environment variable files | ||
| .env | ||
| /.env |
There was a problem hiding this comment.
Potential secret-leak regression from narrowing .env ignore scope.
Switching to /.env only ignores the repository-root .env and allows nested .env files to be accidentally committed. If nested env files are not intended to be tracked, keep .env ignored globally and unignore only explicit safe templates.
Suggested adjustment
-/.env
+.env📝 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.
| /.env | |
| .env |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.gitignore at line 58, The .gitignore change narrowed ignoring to "/.env",
which only ignores the repo-root file and risks committing nested .env files;
revert to a global ignore by restoring ".env" instead of "/.env" and, if you
need a checked-in template, explicitly unignore that template (e.g., add an
allow rule like "!<template-name>.env" or ".env.example") so only the safe
template is tracked; update the .gitignore entry accordingly.
| @@ -0,0 +1,2 @@ | |||
| NO_BROWSER=true | |||
| PLUGIN_ROOT_DIRECTORIES=../../packages/project-builder-common | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, understand the structure and find relevant config files
find packages/project-builder-dev -type f \( -name "*.ts" -o -name "*.js" -o -name ".env*" \) | head -20Repository: halfdomelabs/baseplate
Length of output: 1098
🏁 Script executed:
# Search for config loading and PLUGIN_ROOT_DIRECTORIES usage
rg -n "PLUGIN_ROOT_DIRECTORIES|getEnvConfig|dotenv|loadEnv" packages/project-builder-dev --type ts --type jsRepository: halfdomelabs/baseplate
Length of output: 804
🏁 Script executed:
# Find the .env file and any config parsing logic
find packages/project-builder-dev -name ".env*" -o -name "*config*" | grep -E "\.(ts|js|env)" | head -20Repository: halfdomelabs/baseplate
Length of output: 381
🏁 Script executed:
cat -n packages/project-builder-dev/src/utils/config.tsRepository: halfdomelabs/baseplate
Length of output: 561
🏁 Script executed:
# Also check the context where PLUGIN_ROOT_DIRECTORIES is used
cat -n packages/project-builder-dev/src/utils/create-service-action-context.ts | head -40Repository: halfdomelabs/baseplate
Length of output: 1704
🏁 Script executed:
# Find expandPathWithTilde implementation
find packages -name "*.ts" -type f | xargs rg -l "expandPathWithTilde" | grep -E "(utils|node)" | head -5Repository: halfdomelabs/baseplate
Length of output: 359
🏁 Script executed:
# Find discoverPlugins implementation
find packages -name "*.ts" -type f | xargs rg -l "discoverPlugins" | grep -E "project-builder-server" | head -5Repository: halfdomelabs/baseplate
Length of output: 416
🏁 Script executed:
# Search for the actual implementations
rg -n "export.*expandPathWithTilde|function expandPathWithTilde" packagesRepository: halfdomelabs/baseplate
Length of output: 187
🏁 Script executed:
# Also check project-builder-server for discoverPlugins
rg -n "export.*discoverPlugins|function discoverPlugins" packagesRepository: halfdomelabs/baseplate
Length of output: 171
🏁 Script executed:
cat -n packages/utils/src/paths/expand-path-with-tilde.tsRepository: halfdomelabs/baseplate
Length of output: 404
🏁 Script executed:
cat -n packages/project-builder-server/src/plugins/plugin-discovery.ts | head -60Repository: halfdomelabs/baseplate
Length of output: 2581
🏁 Script executed:
# Look for .env.example or documentation
find packages/project-builder-dev -name ".env*" -o -name "README*" | xargs cat 2>/dev/nullRepository: halfdomelabs/baseplate
Length of output: 2083
🏁 Script executed:
# Check if there's any documentation about running the dev tool
rg -n "PLUGIN_ROOT_DIRECTORIES|launch|cwd|working.*directory|run from" packages/project-builder-dev --type ts --type md | head -20Repository: halfdomelabs/baseplate
Length of output: 2411
🏁 Script executed:
# Check package.json scripts to see expected launch directory
cat -n packages/project-builder-dev/package.json | grep -A5 -B5 "scripts"Repository: halfdomelabs/baseplate
Length of output: 602
Document required working directory for relative paths in PLUGIN_ROOT_DIRECTORIES.
Line 2 uses a relative path that is resolved against process.cwd() (via path.resolve() in expandPathWithTilde). This breaks if the tool is not run from the repository root.
Update the README to explicitly document that relative paths in environment variables are resolved from the launch directory, or add safeguards (e.g., resolve relative to the .env file location instead of process.cwd()).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/project-builder-dev/.env` at line 2, Document or fix resolution of
relative paths for PLUGIN_ROOT_DIRECTORIES: either update README to state that
environment-variable relative paths (e.g., PLUGIN_ROOT_DIRECTORIES) are resolved
against the launch directory (process.cwd()), or change expandPathWithTilde to
resolve relative paths against the .env file location by deriving the .env file
directory and using that as the base instead of process.cwd() when calling
path.resolve; reference the PLUGIN_ROOT_DIRECTORIES env var and the
expandPathWithTilde helper to implement the chosen approach.
| - * | ||
| - 6. Disclaimer of Warranty \* | ||
| - ------------------------- \* | ||
| - * | ||
| - Covered Software is provided under this License on an "as is" \* | ||
| - basis, without warranty of any kind, either expressed, implied, or \* | ||
| - statutory, including, without limitation, warranties that the \* | ||
| - Covered Software is free of defects, merchantable, fit for a \* | ||
| - particular purpose or non-infringing. The entire risk as to the \* | ||
| - quality and performance of the Covered Software is with You. \* | ||
| - Should any Covered Software prove defective in any respect, You \* | ||
| - (not any Contributor) assume the cost of any necessary servicing, \* | ||
| - repair, or correction. This disclaimer of warranty constitutes an \* | ||
| - essential part of this License. No use of any Covered Software is \* | ||
| - authorized under this License except under this disclaimer. \* | ||
| - * | ||
|
|
||
| --- | ||
|
|
||
| --- | ||
|
|
||
| - * | ||
| - 7. Limitation of Liability \* | ||
| - -------------------------- \* | ||
| - * | ||
| - Under no circumstances and under no legal theory, whether tort \* | ||
| - (including negligence), contract, or otherwise, shall any \* | ||
| - Contributor, or anyone who distributes Covered Software as \* | ||
| - permitted above, be liable to You for any direct, indirect, \* | ||
| - special, incidental, or consequential damages of any character \* | ||
| - including, without limitation, damages for lost profits, loss of \* | ||
| - goodwill, work stoppage, computer failure or malfunction, or any \* | ||
| - and all other commercial damages or losses, even if such party \* | ||
| - shall have been informed of the possibility of such damages. This \* | ||
| - limitation of liability shall not apply to liability for death or \* | ||
| - personal injury resulting from such party's negligence to the \* | ||
| - extent applicable law prohibits such limitation. Some \* | ||
| - jurisdictions do not allow the exclusion or limitation of \* | ||
| - incidental or consequential damages, so this exclusion and \* | ||
| - limitation may not apply to You. \* | ||
| - * |
There was a problem hiding this comment.
Restore Sections 6 and 7 as valid license text (currently malformed/removed).
Disclaimer of Warranty and Limitation of Liability are currently represented as hyphen-prefixed/escaped lines, which makes this MPL body non-canonical and legally ambiguous. Please include these sections as normal, intact license clauses (or replace the full file with the exact upstream MPL-2.0 text plus your explicit exception addendum).
Proposed fix direction
- - *
- - 6. Disclaimer of Warranty \*
- - ------------------------- \*
- ...
- - 7. Limitation of Liability \*
- - -------------------------- \*
- ...
+6. Disclaimer of Warranty
+Covered Software is provided under this License on an "as is" basis, ...
+
+7. Limitation of Liability
+Under no circumstances and under no legal theory, whether tort ...🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/project-builder-dev/LICENSE` around lines 275 - 315, The LICENSE
file has Sections 6 and 7 mangled into hyphen-prefixed/escaped lines; restore
the canonical MPL-2.0 text for "6. Disclaimer of Warranty" and "7. Limitation of
Liability" (or replace the entire LICENSE with the exact upstream MPL-2.0 text
plus your explicit exception addendum) so the clauses are normal, intact
paragraphs rather than hyphen-escaped lines; locate the malformed blocks by the
headers "Disclaimer of Warranty" and "Limitation of Liability" and update the
text to match the official MPL-2.0 wording verbatim (or drop in the full
upstream license file and then append the project-specific exception) to remove
legal ambiguity.
| * Override with EXAMPLES_DIRECTORIES env var (comma-separated paths) to skip | ||
| * discovery entirely. |
There was a problem hiding this comment.
EXAMPLES_DIRECTORIES override is documented but not implemented.
Lines 9-10 promise env-based override, but the function always performs filesystem walk-up. This breaks explicit config flows.
🔧 Suggested fix
-import { dirExists } from '@baseplate-dev/utils/node';
+import { dirExists, expandPathWithTilde } from '@baseplate-dev/utils/node';
@@
export async function findExamplesDirectories(): Promise<string[]> {
+ const explicitDirectories = process.env.EXAMPLES_DIRECTORIES?.split(',')
+ .map((d) => d.trim())
+ .filter(Boolean);
+
+ if (explicitDirectories && explicitDirectories.length > 0) {
+ return explicitDirectories.map((d) => expandPathWithTilde(d));
+ }
+
let dir = process.cwd();Also applies to: 15-35
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/project-builder-dev/src/utils/find-examples-directories.ts` around
lines 9 - 10, The code promises an EXAMPLES_DIRECTORIES env override but never
uses it—update the findExamplesDirectories function to check
process.env.EXAMPLES_DIRECTORIES at the top and if present parse it as a
comma-separated list (trim entries, filter out empties), resolve/normalize paths
as needed, and immediately return that array instead of performing the
filesystem walk-up; keep the existing discovery logic unchanged for the no-env
case and ensure the early-return prevents further directory discovery.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
packages/project-builder-dev/src/commands/serve.ts (1)
55-58:PORT_OFFSETNaN not validated —effectivePortcan beNaN.This is a carry-over from the previous review cycle.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/commands/serve.ts` around lines 55 - 58, The current PORT_OFFSET parsing can yield NaN and make effectivePort NaN; update the logic around process.env.PORT_OFFSET and portOffset so you parse and validate it (use Number.parseInt/process.env.PORT_OFFSET and check Number.isFinite or !Number.isNaN) and fall back to 0 on invalid values before computing effectivePort; ensure the calculation of effectivePort (using DEFAULT_SERVER_PORT, port, and portOffset) only uses the validated numeric portOffset so effectivePort can never be NaN.
🧹 Nitpick comments (1)
packages/project-builder-dev/src/commands/serve.ts (1)
87-91: Use an explicit radix wrapper instead of passingNumber.parseIntdirectly.Commander invokes the parser as
fn(valueString, previousValue), so the radix argument toNumber.parseIntwill be whatever Commander passes aspreviousValue(usuallyundefined, which defaults to base-10, but that's implicit and fragile). Wrapping it also makes NaN handling easier.♻️ Proposed refactor
.option( '--port <number>', 'Port to listen on', - Number.parseInt, + (v: string) => Number.parseInt(v, 10), process.env.PORT ? Number.parseInt(process.env.PORT, 10) : undefined, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/commands/serve.ts` around lines 87 - 91, Replace the direct use of Number.parseInt as the Commander parser for the '--port <number>' option with an explicit wrapper that calls Number.parseInt(value, 10) (and normalizes NaN to undefined or a safe default); update the option definition in serve.ts where Number.parseInt is currently passed so the parser signature is fn(valueString, previousValue) and you control the radix and NaN handling for the port value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/project-builder-dev/src/commands/serve.ts`:
- Around line 77-79: Update the description string passed to the serve command's
.description(...) to remove references to the removed environment flags
EXCLUDE_EXAMPLES and EXAMPLES_DIRECTORIES; locate the .description call on the
serve command (the serve command definition in serve.ts) and replace the stale
text with a brief accurate description such as "Starts the project builder web
service for discovered projects" or otherwise reflect current behavior (e.g.,
mention INCLUDE_EXAMPLES only if still applicable).
- Around line 33-42: resolveModule(...) can throw when the module isn't
installed, so wrap the resolveModule call used to compute projectBuilderWebDir
in a try/catch and handle the error before calling packageDirectory or
getPackageVersion; specifically, catch errors from
resolveModule(import.meta.resolve...) inside the code that sets
projectBuilderWebDir (the resolveModule call referenced alongside
packageDirectory and projectBuilderWebDir), and either set projectBuilderWebDir
to undefined or rethrow a new Error with the same user-friendly message (`Unable
to find project-builder-web package to host website`) so the null guard that
checks projectBuilderWebDir (and getPackageVersion usage) never runs into an
uncaught import.meta.resolve exception.
---
Duplicate comments:
In `@packages/project-builder-dev/src/commands/serve.ts`:
- Around line 55-58: The current PORT_OFFSET parsing can yield NaN and make
effectivePort NaN; update the logic around process.env.PORT_OFFSET and
portOffset so you parse and validate it (use
Number.parseInt/process.env.PORT_OFFSET and check Number.isFinite or
!Number.isNaN) and fall back to 0 on invalid values before computing
effectivePort; ensure the calculation of effectivePort (using
DEFAULT_SERVER_PORT, port, and portOffset) only uses the validated numeric
portOffset so effectivePort can never be NaN.
---
Nitpick comments:
In `@packages/project-builder-dev/src/commands/serve.ts`:
- Around line 87-91: Replace the direct use of Number.parseInt as the Commander
parser for the '--port <number>' option with an explicit wrapper that calls
Number.parseInt(value, 10) (and normalizes NaN to undefined or a safe default);
update the option definition in serve.ts where Number.parseInt is currently
passed so the parser signature is fn(valueString, previousValue) and you control
the radix and NaN handling for the port value.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
knip.config.jspackages/project-builder-cli/package.jsonpackages/project-builder-cli/src/utils/find-examples-directories.tspackages/project-builder-dev/README.mdpackages/project-builder-dev/src/commands/serve.tspackages/project-builder-dev/src/services/logger.tspackages/project-builder-dev/tsconfig.json
💤 Files with no reviewable changes (2)
- packages/project-builder-cli/package.json
- packages/project-builder-cli/src/utils/find-examples-directories.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/project-builder-dev/tsconfig.json
- packages/project-builder-dev/README.md
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/project-builder-dev/src/commands/serve.ts (1)
92-97:⚠️ Potential issue | 🟡 MinorValidate parsed
--portandPORTenv values to prevent NaN.The port parsing at lines 95-96 can yield
NaNif given non-numeric input. UnlikePORT_OFFSET(which now has NaN handling at line 63), invalid--portorPORTvalues will passNaNthrough tostartWebServer.🛡️ Proposed fix to add validation
+function parsePort(value: string): number | undefined { + const parsed = Number.parseInt(value, 10); + return Number.isNaN(parsed) ? undefined : parsed; +} + export function addServeCommand(program: Command): void { program .command('serve') @@ .option( '--port <number>', 'Port to listen on', - (v: string) => Number.parseInt(v, 10), - process.env.PORT ? Number.parseInt(process.env.PORT, 10) : undefined, + (v: string) => parsePort(v), + process.env.PORT ? parsePort(process.env.PORT) : undefined, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/commands/serve.ts` around lines 92 - 97, The parsed port value from the command option '--port' and process.env.PORT can become NaN and be forwarded into startWebServer; update the option handler in serve.ts to validate the parsed number (e.g., after parsing check Number.isFinite or Number.isInteger and !Number.isNaN and that it’s within valid port range 1–65535) and return undefined or a safe default when invalid so startWebServer never receives NaN; ensure the same validation logic is applied where process.env.PORT is read and mention the validated symbol names '--port' option and startWebServer so you can locate the change.
🧹 Nitpick comments (2)
packages/project-builder-dev/src/runner/generate.ts (2)
24-29: Consider replacing hardcoded version with a dynamic value.The CLI version
'0.1.0'is hardcoded, which may become stale as the package evolves. Consider importing the version from the package'spackage.jsonor using a centralized version constant to keep it synchronized with the actual package version.♻️ Suggested approach
+import { version } from '../../package.json' with { type: 'json' }; +// or import from a centralized version utility if available + const nodeSchemaParserContext = await createNodeSchemaParserContext( projectInfo, logger, plugins, - '0.1.0', + version, );Alternatively, if there's a centralized version utility in the monorepo (as mentioned in the PR summary about centralized utilities), that would be preferred.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/runner/generate.ts` around lines 24 - 29, Replace the hardcoded CLI version string passed to createNodeSchemaParserContext ('0.1.0') with a dynamic value: import the package version from this package's package.json (or use the centralized version constant/utility if one exists in the monorepo) and pass that variable into createNodeSchemaParserContext so the runtime always uses the actual package/CLI version; update the call site where nodeSchemaParserContext is created to use the imported/centralized version variable instead of the literal.
37-40: Consider using pino's standard error logging pattern.For better error serialization (including stack traces in structured logs), pino recommends passing the error object as the first argument with
errkey:♻️ Suggested fix
} catch (error) { - logger.error('Project sync failed:', error); + logger.error({ err: error }, 'Project sync failed'); throw error; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/project-builder-dev/src/runner/generate.ts` around lines 37 - 40, In the catch block inside the generate runner, change the logger.error call to use pino's structured error pattern by passing the error object as the first argument (e.g., logger.error({ err: error }, 'Project sync failed')) so the stack and error properties are serialized correctly; keep rethrowing the error after logging. Target the catch block containing logger.error('Project sync failed:', error) in the generate.ts file and replace that call with the structured-object form using the same error variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/project-builder-dev/src/commands/serve.ts`:
- Around line 92-97: The parsed port value from the command option '--port' and
process.env.PORT can become NaN and be forwarded into startWebServer; update the
option handler in serve.ts to validate the parsed number (e.g., after parsing
check Number.isFinite or Number.isInteger and !Number.isNaN and that it’s within
valid port range 1–65535) and return undefined or a safe default when invalid so
startWebServer never receives NaN; ensure the same validation logic is applied
where process.env.PORT is read and mention the validated symbol names '--port'
option and startWebServer so you can locate the change.
---
Nitpick comments:
In `@packages/project-builder-dev/src/runner/generate.ts`:
- Around line 24-29: Replace the hardcoded CLI version string passed to
createNodeSchemaParserContext ('0.1.0') with a dynamic value: import the package
version from this package's package.json (or use the centralized version
constant/utility if one exists in the monorepo) and pass that variable into
createNodeSchemaParserContext so the runtime always uses the actual package/CLI
version; update the call site where nodeSchemaParserContext is created to use
the imported/centralized version variable instead of the literal.
- Around line 37-40: In the catch block inside the generate runner, change the
logger.error call to use pino's structured error pattern by passing the error
object as the first argument (e.g., logger.error({ err: error }, 'Project sync
failed')) so the stack and error properties are serialized correctly; keep
rethrowing the error after logging. Target the catch block containing
logger.error('Project sync failed:', error) in the generate.ts file and replace
that call with the structured-object form using the same error variable.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
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 (16)
AGENTS.mdknip.config.jspackages/create-project/src/version.tspackages/project-builder-cli/src/utils/project-resolver.tspackages/project-builder-cli/src/utils/project-resolver.unit.test.tspackages/project-builder-dev/README.mdpackages/project-builder-dev/package.jsonpackages/project-builder-dev/src/commands/serve.tspackages/project-builder-dev/src/commands/sync.tspackages/project-builder-dev/src/runner/generate.tspackages/project-builder-dev/src/utils/config.tspackages/project-builder-dev/src/utils/find-examples-directories.tspackages/project-builder-dev/src/utils/list-projects.tspackages/utils/src/fs/get-package-version.tspackages/utils/src/fs/read-json-with-schema.tspackages/utils/src/fs/read-json-with-schema.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- packages/project-builder-dev/src/commands/sync.ts
- packages/utils/src/fs/get-package-version.ts
- packages/project-builder-cli/src/utils/project-resolver.ts
- packages/project-builder-dev/src/utils/find-examples-directories.ts
- knip.config.js
- packages/project-builder-dev/package.json
- packages/project-builder-dev/src/utils/config.ts
- packages/project-builder-dev/src/utils/list-projects.ts
- packages/project-builder-cli/src/utils/project-resolver.unit.test.ts
Summary by CodeRabbit
New Features
Bug Fixes
Chores