
Refly CLI 文件命令完全解析refly file 的 list、get、download、upload 实操与实现原理【免费下载链接】reflyThe first open-source agent skills builder. Define skills by vibe workflow, run on Claude Code, Cursor, Codex more. Build Clawdbot · APIs for Lovable · Bots for Slack Lark/Feishu · Skills are infrastructure, not prompts.项目地址: https://gitcode.com/GitHub_Trending/re/refly在 Refly 开源项目中refly/cli是让 Agent如 Claude Code、Cursor通过命令行编排后端工作流的入口而refly file命令组正是 Agent 获取和回传工作流产出物图片、文档、报表等的关键通道。本文以 File Reference 文档 为骨架结合 file 命令组源码 与后端 Drive CLI 控制器逐一拆解refly file list / get / download / upload四个子命令的完整参数、底层实现链路、鉴权与错误处理机制读完即可在自己的脚本或 Skill 中安全地拉取和上传 Refly Drive 文件。1. 文件命令组的定位Agent 与 Drive 之间的桥梁refly file是 File Reference 参考文档 所描述的命令集合在 CLI 中注册为一个独立的命令组。从 入口定义 可以看到它聚合了四个子命令export const fileCommand new Command(file) .description(Manage files and documents) .addCommand(fileListCommand) .addCommand(fileGetCommand) .addCommand(fileDownloadCommand) .addCommand(fileUploadCommand);这四个子命令分别对应refly file list—— 分页列出 Drive 中的文件支持按画布/执行结果过滤refly file get—— 查询单个文件的元数据可选返回文件内容refly file download—— 将文件下载为本地文件二进制流refly file upload—— 将本地文件或目录批量上传到指定画布canvas。Refly CLI 遵循 JSON-First 设计所有命令输出统一的结构化 JSONAgent 只需信任ok、payload、error、hint字段即可完成自动化决策。这一约定见 SKILL.md 基础规则也是 File Reference 中Trust CLI JSON理念的基础。File Reference 文档还给出了文件命令的使用语境文件 ID 通常来自action results见 Node Reference或workflow outputs见 Workflow Reference推荐用--result-id或--canvas-id把文件列表收敛到某次具体的运行上下文中。2.refly file list分页列出文件并支持上下文档位过滤File Reference 中给出的用法# List files refly file list [options] --page n # Page number (default: 1) --page-size n # Files per page (default: 20) --canvas-id id # Filter by canvas ID --result-id id # Filter by action result ID --include-content # Include file content in response对照 list 命令源码参数定义与默认值完全一致export const fileListCommand new Command(list) .description(List files) .option(--page n, Page number (default: 1), 1) .option(--page-size n, Number of files per page (default: 20), 20) .option(--canvas-id id, Filter by canvas ID) .option(--result-id id, Filter by action result ID) .option(--include-content, Include file content in response)实现上有两个值得注意的细节查询参数拼装page、pageSize必发canvasId、resultId、includeContent值为true按需追加最终请求/v1/cli/drive/files?${params}list.ts 第 35-49 行。后端默认值兜底服务端在 DriveCliController.listFiles 中对查询参数做了parseInt并回退默认值page回退 1、pageSize回退 20includeContent仅当字面量true时生效。这意味着即使 CLI 侧传参异常后端也能保证分页语义稳定。响应结构由 CLI 侧的ListFilesResponse类型声明list.ts 第 19-24 行interface ListFilesResponse { files: FileInfo[]; // fileId / name / type / size? / createdAt / updatedAt total: number; page: number; pageSize: number; }成功时 CLI 输出ok(file.list, ...)并原样透出total/page/pageSize/files字段失败时走统一的错误通道见第 7 节。实践提示当一次工作流运行产生多个文件时先用refly file list --canvas-id c-xxx拿到该画布下所有fileId再结合--result-id ar-xxx精确到某一次 action 结果比盲目翻页效率高得多。3.refly file get查询文件详情控制是否返回内容File Reference 中的定义# Get file details refly file get fileId [options] --no-content # Exclude file contentget 命令源码 中有一个容易踩坑的 Commander 语义--no-content是反向开关默认行为是包含内容.option(--no-content, Exclude file content from response) .action(async (fileId, options) { const includeContent options.content ! false; const result await apiRequestFileInfo( /v1/cli/drive/files/${fileId}?includeContent${includeContent}, );也就是说refly file get fileId→ 请求带includeContenttrue返回含content字段的完整信息refly file get fileId --no-content→ 请求带includeContentfalse响应中content被省略。这与后端 DriveCliController.getFile 的默认值一致——服务端同样以includeContent查询参数是否为true决定返回内容。对于只需要元数据名称、类型、大小、时间戳的场景加上--no-content可以显著减小 JSON 体积在 Agent 多轮调用时节省 token。get返回的FileInfo类型get.ts 第 10-18 行在 list 的基础上多了可选的content?: string字段。4.refly file download流式下载与默认文件名的来源File Reference 给出的用法# Download file refly file download fileId [options] -o, --output path # Output path (defaults to original filename)defaults to original filename 这句承诺背后有一条完整的实现链路值得展开后端以附件流返回DriveCliController.downloadFile 调用driveService.getDriveFileStream后设置了四个关键响应头再发送二进制数据res.setHeader(Content-Type, contentType || application/octet-stream); res.setHeader(Content-Disposition, attachment; filename${encodeURIComponent(filename)}); res.setHeader(Content-Length, data.length.toString()); res.setHeader(Last-Modified, lastModified.toUTCString());CLI 侧用流式请求解析apiRequestStream 与普通apiRequest共用同一套 OAuth / API Key 鉴权逻辑但默认超时放宽到5 分钟普通 JSON 请求为 30 秒并会从Content-Disposition头中解析原始文件名。它同时兼容filenamename.ext与 RFC 5987 的filename*UTF-8name.ext两种写法并对解析结果做decodeURIComponentconst match contentDisposition.match(/filename\*?(?:UTF-8)?[]?([^;\n])[]?/i); if (match) { filename decodeURIComponent(match[1]); }落地写入download 命令 按优先级确定落盘路径-o/--output指定路径 响应头中的原始文件名 fileId本身最终通过path.resolve转为绝对路径并用fs.writeFileSync写入成功后输出ok(file.download, { fileId, path, filename, contentType, size })。这条链路意味着不指定-o时中文文件名也能被正确还原后端encodeURIComponent 前端decodeURIComponent的对称处理而在脚本中批量下载时用-o显式指定路径可以完全绕过响应头依赖行为更确定。SKILL.md 中的 Pattern A: File Generation Skills 就示范了典型用法——工作流跑完后遍历工具调用产出的文件列表逐个执行refly file download $FILE_ID -o $HOME/Desktop/${FILE_NAME}并打开这正是图片/视频/音频生成类技能的标准收尾动作。5.refly file upload预签名三步上传流程与目录过滤File Reference 中的定义# Upload file(s) refly file upload path [options] --canvas-id id # Canvas ID (required) --filter ext # Filter by extensions (e.g., pdf,docx,png)path可以是单个文件也可以是目录--canvas-id为必填项。其实现分为本地文件解析与上传协议两层。5.1 本地文件解析过滤、排序与数量上限upload 命令源码 中定义了MAX_FILES 10并通过 resolveFilesToUpload 处理两种输入单文件若给了--filter则检查扩展名不含点、转小写是否在白名单中不匹配直接返回空列表最终以NOT_FOUND错误退出并提示 No files matching filter目录读取目录下第一层的文件不递归子目录先剔除非文件条目再按--filter过滤然后按文件大小升序排序小文件优先上传快速出结果最后截取前 10 个。5.2 上传协议presign → PUT → confirmapiUploadDriveFile 注释明确写道 3-step process: presign - PUT to OSS - confirm对应后端两个端点DriveCliController步骤请求说明1. presignPOST /v1/cli/drive/file/upload/presign提交canvasId / filename / size / contentType返回uploadId、presignedUrl、expiresIn2. PUT 存储PUT presignedUrl文件字节直传对象存储带Content-Type与Content-Length超时 5 分钟网络错误自动重试 1 次uploadToPresignedUrl3. confirmPOST /v1/cli/drive/file/upload/confirm提交uploadId返回最终DriveFileUploadResultfileId / name / type / size / storageKey / url?MIME 类型由mime包按扩展名推断未知类型回退application/octet-streamgetMimeType。5.3 顺序上传、进度展示与部分失败语义多文件顺序串行上传pretty 输出模式下逐阶段刷新进度Getting upload URL...→Uploading name (size)...→Confirming upload...upload.ts 第 68-89 行单个文件失败不会中断整批错误被收集进errors数组批次结束后若results.length 0则以INTERNAL_ERROR退出并附每个文件的错误明细否则输出Uploaded X of Y file(s)的部分成功摘要upload.ts 第 121-148 行。因此在脚本中判断上传结果时应检查 JSON 中payload.uploaded与payload.failed两个计数而不是只看进程退出码。6. 鉴权机制OAuth 与 API Key 双通道所有 file 子命令的 API 调用都经由 apiRequest / apiRequestStream 发起两者复用同一套鉴权逻辑由getAuthMethod()决定走哪条通道API Key 模式请求头携带X-API-Key: apiKeyOAuth 模式默认请求头携带Authorization: Bearer accessToken若本地 token 已过期会先调用POST /v1/auth/cli/oauth/refresh用 refresh token 换新 token 并持久化refreshAccessToken刷新失败则抛出Session expired, please login again。后端侧对应地整个v1/cli/drive路由都挂载了JwtAuthGuardDriveCliController 类定义并从中提取登录用户作为数据隔离依据——文件列表、详情、下载、上传均只对当前用户自己的 Drive 数据可见。使用前提先完成npm install -g refly/cli与refly login见 CLI README可用refly status验证连接与认证状态。7. 统一输出契约与错误处理让 Agent 可机读File Reference 面向的读者不仅是人更是执行 SKILL.md 规则的 Agent因此输出契约值得单独说明。所有 file 子命令成功时调用ok(type, payload)、失败时调用fail(code, message, ...)这两者定义在 output.ts成功格式{ ok: true, type: file.list | file.get | file.download | file.upload, version: 1.0, payload: {...} }退出码 0错误格式{ ok: false, type: error, error: { code, message, details?, hint?, suggestedFix?, recoverable? } }其中recoverable标记该错误是否可通过调整参数重试同一命令如INVALID_INPUT、TIMEOUT、RATE_LIMIT属可恢复见 isRecoverableError。错误码到退出码的映射getExitCode错误类别退出码认证类AUTH_*2参数校验VALIDATION_*/INVALID_INPUT3网络 / 超时NETWORK_*/TIMEOUT4未找到*_NOT_FOUND/NOT_FOUND5其他1服务端 HTTP 状态还会被 mapAPIError 细化映射401/403 →AuthError404 →NOT_FOUNDhint: Check the resource ID409 →CONFLICT422 →INVALID_INPUT5xx →API_ERROR。这对脚本化很有价值refly file get拿错 ID 会得到退出码 5与网络不通退出码 4在自动化分支中可以明确区分。8. 与工作流的协作fileId 从哪里来回到 File Reference 的 Interaction 一节完整的取文件闭环是运行技能/工作流refly skill run --id installationId --input json返回RUN_IDwe-xxx前缀等待完成refly workflow status runId --watch拿到文件列表refly workflow toolcalls runId --files --latest直接返回最近一次工具调用的files数组含fileIddf-xxx前缀下载refly file download fileId -o path回传输入反向流程则用refly file upload path --canvas-id c-xxx把本地材料挂到画布供后续工作流节点引用。各类 ID 的前缀约定在 SKILL.md 的 ID Types 表 中有明确登记df-xxx专用于file downloadwe-xxx用于 workflow 命令c-xxx仅出现在浏览器 URL 中——这也是 File Reference 强调不要伪造 IDNo fabricated IDs的原因所有 ID 都应从 CLI JSON 输出中提取。9. 速查小结命令关键参数底层端点适用场景refly file list--page、--page-size、--canvas-id、--result-id、--include-contentGET /v1/cli/drive/files盘点画布/某次运行产出的文件refly file get fileId--no-content默认含内容GET /v1/cli/drive/files/:fileId读取文本类文件内容或仅取元数据refly file download fileId-o, --output默认原始文件名GET /v1/cli/drive/files/:fileId/download把二进制产物落到本地refly file upload path--canvas-id必填、--filterPOST .../file/upload/presign→PUT→POST .../file/upload/confirm上传单文件或目录≤10 个小文件优先以上全部内容均可在当前仓库中追溯验证命令参考见 file.md命令实现见 packages/cli/src/commands/file/客户端传输逻辑见 packages/cli/src/api/client.ts服务端路由见 apps/api/src/modules/drive/drive-cli.controller.ts。掌握了这四个命令及其 JSON 契约就能在任意 Agent 环境中稳定地完成 Refly 工作流产出文件 → 拉取到本地 → 输入文件 → 回传到画布的双向文件交换。【免费下载链接】reflyThe first open-source agent skills builder. Define skills by vibe workflow, run on Claude Code, Cursor, Codex more. Build Clawdbot · APIs for Lovable · Bots for Slack Lark/Feishu · Skills are infrastructure, not prompts.项目地址: https://gitcode.com/GitHub_Trending/re/refly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考