Merge pull request #1606 from code-yeongyu/fix/658-tools-ctx-directory
fix: use ctx.directory instead of process.cwd() in tools for Desktop app support
This commit is contained in:
commit
c81384456c
@ -86,6 +86,10 @@ import {
|
||||
createTaskGetTool,
|
||||
createTaskList,
|
||||
createTaskUpdateTool,
|
||||
createGrepTools,
|
||||
createGlobTools,
|
||||
createAstGrepTools,
|
||||
createSessionManagerTools,
|
||||
} from "./tools";
|
||||
import {
|
||||
CATEGORY_DESCRIPTIONS,
|
||||
@ -542,6 +546,10 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
|
||||
const allTools: Record<string, ToolDefinition> = {
|
||||
...builtinTools,
|
||||
...createGrepTools(ctx),
|
||||
...createGlobTools(ctx),
|
||||
...createAstGrepTools(ctx),
|
||||
...createSessionManagerTools(ctx),
|
||||
...backgroundTools,
|
||||
call_omo_agent: callOmoAgent,
|
||||
...(lookAt ? { look_at: lookAt } : {}),
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import type { ToolDefinition } from "@opencode-ai/plugin"
|
||||
import { ast_grep_search, ast_grep_replace } from "./tools"
|
||||
|
||||
export const builtinTools: Record<string, ToolDefinition> = {
|
||||
ast_grep_search,
|
||||
ast_grep_replace,
|
||||
}
|
||||
|
||||
export { ast_grep_search, ast_grep_replace }
|
||||
export { createAstGrepTools } from "./tools"
|
||||
export { ensureAstGrepBinary, getCachedBinaryPath, getCacheDir } from "./downloader"
|
||||
export { getAstGrepPath, isCliAvailable, ensureCliAvailable, startBackgroundInit } from "./cli"
|
||||
export { checkEnvironment, formatEnvironmentCheck } from "./constants"
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||
import { CLI_LANGUAGES } from "./constants"
|
||||
import { runSg } from "./cli"
|
||||
@ -34,7 +35,8 @@ function getEmptyResultHint(pattern: string, lang: CliLanguage): string | null {
|
||||
return null
|
||||
}
|
||||
|
||||
export const ast_grep_search: ToolDefinition = tool({
|
||||
export function createAstGrepTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
||||
const ast_grep_search: ToolDefinition = tool({
|
||||
description:
|
||||
"Search code patterns across filesystem using AST-aware matching. Supports 25 languages. " +
|
||||
"Use meta-variables: $VAR (single node), $$$ (multiple nodes). " +
|
||||
@ -53,7 +55,7 @@ export const ast_grep_search: ToolDefinition = tool({
|
||||
const result = await runSg({
|
||||
pattern: args.pattern,
|
||||
lang: args.lang as CliLanguage,
|
||||
paths: args.paths,
|
||||
paths: args.paths ?? [ctx.directory],
|
||||
globs: args.globs,
|
||||
context: args.context,
|
||||
})
|
||||
@ -77,7 +79,7 @@ export const ast_grep_search: ToolDefinition = tool({
|
||||
},
|
||||
})
|
||||
|
||||
export const ast_grep_replace: ToolDefinition = tool({
|
||||
const ast_grep_replace: ToolDefinition = tool({
|
||||
description:
|
||||
"Replace code patterns across filesystem with AST-aware rewriting. " +
|
||||
"Dry-run by default. Use meta-variables in rewrite to preserve matched content. " +
|
||||
@ -96,7 +98,7 @@ export const ast_grep_replace: ToolDefinition = tool({
|
||||
pattern: args.pattern,
|
||||
rewrite: args.rewrite,
|
||||
lang: args.lang as CliLanguage,
|
||||
paths: args.paths,
|
||||
paths: args.paths ?? [ctx.directory],
|
||||
globs: args.globs,
|
||||
updateAll: args.dryRun === false,
|
||||
})
|
||||
@ -111,3 +113,5 @@ export const ast_grep_replace: ToolDefinition = tool({
|
||||
},
|
||||
})
|
||||
|
||||
return { ast_grep_search, ast_grep_replace }
|
||||
}
|
||||
|
||||
@ -1,3 +1 @@
|
||||
import { glob } from "./tools"
|
||||
|
||||
export { glob }
|
||||
export { createGlobTools } from "./tools"
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||
import { runRgFiles } from "./cli"
|
||||
import { resolveGrepCliWithAutoInstall } from "./constants"
|
||||
import { formatGlobResult } from "./utils"
|
||||
|
||||
export const glob: ToolDefinition = tool({
|
||||
export function createGlobTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
||||
const glob: ToolDefinition = tool({
|
||||
description:
|
||||
"Fast file pattern matching tool with safety limits (60s timeout, 100 file limit). " +
|
||||
"Supports glob patterns like \"**/*.js\" or \"src/**/*.ts\". " +
|
||||
@ -23,8 +25,7 @@ export const glob: ToolDefinition = tool({
|
||||
execute: async (args) => {
|
||||
try {
|
||||
const cli = await resolveGrepCliWithAutoInstall()
|
||||
// Use process.cwd() as the default search path when no path is provided
|
||||
const searchPath = args.path ?? process.cwd()
|
||||
const searchPath = args.path ?? ctx.directory
|
||||
const paths = [searchPath]
|
||||
|
||||
const result = await runRgFiles(
|
||||
@ -41,3 +42,6 @@ export const glob: ToolDefinition = tool({
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return { glob }
|
||||
}
|
||||
|
||||
@ -1,3 +1 @@
|
||||
import { grep } from "./tools"
|
||||
|
||||
export { grep }
|
||||
export { createGrepTools } from "./tools"
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||
import { runRg } from "./cli"
|
||||
import { formatGrepResult } from "./utils"
|
||||
|
||||
export const grep: ToolDefinition = tool({
|
||||
export function createGrepTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
||||
const grep: ToolDefinition = tool({
|
||||
description:
|
||||
"Fast content search tool with safety limits (60s timeout, 10MB output). " +
|
||||
"Searches file contents using regular expressions. " +
|
||||
@ -23,8 +25,7 @@ export const grep: ToolDefinition = tool({
|
||||
execute: async (args) => {
|
||||
try {
|
||||
const globs = args.include ? [args.include] : undefined
|
||||
// Use process.cwd() as the default search path when no path is provided
|
||||
const searchPath = args.path ?? process.cwd()
|
||||
const searchPath = args.path ?? ctx.directory
|
||||
const paths = [searchPath]
|
||||
|
||||
const result = await runRg({
|
||||
@ -40,3 +41,6 @@ export const grep: ToolDefinition = tool({
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return { grep }
|
||||
}
|
||||
|
||||
@ -10,21 +10,11 @@ import {
|
||||
|
||||
export { lspManager }
|
||||
|
||||
import {
|
||||
ast_grep_search,
|
||||
ast_grep_replace,
|
||||
} from "./ast-grep"
|
||||
|
||||
import { grep } from "./grep"
|
||||
import { glob } from "./glob"
|
||||
export { createAstGrepTools } from "./ast-grep"
|
||||
export { createGrepTools } from "./grep"
|
||||
export { createGlobTools } from "./glob"
|
||||
export { createSlashcommandTool, discoverCommandsSync } from "./slashcommand"
|
||||
|
||||
import {
|
||||
session_list,
|
||||
session_read,
|
||||
session_search,
|
||||
session_info,
|
||||
} from "./session-manager"
|
||||
export { createSessionManagerTools } from "./session-manager"
|
||||
|
||||
export { sessionExists } from "./session-manager/storage"
|
||||
|
||||
@ -70,12 +60,4 @@ export const builtinTools: Record<string, ToolDefinition> = {
|
||||
lsp_diagnostics,
|
||||
lsp_prepare_rename,
|
||||
lsp_rename,
|
||||
ast_grep_search,
|
||||
ast_grep_replace,
|
||||
grep,
|
||||
glob,
|
||||
session_list,
|
||||
session_read,
|
||||
session_search,
|
||||
session_info,
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export * from "./tools"
|
||||
export { createSessionManagerTools } from "./tools"
|
||||
export * from "./types"
|
||||
export * from "./constants"
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { describe, test, expect } from "bun:test"
|
||||
import { session_list, session_read, session_search, session_info } from "./tools"
|
||||
import { createSessionManagerTools } from "./tools"
|
||||
import type { ToolContext } from "@opencode-ai/plugin/tool"
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
|
||||
const projectDir = "/Users/yeongyu/local-workspaces/oh-my-opencode"
|
||||
|
||||
const mockCtx = { directory: projectDir } as PluginInput
|
||||
|
||||
const mockContext: ToolContext = {
|
||||
sessionID: "test-session",
|
||||
messageID: "test-message",
|
||||
@ -15,6 +18,9 @@ const mockContext: ToolContext = {
|
||||
ask: async () => {},
|
||||
}
|
||||
|
||||
const tools = createSessionManagerTools(mockCtx)
|
||||
const { session_list, session_read, session_search, session_info } = tools
|
||||
|
||||
describe("session-manager tools", () => {
|
||||
test("session_list executes without error", async () => {
|
||||
const result = await session_list.execute({}, mockContext)
|
||||
@ -38,23 +44,23 @@ describe("session-manager tools", () => {
|
||||
})
|
||||
|
||||
test("session_list filters by project_path", async () => {
|
||||
// given
|
||||
//#given
|
||||
const projectPath = "/Users/yeongyu/local-workspaces/oh-my-opencode"
|
||||
|
||||
// when
|
||||
//#when
|
||||
const result = await session_list.execute({ project_path: projectPath }, mockContext)
|
||||
|
||||
// then
|
||||
//#then
|
||||
expect(typeof result).toBe("string")
|
||||
})
|
||||
|
||||
test("session_list uses process.cwd() as default project_path", async () => {
|
||||
// given - no project_path provided
|
||||
test("session_list uses ctx.directory as default project_path", async () => {
|
||||
//#given - no project_path provided
|
||||
|
||||
// when
|
||||
//#when
|
||||
const result = await session_list.execute({}, mockContext)
|
||||
|
||||
// then - should not throw and return string (uses process.cwd() internally)
|
||||
//#then
|
||||
expect(typeof result).toBe("string")
|
||||
})
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
||||
import {
|
||||
SESSION_LIST_DESCRIPTION,
|
||||
@ -26,7 +27,8 @@ function withTimeout<T>(promise: Promise<T>, ms: number, operation: string): Pro
|
||||
])
|
||||
}
|
||||
|
||||
export const session_list: ToolDefinition = tool({
|
||||
export function createSessionManagerTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
||||
const session_list: ToolDefinition = tool({
|
||||
description: SESSION_LIST_DESCRIPTION,
|
||||
args: {
|
||||
limit: tool.schema.number().optional().describe("Maximum number of sessions to return"),
|
||||
@ -36,7 +38,7 @@ export const session_list: ToolDefinition = tool({
|
||||
},
|
||||
execute: async (args: SessionListArgs, _context) => {
|
||||
try {
|
||||
const directory = args.project_path ?? process.cwd()
|
||||
const directory = args.project_path ?? ctx.directory
|
||||
let sessions = await getMainSessions({ directory })
|
||||
let sessionIDs = sessions.map((s) => s.id)
|
||||
|
||||
@ -55,7 +57,7 @@ export const session_list: ToolDefinition = tool({
|
||||
},
|
||||
})
|
||||
|
||||
export const session_read: ToolDefinition = tool({
|
||||
const session_read: ToolDefinition = tool({
|
||||
description: SESSION_READ_DESCRIPTION,
|
||||
args: {
|
||||
session_id: tool.schema.string().describe("Session ID to read"),
|
||||
@ -84,7 +86,7 @@ export const session_read: ToolDefinition = tool({
|
||||
},
|
||||
})
|
||||
|
||||
export const session_search: ToolDefinition = tool({
|
||||
const session_search: ToolDefinition = tool({
|
||||
description: SESSION_SEARCH_DESCRIPTION,
|
||||
args: {
|
||||
query: tool.schema.string().describe("Search query string"),
|
||||
@ -125,7 +127,7 @@ export const session_search: ToolDefinition = tool({
|
||||
},
|
||||
})
|
||||
|
||||
export const session_info: ToolDefinition = tool({
|
||||
const session_info: ToolDefinition = tool({
|
||||
description: SESSION_INFO_DESCRIPTION,
|
||||
args: {
|
||||
session_id: tool.schema.string().describe("Session ID to inspect"),
|
||||
@ -144,3 +146,6 @@ export const session_info: ToolDefinition = tool({
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return { session_list, session_read, session_search, session_info }
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user