import logging from pathlib import Path from typing import Any, Dict from tools.utils import format_relative_time, ToolError, get_file_info_list, sort_file_list logger = logging.getLogger("MooseCP") async def handle(args: Dict[str, Any]): """ Lists the contents of a directory in a file browser format. Directories are listed first, then files. Supports pagination and sorting. """ path_str = args.get("path") page = int(args.get("page", 1)) page_size = int(args.get("page_size", 64)) sort_by = args.get("sort_by", "mtime") if not path_str: raise ToolError("Missing path argument") path = Path(path_str) if not path.is_dir(): raise ToolError(f"{path_str} is not a directory.") all_items = get_file_info_list(path) all_items = sort_file_list(all_items, sort_by) total_items = len(all_items) # Custom Pagination: show all if <= 100, otherwise paginate by page_size if total_items <= 100: start_idx = 0 end_idx = total_items effective_page = 1 total_pages = 1 else: start_idx = (page - 1) * page_size end_idx = start_idx + page_size total_pages = (total_items + page_size - 1) // page_size effective_page = page paged_items = all_items[start_idx:end_idx] if not paged_items: return {"text": f"No items found on page {page}."} output = [] for item in paged_items: mtime_rel = format_relative_time(item["mtime"]) if item["is_dir"]: try: count = len(list(item["path"].iterdir())) info = f"{count} items" except: info = "0 items" output.append(f"[DIR] {item['name']} | {info} | {mtime_rel}") else: size_kb = item["size"] / 1024 output.append(f" {item['name']} | {size_kb:.1f}KB | {mtime_rel}") header = f"Listing of {path_str}\nPage {effective_page} of {total_pages} ({total_items} total items). Showing {start_idx+1}-{min(end_idx, total_items)}." return {"text": f"{header}\n\n" + "\n".join(output)}