# 审阅评论与分享链接

钉在视频某个时间点或画面某个区域的意见、回复和解决；给没有账号的人用的审阅链接；以及 AI agent 怎么参与。

评论者及以上的成员可以在文件上留评论。视频和音频的评论可以钉在某个时间点（`at_ms`，毫秒）或一段时间（`until_ms`）；图片和画面可以圈一个区域（`x`、`y`、`w`、`h`，按画面比例 0 到 1）。回复只有一层：回复的回复会并进同一个讨论。

## 读和写

| 要做的事 | 调用 |
|---|---|
| 文件的所有讨论，按时间码排序，带回复 | `GET /v1/spaces/{sid}/nodes/{nid}/comments`（`?resolved=1` 包括已解决的） |
| 评论或回复 | `POST /v1/spaces/{sid}/nodes/{nid}/comments` |
| 修改、解决或重新打开 | `PATCH /v1/spaces/{sid}/comments/{cid}`，带 `body` 或 `resolved` |
| 删除 | `DELETE /v1/spaces/{sid}/comments/{cid}` |

```sh tab=curl
curl -X POST "https://side.example.com/v1/spaces/$SPACE/nodes/$NODE/comments" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
  -d '{"body": "这句台词下面音乐太响", "at_ms": 83500, "region": {"x": 0.1, "y": 0.6, "w": 0.3, "h": 0.2}}'
```

```ts tab=TypeScript
for (const c of await side.comments("Film A", "/Ep01/cut.mp4")) console.log(c.at_ms, c.body, c.replies?.length);
const note = await side.addComment("Film A", "/Ep01/cut.mp4", { body: "音乐太响", at_ms: 83_500 });
await side.resolveComment("Film A", note.id);
```

```python tab=Python
for c in side.comments("Film A", "/Ep01/cut.mp4"):
    print(c["at_ms"], c["body"], len(c.get("replies", [])))
note = side.add_comment("Film A", "/Ep01/cut.mp4", "音乐太响", at_ms=83_500)
side.resolve_comment("Film A", note["id"])
```

```sh tab=CLI
sidespace comments "Film A" Ep01/cut.mp4                       # 未解决的讨论，按时间码排
sidespace comments "Film A" Ep01/cut.mp4 --add "音乐太响" --at 1:23.5
sidespace comments "Film A" Ep01/cut.mp4 --resolve cmt_…
```

- 令牌需要 `comments:write` 才能写。
- 改文字只能作者；解决或重新打开是作者或编辑者；删除是作者或管理员。
- 评论会记下当时屏幕上的版本（`version_id`），所以第 4 版传上来之后，第 3 版上的意见仍然看得懂。
- 保存这个版本的人、被回复的人会收到通知。

## 审阅链接

把文件或文件夹分享给没有账号的人。加上 `--comments`（`can_comment: true`）后，对方填个名字就能在分享页上评论：输入时视频自动暂停，评论钉在当前时间点，进度条下方有每条评论的标记。

```sh
sidespace share "Film A" Ep01/cut.mp4 --comments
sidespace share "Film A" Ep01/Deliveries --upload --password "…"   # 对方可以往这个文件夹里上传
sidespace shares "Film A"                                          # 空间里所有链接
sidespace shares "Film A" --revoke shr_…
```

用 API：`POST /v1/spaces/{sid}/shares`，带 `node_id`、`mode`（`view`、`upload` 或 `request`）、`can_comment`、`password` 和 `expires_at`（网页版提供 1、7、30 天）。返回里有链接的 `url`。令牌需要 `shares:manage`。每个分享的 `uploads` 是通过它收到的文件数。

## 收集文件

向没有账号的人要文件（外拍素材、配音、客户的参考图），做一个收集文件链接。网页版在文件夹的菜单里选“收集文件…”。

```sh
sidespace share "Film A" Ep03/素材 --request "第三集素材" --message "MOV 或 MP4，每个机位一个文件夹" --days 7
sidespace shares "Film A"          # 每个链接收到了几个文件
```

- 打开链接的人只看到标题、说明、谁在要和截止时间，看不到文件夹里已有的东西，也打不开里面的文件。
- 发送前要填名字（邮箱可选）。每个人的文件放在以他名字命名的子文件夹里，比如 `Ep03/素材/Mia Chen/a.mov`；同名文件自动改名，不会覆盖，每个文件的版本记在发送人名下。
- 页面逐个文件上传并显示进度，可以拖文件进来；某个文件失败只需重发那一个。
- 每收到一个文件你都会收到通知，带发送人的名字、邮箱和请求标题。
- 到截止时间（`expires_at`）或撤销后，链接不再收文件。可以加密码。
- 用 API 时，`mode: "request"` 必须带 `title`（最多 200 字），可选 `message`（最多 4000 字）。MCP 工具 `request_files` 做同样的事，文件夹不存在会先建好。

## 给 AI agent

MCP 工具 `list_comments`、`add_comment`、`resolve_comment` 让 agent 读审阅意见、回复，改完后标记为已解决。Webhook 事件 `comment.created` 和 `comment.updated` 带有评论内容，所以机器人可以在评论写下的那一刻接手。
