✨ feat(vscode): 审查列可以手动标记为通过

This commit is contained in:
cruldra committed 2026-10-04 10:01:41 +08:00
1 parent 20249d6a08
commit 4094ffa49e
12 files changed
+157 -6

No files matched your search

+4
View File
@@ -598,6 +598,10 @@ export class KanbanWebviewPanel {
void issues.handleUpdateAutoReview(this, msg.issueNumber, msg.value) void issues.handleUpdateAutoReview(this, msg.issueNumber, msg.value)
return return
} }
if (msg.type === 'issue/update-review-passed') {
void issues.handleUpdateReviewPassed(this, msg.issueNumber, msg.value)
return
}
if (msg.type === 'issue/update-profile-path') { if (msg.type === 'issue/update-profile-path') {
void issues.handleUpdateProfilePath(this, msg.issueNumber, msg.profilePath) void issues.handleUpdateProfilePath(this, msg.issueNumber, msg.profilePath)
return return
+79
View File
@@ -1893,6 +1893,85 @@ export async function handleUpdateAutoReview(panel: KanbanWebviewPanel, issueNum
} }
} }
export async function handleUpdateReviewPassed(panel: KanbanWebviewPanel, issueNumber: number, value: boolean): Promise<void> {
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath
if (!workspaceRoot) {
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: '请先打开一个工作区文件夹',
dismissOnTimer: 5000,
})
return
}
const remote = await detectRepo(workspaceRoot)
if (!remote) {
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: '当前工作区没有 Gitea 远程仓库',
dismissOnTimer: 5000,
})
return
}
const token = await getToken(panel.context, remote.host)
if (!token) {
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: '请先完成 Gitea 配置',
dismissOnTimer: 5000,
})
return
}
let previousValue: boolean | undefined
try {
const existingState = await panel.readIssueState(issueNumber)
previousValue = typeof existingState.reviewPassed === 'boolean'
? existingState.reviewPassed
: undefined
}
catch {
previousValue = undefined
}
try {
await panel.mergeIssueState(issueNumber, { reviewPassed: value })
logger.add({
level: 'info',
source: 'panel',
message: `工单 #${issueNumber} reviewPassed=${value} 已持久化`,
})
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'error',
source: 'panel',
message: `持久化 reviewPassed 失败 (issue #${issueNumber})`,
details: message,
})
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: `保存工单 #${issueNumber} 审查通过标记失败: ${message}`,
dismissOnTimer: 6000,
})
panel.postMessage({
type: 'issue/patch',
issueNumber,
patch: { reviewPassed: previousValue },
})
}
}
/** /**
* Persist a per-issue `profilePath` override into the issue's state JSON * Persist a per-issue `profilePath` override into the issue's state JSON
* comment. Implement / implement-resume sessions use this profile * comment. Implement / implement-resume sessions use this profile
+1
View File
@@ -228,6 +228,7 @@ export type WebviewToExtension
| { type: 'dependency/set', issueNumber: number, prerequisiteNumber: number } | { type: 'dependency/set', issueNumber: number, prerequisiteNumber: number }
| { type: 'dependency/clear', issueNumber: number, prerequisiteNumber: number } | { type: 'dependency/clear', issueNumber: number, prerequisiteNumber: number }
| { type: 'issue/update-auto-review', issueNumber: number, value: boolean } | { type: 'issue/update-auto-review', issueNumber: number, value: boolean }
| { type: 'issue/update-review-passed', issueNumber: number, value: boolean }
| { type: 'issue/update-profile-path', issueNumber: number, profilePath: string } | { type: 'issue/update-profile-path', issueNumber: number, profilePath: string }
| { type: 'issue/update-brainstorm-profile-path', issueNumber: number, brainstormProfilePath: string } | { type: 'issue/update-brainstorm-profile-path', issueNumber: number, brainstormProfilePath: string }
| { type: 'issue/clear-session', issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype' } | { type: 'issue/clear-session', issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype' }
+1
View File
@@ -8,6 +8,7 @@ describe('isOwnerOnlyMessage', () => {
expect(isOwnerOnlyMessage('issue/close')).toBe(true) expect(isOwnerOnlyMessage('issue/close')).toBe(true)
expect(isOwnerOnlyMessage('dependency/set')).toBe(true) expect(isOwnerOnlyMessage('dependency/set')).toBe(true)
expect(isOwnerOnlyMessage('issue/update-auto-review')).toBe(true) expect(isOwnerOnlyMessage('issue/update-auto-review')).toBe(true)
expect(isOwnerOnlyMessage('issue/update-review-passed')).toBe(true)
expect(isOwnerOnlyMessage('issue/clear-session')).toBe(true) expect(isOwnerOnlyMessage('issue/clear-session')).toBe(true)
}) })
+1
View File
@@ -27,6 +27,7 @@ export const OWNER_ONLY_MESSAGE_TYPES: ReadonlySet<string> = new Set([
'issue/close', 'issue/close',
'issue/generate-pr-diff-summary', 'issue/generate-pr-diff-summary',
'issue/update-auto-review', 'issue/update-auto-review',
'issue/update-review-passed',
'issue/update-profile-path', 'issue/update-profile-path',
'issue/update-brainstorm-profile-path', 'issue/update-brainstorm-profile-path',
'issue/clear-session', 'issue/clear-session',
+3
View File
@@ -69,6 +69,7 @@ export function App() {
setDependency, setDependency,
clearDependency, clearDependency,
updateIssueAutoReview, updateIssueAutoReview,
updateIssueReviewPassed,
updateIssueProfilePath, updateIssueProfilePath,
updateIssueBrainstormProfilePath, updateIssueBrainstormProfilePath,
updateIssueTestProfilePath, updateIssueTestProfilePath,
@@ -399,6 +400,7 @@ export function App() {
onColumnChange={changeColumn} onColumnChange={changeColumn}
onDependencySet={setDependency} onDependencySet={setDependency}
onDependencyClear={clearDependency} onDependencyClear={clearDependency}
onSetReviewPassed={updateIssueReviewPassed}
me={me} me={me}
avatars={avatars} avatars={avatars}
/> />
@@ -435,6 +437,7 @@ export function App() {
onContinueBrainstorm={continueBrainstorm} onContinueBrainstorm={continueBrainstorm}
onClearSession={clearSession} onClearSession={clearSession}
onUpdateAutoReview={updateIssueAutoReview} onUpdateAutoReview={updateIssueAutoReview}
onUpdateReviewPassed={updateIssueReviewPassed}
onUpdateProfilePath={updateIssueProfilePath} onUpdateProfilePath={updateIssueProfilePath}
onUpdateBrainstormProfilePath={updateIssueBrainstormProfilePath} onUpdateBrainstormProfilePath={updateIssueBrainstormProfilePath}
onUpdateTestProfilePath={updateIssueTestProfilePath} onUpdateTestProfilePath={updateIssueTestProfilePath}
@@ -55,6 +55,7 @@ export interface BottomTabsProps {
onContinueBrainstorm: (issueNumber: number) => void onContinueBrainstorm: (issueNumber: number) => void
onClearSession: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype') => void onClearSession: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype') => void
onUpdateAutoReview: (issueNumber: number, value: boolean) => void onUpdateAutoReview: (issueNumber: number, value: boolean) => void
onUpdateReviewPassed: (issueNumber: number, value: boolean) => void
onUpdateProfilePath: (issueNumber: number, profilePath: string) => void onUpdateProfilePath: (issueNumber: number, profilePath: string) => void
onUpdateBrainstormProfilePath: (issueNumber: number, brainstormProfilePath: string) => void onUpdateBrainstormProfilePath: (issueNumber: number, brainstormProfilePath: string) => void
onUpdateTestProfilePath: (issueNumber: number, testProfilePath: string) => void onUpdateTestProfilePath: (issueNumber: number, testProfilePath: string) => void
@@ -171,6 +172,7 @@ export function BottomTabs(props: BottomTabsProps) {
onContinueBrainstorm={props.onContinueBrainstorm} onContinueBrainstorm={props.onContinueBrainstorm}
onClearSession={props.onClearSession} onClearSession={props.onClearSession}
onUpdateAutoReview={props.onUpdateAutoReview} onUpdateAutoReview={props.onUpdateAutoReview}
onUpdateReviewPassed={props.onUpdateReviewPassed}
onUpdateProfilePath={props.onUpdateProfilePath} onUpdateProfilePath={props.onUpdateProfilePath}
onUpdateBrainstormProfilePath={props.onUpdateBrainstormProfilePath} onUpdateBrainstormProfilePath={props.onUpdateBrainstormProfilePath}
onUpdateTestProfilePath={props.onUpdateTestProfilePath} onUpdateTestProfilePath={props.onUpdateTestProfilePath}
+32 -5
View File
@@ -2,7 +2,7 @@ import type { Ref } from 'react'
import type { Issue } from '../types' import type { Issue } from '../types'
import { useSortable } from '@dnd-kit/sortable' import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities' import { CSS } from '@dnd-kit/utilities'
import { Lock } from 'lucide-react' import { Check, Lock } from 'lucide-react'
import { forwardRef } from 'react' import { forwardRef } from 'react'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { Card } from './ui/card' import { Card } from './ui/card'
@@ -26,6 +26,8 @@ interface IssueCardProps {
ownerLogin?: string ownerLogin?: string
/** 归属人头像 data URI;缺失时回退首字母圆点。 */ /** 归属人头像 data URI;缺失时回退首字母圆点。 */
ownerAvatar?: string ownerAvatar?: string
/** 审查列:手动标通过或改回审查中。 */
onSetReviewPassed?: (issueNumber: number, value: boolean) => void
} }
/** 同事工单的归属人标记:有头像用头像,没有就用 login 首字母。 */ /** 同事工单的归属人标记:有头像用头像,没有就用 login 首字母。 */
@@ -52,7 +54,7 @@ function OwnerBadge({ login, avatar }: { login: string, avatar?: string }) {
} }
export const IssueCard = forwardRef<HTMLDivElement, IssueCardProps>( export const IssueCard = forwardRef<HTMLDivElement, IssueCardProps>(
({ issue, selected, onSelect, depth = 0, locked, lockedPrerequisite, readOnly, ownerLogin, ownerAvatar }, ref) => { ({ issue, selected, onSelect, depth = 0, locked, lockedPrerequisite, readOnly, ownerLogin, ownerAvatar, onSetReviewPassed }, ref) => {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } const { attributes, listeners, setNodeRef, transform, transition, isDragging }
= useSortable({ id: issue.id, data: { column: issue.column }, disabled: readOnly }) = useSortable({ id: issue.id, data: { column: issue.column }, disabled: readOnly })
@@ -72,6 +74,9 @@ export const IssueCard = forwardRef<HTMLDivElement, IssueCardProps>(
(ref as React.MutableRefObject<HTMLDivElement | null>).current = node (ref as React.MutableRefObject<HTMLDivElement | null>).current = node
} }
const showMark = issue.column === 'review' && !readOnly && issue.source !== 'youtrack' && onSetReviewPassed != null
const cornerCount = (showMark ? 1 : 0) + (locked ? 1 : 0) + (readOnly && ownerLogin ? 1 : 0)
return ( return (
<Card <Card
ref={setRefs as unknown as Ref<HTMLDivElement>} ref={setRefs as unknown as Ref<HTMLDivElement>}
@@ -91,6 +96,26 @@ export const IssueCard = forwardRef<HTMLDivElement, IssueCardProps>(
: undefined} : undefined}
> >
<div className="absolute right-1.5 top-1.5 flex items-center gap-1"> <div className="absolute right-1.5 top-1.5 flex items-center gap-1">
{showMark
? (
<button
type="button"
className={cn(
'grid size-3.5 place-items-center rounded-sm hover:bg-black/10 dark:hover:bg-white/10',
issue.reviewPassed === true ? 'text-green-400' : 'text-amber-400',
)}
data-tooltip={issue.reviewPassed === true ? '已通过,点击改回审查中' : '标记为已通过'}
aria-label={issue.reviewPassed === true ? '改回审查中' : '标记为已通过'}
onPointerDown={e => e.stopPropagation()}
onClick={(e) => {
e.stopPropagation()
onSetReviewPassed(issue.number, issue.reviewPassed !== true)
}}
>
<Check className="size-3" />
</button>
)
: null}
{locked {locked
? ( ? (
<span <span
@@ -116,10 +141,12 @@ export const IssueCard = forwardRef<HTMLDivElement, IssueCardProps>(
: null} : null}
<div className={cn( <div className={cn(
'truncate', 'truncate',
(locked || (readOnly && ownerLogin)) && 'pr-5', cornerCount === 1 && 'pr-5',
locked && readOnly && ownerLogin && 'pr-10', cornerCount === 2 && 'pr-10',
cornerCount >= 3 && 'pr-14',
issue.column === 'review' && (issue.reviewPassed === true ? 'text-green-400' : 'text-amber-400'), issue.column === 'review' && (issue.reviewPassed === true ? 'text-green-400' : 'text-amber-400'),
)}> )}
>
<span className="font-mono opacity-60"> <span className="font-mono opacity-60">
{issue.source === 'youtrack' ? issue.externalId : `#${issue.number}`} {issue.source === 'youtrack' ? issue.externalId : `#${issue.number}`}
</span> </span>
@@ -119,6 +119,8 @@ interface IssueDetailPanelProps {
onClearSession: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype') => void onClearSession: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype') => void
/** Persist a per-issue `autoReview` override into the state JSON. */ /** Persist a per-issue `autoReview` override into the state JSON. */
onUpdateAutoReview: (issueNumber: number, value: boolean) => void onUpdateAutoReview: (issueNumber: number, value: boolean) => void
/** 审查列手动标记通过。 */
onUpdateReviewPassed: (issueNumber: number, value: boolean) => void
/** 已知 Claude profile 列表,用于「配置文件」下拉选项。 */ /** 已知 Claude profile 列表,用于「配置文件」下拉选项。 */
profiles: ClaudeProfile[] profiles: ClaudeProfile[]
/** Persist a per-issue `profilePath` override into the state JSON. */ /** Persist a per-issue `profilePath` override into the state JSON. */
@@ -180,6 +182,7 @@ export function IssueDetailPanel({
onContinueBrainstorm, onContinueBrainstorm,
onClearSession, onClearSession,
onUpdateAutoReview, onUpdateAutoReview,
onUpdateReviewPassed,
profiles, profiles,
onUpdateProfilePath, onUpdateProfilePath,
onUpdateBrainstormProfilePath, onUpdateBrainstormProfilePath,
@@ -559,6 +562,14 @@ export function IssueDetailPanel({
type: 'boolean', type: 'boolean',
description: `打开新 PR 时是否自动启动 codex 审查;未设置时跟随全局(当前全局:${globalAutoReview ? '开' : '关'})`, description: `打开新 PR 时是否自动启动 codex 审查;未设置时跟随全局(当前全局:${globalAutoReview ? '开' : '关'})`,
}, },
...(issue?.column === 'review' && issue.source !== 'youtrack'
? [{
key: 'reviewPassed',
label: '审查通过',
type: 'boolean' as const,
description: '手动标成已通过,标题变绿。新的提交会清掉这个标记。',
}]
: []),
{ {
key: 'color', key: 'color',
label: '颜色', label: '颜色',
@@ -772,6 +783,7 @@ export function IssueDetailPanel({
testSessionId: issue.testSessionId ?? null, testSessionId: issue.testSessionId ?? null,
prototypeSessionId: issue.prototypeSessionId ?? null, prototypeSessionId: issue.prototypeSessionId ?? null,
autoReview: issue.autoReview ?? globalAutoReview, autoReview: issue.autoReview ?? globalAutoReview,
reviewPassed: issue.reviewPassed === true,
color: issue.color ?? null, color: issue.color ?? null,
// 展示/选中值按 basename 映射到本机 profiles,避免跨机绝对路径变成「自定义」项。 // 展示/选中值按 basename 映射到本机 profiles,避免跨机绝对路径变成「自定义」项。
brainstormProfilePath: matchProfileOption(issue.brainstormProfilePath, profiles) || null, brainstormProfilePath: matchProfileOption(issue.brainstormProfilePath, profiles) || null,
@@ -1008,6 +1020,8 @@ export function IssueDetailPanel({
return return
if (key === 'autoReview' && issue && typeof value === 'boolean') if (key === 'autoReview' && issue && typeof value === 'boolean')
onUpdateAutoReview(issue.number, value) onUpdateAutoReview(issue.number, value)
if (key === 'reviewPassed' && issue && typeof value === 'boolean')
onUpdateReviewPassed(issue.number, value)
if (key === 'brainstormProfilePath' && issue && typeof value === 'string') if (key === 'brainstormProfilePath' && issue && typeof value === 'string')
onUpdateBrainstormProfilePath(issue.number, value) onUpdateBrainstormProfilePath(issue.number, value)
if (key === 'profilePath' && issue && typeof value === 'string') if (key === 'profilePath' && issue && typeof value === 'string')
@@ -41,6 +41,7 @@ interface KanbanBoardProps {
onColumnChange?: (issueNumber: number, toColumn: IssueColumn, source?: 'gitea' | 'youtrack', externalId?: string) => void onColumnChange?: (issueNumber: number, toColumn: IssueColumn, source?: 'gitea' | 'youtrack', externalId?: string) => void
onDependencySet?: (issueNumber: number, prerequisiteNumber: number) => void onDependencySet?: (issueNumber: number, prerequisiteNumber: number) => void
onDependencyClear?: (issueNumber: number, prerequisiteNumber: number) => void onDependencyClear?: (issueNumber: number, prerequisiteNumber: number) => void
onSetReviewPassed?: (issueNumber: number, value: boolean) => void
/** 当前 Gitea login;用于判定哪些卡是同事的(只读)。 */ /** 当前 Gitea login;用于判定哪些卡是同事的(只读)。 */
me?: string me?: string
/** Gitea login → 头像 data URI。 */ /** Gitea login → 头像 data URI。 */
@@ -117,6 +118,7 @@ export function KanbanBoard({
onColumnChange, onColumnChange,
onDependencySet, onDependencySet,
onDependencyClear, onDependencyClear,
onSetReviewPassed,
me, me,
avatars, avatars,
}: KanbanBoardProps) { }: KanbanBoardProps) {
@@ -281,6 +283,7 @@ export function KanbanBoard({
readOnly={readOnly} readOnly={readOnly}
ownerLogin={ownerLogin} ownerLogin={ownerLogin}
ownerAvatar={ownerLogin ? avatars?.[ownerLogin] : undefined} ownerAvatar={ownerLogin ? avatars?.[ownerLogin] : undefined}
onSetReviewPassed={onSetReviewPassed}
/> />
) )
})} })}
+16 -1
View File
@@ -232,6 +232,7 @@ export interface UseIssuesResult {
setDependency: (issueNumber: number, prerequisiteNumber: number) => void setDependency: (issueNumber: number, prerequisiteNumber: number) => void
clearDependency: (issueNumber: number, prerequisiteNumber: number) => void clearDependency: (issueNumber: number, prerequisiteNumber: number) => void
updateIssueAutoReview: (issueNumber: number, value: boolean) => void updateIssueAutoReview: (issueNumber: number, value: boolean) => void
updateIssueReviewPassed: (issueNumber: number, value: boolean) => void
/** /**
* 覆盖该工单实施会话使用的 Claude 配置文件,乐观更新本地 state 后 * 覆盖该工单实施会话使用的 Claude 配置文件,乐观更新本地 state 后
* postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。 * postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。
@@ -730,6 +731,20 @@ export function useIssues(): UseIssuesResult {
postMessage({ type: 'issue/update-auto-review', issueNumber, value }) postMessage({ type: 'issue/update-auto-review', issueNumber, value })
}, []) }, [])
const updateIssueReviewPassed = useCallback((issueNumber: number, value: boolean): void => {
setState((prev) => {
if (prev.status !== 'ready')
return prev
return {
status: 'ready',
issues: prev.issues.map(i =>
i.number === issueNumber ? { ...i, reviewPassed: value } : i,
),
}
})
postMessage({ type: 'issue/update-review-passed', issueNumber, value })
}, [])
const updateIssueProfilePath = useCallback((issueNumber: number, profilePath: string): void => { const updateIssueProfilePath = useCallback((issueNumber: number, profilePath: string): void => {
// Optimistically update local state so the dropdown reflects immediately // Optimistically update local state so the dropdown reflects immediately
// without remounting the issues list / detail panel via a full reload. // without remounting the issues list / detail panel via a full reload.
@@ -1097,5 +1112,5 @@ export function useIssues(): UseIssuesResult {
]) ])
}, [state, me]) }, [state, me])
return { state, settings, avatars, isSessionTabPending, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, refreshing, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startReviewSession, startTestSession, resumeTestSession, startPrototypeSession, resumePrototypeSession, focusSession, openFile, openPrototypeInFigma, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, clearSession, updateIssueTestProfilePath, updateIssuePrototypeProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, pendingSelectTab, clearPendingSelectTab, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning, askHandoff, cancelHandoffRequest, acceptHandoffRequest, rejectHandoffRequest } return { state, settings, avatars, isSessionTabPending, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, refreshing, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startReviewSession, startTestSession, resumeTestSession, startPrototypeSession, resumePrototypeSession, focusSession, openFile, openPrototypeInFigma, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueReviewPassed, updateIssueProfilePath, updateIssueBrainstormProfilePath, clearSession, updateIssueTestProfilePath, updateIssuePrototypeProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, pendingSelectTab, clearPendingSelectTab, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning, askHandoff, cancelHandoffRequest, acceptHandoffRequest, rejectHandoffRequest }
} }
+1
View File
@@ -267,6 +267,7 @@ export type WebviewToExtension
| { type: 'dependency/set', issueNumber: number, prerequisiteNumber: number } | { type: 'dependency/set', issueNumber: number, prerequisiteNumber: number }
| { type: 'dependency/clear', issueNumber: number, prerequisiteNumber: number } | { type: 'dependency/clear', issueNumber: number, prerequisiteNumber: number }
| { type: 'issue/update-auto-review', issueNumber: number, value: boolean } | { type: 'issue/update-auto-review', issueNumber: number, value: boolean }
| { type: 'issue/update-review-passed', issueNumber: number, value: boolean }
| { type: 'issue/update-profile-path', issueNumber: number, profilePath: string } | { type: 'issue/update-profile-path', issueNumber: number, profilePath: string }
| { type: 'issue/update-brainstorm-profile-path', issueNumber: number, brainstormProfilePath: string } | { type: 'issue/update-brainstorm-profile-path', issueNumber: number, brainstormProfilePath: string }
| { type: 'issue/clear-session', issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype' } | { type: 'issue/clear-session', issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test' | 'prototype' }