Skip to content

feat(web): tag files and directories from anywhere on the filesystem - #5446

Open
chrisdeeming wants to merge 3 commits into
pingdotgg:mainfrom
chrisdeeming:file-tag-any-path
Open

feat(web): tag files and directories from anywhere on the filesystem#5446
chrisdeeming wants to merge 3 commits into
pingdotgg:mainfrom
chrisdeeming:file-tag-any-path

Conversation

@chrisdeeming

@chrisdeeming chrisdeeming commented Aug 5, 2026

Copy link
Copy Markdown

What Changed

The composer's @ picker can now complete filesystem paths. Type /, ~/, ./ or ../ and it browses the thread's environment a segment at a time, so you can tag any file or directory. Plain @foo queries still search the workspace exactly as before.

Tags pointing outside the workspace now render as chips instead of plain links.

filesystem.browse gains optional kinds and limit inputs and returns a kind per entry. Leave kinds off and it returns directories only, so the project picker is untouched.

Why

The picker only knew about workspace files, so there was no way to tag anything outside the project.

Completing one explicit segment keeps it small: no new index, no fuzzy search outside the workspace, no change to plain @ queries. Browsing runs over the environment RPC, so on a remote thread ~ means the remote home, matching where the agent runs.

Bare paths keep the existing heuristics, so routes like /chat/settings still never become chips.

Unchanged: the text sent to the agent, and projects.readFile containment. One fix along the way — workspace containment now normalises .., so /repo/../outside/page.html no longer counts as inside /repo.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Touches composer path routing, filesystem browse RPC contracts, and markdown link/open behavior; changes are well-tested but span client UI and server browse semantics.

Overview
The composer @ path picker now branches on explicit filesystem queries (/, ~/, ./, ../, Windows drives): those use filesystem.browse via useComposerFilesystemBrowse instead of workspace search, while plain @foo behavior is unchanged.

filesystem.browse gains optional kinds and limit, returns a kind per entry, and applies directories-first ordering with a limit split so files are not hidden behind many directories. Default kinds stays directory-only for existing callers.

Chat markdown resolves canonical composer file links (label matches basename) into file tag chips, including paths outside the workspace. Unresolved paths (~, scoped package refs like @scope/package.json) stay display-only via openTargetPath: null (no open-in-editor). Workspace containment now normalizes .. and uses platform-appropriate casing on Windows paths.

Serialized composer links escape more markdown-sensitive label characters and encode & / | in destinations; Windows drive hrefs are preserved through the URL transform.

Reviewed by Cursor Bugbot for commit 8f5d400. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add filesystem path browsing and file tag support for any path in the composer

  • Adds filesystem path browsing to the chat composer: typing an absolute, home-tilde, Windows drive, or relative path now triggers live suggestions fetched via a new useComposerFilesystemBrowse hook with debounce and a configurable limit.
  • Extends the filesystem browse API (FilesystemBrowseInput/FilesystemBrowseEntry) to support kinds filtering and a bounded limit; the server-side browse handler returns entries with a kind field, sorted directories-first, with proportional limit splitting between directories and files.
  • Improves markdown file link handling in ChatMarkdown: formatted labels (e.g. bold/italic filenames) now resolve to file chips, Windows drive path hrefs are preserved rather than rewritten, and links that cannot be opened render as non-clickable chips without an 'Open in editor' menu item.
  • Fixes serialization of composer file link labels and destinations: escapeMarkdownLinkLabel now escapes *, _, |, `, &, and other markdown-sensitive characters; encodeMarkdownLinkDestination encodes &.
  • Behavioral Change: browse requests with an empty kinds array return no entries; existing clients omitting kinds are unaffected.

Macroscope summarized 8f5d400.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c00dafdb-c97c-47ba-a850-ff834b7cd629

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 5, 2026
Comment thread apps/web/src/markdown-links.ts
@macroscopeapp

macroscopeapp Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. New feature enabling file tagging for arbitrary filesystem paths, with substantial cross-layer changes. Two unresolved medium-severity bug reports (label key mismatch, pipe encoding) identify potential correctness issues.

You can customize Macroscope's approvability policy. Learn more.

Comment thread apps/web/src/components/ChatMarkdown.tsx Outdated
Comment thread apps/web/src/markdown-links.ts
Comment thread apps/server/src/workspace/WorkspaceEntries.ts Outdated
The browse RPC only listed directories, which is all the project picker
needs. Add optional `kinds` and `limit` inputs and a `kind` on each entry
so callers can ask for files too.

Both fields are optional: with `kinds` absent the server still returns
directories only, so the project picker is unchanged. Entries are sorted
directories-first and the limit is applied last, keeping prefix
completion deterministic rather than dependent on directory iteration
order.
The `@` picker only searched the indexed workspace, so files outside the
project could not be tagged. Queries that are unambiguously filesystem
paths (`/`, `~/`, `./`, `../`, and Windows absolute paths on Windows) now
browse the thread's environment one segment at a time.

Ordinary `@foo` queries keep the existing workspace search untouched.
Browsing runs through the environment RPC, so remote threads complete
against the filesystem where the agent actually runs, and the inserted
tag preserves the spelling the user typed rather than a resolved path.
Comment thread apps/web/src/markdown-links.ts Outdated
Comment thread apps/web/src/components/ChatMarkdown.tsx
Comment thread apps/web/src/components/ChatMarkdown.tsx
Rendering used path-shape heuristics to decide what became a file chip,
so an out-of-workspace tag could fall back to a plain link, and a `~/`
path needed a cwd it could infer a home from.

Canonical `[basename](path)` tags now resolve through their own path,
keeping the heuristics for bare paths so application routes such as
`/chat/settings` still never become chips. A tag that cannot be resolved
in the current context renders and copies but is not offered as an open
action.

Workspace containment now normalizes `..` segments before comparing, so
a path such as `/repo/../outside/page.html` is no longer treated as
inside the project, and comparison is case-sensitive except on Windows.
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 5, 2026

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8f5d400. Configure here.

Comment thread packages/shared/src/composerTrigger.ts
@chrisdeeming chrisdeeming changed the title File tag any path feat(web): tag files and directories from anywhere on the filesystem Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant