# 发布 SDK

把一个应用从本地开发、到 Developer 测试、再到 Nexus 上线。发布 SDK = `aidc app` 命令 + Developer API；UI（Console）以后也只调同一套 API。

## 应用清单 `aidc.app.json`

```json
{
  "$schema": "https://www.ai-dc.ai/developer/schemas/aidc.app.schema.json",
  "manifestVersion": 1,
  "slug": "defect-inspection",
  "version": "1.0.0",
  "title": "瑕疵检测",
  "summary": "拍一张照片，判断制作工艺有没有污渍、破损",
  "category": "vision",
  "entry": "index.html",
  "sdk": ["vision", "model"],
  "permissions": { "camera": true, "microphone": false },
  "models": ["gpt-6-luna"],
  "datasets": [],
  "streams": [],
  "agents": false,
  "storage": { "type": "none" },
  "limits": { "dailyTokens": 1000000, "requestsPerMinute": 30, "realtimeSessionsPerDay": 100 },
  "cdn": []
}
```

| 字段 | 说明 |
| --- | --- |
| `slug` | 应用标识，出现在 URL 里（小写字母开头，字母 / 数字 / 连字符） |
| `version` | **版本号**（语义化：`1.2.0`，可带 `-rc.1`）。测试与发布都用它称呼这个版本；**改了任何东西就要升**——同一应用里一个版本号只对应一份内容 |
| `namespace` | 缺省 = 开发者 Key 所属公司（`cell-…`）；`public` 是 AIDC 官方公开应用，只有 AIDC 平台账号能发 |
| `permissions` | 要不要摄像头 / 麦克风——平台据此下发 `Permissions-Policy` |
| `models` / `datasets` / `streams` | 应用会调的模型、数据集与会订阅的实时数据流（同一命名空间）；应用票据只放行这里列出的 |
| `agents` | 是否会调智能体（访客自带 Agent Key，见 [连接 SDK](connect.md)） |
| `storage` | 数据存储。Nexus 应用是**无状态**的，目前只有 `none`；需要存记录的应用走数据应用车道 |
| `limits` | 每日 token、每 IP 每分钟请求、每日实时转写场次 |
| `cdn` | 允许加载第三方脚本的 CDN（`cdn.jsdelivr.net`、`cdnjs.cloudflare.com`），写进 CSP |

完整 JSON Schema：[`/developer/schemas/aidc.app.schema.json`](https://www.ai-dc.ai/developer/schemas/aidc.app.schema.json)。

## 版本包

应用目录里除清单、隐藏文件与 `node_modules` 之外的所有文件。限制：≤ 200 个文件、解码后 ≤ 3 MB、只接受网页常用类型（html / css / js / json / svg / png / jpg / webp / gif / woff2 / md / txt …）。包里一律写**相对路径**——平台在入口页注入 `<base>`，同一个包挂在 Developer 和 Nexus 两个地址下都能用。

应用是单页应用：入口 HTML + 资源。多页请用 hash 路由。SDK 从 `/developer/sdk/v1/aidc.js` 引入（绝对路径）。

## 通道

```
aidc app deploy   →  上传版本 v1.2.0（内容寻址）→ test 通道   /developer/…/apps/<slug>
aidc app publish  →  test 上的 v1.2.0 → production 通道        /nexus/…/apps/<slug>
aidc app rollback →  production 切回更早的已测版本（--version 1.1.0）
```

- **内容寻址**：版本的 digest = 包内「路径 + 内容哈希」再加上清单（去掉 `namespace` / `$schema`）的哈希。同样的内容重复部署，返回已有版本、不产生新版本——重试永远安全。
- **版本号一号一内容**：内容（文件或清单）变了但 `version` 没升，部署被拒（409 `version_conflict`）。
- **测过什么发什么**：production 只接受进过 test 的版本；发布不重新打包。
- **不可变资源**：版本资源挂在 `…/apps/<slug>/_v/<digest 前 16 位>/`，长缓存；入口页不缓存、始终指向通道当前版本。
- 所有写操作支持 `--dry-run`（API：`x-aidc-dry-run: true`，返回 202 + 计划）。

## 版本号与更新状态

每个版本有两个编号：**版本号**（清单 `version`，如 `1.2.0`）和**构建序号**（`#3`，第几次上传）。Developer 预览页与 Nexus 正式页都显示版本号（`app().version`；预览页显示「Developer 预览 · v1.2.0」）。

每个版本都有一个**更新状态**，由通道指针和发布记录推出来：

| 状态 | 含义 |
| --- | --- |
| 已上线 `live` | production 当前版本 |
| 测试中 `testing` | test 当前版本（还没上线） |
| 已测未发 `tested` | 进过 test、比线上新，但被更新的测试版替换、没发布过 |
| 已被替换 `superseded` | 比线上版本旧（被新版本替换下线） |
| 已回滚 `rolled_back` | 上过线、后来被回滚到更早的版本 |
| 未测试 `untested` | 上传了还没进过 test（不对外暴露任何文件） |

通道每变一次记一条**发布记录**：谁、何时、哪个通道、动作（进测试 / 发布 / 回滚）、从哪个版本到哪个版本、说明（`--notes`）。`aidc app status` 看版本与状态，`aidc app history` 看发布记录。

## 地址

| | test（Developer） | production（Nexus） |
| --- | --- | --- |
| AIDC 官方公开应用 | `/developer/apps/<slug>` | `/nexus/apps/<slug>` |
| 客户应用 | `/developer/<cellId>/apps/<slug>`（本公司 developer） | `/nexus/<cellId>/apps/<slug>`（本公司成员） |

官方公开应用任何人可以打开。客户应用要求登录且属于该公司；它们跑在 CSP 沙箱里（不透明源），凭平台注入的应用票据调 API。客户应用使用摄像头 / 麦克风需要独立的用户内容域名，正在规划中。

## API

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| `GET` | `/api/v1/developer/me` | 当前开发者 Key 的身份与可写命名空间 |
| `GET` | `/api/v1/developer/apps` | 应用列表 |
| `GET` | `/api/v1/developer/apps/{namespace}/{slug}` | 通道、版本（版本号、构建序号、更新状态）、发布记录、地址 |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/versions` | 上传版本包 `{manifest, files:[{path, encoding, content}], notes?}` |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/channels/{test\|production}` | 晋升 `{version?, notes?}`（version = 版本号 `1.2.0` 或构建序号 `3`），记一条发布记录 |
| `POST` | `/api/v1/developer/apps/{namespace}/{slug}/tickets?channel=` | 应用票据续期（SDK 自动调用） |

鉴权：`Authorization: Bearer aidc-dk-…`（开发者 Key）。完整契约见 [OpenAPI](https://www.ai-dc.ai/developer/openapi.json)。

## 命令

```bash
aidc app init <slug> --template camera|voice|data|blank
aidc app check [目录]
aidc app dev [目录] --port 5173
aidc app deploy [目录] --notes "修复框选偏移" [--dry-run]     # 版本号取清单 version
aidc app publish <slug|目录> [--version 1.2.0] [--notes "…"] [--dry-run]
aidc app rollback <slug> --version 1.1.0 --notes "回退：…"
aidc app status <slug>                                           # 版本号 / 构建序号 / 更新状态
aidc app history <slug>                                          # 发布记录
aidc app list
```
