FDE 开发者接入

PROJECT IMPORT / API + DOCUMENTATION

把 URL 交给 WorkBuddy,
项目自动整理成草稿。

无需手填应用元信息。你选择项目并确认首次授权,WorkBuddy 上传必要源码;FDE 自动推断资料,你再检查与编辑。

上传成功不等于上架成功。不会自动运行、部署、付费审核或公开发布。

1. 复制引导语给 WorkBuddy

在 WorkBuddy 中选择且明确授权一个应用项目。本页 URL 使用当前 FDE 服务的同源地址,不附带授权凭据。

2. 在 FDE 确认首次授权

WorkBuddy 请求授权后会给你短 user_code。请核对它来自你刚发起的操作,再在此输入。不要批准陌生人发来的授权码。

本次仅允许向你的账户成功上传一个私有草稿,权限为 apps:upload,不包含覆盖文件、管理账户、审核或发布。此页面不会读取或上传你的磁盘。

正在检查登录身份…

前往 /#workspace 登录开发者账户,登录后返回

仅已登录 developer 可批准;不开放管理员注册或管理员公共授权。授权码在 600 秒后过期,过期请让 WorkBuddy 重新发起。

3. 上传后检查资料

WorkBuddy 应返回应用 ID、缺失字段、上传文件数及编辑链接 /#workspace。打开工作台,在已有草稿点击“编辑资料”,修订名称、简介、行业、场景、定价和运行入口。

metadata_status.missing_fields 表示待确认项,metadata_status.inferred_fields 表示自动推断项。need_confirm_pricing: true 时,即使兼容字段为 free 也不代表免费;不得替开发者擅自确认定价。

进入工作台编辑草稿

4. 提交审核与上架

流程:草稿 → 提交审核 → 平台审核 → 已上架。上传和编辑都不会自动提交审核;提交须由开发者本人在工作台点击“成本预估 / 提交”并确认。

WorkBuddy / Agent 不得代替开发者提交审核、确认定价或下架。

给 WorkBuddy / Agent 的完整执行约定

  1. 读取本页公开说明不构成上传许可。先确定用户明确授权的项目根目录、必要源码范围与目的地;若不明确,先问用户。展示拟上传相对路径及排除类别,不得偷偷上传或扫描整个磁盘、主目录、工作区内其他项目。
  2. 仅在选定项目范围内收集必要 UTF-8 源码和配置,例如 package.json、index.html 与必要业务源码。先按路径排除敏感文件,再对候选内容做凭据检查。遇到疑似秘密或私人数据应停下并让用户处理,不修改原文件、不自动删除或替换项目内容。
  3. 必须排除所有 .env*(包括示例环境文件)、密钥/证书/凭据、.git、.ssh、云账户目录、.npmrc、node_modules、虚拟环境、构建产物、缓存、日志、数据库、备份、无关文件及二进制内容。不要读取排除目录来“检查”。不要跟随符号链接越出授权范围,仅允许名单内的图片、字体、音视频与 PDF 资源经分批会话以 base64 上传;不得把压缩包、可执行文件或其他二进制改扩展名或转 Base64 绕过限制。
  4. 机器调用 POST /api/publish/device/start {};只把返回的短 user_code 和同源 verification_uri 交给用户。开发者本人在 FDE 页面登录并点击确认。Agent 不读取浏览器 Cookie、密码,不替用户调用 approve。
  5. 按返回的 interval(5 秒)调用 token,最多等到授权过期。仅 409 authorization_pending 继续等待;429 slow_down 降低频率,授权过期或拒绝则停止。不得暴力重试或自动代替用户确认。
  6. 取得上传 token 后只在内存中暂存,用 Bearer 发到当前 FDE 服务的 import。不得放进 URL、HTML 元数据、聊天回复、日志、源文件、浏览器存储或发给其他站点。不得携带 session 或模型 API Key 代替上传 token。非本机部署必须先确认 HTTPS 服务可用,不能经不受信任网络发送源码。
  7. 文件不超过 100 个、合计不超过 4 MiB 且全为文本时用 import;否则用分批会话:先 sessions,再按每批 ≤200 个、请求体 ≤8 MiB 分批 files,最后以本地文件总数 complete。提交必要文件,metadata 整体及每个字段均可省略;不要求开发者填写表单,不填猜测价格。服务端依据项目材料生成可推断的资料;不确定字段保持待确认。
  8. 只在成功响应后报告“已保存私有草稿”,显示缺失字段、上传摘要和同源编辑链接;编辑链接必须解析到当前 FDE origin。请求失败或结果不确定不得声称上传成功,不调用 estimate、submit、审核、支付或发布接口。

代码只私有保存,不自动执行或公开,不覆盖已有本地文件。源码及上传摘要不是部署结果,也不是认证或上架证明。

真实 API 合同

以下相对路径均解析到本页所在 FDE origin。所有 POST / PATCH 请求使用 Content-Type: application/json;响应统一封装为 {"ok":true,"data":…},失败为 {"ok":false,"error":"…","error_code":"…"}(error_code 仅部分错误包含)。以 HTTP 状态和 ok 同时判断,不能直接把封装体当业务数据。

