From 1ecf5ab8f210c2f9af485cd4eeeca74fc7efb21b Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 22 Apr 2026 12:56:10 +0900 Subject: [PATCH] refactor(ast-grep): inline tool descriptions and simplify pattern hints Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/tools/ast-grep/tools.ts | 45 ++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/tools/ast-grep/tools.ts b/src/tools/ast-grep/tools.ts index 2a2454fd2..98b2d0c7e 100644 --- a/src/tools/ast-grep/tools.ts +++ b/src/tools/ast-grep/tools.ts @@ -3,12 +3,6 @@ import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool" import { CLI_LANGUAGES } from "./constants" import { runSg } from "./cli" import { formatSearchResult, formatReplaceResult } from "./result-formatter" -import { getPatternHint } from "./pattern-hints" -import { - AST_GREP_REPLACE_DESCRIPTION, - AST_GREP_SEARCH_DESCRIPTION, - AST_GREP_SEARCH_PATTERN_PARAM, -} from "./tool-descriptions" import type { CliLanguage } from "./types" async function showOutputToUser(context: unknown, output: string): Promise { @@ -18,11 +12,39 @@ async function showOutputToUser(context: unknown, output: string): Promise await ctx.metadata?.({ metadata: { output } }) } +function getEmptyResultHint(pattern: string, lang: CliLanguage): string | null { + const src = pattern.trim() + + if (lang === "python") { + if (src.startsWith("class ") && src.endsWith(":")) { + const withoutColon = src.slice(0, -1) + return `Hint: Remove trailing colon. Try: "${withoutColon}"` + } + if ((src.startsWith("def ") || src.startsWith("async def ")) && src.endsWith(":")) { + const withoutColon = src.slice(0, -1) + return `Hint: Remove trailing colon. Try: "${withoutColon}"` + } + } + + if (["javascript", "typescript", "tsx"].includes(lang)) { + if (/^(export\s+)?(async\s+)?function\s+\$[A-Z_]+\s*$/i.test(src)) { + return `Hint: Function patterns need params and body. Try "function $NAME($$$) { $$$ }"` + } + } + + return null +} + export function createAstGrepTools(ctx: PluginInput): Record { const ast_grep_search: ToolDefinition = tool({ - description: AST_GREP_SEARCH_DESCRIPTION, + description: + "Search code patterns across filesystem using AST-aware matching. Supports 25 languages. " + + "Use meta-variables: $VAR (single node), $$$ (multiple nodes). " + + "IMPORTANT: Patterns must be complete AST nodes (valid code). " + + "For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'. " + + "Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'", args: { - pattern: tool.schema.string().describe(AST_GREP_SEARCH_PATTERN_PARAM), + pattern: tool.schema.string().describe("AST pattern with meta-variables ($VAR, $$$). Must be complete AST node."), lang: tool.schema.enum(CLI_LANGUAGES).describe("Target language"), paths: tool.schema.array(tool.schema.string()).optional().describe("Paths to search (default: ['.'])"), globs: tool.schema.array(tool.schema.string()).optional().describe("Include/exclude globs (prefix ! to exclude)"), @@ -41,7 +63,7 @@ export function createAstGrepTools(ctx: PluginInput): Record