files.list
Schema
Input = { path?: string, // directory relative to the workspace root; '' = root recursive?: boolean, // default false maxEntries?: number, // 1-5000, default 500 includeHidden?: boolean, // default false}
Output = { root: 'project' | 'uploads', path: string, entries: Array<{ path: string, name: string, ext: string, size: number, mtime: string, isDir: boolean }>, truncated: boolean,}Which root it lists
Every file skill shares the same root resolution (skillRoot(ctx), packages/skills/src/util/paths.ts):
inside a Studio project, it’s workspace/projects/<projectId>/; outside one (e.g. Muse calling
files.search), it’s workspace/uploads/<beingId>/. Paths in every input/output are always relative
to that root, forward-slash separated, and traversal outside it is refused — see
Environment variables on WORKSPACE_DIR.
Directories are listed depth-first, folders before files, alphabetically; the usual build/VCS noise
(node_modules, .git, dist, .cache, __pycache__, dotfiles by default) is skipped
automatically.
Example
curl -s -X POST http://localhost:4000/api/studio/skills/invoke \ -H 'content-type: application/json' -b cookies.txt \ -d '{"name":"files.list","input":{"path":"","recursive":true}}'{ "ok": true, "output": { "root": "uploads", "path": "", "entries": [ { "path": "logo.png", "name": "logo.png", "ext": "png", "size": 48213, "mtime": "2026-09-06T09:10:00.000Z", "isDir": false } ], "truncated": false }}