方法与路径身份与请求体data 返回 / 状态
POST /api/publish/device/start机器,无 session。{}device_code, user_code, expires_in:600, verification_uri:"/publish.html", interval:5
POST /api/publish/device/approvedeveloper 登录 session + 同源 CSRF 校验。{user_code}{approved:true, scope:"apps:upload"};不返回上传 token。
POST /api/publish/device/token机器,无 session。{device_code}approved 后仅兑换一次:access_token, expires_in:900, scope:"apps:upload", token_type:"Bearer"。未确认:HTTP 409 + error_code:"authorization_pending";过快:429 slow_down;无效/过期/已兑换:401 invalid_grant。
POST /api/publish/importAuthorization: Bearer <access_token>
{idempotency_key,files:[{path,content}],metadata?}
{app,inferred_fields,missing_fields,edit_url:"/#workspace",upload:{files,bytes,sha256},status:"draft",notice}
POST /api/publish/sessionsAuthorization: Bearer <access_token>
{idempotency_key,metadata?}
大型项目或含图片/字体等资源时使用。{session_id,status:"open",files,bytes,expires_in:3600,limits}。同一 token 只能二选一:单次 import 或一个会话。
POST /api/publish/sessions/:session_id/files同一 Bearer。{files:[{path,content,encoding?}]},每批 1–200 个;encoding 为 utf-8(默认)或 base64。{accepted,skipped,files,bytes}。同路径同内容重传计入 skipped;同路径不同内容 409,不覆盖。
POST /api/publish/sessions/:session_id/complete同一 Bearer。{expected_files} 为本地清单总数。与 import 相同的草稿结果,另含 session_id 和 upload.binary_files。数量不一致:409 file_count_mismatch。重复 complete 返回同一结果。
GET /api/publish/grants
POST /api/publish/grants/:id/revoke
developer 登录 session;revoke 需同源 Origin,请求体 {}。开发者在工作台查看与撤销授权;授权码打码显示。撤销会丢弃未完成会话,保留已生成草稿。Agent 不调用。
GET /api/apps/:id/files本人 session(或管理员)。文件清单:path、kind(text/binary)、bytes、sha256;不返回内容。
GET /api/apps/:id/reviews本人 session(或管理员)。当前状态、资料完整性检查 check,以及审核记录(提交、驳回、通过、撤回、下架及理由)。
POST /api/apps/:id/submit本人 developer session;{"confirmed_estimate":true}。资料须完整。平台有在线隔离测试执行器时:{app,test},应用进入 submitted、测试 queued;测试通过转为 pending_review 等待平台审核,未通过转为 review_blocked 并发站内通知(含未通过的检查项)。无在线执行器时:HTTP 503,状态 review_blocked,未执行、未扣费。已在队列中重复提交:409。
POST /api/apps/:id/withdraw本人 developer session;请求体 {}。审核中或受阻时撤回为草稿;其他状态 409。
POST /api/apps/:id/unpublish本人 developer 或管理员 session;{"reason":"…"}。仅已上架应用;下架为 unpublished,退出公开目录,证书保留。
GET /api/notifications登录 session;可选 before(上一页 next_before)、limit(1-50,默认 20)、unread=1。本人站内通知(按时间倒序分页)及未读数;平台审核通过、驳回、平台下架时通知开发者;开发者提交审核时通知管理员(撤回或审核后自动标为已处理),其余自身操作不产生通知。
POST /api/notifications/read登录 session;{"all":true} 或 {"ids":[…]}(1-100 个)。只能标记本人通知;返回最新列表。
PATCH /api/apps/:id本人应用、登录 session + 同源 CSRF 校验;请求体为已修改的 metadata 字段,非 metadata 包装对象。data 为更新后的 app,含 metadata_status;仅已有草稿、审核阻断或拒绝状态可编辑;不会上传源码。

CSRF 与部署边界

浏览器使用 credentials:'same-origin' 携带 HttpOnly session,由浏览器自动发送 Origin。后端当前以同源 Origin 与 Fetch Metadata 校验防 CSRF,没有独立 CSRF token 接口;不要编造 X-CSRF-Token。机器免 session 的路径仅为 start、token、import,不能把此豁免用于 approve 或 PATCH。

当前本地实现按 http://Host 核对浏览器 Origin;HTTPS 反向代理部署需先完成服务端适配。本指南不承诺代理部署已经可用。

文件约束与幂等

metadata 与推断

可省略的字段:name, summary, industry, scene, pricing, price_cents, entry_url。name 最多120字符,summary 最多4000字符,industry 为有效三级行业路径,scene 为有效场景,pricing 为 free / paid / iap(空表示待确认),price_cents 为 0 至 10^12 的整数,entry_url 为校验通过的 HTTPS 公网入口。免费价格须为0,付费须大于0。

当前推断主要读取根目录 package.json 的 name / description / homepage,以及 index.html 的 title;行业场景只在名称与简介中唯一匹配时推断。不是任意源码语义都能识别,未知值标待确认,定价不能擅自确认。

JSON 请求结构示例(不是自动执行命令)

{
  "idempotency_key": "authorized-project-draft-001",
  "files": [
    {"path": "package.json", "content": "{\"name\":\"my-app\",\"description\":\"应用说明\"}"},
    {"path": "index.html", "content": "<!doctype html><title>我的应用</title>"}
  ]
}

示例仅解释协议,实际 files 必须来自用户授权项目的必要源码,不上传本示例冒充真实项目。全部元信息可省略,由服务端推断。