Skip to content

Monorepo project selection doesn't filter dirListing/fileCache to the selected app #656

@sentry-junior

Description

@sentry-junior

Summary

In a monorepo, when the user selects a specific sub-application to instrument, the dirListing and fileCache passed to downstream steps (detect-platform, plan-codemods) still contain entries for the entire repository root, not just the selected project. This means the AI agents see — and can instrument — files from sibling projects the user never chose.

Root Cause

The CLI computes dirListing upfront from the user-supplied directory (the monorepo root) in wizard-runner.ts:

// wizard-runner.ts
const dirListing = precomputeDirListing(directory);
run.startAsync({ inputData: { directory, yes, dryRun, features, dirListing } });

discover-context receives this full root-level listing, runs the monorepo agent, and emits:

// discover-context.ts (output)
return {
  rootDir: result.object.rootDir,
  isMonorepo: result.object.isMonorepo,
  apps: result.object.apps,
  dirListing,       // ← still the FULL root listing
  fileCache: manifestEntries,  // ← files read from rootDir
  ...
};

select-target-app then resolves projectDir to the selected app's path:

// select-target-app.ts
return {
  projectDir: selected.path,  // e.g. "apps/my-next-app"
  rootDir: inputData.rootDir,
  dirListing: (inputData as any).dirListing,   // ← unfiltered root listing passed through as-is
  fileCache: (inputData as any).fileCache,     // ← unfiltered root file cache passed through as-is
  ...
};

detect-platform and plan-codemods then use readCwd = rootDir (not projectDir) when the listing is cached, and present the full root listing to the file-selection agent:

// detect-platform.ts / plan-codemods.ts
const cachedListing = (inputData as any).dirListing as DirEntry[] | undefined;
const readCwd = cachedListing
  ? (inputData as any).rootDir   // ← reads files relative to rootDir
  : inputData.projectDir;

As a result, the framework detector and codemod planner are given a file list that spans the entire monorepo. In practice this means:

  • A Python project's pyproject.toml is visible when the user selected a Next.js app, and vice-versa.
  • The agent may misidentify the platform or produce codemods targeting the wrong project.
  • pnpm install being run against a Python subproject is a concrete symptom of this.

Expected Behavior

After select-target-app resolves projectDir, downstream steps should only see files scoped to that directory:

  1. dirListing should be filtered to entries whose path starts with selected.path (with the prefix stripped, or kept relative to rootDir but filtered).
  2. fileCache should be filtered similarly.
  3. readCwd for subsequent read-file suspensions should be projectDir, not rootDir.

Versions Affected

  • getsentry/cli-init-apiselect-target-app step (current main)
  • getsentry/cliwizard-runner.ts precomputeDirListing call (current main)

Suggested Fix Options

Option A — filter in select-target-app (server-side):
After resolving selected.path, filter dirListing to entries under that path and strip the prefix so all downstream path values are relative to projectDir. Filter fileCache the same way.

Option B — re-list in detect-platform / plan-codemods (skip cache):
When isMonorepo && projectDir !== rootDir, discard the cached listing and issue a fresh list-dir suspend against projectDir instead of reusing the root listing.

Option A is lower-latency and doesn't require an extra round-trip; Option B is simpler but adds a suspend round-trip for every monorepo run.

Action taken on behalf of Miguel Betegon.

Metadata

Metadata

Labels

No labels
No labels
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions