@agentunion/fastaun-browser 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/_packed_docs/CHANGELOG-validators.md +144 -0
  3. package/_packed_docs/CHANGELOG.md +56 -0
  4. package/_packed_docs/INDEX.md +198 -181
  5. package/_packed_docs/KITE_DOCS_GUIDE.md +26 -23
  6. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +4 -3
  7. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
  8. package/_packed_docs/protocol/08-AUN-E2EE-Group.md +296 -902
  9. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +64 -114
  10. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +7 -1
  11. package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -0
  12. package/_packed_docs/protocol/README.md +2 -1
  13. package/_packed_docs/protocol/index.md +8 -3
  14. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +4 -252
  15. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +483 -457
  16. package/_packed_docs/sdk/09-collab-rpc-manual.md +581 -550
  17. package/_packed_docs/sdk/09-group-rpc-manual.md +248 -335
  18. package/_packed_docs/sdk/09-storage-rpc-manual.md +56 -19
  19. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -13
  20. package/_packed_docs/sdk/INDEX.md +14 -14
  21. package/dist/bundle.js +1560 -1159
  22. package/dist/client/delivery.d.ts +13 -2
  23. package/dist/client/delivery.d.ts.map +1 -1
  24. package/dist/client/delivery.js +251 -46
  25. package/dist/client/delivery.js.map +1 -1
  26. package/dist/client/group-state.d.ts.map +1 -1
  27. package/dist/client/group-state.js +36 -14
  28. package/dist/client/group-state.js.map +1 -1
  29. package/dist/client/lifecycle.js +2 -2
  30. package/dist/client/lifecycle.js.map +1 -1
  31. package/dist/client/rpc-pipeline.d.ts +1 -0
  32. package/dist/client/rpc-pipeline.d.ts.map +1 -1
  33. package/dist/client/rpc-pipeline.js +166 -50
  34. package/dist/client/rpc-pipeline.js.map +1 -1
  35. package/dist/client/v2-e2ee.d.ts +14 -1
  36. package/dist/client/v2-e2ee.d.ts.map +1 -1
  37. package/dist/client/v2-e2ee.js +300 -121
  38. package/dist/client/v2-e2ee.js.map +1 -1
  39. package/dist/client.d.ts +5 -4
  40. package/dist/client.d.ts.map +1 -1
  41. package/dist/client.js +187 -46
  42. package/dist/client.js.map +1 -1
  43. package/dist/collab/client.d.ts +8 -0
  44. package/dist/collab/client.d.ts.map +1 -1
  45. package/dist/collab/client.js +12 -0
  46. package/dist/collab/client.js.map +1 -1
  47. package/dist/errors.d.ts +0 -20
  48. package/dist/errors.d.ts.map +1 -1
  49. package/dist/errors.js +8 -51
  50. package/dist/errors.js.map +1 -1
  51. package/dist/facades.d.ts +9 -4
  52. package/dist/facades.d.ts.map +1 -1
  53. package/dist/facades.js +192 -31
  54. package/dist/facades.js.map +1 -1
  55. package/dist/group-fs.d.ts +17 -0
  56. package/dist/group-fs.d.ts.map +1 -1
  57. package/dist/group-fs.js +54 -11
  58. package/dist/group-fs.js.map +1 -1
  59. package/dist/group-id.d.ts +9 -12
  60. package/dist/group-id.d.ts.map +1 -1
  61. package/dist/group-id.js +41 -63
  62. package/dist/group-id.js.map +1 -1
  63. package/dist/index.d.ts +4 -2
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +4 -1
  66. package/dist/index.js.map +1 -1
  67. package/dist/keystore/index.d.ts +2 -54
  68. package/dist/keystore/index.d.ts.map +1 -1
  69. package/dist/keystore/indexeddb-identity-store.d.ts +3 -0
  70. package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
  71. package/dist/keystore/indexeddb-identity-store.js +65 -0
  72. package/dist/keystore/indexeddb-identity-store.js.map +1 -1
  73. package/dist/keystore/indexeddb-shared.d.ts +3 -17
  74. package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
  75. package/dist/keystore/indexeddb-shared.js +4 -47
  76. package/dist/keystore/indexeddb-shared.js.map +1 -1
  77. package/dist/keystore/indexeddb-token-store.d.ts +1 -64
  78. package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
  79. package/dist/keystore/indexeddb-token-store.js +45 -774
  80. package/dist/keystore/indexeddb-token-store.js.map +1 -1
  81. package/dist/logger.d.ts +2 -0
  82. package/dist/logger.d.ts.map +1 -1
  83. package/dist/logger.js +4 -0
  84. package/dist/logger.js.map +1 -1
  85. package/dist/storage/lowlevel.d.ts +9 -1
  86. package/dist/storage/lowlevel.d.ts.map +1 -1
  87. package/dist/storage/lowlevel.js +12 -1
  88. package/dist/storage/lowlevel.js.map +1 -1
  89. package/dist/storage/vfs.d.ts +22 -0
  90. package/dist/storage/vfs.d.ts.map +1 -1
  91. package/dist/storage/vfs.js +54 -0
  92. package/dist/storage/vfs.js.map +1 -1
  93. package/dist/tools/cross-sdk-agent.js +336 -49
  94. package/dist/tools/cross-sdk-agent.js.map +1 -1
  95. package/dist/transport.d.ts +2 -0
  96. package/dist/transport.d.ts.map +1 -1
  97. package/dist/transport.js +96 -3
  98. package/dist/transport.js.map +1 -1
  99. package/dist/types.d.ts +39 -56
  100. package/dist/types.d.ts.map +1 -1
  101. package/dist/v2/session/session.d.ts +2 -0
  102. package/dist/v2/session/session.d.ts.map +1 -1
  103. package/dist/v2/session/session.js +58 -22
  104. package/dist/v2/session/session.js.map +1 -1
  105. package/dist/v2/state/commitment.d.ts +1 -1
  106. package/dist/v2/state/commitment.d.ts.map +1 -1
  107. package/dist/v2/state/commitment.js +5 -3
  108. package/dist/v2/state/commitment.js.map +1 -1
  109. package/dist/validators.d.ts +35 -0
  110. package/dist/validators.d.ts.map +1 -0
  111. package/dist/validators.js +127 -0
  112. package/dist/validators.js.map +1 -0
  113. package/dist/version.d.ts +1 -1
  114. package/dist/version.js +1 -1
  115. package/package.json +1 -1
  116. package/_packed_docs/collab-gateway-boundary-test-report.md +0 -164
@@ -1,550 +1,581 @@
1
- # 协作 — RPC Manual
2
-
3
- > collab 层是「锚定在某块存储上的自包含版本化目录」。每个协作文档有独立版本线(`<doc>@current` 软链 + 台账),整目录有标签线(公开 API 为 `collab.tag.*`;内部仍使用 `@snapshot` 软链和 `.collab-snapshots/` manifest)。
4
- >
5
- > **服务端编排**:collab 编排已并入 storage 服务进程,`collab.*` RPC handler 与 `storage.*` 并列注册。collab handler 以调用者身份(Gateway 注入的 `_auth.aid`)直调 storage 原语,无特权通道。
6
- >
7
- > **授权 = 存储 ACL**:谁能 `commit` = 谁对 `collab_root` 有写权限(`storage.set_acl`)。无独立发起人特权。
8
- >
9
- > SDK 侧通过 `client.collab` 访问(`CollabClient`),每个命令 1:1 映射一条 `collab.*` RPC。
10
-
11
- ## 方法索引
12
-
13
- ### 文档版本线
14
-
15
- | 方法 | 说明 |
16
- |------|------|
17
- | [collab.ls-files](#collabls-files) | 列出协作根下所有文档 |
18
- | [collab.create](#collabcreate) | 创建协作文档(首版本) |
19
- | [collab.show](#collabshow) | 读当前或指定版本内容 |
20
- | [collab.commit](#collabcommit) | 提交新版本(乐观锁 CAS) |
21
- | [collab.merge](#collabmerge) | 三方合并(服务端 diff3) |
22
- | [collab.log](#collablog) | 查版本台账 |
23
- | [collab.diff](#collabdiff) | 比较两版本 |
24
- | [collab.revert](#collabrevert) | 以历史版本内容提交一个新版本 |
25
- | [collab.prune](#collabprune) | 清理某文档的历史版本文件 |
26
-
27
- ### 运维、备份与迁移
28
-
29
- | 方法 | 说明 |
30
- |------|------|
31
- | [collab.gc](#collabgc) | 扫描不可达版本文件并可选删除 |
32
- | [collab.reflog](#collabreflog) | 查看协作审计日志 |
33
- | [collab.clone](#collabclone) | 深拷贝整个协作到新位置(可选 reroot) |
34
-
35
- ### 目录级标签(Tag)
36
-
37
- | 方法 | 说明 |
38
- |------|------|
39
- | [collab.tag.create](#collabtag.create) | 打目录标签(语义化版本) |
40
- | [collab.tag.list](#collabtag.list) | 列出标签 |
41
- | [collab.tag.show](#collabtag.show) | 查看标签详情 |
42
- | [collab.tag.diff](#collabtag.diff) | 比较两标签 |
43
- | [collab.tag.restore](#collabtag.restore) | 回滚到某标签(forward-only) |
44
- | [collab.tag.rm](#collabtag.rm) | 删除单个标签 |
45
- | [collab.tag.prune](#collabtag.prune) | 批量清理旧标签 |
46
-
47
- ### 群内发现
48
-
49
- | 方法 | 说明 |
50
- |------|------|
51
- | [collab.ls-remote](#collabls-remote) | 列出群内已登记的协作根 |
52
- | [collab.unregister](#collabunregister) | 注销注册表中的协作根条目 |
53
-
54
- ---
55
-
56
- ## 核心概念
57
-
58
- ### 协作根目录结构
59
-
60
- ```
61
- <aid>:<collab_root>/
62
- ├── .collab ← 发现锚点(YAML frontmatter: name/authority/root)
63
- ├── <doc>@current ← 软链 → .collab-versions/<doc>/<author>/vN
64
- ├── <doc>@ledger 版本台账
65
- ├── @snapshot 标签头软链 → .collab-snapshots/<semver>.json
66
- ├── .collab-versions/<doc>/<author>/v1…vN 不可变版本文件(write-once)
67
- └── .collab-snapshots/<semver>.json ← 不可变标签 manifest
68
- ```
69
-
70
- - **`collab_root` 参数格式**:`<aid>:<path>`(如 `alice.aid.pub:/projects/myapp`),来自 `.collab` 文件的 `root` 字段或上层响应。
71
- - **响应一律回吐相对 `collab_root` 的内部 target 拼成的绝对 `<aid>:<path>`**——agent 原样用于下一条命令,无需拼接。
72
-
73
- ### 乐观锁(commit)
74
-
75
- 1. `put_object`(写新版本文件,永不失败,数据先存下)。
76
- 2. 同一事务:`atomic_repoint(<doc>@current, new_target, expected_version=onto)` + 台账追加。
77
- 3. CAS 成功 → version+1;CAS 失败 → 整事务回滚,返回 `{ok:false, current_version, hint}`。
78
-
79
- `onto` 来源:`collab.show` 响应的 `version` 字段;merge 后用 commit 失败响应的 `current_version`。
80
-
81
- ### 数据不变量
82
-
83
- - 版本文件写一次永不覆盖;删指针不删数据。
84
- - 回滚是 **forward-only**:restore 不回退 version 计数器,而是以旧内容写新版本,保证 version 单调递增。
85
-
86
- ---
87
-
88
- ## collab.ls-files
89
-
90
- 列出协作根下所有协作文档(含当前 version)。
91
-
92
- ### 参数
93
-
94
- | 参数 | 类型 | 必填 | 说明 |
95
- |------|------|------|------|
96
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
97
-
98
- ### 响应
99
-
100
- 返回文档数组,每项:
101
-
102
- | 字段 | 类型 | 说明 |
103
- |------|------|------|
104
- | `doc` | string | 文档当前显示名 |
105
- | `version` | integer | 当前版本号 |
106
- | `author` | string | 最新版本作者 AID |
107
- | `current_target` | string | 当前版本文件绝对路径 `<aid>:<path>` |
108
-
109
- ### 示例
110
-
111
- ```python
112
- docs = await client.collab.ls_files("alice.aid.pub:/projects/myapp")
113
- ```
114
-
115
- ---
116
-
117
- ## collab.create
118
-
119
- 创建协作文档,写入首版本(version=1)。
120
-
121
- ### 参数
122
-
123
- | 参数 | 类型 | 必填 | 说明 |
124
- |------|------|------|------|
125
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
126
- | `doc` | string | 是 | 文档名 |
127
- | `source` | string | 是 | 初始内容:本地文件路径或 `<aid>:<path>` |
128
-
129
- ### 响应
130
-
131
- | 字段 | 类型 | 说明 |
132
- |------|------|------|
133
- | `version` | integer | 固定为 `1` |
134
- | `current_target` | string | 版本文件绝对路径 |
135
-
136
- ---
137
-
138
- ## collab.show
139
-
140
- 读取文档当前内容或指定历史版本内容。`rev` 为空时返回当前版本;`rev` 有值时返回该历史版本。
141
-
142
- ### 参数
143
-
144
- | 参数 | 类型 | 必填 | 说明 |
145
- |------|------|------|------|
146
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
147
- | `doc` | string | 是 | 文档名 |
148
- | `rev` | integer | | 指定历史版本号;不传则读取当前版本 |
149
-
150
- ### 响应
151
-
152
- | 字段 | 类型 | 说明 |
153
- |------|------|------|
154
- | `content` | string | base64 编码的当前内容 |
155
- | `version` | integer | 当前或指定版本号(**commit 的 onto 来源**) |
156
- | `author` | string | 当前版本作者 AID |
157
- | `anchor` | string | 台账锚点(读取历史版本时返回) |
158
- | `current_target` | string | 当前版本文件绝对路径(读取当前版本时返回) |
159
-
160
- ---
161
-
162
- ## collab.commit
163
-
164
- 提交新版本,乐观锁 CAS 切换 `@current`。
165
-
166
- ### 参数
167
-
168
- | 参数 | 类型 | 必填 | 说明 |
169
- |------|------|------|------|
170
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
171
- | `doc` | string | 是 | 文档名 |
172
- | `source` | string | 是 | 新内容:本地路径或 `<aid>:<path>` |
173
- | `onto` | integer | 是 | 基线版本号(来自 `collab.show` 的 `version`) |
174
-
175
- ### 响应
176
-
177
- **成功**:
178
-
179
- | 字段 | 类型 | 说明 |
180
- |------|------|------|
181
- | `ok` | boolean | `true` |
182
- | `version` | integer | 新版本号(onto+1) |
183
- | `current_target` | string | 新版本文件绝对路径 |
184
-
185
- **撞版本失败**(数据已安全保存,需 merge 后重提):
186
-
187
- | 字段 | 类型 | 说明 |
188
- |------|------|------|
189
- | `ok` | boolean | `false` |
190
- | `current_version` | integer | 当前权威版本号(**merge 后 commit 用此作新 onto**) |
191
- | `current_target` | string | 当前权威版本文件绝对路径 |
192
- | `hint` | string | 后端格式化好的下一步命令行字符串 |
193
-
194
- ### 示例
195
-
196
- ```python
197
- cur = await client.collab.show(root, "design.md")
198
- res = await client.collab.commit(root, "design.md", "./design.md", cur["version"])
199
- if not res["ok"]:
200
- await client.collab.merge(root, "design.md", "./design.md", cur["version"])
201
- res = await client.collab.commit(root, "design.md", "./design.md", res["current_version"])
202
- ```
203
-
204
- ---
205
-
206
- ## collab.merge
207
-
208
- 三方合并(服务端 diff3,四语言 SDK 不实现 diff3)。合并 base 版本、本地 source、当前 `@current` 三方内容。
209
-
210
- ### 参数
211
-
212
- | 参数 | 类型 | 必填 | 说明 |
213
- |------|------|------|------|
214
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
215
- | `doc` | string | 是 | 文档名 |
216
- | `source` | string | 是 | 本地草稿内容(ours):本地路径或 `<aid>:<path>` |
217
- | `onto` | integer | 是 | 共同祖先版本号 |
218
-
219
- ### 响应
220
-
221
- | 字段 | 类型 | 说明 |
222
- |------|------|------|
223
- | `content` | string | base64 编码的合并结果 |
224
- | `conflicts` | boolean | 是否含冲突标记(`<<<<<<<` / `=======` / `>>>>>>>`) |
225
-
226
- `conflicts=true` 时需人工编辑消解冲突后再 commit。
227
-
228
- ---
229
-
230
- ## collab.log
231
-
232
- 查文档版本台账。
233
-
234
- ### 参数
235
-
236
- | 参数 | 类型 | 必填 | 说明 |
237
- |------|------|------|------|
238
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
239
- | `doc` | string | 是 | 文档名(按物理目录名索引,改显示名后仍按原名查) |
240
-
241
- ### 响应
242
-
243
- 返回版本数组,每项 `{version, author, target, time}`,`target` 为完整 `<aid>:<path>`。
244
-
245
- ---
246
-
247
- ## collab.diff
248
-
249
- 比较同一文档的两个版本,返回 unified diff 文本。
250
-
251
- ### 参数
252
-
253
- | 参数 | 类型 | 必填 | 说明 |
254
- |------|------|------|------|
255
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
256
- | `doc` | string | 是 | 文档名 |
257
- | `from` | integer | 是 | 起始版本号(SDK 形参 `v_from`) |
258
- | `to` | integer | 是 | 目标版本号(SDK 形参 `v_to`) |
259
-
260
- ### 响应
261
-
262
- | 字段 | 类型 | 说明 |
263
- |------|------|------|
264
- | `diff` | string | unified diff 文本 |
265
-
266
- ---
267
-
268
- ## collab.revert
269
-
270
- 以指定历史版本的内容提交一个新版本。revert 不回退版本号,也不直接改写历史文件;它读取目标版本内容,以当前版本为 `onto` 再走普通 `commit` 流程,因此仍保持 forward-only 不变量。
271
-
272
- ### 参数
273
-
274
- | 参数 | 类型 | 必填 | 默认 | 说明 |
275
- |------|------|------|------|------|
276
- | `collab_root` | string | | | 协作根 `<aid>:<path>` |
277
- | `doc` | string | 是 | — | 文档名 |
278
- | `rev` | integer | 是 | — | 要恢复内容的历史版本号 |
279
- | `message` | string | | `""` | 记录到台账/审计日志的说明 |
280
-
281
- ### 响应
282
-
283
- 返回普通 `collab.commit` 的响应字段;如果当前版本已经等于目标版本,返回包含 `no_change: true` 的结果。
284
-
285
- ---
286
-
287
- ## collab.prune
288
-
289
- 清理某文档的历史版本文件(保留台账与当前版本,回收旧 blob)。
290
-
291
- ### 参数
292
-
293
- | 参数 | 类型 | 必填 | 说明 |
294
- |------|------|------|------|
295
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
296
- | `doc` | string | 是 | 文档名 |
297
-
298
- ### 响应
299
-
300
- | 字段 | 类型 | 说明 |
301
- |------|------|------|
302
- | `pruned` | integer | 清理的版本文件数 |
303
-
304
- ---
305
-
306
- ## collab.gc
307
-
308
- 目录级垃圾扫描。服务端会扫描 `.collab-versions`,从台账、当前指针和标签 manifest 标记可达版本文件;未被引用的版本文件计为 garbage。默认 `dry_run=true` 只返回统计,不删除。
309
-
310
- ### 参数
311
-
312
- | 参数 | 类型 | 必填 | 默认 | 说明 |
313
- |------|------|------|------|------|
314
- | `collab_root` | string | | | 协作根 `<aid>:<path>` |
315
- | `dry_run` | boolean | 否 | `true` | 只扫描不删除 |
316
-
317
- ### 响应
318
-
319
- | 字段 | 类型 | 说明 |
320
- |------|------|------|
321
- | `scanned` | integer | 扫描到的版本文件数 |
322
- | `reachable` | integer | 可达版本文件数 |
323
- | `garbage` | integer | 不可达版本文件数 |
324
- | `deleted` | integer | 实际删除数量;`dry_run=true` 时为 0 |
325
- | `freed_bytes` | integer | 实际释放字节数 |
326
-
327
- ---
328
-
329
- ## collab.reflog
330
-
331
- 读取协作审计日志,用于排查 commit/merge/revert/tag 等操作历史。可按文档过滤并限制条数。
332
-
333
- ### 参数
334
-
335
- | 参数 | 类型 | 必填 | 默认 | 说明 |
336
- |------|------|------|------|------|
337
- | `collab_root` | string | | | 协作根 `<aid>:<path>` |
338
- | `doc` | string | 否 | — | 仅查看某个文档的日志 |
339
- | `limit` | integer | | `100` | 返回条数上限 |
340
-
341
- ### 响应
342
-
343
- 返回日志数组,每项包含 `seq`、`action`、`requester`、`doc`、`version`、`onto`、`target`、`status`、`error_code`、`error_msg`、`metadata`、`timestamp` 等字段。
344
-
345
- ---
346
-
347
- ## collab.clone
348
-
349
- 克隆整个协作到新位置。默认 `reroot=false` 时做纯子树拷贝(用于备份);`reroot=true` 时在目标根重建并让目标 owner 成为新授权方(用于迁移 / 换主理人)。
350
-
351
- ### 参数
352
-
353
- | 参数 | 类型 | 必填 | 说明 |
354
- |------|------|------|------|
355
- | `src` | string | | 源协作根 `<aid>:<path>` |
356
- | `dest` | string | 是 | 目标路径 `<aid>:<path>` |
357
- | `reroot` | boolean | | 默认 `false`;`true` 表示重建 root 和授权方 |
358
-
359
- ### 响应
360
-
361
- | 字段 | 类型 | 说明 |
362
- |------|------|------|
363
- | `ok` | boolean | `true` |
364
- | `dest` | string | 目标路径 |
365
- | `copied_objects` | integer | 拷贝的对象数 |
366
- | `new_root` | string | `reroot=true` 时的新协作根 |
367
- | `new_authority_aid` | string | `reroot=true` 时的新授权方 AID(= dest 存储 owner) |
368
-
369
- > collabRoot 整体改名/迁移用 `collab.clone(..., reroot=true)`,不要用 `storage.fs.rename`:后者在对象存储上可能是 O(n) copy+delete,且会让 `.collab` `root` 字段失效。
370
-
371
- ---
372
-
373
- ## collab.tag.create
374
-
375
- 打目录级标签。语义化版本自动判定:doc 集合变化 → minor;仅内容变化 → patch;`major=true` 强制 major;无变化 → 报错。
376
-
377
- ### 参数
378
-
379
- | 参数 | 类型 | 必填 | 默认 | 说明 |
380
- |------|------|------|------|------|
381
- | `collab_root` | string | | | 协作根 `<aid>:<path>` |
382
- | `message` | string | 否 | `""` | 标签说明 |
383
- | `major` | boolean | | `false` | 强制 major bump |
384
-
385
- ### 响应
386
-
387
- | 字段 | 类型 | 说明 |
388
- |------|------|------|
389
- | `version` | string | 新标签语义化版本(如 `2.3.1`) |
390
- | `bump` | string | 本次 bump 级别(`major`/`minor`/`patch`) |
391
- | `changed` | array | 变化的文档名列表 |
392
-
393
- ---
394
-
395
- ## collab.tag.list
396
-
397
- 列出所有标签。
398
-
399
- ### 参数
400
-
401
- | 参数 | 类型 | 必填 | 说明 |
402
- |------|------|------|------|
403
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
404
-
405
- ### 响应
406
-
407
- 返回标签数组,每项 `{version, message, created_at, ...}`,按语义化版本升序。
408
-
409
- ---
410
-
411
- ## collab.tag.show
412
-
413
- 查看单个标签详情(含文档清单 entries)。
414
-
415
- ### 参数
416
-
417
- | 参数 | 类型 | 必填 | 说明 |
418
- |------|------|------|------|
419
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
420
- | `version` | string | 是 | 标签版本(如 `2.3.1`) |
421
-
422
- ### 响应
423
-
424
- 标签 manifest,含 `collab_root`、`version` 与 `entries`(每项含 `doc`/`version`/`current_target` 绝对路径)。
425
-
426
- ---
427
-
428
- ## collab.tag.diff
429
-
430
- 比较两标签的文档版本差异。
431
-
432
- ### 参数
433
-
434
- | 参数 | 类型 | 必填 | 说明 |
435
- |------|------|------|------|
436
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
437
- | `version_a` | string | 是 | 标签 A 版本 |
438
- | `version_b` | string | 是 | 标签 B 版本 |
439
-
440
- ### 响应
441
-
442
- 返回新增/删除/版本变化的文档清单。
443
-
444
- ---
445
-
446
- ## collab.tag.restore
447
-
448
- 回滚到某标签。**forward-only**:不回退 version 计数器,而是对每个文档以标签中的旧内容写一个新版本(vN+1),最后以回滚后状态自动创建新标签。
449
-
450
- ### 参数
451
-
452
- | 参数 | 类型 | 必填 | 默认 | 说明 |
453
- |------|------|------|------|------|
454
- | `collab_root` | string | | | 协作根 `<aid>:<path>` |
455
- | `version` | string | 是 | — | 要回滚到的标签版本 |
456
- | `message` | string | | `""` | 回滚说明 |
457
-
458
- ### 响应
459
-
460
- | 字段 | 类型 | 说明 |
461
- |------|------|------|
462
- | `restored_from` | string | 回滚来源标签版本 |
463
- | `new_snapshot_version` | string | 回滚后自动创建的新标签版本(历史字段名保留为 `new_snapshot_version`) |
464
- | `warnings` | array | 回滚过程中的告警(如某文档被他人并发提交而跳过) |
465
-
466
- ---
467
-
468
- ## collab.tag.rm
469
-
470
- 删除单个标签。
471
-
472
- ### 参数
473
-
474
- | 参数 | 类型 | 必填 | 说明 |
475
- |------|------|------|------|
476
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
477
- | `version` | string | 是 | 要删除的标签版本 |
478
-
479
- ### 响应
480
-
481
- | 字段 | 类型 | 说明 |
482
- |------|------|------|
483
- | `ok` | boolean | `true` |
484
-
485
- ---
486
-
487
- ## collab.tag.prune
488
-
489
- 批量清理旧标签。
490
-
491
- ### 参数
492
-
493
- | 参数 | 类型 | 必填 | 说明 |
494
- |------|------|------|------|
495
- | `collab_root` | string | | 协作根 `<aid>:<path>` |
496
- | `before` | integer\|string | 否 | 清理此时间点之前的标签 |
497
- | `keep_last` | integer | | 保留最近 N 个标签 |
498
-
499
- ### 响应
500
-
501
- | 字段 | 类型 | 说明 |
502
- |------|------|------|
503
- | `pruned` | integer | 清理的标签数 |
504
-
505
- ---
506
-
507
- ## collab.ls-remote
508
-
509
- 列出群内已登记的协作根(群 owner 优先查 `collab_registry`,免 O(n) 全树扇出)。
510
-
511
- ### 参数
512
-
513
- | 参数 | 类型 | 必填 | 说明 |
514
- |------|------|------|------|
515
- | `group_aid` | string | | AID |
516
-
517
- ### 响应
518
-
519
- 返回协作根数组,每项含 `collab_root` 等登记信息。
520
-
521
- ---
522
-
523
- ## collab.unregister
524
-
525
- 注销注册表中的协作根条目(不删数据,仅去登记)。
526
-
527
- ### 参数
528
-
529
- | 参数 | 类型 | 必填 | 说明 |
530
- |------|------|------|------|
531
- | `group_aid` | string | | AID |
532
- | `collab_root` | string | 是 | 要注销的协作根 `<aid>:<path>` |
533
-
534
- ### 响应
535
-
536
- | 字段 | 类型 | 说明 |
537
- |------|------|------|
538
- | `ok` | boolean | `true` |
539
-
540
- ---
541
-
542
- ## 错误码
543
-
544
- | code | 说明 |
545
- |------|------|
546
- | -32002 | 服务暂不可用(数据库未连接) |
547
- | -32004 | 权限拒绝(requester 对 collab_root 无写权限) |
548
- | -32008 | 协作文档 / 版本 / 标签不存在 |
549
- | -32009 | 版本冲突(commit 撞版本,见 `ok:false` 响应;tag create 时标签头已移动) |
550
- | -32000 | 通用错误(参数校验失败、源内容读取失败、无变更可打标签等) |
1
+ # 协作 — RPC Manual
2
+
3
+ > collab 层是「锚定在某块存储上的自包含版本化目录」。每个协作文档有独立版本线(`<doc>@current` 软链 + 台账),整目录有标签线(公开 API 为 `collab.tag.*`;内部仍使用 `@snapshot` 软链和 `.collab-snapshots/` manifest)。
4
+ >
5
+ > **服务端编排**:collab 编排已并入 storage 服务进程,`collab.*` RPC handler 与 `storage.*` 并列注册。collab handler 以调用者身份(Gateway 注入的 `_auth.aid`)直调 storage 原语,无特权通道。
6
+ >
7
+ > **授权 = 协作根写 ACL**:谁能 `commit` = 谁对 `collab_root` 有写权限。普通 AID storage 可继续用 `storage.set_acl/remove_acl` 管理写授权;群 `memberdata` 协作根必须用 `collab.set_acl/remove_acl` 按 `collab_root` 授权,SDK/CLI 不得拼接真实 `group_data` 路径。
8
+ >
9
+ > SDK 侧通过 `client.collab` 访问(`CollabClient`),每个命令 1:1 映射一条 `collab.*` RPC。
10
+
11
+ ## 方法索引
12
+
13
+ ### 文档版本线
14
+
15
+ | 方法 | 说明 |
16
+ |------|------|
17
+ | [collab.ls-files](#collabls-files) | 列出协作根下所有文档 |
18
+ | [collab.create](#collabcreate) | 创建协作文档(首版本) |
19
+ | [collab.show](#collabshow) | 读当前或指定版本内容 |
20
+ | [collab.commit](#collabcommit) | 提交新版本(乐观锁 CAS) |
21
+ | [collab.merge](#collabmerge) | 三方合并(服务端 diff3) |
22
+ | [collab.log](#collablog) | 查版本台账 |
23
+ | [collab.diff](#collabdiff) | 比较两版本 |
24
+ | [collab.revert](#collabrevert) | 以历史版本内容提交一个新版本 |
25
+ | [collab.prune](#collabprune) | 清理某文档的历史版本文件 |
26
+
27
+ ### 运维、备份与迁移
28
+
29
+ | 方法 | 说明 |
30
+ |------|------|
31
+ | [collab.gc](#collabgc) | 扫描不可达版本文件并可选删除 |
32
+ | [collab.reflog](#collabreflog) | 查看协作审计日志 |
33
+ | [collab.clone](#collabclone) | 深拷贝整个协作到新位置(可选 reroot) |
34
+
35
+ ### 目录级标签(Tag)
36
+
37
+ | 方法 | 说明 |
38
+ |------|------|
39
+ | [collab.tag.create](#collabtag.create) | 打目录标签(语义化版本) |
40
+ | [collab.tag.list](#collabtag.list) | 列出标签 |
41
+ | [collab.tag.show](#collabtag.show) | 查看标签详情 |
42
+ | [collab.tag.diff](#collabtag.diff) | 比较两标签 |
43
+ | [collab.tag.restore](#collabtag.restore) | 回滚到某标签(forward-only) |
44
+ | [collab.tag.rm](#collabtag.rm) | 删除单个标签 |
45
+ | [collab.tag.prune](#collabtag.prune) | 批量清理旧标签 |
46
+
47
+ ### 群内发现
48
+
49
+ | 方法 | 说明 |
50
+ |------|------|
51
+ | [collab.ls-remote](#collabls-remote) | 列出群内已登记的协作根 |
52
+ | [collab.unregister](#collabunregister) | 注销注册表中的协作根条目 |
53
+ | [collab.set_acl](#collabset_acl) | owner 授予具体 AID 对协作根的写权限 |
54
+ | [collab.remove_acl](#collabremove_acl) | owner 撤销具体 AID 对协作根的写权限 |
55
+
56
+ ---
57
+
58
+ ## 核心概念
59
+
60
+ ### 协作根目录结构
61
+
62
+ ```
63
+ <aid>:<collab_root>/
64
+ ├── .collab 发现锚点(YAML frontmatter: name/authority/root)
65
+ ├── <doc>@current 软链 → .collab-versions/<doc>/<author>/vN
66
+ ├── <doc>@ledger 版本台账
67
+ ├── @snapshot ← 标签头软链 → .collab-snapshots/<semver>.json
68
+ ├── .collab-versions/<doc>/<author>/v1…vN ← 不可变版本文件(write-once)
69
+ └── .collab-snapshots/<semver>.json ← 不可变标签 manifest
70
+ ```
71
+
72
+ - **`collab_root` 参数格式**:`<aid>:<path>`(如 `alice.aid.pub:/projects/myapp`),来自 `.collab` 文件的 `root` 字段或上层响应。
73
+ - **响应一律回吐相对 `collab_root` 的内部 target 拼成的绝对 `<aid>:<path>`**——agent 原样用于下一条命令,无需拼接。
74
+
75
+ ### 乐观锁(commit)
76
+
77
+ 1. `put_object`(写新版本文件,永不失败,数据先存下)。
78
+ 2. 同一事务:`atomic_repoint(<doc>@current, new_target, expected_version=onto)` + 台账追加。
79
+ 3. CAS 成功 → version+1;CAS 失败 整事务回滚,返回 `{ok:false, current_version, hint}`。
80
+
81
+ `onto` 来源:`collab.show` 响应的 `version` 字段;merge 后用 commit 失败响应的 `current_version`。
82
+
83
+ ### 数据不变量
84
+
85
+ - 版本文件写一次永不覆盖;删指针不删数据。
86
+ - 回滚是 **forward-only**:restore 不回退 version 计数器,而是以旧内容写新版本,保证 version 单调递增。
87
+
88
+ ---
89
+
90
+ ## collab.ls-files
91
+
92
+ 列出协作根下所有协作文档(含当前 version)。
93
+
94
+ ### 参数
95
+
96
+ | 参数 | 类型 | 必填 | 说明 |
97
+ |------|------|------|------|
98
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
99
+
100
+ ### 响应
101
+
102
+ 返回文档数组,每项:
103
+
104
+ | 字段 | 类型 | 说明 |
105
+ |------|------|------|
106
+ | `doc` | string | 文档当前显示名 |
107
+ | `version` | integer | 当前版本号 |
108
+ | `author` | string | 最新版本作者 AID |
109
+ | `current_target` | string | 当前版本文件绝对路径 `<aid>:<path>` |
110
+
111
+ ### 示例
112
+
113
+ ```python
114
+ docs = await client.collab.ls_files("alice.aid.pub:/projects/myapp")
115
+ ```
116
+
117
+ ---
118
+
119
+ ## collab.create
120
+
121
+ 创建协作文档,写入首版本(version=1)。
122
+
123
+ ### 参数
124
+
125
+ | 参数 | 类型 | 必填 | 说明 |
126
+ |------|------|------|------|
127
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
128
+ | `doc` | string | 是 | 文档名 |
129
+ | `source` | string | 是 | 初始内容:本地文件路径或 `<aid>:<path>` |
130
+
131
+ ### 响应
132
+
133
+ | 字段 | 类型 | 说明 |
134
+ |------|------|------|
135
+ | `version` | integer | 固定为 `1` |
136
+ | `current_target` | string | 版本文件绝对路径 |
137
+
138
+ ---
139
+
140
+ ## collab.show
141
+
142
+ 读取文档当前内容或指定历史版本内容。`rev` 为空时返回当前版本;`rev` 有值时返回该历史版本。
143
+
144
+ ### 参数
145
+
146
+ | 参数 | 类型 | 必填 | 说明 |
147
+ |------|------|------|------|
148
+ | `collab_root` | string | | 协作根 `<aid>:<path>` |
149
+ | `doc` | string | 是 | 文档名 |
150
+ | `rev` | integer | 否 | 指定历史版本号;不传则读取当前版本 |
151
+
152
+ ### 响应
153
+
154
+ | 字段 | 类型 | 说明 |
155
+ |------|------|------|
156
+ | `content` | string | base64 编码的当前内容 |
157
+ | `version` | integer | 当前或指定版本号(**commit 的 onto 来源**) |
158
+ | `author` | string | 当前版本作者 AID |
159
+ | `anchor` | string | 台账锚点(读取历史版本时返回) |
160
+ | `current_target` | string | 当前版本文件绝对路径(读取当前版本时返回) |
161
+
162
+ ---
163
+
164
+ ## collab.commit
165
+
166
+ 提交新版本,乐观锁 CAS 切换 `@current`。
167
+
168
+ ### 参数
169
+
170
+ | 参数 | 类型 | 必填 | 说明 |
171
+ |------|------|------|------|
172
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
173
+ | `doc` | string | 是 | 文档名 |
174
+ | `source` | string | 是 | 新内容:本地路径或 `<aid>:<path>` |
175
+ | `onto` | integer | 是 | 基线版本号(来自 `collab.show` 的 `version`) |
176
+
177
+ ### 响应
178
+
179
+ **成功**:
180
+
181
+ | 字段 | 类型 | 说明 |
182
+ |------|------|------|
183
+ | `ok` | boolean | `true` |
184
+ | `version` | integer | 新版本号(onto+1) |
185
+ | `current_target` | string | 新版本文件绝对路径 |
186
+
187
+ **撞版本失败**(数据已安全保存,需 merge 后重提):
188
+
189
+ | 字段 | 类型 | 说明 |
190
+ |------|------|------|
191
+ | `ok` | boolean | `false` |
192
+ | `current_version` | integer | 当前权威版本号(**merge 后 commit 用此作新 onto**) |
193
+ | `current_target` | string | 当前权威版本文件绝对路径 |
194
+ | `hint` | string | 后端格式化好的下一步命令行字符串 |
195
+
196
+ ### 示例
197
+
198
+ ```python
199
+ cur = await client.collab.show(root, "design.md")
200
+ res = await client.collab.commit(root, "design.md", "./design.md", cur["version"])
201
+ if not res["ok"]:
202
+ await client.collab.merge(root, "design.md", "./design.md", cur["version"])
203
+ res = await client.collab.commit(root, "design.md", "./design.md", res["current_version"])
204
+ ```
205
+
206
+ ---
207
+
208
+ ## collab.merge
209
+
210
+ 三方合并(服务端 diff3,四语言 SDK 不实现 diff3)。合并 base 版本、本地 source、当前 `@current` 三方内容。
211
+
212
+ ### 参数
213
+
214
+ | 参数 | 类型 | 必填 | 说明 |
215
+ |------|------|------|------|
216
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
217
+ | `doc` | string | 是 | 文档名 |
218
+ | `source` | string | 是 | 本地草稿内容(ours):本地路径或 `<aid>:<path>` |
219
+ | `onto` | integer | 是 | 共同祖先版本号 |
220
+
221
+ ### 响应
222
+
223
+ | 字段 | 类型 | 说明 |
224
+ |------|------|------|
225
+ | `content` | string | base64 编码的合并结果 |
226
+ | `conflicts` | boolean | 是否含冲突标记(`<<<<<<<` / `=======` / `>>>>>>>`) |
227
+
228
+ `conflicts=true` 时需人工编辑消解冲突后再 commit。
229
+
230
+ ---
231
+
232
+ ## collab.log
233
+
234
+ 查文档版本台账。
235
+
236
+ ### 参数
237
+
238
+ | 参数 | 类型 | 必填 | 说明 |
239
+ |------|------|------|------|
240
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
241
+ | `doc` | string | 是 | 文档名(按物理目录名索引,改显示名后仍按原名查) |
242
+
243
+ ### 响应
244
+
245
+ 返回版本数组,每项 `{version, author, target, time}`,`target` 为完整 `<aid>:<path>`。
246
+
247
+ ---
248
+
249
+ ## collab.diff
250
+
251
+ 比较同一文档的两个版本,返回 unified diff 文本。
252
+
253
+ ### 参数
254
+
255
+ | 参数 | 类型 | 必填 | 说明 |
256
+ |------|------|------|------|
257
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
258
+ | `doc` | string | 是 | 文档名 |
259
+ | `from` | integer | 是 | 起始版本号(SDK 形参 `v_from`) |
260
+ | `to` | integer | 是 | 目标版本号(SDK 形参 `v_to`) |
261
+
262
+ ### 响应
263
+
264
+ | 字段 | 类型 | 说明 |
265
+ |------|------|------|
266
+ | `diff` | string | unified diff 文本 |
267
+
268
+ ---
269
+
270
+ ## collab.revert
271
+
272
+ 以指定历史版本的内容提交一个新版本。revert 不回退版本号,也不直接改写历史文件;它读取目标版本内容,以当前版本为 `onto` 再走普通 `commit` 流程,因此仍保持 forward-only 不变量。
273
+
274
+ ### 参数
275
+
276
+ | 参数 | 类型 | 必填 | 默认 | 说明 |
277
+ |------|------|------|------|------|
278
+ | `collab_root` | string | 是 | — | 协作根 `<aid>:<path>` |
279
+ | `doc` | string | | | 文档名 |
280
+ | `rev` | integer | 是 | — | 要恢复内容的历史版本号 |
281
+ | `message` | string | 否 | `""` | 记录到台账/审计日志的说明 |
282
+
283
+ ### 响应
284
+
285
+ 返回普通 `collab.commit` 的响应字段;如果当前版本已经等于目标版本,返回包含 `no_change: true` 的结果。
286
+
287
+ ---
288
+
289
+ ## collab.prune
290
+
291
+ 清理某文档的历史版本文件(保留台账与当前版本,回收旧 blob)。
292
+
293
+ ### 参数
294
+
295
+ | 参数 | 类型 | 必填 | 说明 |
296
+ |------|------|------|------|
297
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
298
+ | `doc` | string | 是 | 文档名 |
299
+
300
+ ### 响应
301
+
302
+ | 字段 | 类型 | 说明 |
303
+ |------|------|------|
304
+ | `pruned` | integer | 清理的版本文件数 |
305
+
306
+ ---
307
+
308
+ ## collab.gc
309
+
310
+ 目录级垃圾扫描。服务端会扫描 `.collab-versions`,从台账、当前指针和标签 manifest 标记可达版本文件;未被引用的版本文件计为 garbage。默认 `dry_run=true` 只返回统计,不删除。
311
+
312
+ ### 参数
313
+
314
+ | 参数 | 类型 | 必填 | 默认 | 说明 |
315
+ |------|------|------|------|------|
316
+ | `collab_root` | string | 是 | — | 协作根 `<aid>:<path>` |
317
+ | `dry_run` | boolean | 否 | `true` | 只扫描不删除 |
318
+
319
+ ### 响应
320
+
321
+ | 字段 | 类型 | 说明 |
322
+ |------|------|------|
323
+ | `scanned` | integer | 扫描到的版本文件数 |
324
+ | `reachable` | integer | 可达版本文件数 |
325
+ | `garbage` | integer | 不可达版本文件数 |
326
+ | `deleted` | integer | 实际删除数量;`dry_run=true` 时为 0 |
327
+ | `freed_bytes` | integer | 实际释放字节数 |
328
+
329
+ ---
330
+
331
+ ## collab.reflog
332
+
333
+ 读取协作审计日志,用于排查 commit/merge/revert/tag 等操作历史。可按文档过滤并限制条数。
334
+
335
+ ### 参数
336
+
337
+ | 参数 | 类型 | 必填 | 默认 | 说明 |
338
+ |------|------|------|------|------|
339
+ | `collab_root` | string | | | 协作根 `<aid>:<path>` |
340
+ | `doc` | string | 否 | — | 仅查看某个文档的日志 |
341
+ | `limit` | integer | 否 | `100` | 返回条数上限 |
342
+
343
+ ### 响应
344
+
345
+ 返回日志数组,每项包含 `seq`、`action`、`requester`、`doc`、`version`、`onto`、`target`、`status`、`error_code`、`error_msg`、`metadata`、`timestamp` 等字段。
346
+
347
+ ---
348
+
349
+ ## collab.clone
350
+
351
+ 克隆整个协作到新位置。默认 `reroot=false` 时做纯子树拷贝(用于备份);`reroot=true` 时在目标根重建并让目标 owner 成为新授权方(用于迁移 / 换主理人)。
352
+
353
+ ### 参数
354
+
355
+ | 参数 | 类型 | 必填 | 说明 |
356
+ |------|------|------|------|
357
+ | `src` | string | | 源协作根 `<aid>:<path>` |
358
+ | `dest` | string | 是 | 目标路径 `<aid>:<path>` |
359
+ | `reroot` | boolean | 否 | 默认 `false`;`true` 表示重建 root 和授权方 |
360
+
361
+ ### 响应
362
+
363
+ | 字段 | 类型 | 说明 |
364
+ |------|------|------|
365
+ | `ok` | boolean | `true` |
366
+ | `dest` | string | 目标路径 |
367
+ | `copied_objects` | integer | 拷贝的对象数 |
368
+ | `new_root` | string | `reroot=true` 时的新协作根 |
369
+ | `new_authority_aid` | string | `reroot=true` 时的新授权方 AID(= dest 存储 owner) |
370
+
371
+ > collabRoot 整体改名/迁移用 `collab.clone(..., reroot=true)`,不要用 `storage.fs.rename`:后者在对象存储上可能是 O(n) copy+delete,且会让 `.collab` 的 `root` 字段失效。
372
+
373
+ ---
374
+
375
+ ## collab.tag.create
376
+
377
+ 打目录级标签。语义化版本自动判定:doc 集合变化 → minor;仅内容变化 → patch;`major=true` 强制 major;无变化 → 报错。
378
+
379
+ ### 参数
380
+
381
+ | 参数 | 类型 | 必填 | 默认 | 说明 |
382
+ |------|------|------|------|------|
383
+ | `collab_root` | string | | | 协作根 `<aid>:<path>` |
384
+ | `message` | string | 否 | `""` | 标签说明 |
385
+ | `major` | boolean | 否 | `false` | 强制 major bump |
386
+
387
+ ### 响应
388
+
389
+ | 字段 | 类型 | 说明 |
390
+ |------|------|------|
391
+ | `version` | string | 新标签语义化版本(如 `2.3.1`) |
392
+ | `bump` | string | 本次 bump 级别(`major`/`minor`/`patch`) |
393
+ | `changed` | array | 变化的文档名列表 |
394
+
395
+ ---
396
+
397
+ ## collab.tag.list
398
+
399
+ 列出所有标签。
400
+
401
+ ### 参数
402
+
403
+ | 参数 | 类型 | 必填 | 说明 |
404
+ |------|------|------|------|
405
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
406
+
407
+ ### 响应
408
+
409
+ 返回标签数组,每项 `{version, message, created_at, ...}`,按语义化版本升序。
410
+
411
+ ---
412
+
413
+ ## collab.tag.show
414
+
415
+ 查看单个标签详情(含文档清单 entries)。
416
+
417
+ ### 参数
418
+
419
+ | 参数 | 类型 | 必填 | 说明 |
420
+ |------|------|------|------|
421
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
422
+ | `version` | string | 是 | 标签版本(如 `2.3.1`) |
423
+
424
+ ### 响应
425
+
426
+ 标签 manifest,含 `collab_root`、`version` 与 `entries`(每项含 `doc`/`version`/`current_target` 绝对路径)。
427
+
428
+ ---
429
+
430
+ ## collab.tag.diff
431
+
432
+ 比较两标签的文档版本差异。
433
+
434
+ ### 参数
435
+
436
+ | 参数 | 类型 | 必填 | 说明 |
437
+ |------|------|------|------|
438
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
439
+ | `version_a` | string | 是 | 标签 A 版本 |
440
+ | `version_b` | string | 是 | 标签 B 版本 |
441
+
442
+ ### 响应
443
+
444
+ 返回新增/删除/版本变化的文档清单。
445
+
446
+ ---
447
+
448
+ ## collab.tag.restore
449
+
450
+ 回滚到某标签。**forward-only**:不回退 version 计数器,而是对每个文档以标签中的旧内容写一个新版本(vN+1),最后以回滚后状态自动创建新标签。
451
+
452
+ ### 参数
453
+
454
+ | 参数 | 类型 | 必填 | 默认 | 说明 |
455
+ |------|------|------|------|------|
456
+ | `collab_root` | string | | | 协作根 `<aid>:<path>` |
457
+ | `version` | string | 是 | — | 要回滚到的标签版本 |
458
+ | `message` | string | 否 | `""` | 回滚说明 |
459
+
460
+ ### 响应
461
+
462
+ | 字段 | 类型 | 说明 |
463
+ |------|------|------|
464
+ | `restored_from` | string | 回滚来源标签版本 |
465
+ | `new_snapshot_version` | string | 回滚后自动创建的新标签版本(历史字段名保留为 `new_snapshot_version`) |
466
+ | `warnings` | array | 回滚过程中的告警(如某文档被他人并发提交而跳过) |
467
+
468
+ ---
469
+
470
+ ## collab.tag.rm
471
+
472
+ 删除单个标签。
473
+
474
+ ### 参数
475
+
476
+ | 参数 | 类型 | 必填 | 说明 |
477
+ |------|------|------|------|
478
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
479
+ | `version` | string | 是 | 要删除的标签版本 |
480
+
481
+ ### 响应
482
+
483
+ | 字段 | 类型 | 说明 |
484
+ |------|------|------|
485
+ | `ok` | boolean | `true` |
486
+
487
+ ---
488
+
489
+ ## collab.tag.prune
490
+
491
+ 批量清理旧标签。
492
+
493
+ ### 参数
494
+
495
+ | 参数 | 类型 | 必填 | 说明 |
496
+ |------|------|------|------|
497
+ | `collab_root` | string | | 协作根 `<aid>:<path>` |
498
+ | `before` | integer\|string | 否 | 清理此时间点之前的标签 |
499
+ | `keep_last` | integer | 否 | 保留最近 N 个标签 |
500
+
501
+ ### 响应
502
+
503
+ | 字段 | 类型 | 说明 |
504
+ |------|------|------|
505
+ | `pruned` | integer | 清理的标签数 |
506
+
507
+ ---
508
+
509
+ ## collab.ls-remote
510
+
511
+ 列出群内已登记的协作根(群 owner 优先查 `collab_registry`,免 O(n) 全树扇出)。
512
+
513
+ ### 参数
514
+
515
+ | 参数 | 类型 | 必填 | 说明 |
516
+ |------|------|------|------|
517
+ | `group_aid` | string | 是 | 群 AID |
518
+
519
+ ### 响应
520
+
521
+ 返回协作根数组,每项含 `collab_root` 等登记信息。
522
+
523
+ ---
524
+
525
+ ## collab.unregister
526
+
527
+ 注销注册表中的协作根条目(不删数据,仅去登记)。
528
+
529
+ ### 参数
530
+
531
+ | 参数 | 类型 | 必填 | 说明 |
532
+ |------|------|------|------|
533
+ | `group_aid` | string | 是 | 群 AID |
534
+ | `collab_root` | string | 是 | 要注销的协作根 `<aid>:<path>` |
535
+
536
+ ### 响应
537
+
538
+ | 字段 | 类型 | 说明 |
539
+ |------|------|------|
540
+ | `ok` | boolean | `true` |
541
+
542
+ ---
543
+
544
+ ## collab.set_acl
545
+
546
+ 授予具体 AID 对协作根的写权限。调用者必须是协作根真实 storage owner。对 `group_aid:/memberdata/{aid}/...` 根,服务端内部映射到成员 storage 的 `group_data/{group_aid}`,但调用参数仍只使用 `collab_root`。
547
+
548
+ ### 参数
549
+
550
+ | 参数 | 类型 | 必填 | 说明 |
551
+ |------|------|------|------|
552
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
553
+ | `grantee_aid` | string | 是 | 被授权 AID;不支持 `role:*` |
554
+ | `perms` | string | 否 | 权限位,默认 `w` |
555
+ | `expires_at` | integer | 否 | 过期时间戳 |
556
+ | `max_uses` | integer | 否 | 最大使用次数 |
557
+
558
+ ---
559
+
560
+ ## collab.remove_acl
561
+
562
+ 撤销具体 AID 对协作根的写权限。调用者必须是协作根真实 storage owner。
563
+
564
+ ### 参数
565
+
566
+ | 参数 | 类型 | 必填 | 说明 |
567
+ |------|------|------|------|
568
+ | `collab_root` | string | 是 | 协作根 `<aid>:<path>` |
569
+ | `grantee_aid` | string | 是 | 被撤销 AID |
570
+
571
+ ---
572
+
573
+ ## 错误码
574
+
575
+ | code | 说明 |
576
+ |------|------|
577
+ | -32002 | 服务暂不可用(数据库未连接) |
578
+ | -32004 | 权限拒绝(requester 对 collab_root 无写权限) |
579
+ | -32008 | 协作文档 / 版本 / 标签不存在 |
580
+ | -32009 | 版本冲突(commit 撞版本,见 `ok:false` 响应;tag create 时标签头已移动) |
581
+ | -32000 | 通用错误(参数校验失败、源内容读取失败、无变更可打标签等) |