diff --git a/space-functions/list-dir.mjs b/space-functions/list-dir.mjs new file mode 100644 index 0000000..274a970 --- /dev/null +++ b/space-functions/list-dir.mjs @@ -0,0 +1,49 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +export const spec = { + name: 'list-dir', + description: 'List items in a directory. Takes a path argument and returns a list of strings representing the items in that directory.', + parameters: { + type: 'object', + properties: { + path: { + type: 'string', + description: 'Directory path relative to the space directory' + } + }, + required: ['path'] + } +}; + +function resolveIn(base, relPath) { + const resolved = path.resolve(base, relPath); + if (resolved !== base && !resolved.startsWith(base + path.sep)) { + throw new Error('Path escapes the space directory'); + } + return resolved; +} + +export default async function (args, ctx) { + const dirPath = resolveIn(ctx.dir, args.path); + + // Check if path exists and is a directory + if (!fs.existsSync(dirPath)) { + throw new Error(`Directory not found: ${args.path}`); + } + + if (!fs.statSync(dirPath).isDirectory()) { + throw new Error(`Path is not a directory: ${args.path}`); + } + + // Read directory and format paths with trailing slash for directories + const items = []; + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + + for (const entry of entries) { + const relPath = args.path ? `${args.path}/${entry.name}` : entry.name; + items.push(entry.isDirectory() ? `${relPath}/` : relPath); + } + + return { items }; +} diff --git a/space-functions/list-files.mjs b/space-functions/list-files.mjs deleted file mode 100644 index a134fc3..0000000 --- a/space-functions/list-files.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -export const spec = { - name: 'list-files', - description: 'List every file in the space, as paths relative to the space directory.', - parameters: { type: 'object', properties: {} }, -}; - -export default async function (args, ctx) { - const files = []; - const walk = (dir, prefix) => { - for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { - const rel = prefix ? `${prefix}/${entry.name}` : entry.name; - if (entry.isDirectory()) walk(path.join(dir, entry.name), rel); - else files.push(rel); - } - }; - walk(ctx.dir, ''); - return { files }; -} \ No newline at end of file diff --git a/space-functions/create-function.mjs b/templates/center/create-function.mjs similarity index 100% rename from space-functions/create-function.mjs rename to templates/center/create-function.mjs diff --git a/space-functions/delete-function.mjs b/templates/center/delete-function.mjs similarity index 100% rename from space-functions/delete-function.mjs rename to templates/center/delete-function.mjs