Repository navigation
fix(search): serve remote workspace content search over the remote transport - #3695
Merged
Merged
Conversation
…ansport The file panel, search_files, and search_file_contents refused every remote content search because Flashgrep only ships for the host platform. Route them through the workspace-stream search the agent Grep tool already uses, with the workspace's own file and shell providers. Interactive search defaults to case folding, which the existing literal prefilter rejected, so it would have streamed every file over SFTP. Add a proven fixed-string hint with case-folded rg and a one-shot recursive grep candidate step, stop scanning once the limit is exceeded, and return structured line matches. Failures stay explicit and nothing touches the controller filesystem. Fixes GCWing#3452
Treat a candidate command that exits 2 with no output as failed rather than as zero results, and scan through the provider. Skip and count per-path refusals while keeping transport errors fatal. Apply the local exclusions, binary detection, and 10 MB cap before results count against the budget, keep whole lines for matches past the agent column cap, handle CRLF end anchors, resolve symlinked roots, and read the root .git/info/exclude. Global search stays local-only, now stated in docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Content search in a remote workspace now runs on the remote host instead of failing with
Flashgrep is not supported for remote workspaces.start_search_file_contents_stream,search_file_contents, and the content branch ofsearch_filesuse the same workspace-stream search as the agent Grep tool, through the workspace's own file and shell providers. Flashgrep is still never selected for a remote root.Fixes #3452
Type and Areas
Type: bug fix
Areas: desktop/Tauri, Rust core, tool-execution, docs
Motivation / Impact
These commands refused every remote content search, since
workspace_search_unavailable_messagealways returns a reason for remote workspaces. The agent Grep tool already fell back to workspace IO, so only the file panel search box was broken. Users can now search file contents in SSH and container workspaces.The existing Grep path was not enough on its own. The search box defaults to case-insensitive, and
literal_alternativesrejects case folding and any escaped literal, so a default query would have streamed every file over SFTP. This PR adds, for interactive search only:content_search_candidate_literal).k,s, and cased non-ASCII characters split the literal, because they have folds thatLC_ALL=C grep -icannot see. The prefilter stays a conservative superset of the native matcher.rg, then a one-shotgrep -rcandidate step guarded by a behavior probe, then provider streaming if neither is usable.InteractiveSearchPolicy): the same default excluded directories, binary suffixes, and 10 MB cap as localtree.rs(now shared constants),BinaryDetection::quit(0)so binary files do not consume the budget, CRLF-aware$, and.git/info/excludeat the workspace root.pwd -Pin the workspace shell. A symlinked root keeps its logical path in results.Agent Grep behavior is unchanged: the new
GrepOptionsfields default to off.Failures stay explicit. A lost connection, an invalid regex, or the new 120s deadline reaches the UI as an error, and the existing "local filesystem fallback was not attempted" wording is kept. Nothing touches the controller filesystem. A candidate command that exits 2 with no output no longer means "no results": the search logs its stderr and scans through the provider.
Verification
cargo test --locked -p tool-runtime --lib search: passedcargo test --locked -p tool-runtime --test tool_io_contracts: 15 passedcargo test --locked -p openbitfun-core --no-default-features --features ssh-remote,workspace-search,agent-runtime --lib service::search::remote_content: 19 passed--lib grep_tool: 31 passed, so agent Grep has no regressioncargo test --locked -p openbitfun-services-core --no-default-features --features filesystem --lib filesystem::tree: 3 passed (shared exclusion constants)cargo check --locked -p openbitfun-core --no-default-features --features workspace-search: passed (disabled-feature stub)cargo test --locked -p openbitfun-desktop --lib api::search_api::tests: 3 passed. This compile used empty placeholders for themobile-web/distandextension-hostresources.pnpm run check:repo-hygiene: passedpnpm run check:core-boundaries: could not run from this nested worktree (Cargo resolves the installer manifest against the parent checkout's workspace). This PR changes no Cargo manifests, so please rely on CI for it.Remote scenarios exercised: none against a real host. The new tests use a real local POSIX shell and filesystem behind the workspace provider ports, with
rgandgrepabsence simulated. They do not establish behavior over real SSH, Docker, or a slow link, and the desktop search UI was not driven manually. By code path only:Proxied, so a Desktop peer runs them on the peer. A CLI peer still reports them as not implemented.Reviewer Notes
rg/grepread files through the provider. A very large tree can hit the 120s deadline, which shows an error rather than partial results.fileSearchProviderkeeps reporting remote projects as unsupported, because each keystroke would hold local file results behind a remote scan. The comment anddocs/features/remote-workspaces.mdnow say so. Enabling it needs per-workspace progressive results.Checklist
docs/features/remote-workspaces.mdis updated; no new UI strings.