diff options
Diffstat (limited to 'lib/dispatch/tool/files/list_files.rb')
| -rw-r--r-- | lib/dispatch/tool/files/list_files.rb | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/dispatch/tool/files/list_files.rb b/lib/dispatch/tool/files/list_files.rb new file mode 100644 index 0000000..7e7510d --- /dev/null +++ b/lib/dispatch/tool/files/list_files.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Dispatch + module Tool + module Files + LIST_FILES = Dispatch::Tools::Definition.new( + name: "list_files", + description: "List files in a directory. Returns paths relative to the worktree root.", + parameters: { + type: "object", + properties: { + path: { + type: "string", + description: "Directory path relative to the worktree root. Defaults to the root." + }, + pattern: { + type: "string", + description: "Glob pattern to filter files (e.g. '**/*.rb')." + }, + recursive: { + type: "boolean", + description: "Whether to list files recursively. Defaults to true." + } + }, + additionalProperties: false + } + ) do |params, context| + worktree_path = context[:worktree_path] + path = params.fetch(:path, ".") + pattern = params[:pattern] + recursive = params.fetch(:recursive, true) + + resolved = begin + Sandbox.resolve_path(path, worktree_path:) + rescue SandboxError => e + next Dispatch::Tools::Result.failure(error: e.message) + end + + unless File.directory?(resolved) + next Dispatch::Tools::Result.failure(error: "Directory not found: #{path}") + end + + glob = if pattern + File.join(resolved, pattern) + elsif recursive + File.join(resolved, "**", "*") + else + File.join(resolved, "*") + end + + entries = Dir.glob(glob).select { |f| File.file?(f) } + + worktree_real = File.realpath(worktree_path) + relative_paths = entries.map { |f| f.delete_prefix("#{worktree_real}/") }.sort + + Dispatch::Tools::Result.success(output: relative_paths.join("\n")) + end + end + end +end |
