✨ 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:
@@ -17,11 +17,10 @@
|
||||
* still display the issue in the computed column.
|
||||
*/
|
||||
|
||||
import * as fs from 'node:fs'
|
||||
import * as path from 'node:path'
|
||||
import { resolveWorktreePath } from '../git/worktree'
|
||||
import type { GiteaComment, GiteaIssue } from './api'
|
||||
import type { Issue, IssueColumn } from './types'
|
||||
import * as fs from 'node:fs'
|
||||
import { resolveWorktreePath } from '../git/worktree'
|
||||
import {
|
||||
getCurrentUser,
|
||||
getDependencies,
|
||||
@@ -52,7 +51,7 @@ export function isValidSpxFilePath(v: unknown): v is string {
|
||||
|
||||
function isValidPrDiffFilePath(v: unknown): v is string {
|
||||
return typeof v === 'string'
|
||||
&& /^docs\/pr-diff\/[^\s]+\.md$/.test(v)
|
||||
&& /^docs\/pr-diff\/\S+\.md$/.test(v)
|
||||
}
|
||||
|
||||
function isIssueColumn(value: unknown): value is IssueColumn {
|
||||
@@ -351,7 +350,6 @@ async function buildIssue(opts: {
|
||||
})
|
||||
}
|
||||
catch (postErr) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`[superpowers] failed to seed state comment on ${id}:`, postErr)
|
||||
}
|
||||
}
|
||||
@@ -405,24 +403,34 @@ export async function loadIssues(opts: {
|
||||
repo: string
|
||||
/** Absolute workspace root used to resolve `worktreeExists` against disk. */
|
||||
workspaceRoot?: string
|
||||
/** 'mine'(默认) = assigned+created 给我的;'all' = 仓库全部工单(团队视图)。 */
|
||||
scope?: 'mine' | 'all'
|
||||
}): Promise<Issue[]> {
|
||||
const { host, token, owner, repo, workspaceRoot } = opts
|
||||
|
||||
// `/user` validates the token and gives us the login. The repo-wide
|
||||
// comments firehose doesn't need the login, so we kick it off in parallel.
|
||||
// The two issue-filter calls need `user.login` and run together after.
|
||||
const userPromise = getCurrentUser({ host, token })
|
||||
// The repo-wide comments firehose doesn't depend on scope; kick it off first.
|
||||
const commentsPromise = listAllRepoComments({ host, token, owner, repo })
|
||||
|
||||
const user = await userPromise
|
||||
|
||||
const [assigned, created, allComments] = await Promise.all([
|
||||
listIssuesByFilter({ host, token, owner, repo, filter: 'assigned_by', user: user.login }),
|
||||
listIssuesByFilter({ host, token, owner, repo, filter: 'created_by', user: user.login }),
|
||||
commentsPromise,
|
||||
])
|
||||
|
||||
const merged = mergeIssues(assigned, created)
|
||||
let merged: Awaited<ReturnType<typeof listIssuesByFilter>>
|
||||
let allComments: Awaited<typeof commentsPromise>
|
||||
if (opts.scope === 'all') {
|
||||
;[merged, allComments] = await Promise.all([
|
||||
listIssuesByFilter({ host, token, owner, repo }),
|
||||
commentsPromise,
|
||||
])
|
||||
}
|
||||
else {
|
||||
// `/user` validates the token and gives us the login. The two
|
||||
// issue-filter calls need `user.login` and run together after.
|
||||
const user = await getCurrentUser({ host, token })
|
||||
const [assigned, created, comments] = await Promise.all([
|
||||
listIssuesByFilter({ host, token, owner, repo, filter: 'assigned_by', user: user.login }),
|
||||
listIssuesByFilter({ host, token, owner, repo, filter: 'created_by', user: user.login }),
|
||||
commentsPromise,
|
||||
])
|
||||
merged = mergeIssues(assigned, created)
|
||||
allComments = comments
|
||||
}
|
||||
const buckets = groupCommentsByIssue(allComments)
|
||||
|
||||
// 先用各工单评论 bucket 算出 column,决定是否需要 per-issue 远程拉取。
|
||||
|
||||
Reference in New Issue
Block a user