Skip to content

fix(mobile): files and @ search follow the .code-workspace folder list - #333

Merged
LoganRupe merged 2 commits into
multi-repo-workspacesfrom
bug/323/mobile-files-follow-workspace-folders
Oct 1, 2026
Merged

LoganRupe merged 2 commits into
multi-repo-workspacesfrom
bug/323/mobile-files-follow-workspace-folders

Conversation

@LoganRupe

@LoganRupe LoganRupe commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

What Changed

For a .code-workspace project, the mobile file tree and @ search now span the folders the file lists, as web does since #325. The tree shows one top-level folder per listed root, named by its label, and an isolated run lists the worktree's files under the repo's name. @ results are described by label/dir and insert an absolute-path link. The tree waits for the first read of the folder list instead of showing the whole workspace folder.

resolveProjectFileRoots and its label helpers moved from apps/web to packages/client-runtime (@t3tools/client-runtime/project-file-roots) so web and mobile share one implementation. Web only changes its imports. No contract or server changes: the list and search RPCs already accept roots.

Why

Follow-up 4 (mobile half) from the review of #325 on #323. Mobile still used the whole workspace folder, so unlisted sibling folders showed up and listed folders outside it, like ../notes, were missing.

Not covered here: multi-repo projects without a workspace file keep the single cwd on mobile, and mobile chat file links are not matched against the roots the way #331 did for web.

UI Changes

Not yet verified on a device. Typecheck and unit tests pass; a recording is still to come.

_Video:

compare.mp4

Mobile listed and searched the folder holding the .code-workspace, so unlisted siblings showed up and listed folders outside it were missing.

The file tree and @ mention search now span the folders the workspace file lists, one labelled top-level folder per root, with a repo an isolated run covers swapped for its worktree. resolveProjectFileRoots and its label helpers move from apps/web to packages/client-runtime so web and mobile share them. Projects without a workspace file are unchanged.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 1, 2026
@LoganRupe
LoganRupe requested a balanced review from Copilot October 1, 2026 06:46

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Slash-containing root labels can collide hierarchically, nesting roots and making files in another root inaccessible.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Extends .code-workspace folder-list behavior to mobile and shares root-resolution logic with web.

Changes:

  • Moves project-file-root utilities into client-runtime.
  • Adds multi-root mobile file trees, navigation, refresh, and isolated-worktree handling.
  • Makes mobile @ search use labeled workspace roots and absolute links.
File Description
packages/​client-runtime/​src/​projectFileRoots.ts Centralizes root resolution and labeling.
packages/​client-runtime/​src/​projectFileRoots.test.ts Tests shared root behavior.
packages/​client-runtime/​package.json Exports the shared utility.
apps/​web/​src/​lib/​projectFileRoots.test.ts Retains web link integration coverage.
apps/​web/​src/​components/​files/​FilePreviewPanel.tsx Uses the shared types and key helper.
apps/​web/​src/​components/​files/​filePath.ts Removes migrated label helpers.
apps/​web/​src/​components/​files/​filePath.test.ts Removes migrated tests.
apps/​web/​src/​components/​files/​FileBrowserPanel.tsx Imports shared root helpers.
apps/​web/​src/​components/​files/​FileBreadcrumbs.tsx Imports shared labels and types.
apps/​web/​src/​components/​ChatView.tsx Uses shared root resolution.
apps/​web/​src/​components/​chat/​ChatComposer.tsx Uses shared root metadata.
apps/​mobile/​src/​state/​queries.ts Sends root lists with path searches.
apps/​mobile/​src/​features/​threads/​use-composer-command-menu.ts Labels and inserts multi-root results.
apps/​mobile/​src/​features/​threads/​ThreadRouteScreen.tsx Supplies roots to the files inspector.
apps/​mobile/​src/​features/​threads/​ThreadComposer.tsx Resolves roots for thread mentions.
apps/​mobile/​src/​features/​threads/​NewTaskDraftScreen.tsx Resolves roots for draft mentions.
apps/​mobile/​src/​features/​files/​useProjectFileRoots.ts Reads and resolves workspace folders.
apps/​mobile/​src/​features/​files/​useFileTreeEntries.ts Builds and queries multi-root trees.
apps/​mobile/​src/​features/​files/​ThreadFilesRouteScreen.tsx Maps tree paths to absolute files.
apps/​mobile/​src/​features/​files/​thread-file-navigator-pane.tsx Integrates roots into the navigator.
apps/​mobile/​src/​features/​files/​fileTree.ts Adds rooted path conversions.
apps/​mobile/​src/​features/​files/​fileTree.test.ts Tests rooted path conversions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/mobile/src/features/files/useFileTreeEntries.ts

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Root labels can still retain a prefix collision when both conflicting labels have reached their full paths, making part of the file tree inaccessible.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (1)

Comment on lines +95 to +100
if (label === otherLabel && canGrow(root)) growing.add(root);
if (otherLabel.startsWith(`${label}/`)) growing.add(canGrow(root) ? root : other);
}
}
const grown = [...growing].filter(canGrow);
if (grown.length === 0) break;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Leaving this one. The loop only stops with a prefix pair once both labels are full paths, which means /api/docs really is inside /api; api/docs/readme.md resolves to /api/docs/readme.md under either root, so nothing becomes unreachable.

@LoganRupe
LoganRupe marked this pull request as ready for review October 1, 2026 07:18
@LoganRupe
LoganRupe merged commit feee30e into multi-repo-workspaces Oct 1, 2026
14 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants