
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
opencode-plugin-search
Advanced tools
An OpenCode plugin providing advanced code search capabilities including AST-based structural search using ast-grep.
This plugin enhances OpenCode with advanced code search capabilities, including structural AST-based search using ast-grep for sophisticated code analysis, linting, and rewriting.
Add this plugin to your OpenCode configuration:
{
"plugins": ["opencode-plugin-search"]
}
Ensure ast-grep is installed and available in your PATH (or via devbox) for AST-based search functionality.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Important: This plugin's web search functionality:
Consider using official APIs instead:
Note: The DuckDuckGo implementation uses browser automation, not their public API. The author provides this plugin "as is" and accepts no responsibility for any issues arising from its use.
The Google search feature requires a Chrome/Chromium browser. The plugin supports multiple browser configurations:
Option 1: System Chrome/Chromium (Recommended if available)
sudo apt-get install chromium-browserOption 2: Remote Browser via Debugging Protocol
chrome --remote-debugging-port=9222browserWSEndpoint: "http://localhost:9222" in Google search optionsOption 3: LightPanda (Headless Chrome in Docker)
docker run -p 9222:9222 ghcr.io/lightpanda-io/lightpanda:latestbrowserWSEndpoint: "http://localhost:9222"Option 4: Custom Browser Path
executablePath: "/usr/bin/chromium"fetch APIIf you encounter library errors (e.g., libglib2.0.so.0: cannot open shared object file) when using Google search, install dependencies:
# Ubuntu/Debian minimal set
sudo apt-get update && sudo apt-get install -y \
libglib2.0-0 \
libnss3 \
libnspr4 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libpango-1.0-0 \
libcairo2 \
libasound2
Browser configuration for Google search can be provided through configuration files. This allows users to set up their browser once, and the LLM doesn't need to know about system-specific paths.
The plugin looks for configuration in the following locations (in order of priority):
.opencode-search.json in your project directory~/.opencode/plugin-search.json in your home directoryIf no configuration is found, the plugin will attempt to auto-detect common browser paths.
User/Project config file (plugin-search.json or .opencode-search.json):
{
"browser": {
"executablePath": "/usr/bin/chromium",
"browserWSEndpoint": "http://localhost:9222",
"args": ["--no-sandbox", "--disable-dev-shm-usage"],
"headless": true,
"timeout": 30000
},
"fetcher": {
"proxy": {
"url": "http://proxy.example.com:8080",
"mode": "fallback",
"testTimeout": 5000
}
},
"searchEngines": {
"google": {
"enabled": true,
"weight": 0.6,
"options": {
"safe_search": true
}
},
"duckduckgo": {
"enabled": true,
"weight": 0.4,
"options": {
"safe_search": true
}
}
}
}
Configuration options:
Fetcher options (under fetcher):
proxy (object): HTTP/SOCKS proxy configuration
url (string): Proxy URL - supports HTTP, HTTPS, SOCKS4, SOCKS5, and SOCKS5H protocols
http://proxy.example.com:8080https://proxy.example.com:8080socks5://proxy.example.com:1080 or socks5h://proxy.example.com:1080 (for DNS resolution through proxy)socks4://proxy.example.com:1080socks5://username:password@proxy.example.com:1080mode (string): Proxy mode - "always" or "fallback"
testTimeout (number): Connection test timeout in milliseconds for fallback mode (default: 5000)Browser options:
executablePath (string): Browser executable path (e.g., "/usr/bin/chromium", "google-chrome-stable")browserWSEndpoint (string): Remote debugging URL (e.g., "http://localhost:9222")browserLaunchCommand (string): Command to launch browser (e.g., "lightpanda serve --port 9222")args (array of strings): Additional arguments for browser launchheadless (boolean): Run browser in headless mode (default: true)timeout (number): Timeout for browser operations in milliseconds (default: 30000)Search engine options (under searchEngines):
google.enabled (boolean): Whether Google search is enabled (default: true)
google.weight (number): Weight for distributing results (default: 1). Weights are normalized across enabled engines, so absolute values don't matter.
google.options.safe_search (boolean): Enable safe search filtering (default: false)
google.options.use_saved_state (boolean): Reuse browser session (experimental, default: false)
duckduckgo.enabled (boolean): Whether DuckDuckGo search is enabled (default: true)
duckduckgo.weight (number): Weight for distributing results (default: 1). Weights are normalized across enabled engines, so absolute values don't matter.
duckduckgo.options.safe_search (boolean): Enable safe search filtering (default: false)
Minimal config (auto-detect browser):
{
"browser": {}
}
Using Docker/LightPanda:
{
"browser": {
"browserWSEndpoint": "http://localhost:9222"
}
}
Custom browser path:
{
"browser": {
"executablePath": "/usr/bin/chromium",
"headless": true
}
}
Using HTTP proxy for webpage fetching:
{
"fetcher": {
"proxy": {
"url": "http://proxy.example.com:8080",
"mode": "always"
}
}
}
Using SOCKS5 proxy:
{
"fetcher": {
"proxy": {
"url": "socks5://proxy.example.com:1080",
"mode": "always"
}
}
}
Using SOCKS5 with authentication:
{
"fetcher": {
"proxy": {
"url": "socks5://username:password@proxy.example.com:1080",
"mode": "always"
}
}
}
Using SOCKS5H for DNS resolution through proxy:
{
"fetcher": {
"proxy": {
"url": "socks5h://proxy.example.com:1080",
"mode": "always"
}
}
}
Using proxy with fallback mode (tries direct connection first):
{
"fetcher": {
"proxy": {
"url": "http://proxy.example.com:8080",
"mode": "fallback",
"testTimeout": 5000
}
}
}
query, limit, timeout, locale, fetch_content, max_content_lengthsearchEngines.google, searchEngines.duckduckgo) with enabled, weight, and options (e.g., safe_search, use_saved_state). Browser configuration (executablePath, browserWSEndpoint, browserLaunchCommand, args, headless, timeout).The LLM only needs to specify search parameters, not system-specific browser paths or engine selection. Search engine and browser configuration is handled through config files.
urls, timeout, optimize_for_llm, max_content_length, include_summaryfetcher.proxy (optional)Webpage fetching requires no browser configuration and works out of the box. Optionally, you can configure an HTTP proxy for scenarios where direct internet access is restricted.
The plugin provides the following tools:
Advanced code search capabilities for structural analysis and pattern matching.
ast_grep_searchSearch codebase using AST pattern matching for fast, structural code search.
Arguments:
pattern (string): The ast-grep pattern with wildcards (e.g., "function $NAME($$$)", "console.log($ARG)")language (string, optional): Programming language (default: auto-detect)max_results (number, optional): Maximum matches to returnoutput_format (string, optional): "text" (human-readable) or "json"detail (string, optional): "concise" (minimal) or "detailed" (full metadata, JSON only)Use cases:
"function $NAME($$$)", "class $NAME""fetch($URL)", "axios.$METHOD""import $MOD from '$PATH'""const $VAR = $VALUE"Example:
{
"pattern": "function $NAME($$$)",
"language": "javascript",
"max_results": 5,
"detail": "concise"
}
ast_grep_search_by_ruleAdvanced codebase search using structured YAML rules for complex queries.
Arguments:
rule (object): The ast-grep rule definition with required id, language, and rule fieldsmax_results (number, optional): Maximum matches to returnoutput_format (string, optional): "text" or "json"detail (string, optional): "concise" (minimal) or "detailed" (full metadata, JSON only)Use cases:
Workflow:
ast_grep_inspect_syntax to understand AST structureast_grep_test_rule to validate rule on snippetsExample:
{
"rule": {
"id": "find-async-functions",
"language": "javascript",
"rule": {
"kind": "function_declaration",
"has": {
"pattern": "await $EXPR",
"stopBy": "end"
}
}
},
"max_results": 10
}
ast_grep_inspect_syntaxVisualize AST/CST structure of code snippets to write effective patterns.
Arguments:
code (string): The code to analyzelanguage (string): Programming languageformat (string, optional): "cst" (concrete syntax tree), "ast" (abstract syntax tree), or "pattern" (pattern interpretation)Use cases:
Workflow:
ast_grep_test_ruleast_grep_searchExample:
{
"code": "async function example() { await fetch(); }",
"language": "javascript",
"format": "cst"
}
ast_grep_test_ruleTest YAML rules against code snippets to validate before searching codebase.
Arguments:
code (string): The code to testrule (object): The ast-grep rule definition with required id, language, and rule fieldsUse cases:
Common issues:
stopBy: "end" to has/inside rules for full-tree searchast_grep_inspect_syntaxExample:
{
"code": "async function test() { await fetch(); }",
"rule": {
"id": "test",
"language": "javascript",
"rule": {
"kind": "function_declaration",
"has": {
"pattern": "await $EXPR",
"stopBy": "end"
}
}
}
}
Tools for searching the web and fetching webpage content.
research_webSearch the web for technical information, documentation, and best practices using configured search engines (Google and/or DuckDuckGo). Search engines are configured via plugin configuration file. This simplifies LLM usage while allowing users to configure engines once. Results are combined based on configured engine weights.
Arguments:
query (string): The search querylimit (number, optional): Maximum total results across all engines (default: 10, max: 20). Results are distributed among enabled engines based on configured weights.timeout (number, optional): Timeout in milliseconds for the entire search operation (default: 30000, max: 120000)locale (string, optional): Locale for search results (e.g., "en-US", "fr-FR")Example:
{
"query": "how to implement binary search in JavaScript",
"limit": 5,
"timeout": 10000,
"locale": "en-US"
}
Notes:
fetch_webpagesFetch webpages and convert them to LLM-optimized markdown. Useful for reading detailed documentation, articles, blog posts, or technical content during development research. Uses the mdream library for efficient HTML-to-markdown conversion optimized for LLM token usage.
Arguments:
url (string, optional): Single URL to fetch (alternative to urls)urls (array of strings, optional): URLs to fetch (1-10 URLs). If both url and urls are provided, both will be fetched (deduplicated).timeout (number, optional): Timeout in milliseconds per request (default: 30000, max: 120000)Example:
Single URL:
{
"url": "https://example.com/docs/getting-started",
"timeout": 15000
}
Multiple URLs:
{
"urls": [
"https://example.com/docs/getting-started",
"https://example.com/api-reference",
"https://example.com/tutorial"
],
"timeout": 15000
}
Output includes:
Features:
The rule object follows the ast-grep rule configuration interface:
interface RuleObject {
pattern?: string | Pattern
kind?: string
regex?: string
inside?: RuleObject & Relation
has?: RuleObject & Relation
follows?: RuleObject & Relation
precedes?: RuleObject & Relation
all?: RuleObject[]
any?: RuleObject[]
not?: RuleObject
matches?: string
}
See ast-grep rule documentation for detailed examples.
The plugin automatically looks for sgconfig.yaml in the project root to support custom languages and rule directories for ast-grep search functionality. See ast-grep documentation for configuration details.
See ROADMAP.md for detailed plans about upcoming features including:
# Install dependencies
bun install
# Build plugin
bun run build
# Type checking
bun run typecheck
# Run tests
bun run test
MIT
FAQs
An OpenCode plugin providing advanced code search capabilities including AST-based structural search using ast-grep.
We found that opencode-plugin-search demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.