Skip to main content

Search SDK

RBS includes a powerful search engine built into every branch server. Search file contents, find files by name, and receive real-time file change notifications — all through a consistent API accessible from your editor or custom tooling.

Overview

FeatureDescriptionProtocol
Content searchSearch text or regex patterns across file contents.REST API
Fuzzy file searchQuick file finder by name (like Cmd+P in your editor).REST API
Streaming searchReal-time search results via Server-Sent Events.SSE
File watcherReal-time file change notifications.WebSocket

Search for text or regex patterns across all files in your workspace. Results include line numbers, column positions, and configurable context lines.
# Simple text search
rbs search "TODO"

# Search with file type filter
rbs search "TODO" --include "*.py"

# Regex search
rbs search "func\s+\w+" --regex --include "*.go"

API: POST /api/search

Full search with all options via JSON body:
{
  "query": "TODO|FIXME",
  "path": "src/",
  "is_regex": true,
  "case_sensitive": false,
  "whole_word": false,
  "include_glob": "*.{ts,tsx}",
  "exclude_glob": "*_test.ts",
  "max_results": 100,
  "context_lines": 2,
  "max_file_size": 1048576
}

Parameters

FieldTypeDefaultDescription
querystringrequiredSearch pattern (text or regex).
pathstring.Directory to search (relative to workspace root).
is_regexbooleanfalseTreat query as a regular expression.
case_sensitivebooleanfalseEnable case-sensitive matching.
whole_wordbooleanfalseMatch whole words only.
include_globstringOnly search files matching this glob pattern.
exclude_globstringSkip files matching this glob pattern.
max_resultsnumber1000Maximum total matches to return.
context_linesnumber0Number of lines to include before and after each match.
max_file_sizenumber1048576Skip files larger than this size (in bytes).

Response

{
  "results": [
    {
      "path": "src/utils/helper.ts",
      "matches": [
        {
          "line": 42,
          "column": 4,
          "end_column": 8,
          "content": "    // TODO: implement caching",
          "match_text": "TODO",
          "pre_context": ["function getData() {", "  const data = fetch('/api');"],
          "post_context": ["  return data;", "}"]
        }
      ],
      "truncated": false
    }
  ],
  "total_matches": 15,
  "total_files": 8,
  "files_searched": 234,
  "duration": "45ms",
  "truncated": false
}
Search via query parameters for simple lookups:
GET /api/search?q=TODO&include=*.ts&context=2&max=50
ParameterAliasesDescription
qquerySearch pattern.
pathDirectory to search.
regexis_regexEnable regex mode.
casecase_sensitiveCase-sensitive search.
wordwhole_wordWhole word matching.
includeinclude_globInclude glob pattern.
excludeexclude_globExclude glob pattern.
maxmax_resultsMax results.
contextcontext_linesContext lines.

For large workspaces, use the streaming endpoint to receive results in real-time via Server-Sent Events (SSE):
GET /api/search/stream?query=error&include=*.log
Results arrive as they’re found:
data: {"path":"app.log","matches":[{"line":1,"content":"Error: connection failed"}]}

data: {"path":"error.log","matches":[...]}

data: {"type":"done","total_matches":42,"total_files":5,"files_searched":100,"duration":"120ms","truncated":false}

Find files quickly by name using fuzzy matching — the same experience as Cmd+P / Ctrl+P in your editor.

API: GET /api/files/fuzzy

GET /api/files/fuzzy?q=srvts&types=ts,tsx&max=20
ParameterDescriptionDefault
q or queryFuzzy search query.
typesComma-separated file extensions to filter.All types
maxMaximum results.50

Response

{
  "results": [
    {
      "path": "src/server.ts",
      "name": "server.ts",
      "directory": "src",
      "score": 4.5,
      "highlights": [0, 1, 2, 6, 7],
      "is_dir": false,
      "extension": ".ts",
      "mod_time": 1706040000
    }
  ],
  "query": "srvts",
  "total": 1,
  "duration": "3ms",
  "cached": true
}
An empty query returns recently modified files sorted by modification time — useful for “recent files” functionality.

