✨ feat(vscode): 申请移交时给负责人发系统通知
This commit is contained in:
1 parent
5bcbb87152
commit
a1fac829f8
3 files changed
+108
-1
No files matched your search
@@ -28,6 +28,7 @@ import { hasReviewMarker, parseClosingIssueNumber, stripReviewMarker } from '../
|
||||
import { hasStateColumn, mergeStateJsonComment, mergeStateJsonCommentGuarded, readStateJsonComment } from '../gitea/stateJson'
|
||||
import { getLocalIssueState, mergeLocalIssueState, overlayLocalIssueState } from '../issues/localState'
|
||||
import { logger } from '../logging/logger'
|
||||
import { handoffRequestSystemNotice } from '../panel/handlers/handoffRequest'
|
||||
import * as issueChat from '../panel/handlers/issueChat'
|
||||
import { hasLiveIssueSessionTerminal } from '../panel/handlers/terminals'
|
||||
import { DEFAULT_KANBAN_SCOPE, KANBAN_SCOPE_KEY } from '../panel/kanbanScope'
|
||||
@@ -68,6 +69,16 @@ const BODY_MARKERS = [
|
||||
/** 本次从 body 里扫出来的 marker 值,按 state JSON 字段名索引。 */
|
||||
type MarkerPatch = { [K in typeof BODY_MARKERS[number]['field']]?: string }
|
||||
|
||||
function handoffRequestFromOf(body: string): string {
|
||||
try {
|
||||
const obj = JSON.parse(body) as { handoffRequestFrom?: unknown }
|
||||
return typeof obj.handoffRequestFrom === 'string' ? obj.handoffRequestFrom.trim() : ''
|
||||
}
|
||||
catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function parseBodyMarkers(body: string): MarkerPatch {
|
||||
const out: MarkerPatch = {}
|
||||
for (const { type, field, ext } of BODY_MARKERS) {
|
||||
@@ -100,6 +111,8 @@ class WebhookCoordinator {
|
||||
private eventSubscription?: { dispose: () => void }
|
||||
/** 同 issue 自动审查启动中不重入(opened 与 synchronize 常连发)。 */
|
||||
private reviewInFlight = new Set<number>()
|
||||
/** 已经为这条移交申请通知过负责人。申请取消后清掉。 */
|
||||
private handoffRequestSeen = new Map<number, string>()
|
||||
|
||||
/** Called once from extension.ts activate(). Idempotent. */
|
||||
init(ctx: ExtensionContext): void {
|
||||
@@ -1436,6 +1449,55 @@ class WebhookCoordinator {
|
||||
* first review and `injectIntoImplTerminal` appends the merge-to-main
|
||||
* suffix.
|
||||
*/
|
||||
/** 申请移交时给负责人发系统通知。看板关着也发。 */
|
||||
private async notifyHandoffRequest(event: IssueCommentWebhookEvent): Promise<void> {
|
||||
const from = handoffRequestFromOf(event.commentBody)
|
||||
if (!from) {
|
||||
this.handoffRequestSeen.delete(event.issueNumber)
|
||||
return
|
||||
}
|
||||
const seen = this.handoffRequestSeen.get(event.issueNumber) ?? ''
|
||||
if (from === seen || !this.ctx)
|
||||
return
|
||||
const ws = workspace.workspaceFolders?.[0]?.uri.fsPath
|
||||
if (!ws)
|
||||
return
|
||||
const remote = await detectRepo(ws)
|
||||
if (!remote)
|
||||
return
|
||||
const token = await getToken(this.ctx, remote.host)
|
||||
if (!token)
|
||||
return
|
||||
const me = await loginForToken(remote.host, token)
|
||||
const payload = event.raw as { issue?: { assignees?: Array<{ login?: string } | null> | null } | null } | null
|
||||
const assignees = (payload?.issue?.assignees ?? []).flatMap(a => (a?.login ? [a.login] : []))
|
||||
if (!me || assignees.length === 0)
|
||||
return
|
||||
const notice = handoffRequestSystemNotice({
|
||||
issueNumber: event.issueNumber,
|
||||
me,
|
||||
assignees,
|
||||
from,
|
||||
seenFrom: seen,
|
||||
})
|
||||
this.handoffRequestSeen.set(event.issueNumber, from)
|
||||
if (!notice)
|
||||
return
|
||||
execFile('osascript', [
|
||||
'-e',
|
||||
`display notification ${JSON.stringify('打开看板同意或拒绝')} with title ${JSON.stringify(notice)}`,
|
||||
], (err) => {
|
||||
if (err) {
|
||||
logger.add({
|
||||
level: 'warn',
|
||||
source: 'webhook',
|
||||
message: `移交申请通知发送失败 #${event.issueNumber}`,
|
||||
details: err.message,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private async handleIssueCommentCreated(event: IssueCommentWebhookEvent): Promise<void> {
|
||||
if (event.action !== 'created') {
|
||||
logger.add({
|
||||
@@ -1519,6 +1581,7 @@ class WebhookCoordinator {
|
||||
source: 'webhook',
|
||||
message: `issue_comment 是 state 评论,刷新 #${event.issueNumber} 的卡片`,
|
||||
})
|
||||
await this.notifyHandoffRequest(event)
|
||||
await this.refreshIssueCard({
|
||||
issueNumber: event.issueNumber,
|
||||
raw: event.raw,
|
||||
|
||||
Reference in new issue
Block a user