diff options
| author | Adam Malczewski <[email protected]> | 2026-05-19 19:40:21 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-19 19:40:21 +0900 |
| commit | f78a91c20f658dd404277919a0b872b352c99bb6 (patch) | |
| tree | 58cfffb655da4443f4b7a39543b86f988f15239f /packages/core/src/tools/list-files.ts | |
| download | dispatch-main.tar.gz dispatch-main.zip | |
- Bun monorepo with @dispatch/core, @dispatch/api, @dispatch/frontend
- Agent runtime with Vercel AI SDK, streaming via WebSocket
- Tools: read_file, write_file, list_files (scoped to working directory)
- Hono API server with POST /chat, GET /status, GET /health, WS /ws
- Svelte 5 + DaisyUI frontend with chat UI, theme switcher, copy button
- OpenCode Go (Zen) as LLM provider, deepseek-v4-flash-free model
- Docker setup (dev + prod) with bin/ scripts and gopass secrets
- Biome v2 linting/formatting, Vitest tests (44 passing)
- Debug info attached to error messages for diagnostics
Diffstat (limited to 'packages/core/src/tools/list-files.ts')
| -rw-r--r-- | packages/core/src/tools/list-files.ts | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/packages/core/src/tools/list-files.ts b/packages/core/src/tools/list-files.ts new file mode 100644 index 0000000..360ac98 --- /dev/null +++ b/packages/core/src/tools/list-files.ts @@ -0,0 +1,38 @@ +import { readdir } from "node:fs/promises"; +import { join, resolve } from "node:path"; +import { z } from "zod"; +import type { ToolDefinition } from "../types/index.js"; + +export function createListFilesTool(workingDirectory: string): ToolDefinition { + return { + name: "list_files", + description: "List files and directories at a path relative to the working directory.", + parameters: z.object({ + path: z + .string() + .optional() + .describe("Path to list, relative to the working directory. Defaults to '.'"), + }), + execute: async (args: Record<string, unknown>): Promise<string> => { + const relPath = (args.path as string | undefined) ?? "."; + const absolutePath = resolve(join(workingDirectory, relPath)); + const absoluteWorkDir = resolve(workingDirectory); + + if (!absolutePath.startsWith(`${absoluteWorkDir}/`) && absolutePath !== absoluteWorkDir) { + return `Error: Path "${relPath}" is outside the working directory.`; + } + + try { + const entries = await readdir(absolutePath, { withFileTypes: true }); + if (entries.length === 0) { + return "(empty directory)"; + } + return entries + .map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name)) + .join("\n"); + } catch (err) { + return `Error listing files: ${err instanceof Error ? err.message : String(err)}`; + } + }, + }; +} |