How fuzzy matching works

The fuzzy matcher scores results based on:
  1. Character matching — all query characters must appear in order in the filename.
  2. Consecutive bonus — higher score for consecutive character matches.
  3. Word boundary bonus — higher score for matches at word boundaries (/, _, -, ., camelCase).
  4. Prefix bonus — higher score for matches at the start of the filename.
  5. Exact match bonus — highest score for exact matches.
  6. Length penalty — shorter filenames score higher.
QueryMatchesWhy
main.gomain.goExact match (highest score)
mainmain.goPrefix match
mgmain.goCharacter matching
srvtsserver.tsWord boundary + character matching
btnButton.tsxWord boundary (camelCase)

Refresh the file index

The file index refreshes automatically every 30 seconds. To force a refresh:
POST /api/files/index/refresh
{
  "message": "file index refreshed",
  "files_count": 1234
}

File watcher

Receive real-time notifications when files change in the workspace via WebSocket.

Connect

WebSocket: /ws/watcher
On connection, you’ll receive a confirmation message:
{
  "type": "connected",
  "workspace": "/workspace/my-project",
  "message": "File watcher connected"
}

Event types

TypeDescription
createA file or directory was created.
writeA file’s content was modified.
removeA file or directory was deleted.
renameA file or directory was renamed.
chmodFile permissions were changed.

Event format

{
  "type": "write",
  "path": "src/app.ts",
  "name": "app.ts",
  "is_dir": false,
  "timestamp": 1706040001
}
For rename events, an additional old_path field is included:
{
  "type": "rename",
  "path": "src/new-name.ts",
  "name": "new-name.ts",
  "old_path": "src/old-name.ts",
  "is_dir": false,
  "timestamp": 1706040003
}

Debouncing

File events are debounced (100ms) to prevent rapid-fire notifications when editors auto-save, build tools generate multiple files, or external tools batch-modify files.

REST endpoints

MethodEndpointDescription
GET/api/watcherWatcher info and configuration.
GET/api/watcher/statusConnection status.

Default ignored patterns

All search and watcher features automatically skip:
  • .git, .hg, .svn directories
  • node_modules, vendor, __pycache__
  • .venv, venv, .env
  • dist, build, target
  • .idea, .vscode, .rbs
  • Binary files (images, executables, archives)
  • Files matching .gitignore patterns

Glob pattern examples

PatternMatches
*.pyAll Python files
*.{ts,tsx}TypeScript and TSX files
test_*.pyPython test files starting with test_
src/**/*.goAll Go files under src/

Editor SDK integration

If you’re building a custom editor integration, use the Search SDK client:
import { RBSSearchClient } from "@rbs/editor-sdk";

const client = new RBSSearchClient("https://your-project.rbs.dev");

// Content search
const results = await client.search({
  query: "TODO",
  includeGlob: "*.ts",
  contextLines: 2,
});
console.log(`Found ${results.total_matches} matches`);

// Streaming search
const cancel = client.searchStream(
  "error",
  (result) => console.log(`Found in ${result.path}`),
  (summary) => console.log(`Done: ${summary.total_matches} matches`)
);

// Fuzzy file search
const files = await client.fuzzySearch("srvts", { max: 10 });
console.log(files.results.map((f) => f.path));

// File watcher
client.connectWatcher();
client.onFileChange((event) => {
  console.log(`${event.type}: ${event.path}`);
});

Performance tips

  1. Use glob filters — always specify include_glob when you know the file type.
  2. Limit results — set a reasonable max_results for UI responsiveness.
  3. Use streaming for large searches — the SSE endpoint returns results as they’re found.
  4. Debounce user input — wait 100–200ms before sending search requests when building a search UI.
  5. Leverage the cache — fuzzy file search results are cached and respond in milliseconds.
  6. Connect the watcher once — reuse a single WebSocket connection for file change events.