summaryrefslogtreecommitdiffhomepage
path: root/lib/dispatch/tool/files/list_files.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dispatch/tool/files/list_files.rb')
-rw-r--r--lib/dispatch/tool/files/list_files.rb60
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