feat(cli): detect SvelteKit apps in a monorepo and offer a picker - #148
Conversation
Running `npx svelte-vitals` at a monorepo root with no path argument used
to dead-end with exit 2 ("No SvelteKit project found"). Now, only when no
explicit path was given and detection fails, it globs for
svelte.config.{js,ts} + src/routes nearby: one match auto-continues with a
stderr notice, multiple matches prompt an interactive single-select (clack,
cancel = exit 0), and non-TTY environments get exit 2 with the app list and
a path hint instead of a prompt. An explicit path's failure is never
reinterpreted. Also fixes the "or pass --config" error text, which named a
flag that doesn't exist.
See docs/superpowers/specs/2026-07-08-monorepo-app-picker-design.md for the
full design.
|
Warning Review limit reached
Next review available in: 48 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR adds monorepo SvelteKit app auto-detection to the svelte-vitals CLI. When run without an explicit path and project detection fails, it discovers candidate apps, auto-analyzes a sole match, prompts interactively for multiple matches in TTY, or exits with code 2 otherwise, with corresponding fixtures, tests, and docs. ChangesMonorepo App Picker
Estimated code review effort: 3 (Moderate) | ~30 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant run
participant discoverApps
participant selectApp
participant analyzeProject
User->>run: invoke CLI without path
run->>analyzeProject: analyzeProject(cwd)
analyzeProject-->>run: throws ProjectError
run->>discoverApps: discoverApps(cwd)
discoverApps-->>run: apps list
alt one app found
run->>analyzeProject: analyzeProject(join(cwd, app))
else multiple apps and TTY
run->>selectApp: selectApp(apps)
selectApp-->>run: chosen app or null
run->>analyzeProject: analyzeProject(join(cwd, chosen))
else multiple apps non-interactive or zero found
run-->>User: exit code 2 with message
end
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli/src/index.ts`:
- Around line 249-260: The app selection prompt in index.ts is currently gated
only by stdout TTY, so selectApp can still run when stdin is not interactive and
hang or fail. Update the condition around the selectApp branch to require an
interactive stdin as well (using process.stdin.isTTY, or both stdin and stdout),
and keep the existing fallback/error path in the same control flow so
non-interactive shells skip the picker.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a5030158-2afa-49b8-8781-642c66dc57f0
📒 Files selected for processing (19)
.changeset/monorepo-app-picker.mdREADME.mddocs/src/content/docs/guides/cli.mddocs/src/content/docs/ja/guides/cli.mddocs/superpowers/specs/2026-07-08-monorepo-app-picker-design.mdpackages/cli/src/bin.tspackages/cli/src/discover-apps.tspackages/cli/src/index.tspackages/cli/src/providers/source/project.tspackages/cli/src/resolve-args.tspackages/cli/test/discover-apps.test.tspackages/cli/test/fixtures/monorepo-project/apps/admin/src/routes/+page.sveltepackages/cli/test/fixtures/monorepo-project/apps/admin/svelte.config.jspackages/cli/test/fixtures/monorepo-project/apps/web/src/routes/+page.sveltepackages/cli/test/fixtures/monorepo-project/apps/web/svelte.config.jspackages/cli/test/fixtures/monorepo-project/packages/ui/svelte.config.jspackages/cli/test/resolve-args.test.tspackages/cli/test/run-discover.test.tspackages/cli/test/run.test.ts
…icker @clack/prompts reads from stdin, so gating the picker only on stdout TTY could hang the prompt when stdin is piped or redirected while stdout is a terminal. Gate on both streams; a non-interactive stdin now takes the existing non-TTY fallback (app list + path hint, exit 2).
Summary
Implements plan
plans/019-monorepo-app-picker.md(design doc included in this PR:docs/superpowers/specs/2026-07-08-monorepo-app-picker-design.md).Running
npx svelte-vitalsat a monorepo root used to dead-end with exit 2, forcing users to know and type the app path (npx svelte-vitals ./apps/web). Now that dead end becomes a helpful path:detected SvelteKit app at apps/web; analyzing it.) and the analysis just runs.@clack/promptssingle-select picker (same style as theinstallwizard); cancel exits 0.pass one as a pathhint.Design decisions (maintainer-approved)
resolveArgsnow recordsexplicitPath).svelte.config.{js,ts}(depth-capped at 4, ignoringnode_modules/.svelte-kit/build/dist/.git), qualified by an adjacentsrc/routes— which also excludes SvelteKit component libraries with nothing to analyze. No workspace-manifest parsing.svelte-vitals.config.*loads from the selected app and--diff/--staged/--baselinekeep working (their subdirectory handling shipped in fix(cli): make --diff/--staged work when the project is not at the git repo root #114/feat(cli): add --baseline <ref> to report only newly introduced findings #142). The cwd computation inrun()is now hoisted to a single variable used everywhere.run()(RunOptions.selectApp) and wired to clack inbin.ts— keeping prompts out of the library entry point and making every branch unit-testable.Changes
packages/cli/src/discover-apps.ts(new), discovery/picker branch inrun(),explicitPathinresolve-args.ts, clack wiring inbin.ts, message fix inproviders/source/project.tsapps/web,apps/admin,packages/uias the excluded library) and 12 new test cases acrossdiscover-apps,run-discover, andresolve-argstests; one pre-existingrun.test.tscase now passesexplicitPath: trueto keep meaning "this exact directory is the target"svelte-vitalsVerification
pnpm typecheck,pnpm --filter svelte-vitals test(436 tests),pnpm lint— all green🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
svelte-vitalscan now detect SvelteKit apps in a monorepo when run from the repository root without a path.Bug Fixes
Documentation