Skip to content

fix(intellij): resolve workspace paths for multi-project windows#12919

Open
houssemzaier wants to merge 1 commit into
continuedev:mainfrom
houssemzaier:fix/intellij-multi-project-workspace-paths
Open

fix(intellij): resolve workspace paths for multi-project windows#12919
houssemzaier wants to merge 1 commit into
continuedev:mainfrom
houssemzaier:fix/intellij-multi-project-workspace-paths

Conversation

@houssemzaier

@houssemzaier houssemzaier commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Description

When an IntelliJ window has more than one project/module open, files from one of them can silently disappear from Continue: @-file references, the file picker, listDir, and indexing all behave as if that project isn't there.

It happens when two project folders share the start of their name (e.g. service and service-api). The code decided whether one folder sat inside another with a plain startsWith text check, so service-api looked like it was inside service and got dropped from the workspace.

This PR compares path segments instead of raw text, so service-api is kept as its own top-level project. It also routes every place that computes workspace paths (startup + the add / remove / rename module listeners) and both readers (IntelliJIDE and GitService workspaceDirectories()) through one shared helper (resolveWorkspacePaths / resolveWorkspacePathsOrGuess), so they can't disagree. moduleRemoved now re-derives the top-level roots from the remaining modules, so removing a parent promotes a previously-nested child instead of leaving a stale list.

We've been running this fix in our downstream fork (3,000+ users) and it's been stable in production.

This is the workspace discovery side of the problem in #10644. #12090 takes the related path-resolution angle (preferring the active workspace for an ambiguous relative path) — the two are complementary.

Tests

  • WorkspacePathsTest — pure unit tests for the segment-aware de-nesting: prefix-sharing siblings, real nesting, dedup, Windows drive paths, trailing slashes.
  • ResolveWorkspacePathsTest — the module-scan glue (ModuleManager → content roots → de-nesting), OS-independent via mockk.
  • Manual repro: open two attached projects named service and service-api, @-reference a file under service-api → now resolves correctly.

Checklist

  • I've read the contributing guide
  • Relevant tests added
  • Docs — n/a (bug fix)

Summary by cubic

Fixes workspace discovery in multi-project IntelliJ windows by comparing URI path segments instead of string prefixes, so sibling projects like service and service-api no longer disappear. All writers/readers now use a shared resolver with a safe read-action scan and consistent fallback, keeping IntelliJIDE and GitService in sync.

  • Bug Fixes

    • Use segment-aware containment to avoid dropping prefix-sharing siblings.
    • Re-derive top-level roots on add/remove/rename; moduleRemoved rescans to promote previously nested children.
  • Refactors

    • Introduced WorkspacePaths (topLevelWorkspacePaths, isNestedUnder) and shared helpers resolveWorkspacePaths / resolveWorkspacePathsOrGuess (stored paths → module scan → guessProjectDir).
    • Routed startup and ModuleListener writers, and readers in IntelliJIDE and GitService, through these helpers.
    • Added unit tests for segment-aware de-nesting and the module-scan glue.

Written for commit 04f23f2. Summary will update on new commits.

Review in cubic

@houssemzaier houssemzaier requested a review from a team as a code owner June 29, 2026 23:44
@houssemzaier houssemzaier requested review from sestinj and removed request for a team June 29, 2026 23:44
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 29, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 6 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

When an IntelliJ window holds several modules or attached projects and two
sibling roots share a textual prefix (e.g. .../service and .../service-api),
the naive String.startsWith() containment check treated one as nested in the
other and dropped it from workspacePaths — so @-references, file lists,
listDir and indexing were broken for that project.

Containment is now computed on URI path segments (WorkspacePaths.isNestedUnder),
so prefix-sharing siblings are kept as separate top-level roots. All workspace-path
writers (startup + the modulesAdded / moduleRemoved / modulesRenamed listeners) and
both consumers (IntelliJIDE and GitService workspaceDirectories()) route through a
single resolveWorkspacePaths / resolveWorkspacePathsOrGuess helper, so the discovered
roots can never drift between callers.

Adds unit tests for the segment-aware de-nesting and the module-scan glue.
@houssemzaier houssemzaier force-pushed the fix/intellij-multi-project-workspace-paths branch from 3ef276f to 04f23f2 Compare June 30, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant