✨ feat(vscode): 多人协作二期:状态分层/写校验/签名/团队视图

- 本机状态(会话id/worktree/profile/prDiffFile)迁 workspaceState,
  共享 state JSON 只留团队字段;读侧本地记录叠加,旧数据兜底
- mergeStateJsonComment 写后读回校验,并发覆盖时在最新状态上重放一次
- webhook 支持 Gitea secret,校验 X-Gitea-Signature(HMAC-SHA256),
  不匹配 401;设置面板新增 Webhook Secret 字段
- 看板新增 我的/全部 范围切换(团队视图),按工作区持久化
This commit is contained in:
cruldra committed 2026-08-19 00:32:06 +08:00
1 parent c370214d12
commit faf227412e
18 files changed
+665 -202

No files matched your search

+25 -8
View File
@@ -71,14 +71,31 @@ export interface MergeStateJsonCommentOpts {
* are responsible for surfacing errors.
*/
export async function mergeStateJsonComment(opts: MergeStateJsonCommentOpts): Promise<void> {
const currentState = await readStateJsonComment({
host: opts.host,
owner: opts.owner,
repo: opts.repo,
token: opts.token,
issueNumber: opts.issueNumber,
})
await postMergedStateJsonComment(opts, currentState, opts.extra)
// 乐观并发:state 评论是"最后一条全量覆盖",两个写者并发时后写者会把
// 先写者的字段整体冲掉。门禁后共享写基本回到单写者,但人工拖列仍可能
// 与 webhook 写并发——post 后读回校验,本次字段若被并发覆盖,就在最新
// 状态上重放一次。两轮后仍冲突的概率可忽略,按最后一轮结果收场。
for (let attempt = 0; attempt < 2; attempt++) {
const currentState = await readStateJsonComment({
host: opts.host,
owner: opts.owner,
repo: opts.repo,
token: opts.token,
issueNumber: opts.issueNumber,
})
await postMergedStateJsonComment(opts, currentState, opts.extra)
const latest = await readStateJsonComment({
host: opts.host,
owner: opts.owner,
repo: opts.repo,
token: opts.token,
issueNumber: opts.issueNumber,
})
const lost = Object.entries(opts.extra)
.some(([k, v]) => JSON.stringify(latest[k]) !== JSON.stringify(v))
if (!lost)
return
}
}
export interface MergeStateJsonCommentGuardedOpts extends MergeStateJsonCommentOpts {