✨ feat(vscode): 头脑风暴会话可清除,悬停提示改窄改紧凑

工单记着的头脑风暴会话 id 此前没有清除入口,续聊只能 resume 旧会话,
把几个版本前的提示词和它当时报的错一起带回来。会话 id 行新增清除按钮,
确认后把 state JSON 的 sessionId 置空,下次续聊新开会话;会话文件不动,
手上有 id 仍可 claude --resume 找回。

悬停气泡此前贴着视口右边测量尺寸:fixed 元素的可用宽度是「视口宽 - left」,
贴边测会被挤窄、行数变多,按那个高度定位就浮高一截。改成先在左上角量再落位,
字号行高收紧,提示文案压成一行。顺带修掉「重置为待办」的错误说明——它会停
会话、删 worktree 和未合并 PR,不是原样保留。

Claude-Session: https://claude.ai/code/session_01REdhpbaNyqWASF2HWsnTFv
This commit is contained in:
cruldra committed 2026-09-13 09:21:53 +08:00
1 parent 9fadcac12b
commit 5bfd759822
11 files changed
+124 -23

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@
"publisher": "clurdra", "publisher": "clurdra",
"name": "superpowers-vscode-clurdra", "name": "superpowers-vscode-clurdra",
"displayName": "Superpowers-clurdra", "displayName": "Superpowers-clurdra",
"version": "0.2.130", "version": "0.2.131",
"packageManager": "pnpm@10.27.0", "packageManager": "pnpm@10.27.0",
"description": "Superpowers specs and plans Kanban explorer", "description": "Superpowers specs and plans Kanban explorer",
"author": "clurdra", "author": "clurdra",
+4
View File
@@ -538,6 +538,10 @@ export class KanbanWebviewPanel {
void issues.handleUpdateBrainstormProfilePath(this, msg.issueNumber, msg.brainstormProfilePath) void issues.handleUpdateBrainstormProfilePath(this, msg.issueNumber, msg.brainstormProfilePath)
return return
} }
if (msg.type === 'issue/clear-brainstorm-session') {
void issues.handleClearBrainstormSession(this, msg.issueNumber)
return
}
if (msg.type === 'issue/update-test-profile-path') { if (msg.type === 'issue/update-test-profile-path') {
void issues.handleUpdateTestProfilePath(this, msg.issueNumber, msg.testProfilePath) void issues.handleUpdateTestProfilePath(this, msg.issueNumber, msg.testProfilePath)
return return
+71
View File
@@ -1976,6 +1976,77 @@ export async function handleUpdateProfilePath(panel: KanbanWebviewPanel, issueNu
} }
} }
/**
* 清掉工单记的头脑风暴会话 id,下次点 ▶ 续聊就新开一个会话。
*
* 用处:旧会话的历史被 `claude --resume` 原样带回来(里面可能还留着几个版本
* 之前的提示词和它报的错),想从干净的上下文重新聊需求时用。会话文件本身不动,
* 手上有 id 仍可用 `claude --resume <id>` 找回。
*/
export async function handleClearBrainstormSession(panel: KanbanWebviewPanel, issueNumber: number): Promise<void> {
let previousValue: string | undefined
try {
const existingState = await panel.readIssueState(issueNumber)
previousValue = typeof existingState.sessionId === 'string' ? existingState.sessionId : undefined
}
catch {
previousValue = undefined
}
if (!previousValue) {
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'info',
message: `工单 #${issueNumber} 本来就没有头脑风暴会话`,
dismissOnTimer: 4000,
})
return
}
const choice = await window.showWarningMessage(
`确定清除工单 #${issueNumber} 的头脑风暴会话 id(${previousValue})?下次续聊会新开一个会话,旧会话记录还在,可用 claude --resume 找回。`,
{ modal: true },
'清除',
)
if (choice !== '清除')
return
try {
await panel.mergeIssueState(issueNumber, { sessionId: '' })
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'error',
source: 'panel',
message: `清除 sessionId 失败 (issue #${issueNumber})`,
details: message,
})
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'error',
message: `清除工单 #${issueNumber} 头脑风暴会话失败: ${message}`,
dismissOnTimer: 6000,
})
return
}
panel.postMessage({
type: 'issue/patch',
issueNumber,
patch: { sessionId: null },
})
panel.postMessage({
type: 'toast/show',
id: makeNonce(),
level: 'success',
message: `工单 #${issueNumber} 头脑风暴会话已清除,下次续聊将新开会话`,
dismissOnTimer: 5000,
})
}
/** /**
* Persist a per-issue `brainstormProfilePath` override into the issue's state * Persist a per-issue `brainstormProfilePath` override into the issue's state
* JSON. Brainstorm start/resume use this profile (see resolveBrainstormProfilePath); * JSON. Brainstorm start/resume use this profile (see resolveBrainstormProfilePath);
+1
View File
@@ -213,6 +213,7 @@ export type WebviewToExtension
| { type: 'issue/update-auto-review', issueNumber: number, value: boolean } | { type: 'issue/update-auto-review', 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-brainstorm-session', issueNumber: number }
| { type: 'issue/update-test-profile-path', issueNumber: number, testProfilePath: string } | { type: 'issue/update-test-profile-path', issueNumber: number, testProfilePath: string }
| { type: 'logs/fetch' } | { type: 'logs/fetch' }
| { type: 'logs/clear' } | { type: 'logs/clear' }
+1
View File
@@ -26,6 +26,7 @@ export const OWNER_ONLY_MESSAGE_TYPES: ReadonlySet<string> = new Set([
'issue/update-auto-review', 'issue/update-auto-review',
'issue/update-profile-path', 'issue/update-profile-path',
'issue/update-brainstorm-profile-path', 'issue/update-brainstorm-profile-path',
'issue/clear-brainstorm-session',
'issue/update-test-profile-path', 'issue/update-test-profile-path',
'dependency/set', 'dependency/set',
'dependency/clear', 'dependency/clear',
+2
View File
@@ -56,6 +56,7 @@ export function App() {
closeIssue, closeIssue,
closeSessionTab, closeSessionTab,
continueBrainstorm, continueBrainstorm,
clearBrainstormSession,
changeColumn, changeColumn,
setDependency, setDependency,
clearDependency, clearDependency,
@@ -388,6 +389,7 @@ export function App() {
onResetToTodo={n => changeColumn(n, 'todo', selectedIssue?.source, selectedIssue?.externalId)} onResetToTodo={n => changeColumn(n, 'todo', selectedIssue?.source, selectedIssue?.externalId)}
onCloseSessionTab={closeSessionTab} onCloseSessionTab={closeSessionTab}
onContinueBrainstorm={continueBrainstorm} onContinueBrainstorm={continueBrainstorm}
onClearBrainstormSession={clearBrainstormSession}
onUpdateAutoReview={updateIssueAutoReview} onUpdateAutoReview={updateIssueAutoReview}
onUpdateProfilePath={updateIssueProfilePath} onUpdateProfilePath={updateIssueProfilePath}
onUpdateBrainstormProfilePath={updateIssueBrainstormProfilePath} onUpdateBrainstormProfilePath={updateIssueBrainstormProfilePath}
@@ -45,6 +45,7 @@ interface BottomTabsProps {
onResetToTodo: (issueNumber: number) => void onResetToTodo: (issueNumber: number) => void
onCloseSessionTab: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test') => void onCloseSessionTab: (issueNumber: number, kind: 'brainstorm' | 'implement' | 'review' | 'test') => void
onContinueBrainstorm: (issueNumber: number) => void onContinueBrainstorm: (issueNumber: number) => void
onClearBrainstormSession: (issueNumber: number) => void
onUpdateAutoReview: (issueNumber: number, value: boolean) => void onUpdateAutoReview: (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
@@ -142,6 +143,7 @@ export function BottomTabs(props: BottomTabsProps) {
onResetToTodo={props.onResetToTodo} onResetToTodo={props.onResetToTodo}
onCloseSessionTab={props.onCloseSessionTab} onCloseSessionTab={props.onCloseSessionTab}
onContinueBrainstorm={props.onContinueBrainstorm} onContinueBrainstorm={props.onContinueBrainstorm}
onClearBrainstormSession={props.onClearBrainstormSession}
onUpdateAutoReview={props.onUpdateAutoReview} onUpdateAutoReview={props.onUpdateAutoReview}
onUpdateProfilePath={props.onUpdateProfilePath} onUpdateProfilePath={props.onUpdateProfilePath}
onUpdateBrainstormProfilePath={props.onUpdateBrainstormProfilePath} onUpdateBrainstormProfilePath={props.onUpdateBrainstormProfilePath}
@@ -1,7 +1,7 @@
import type { ClaudeProfile } from '../hooks/useIssues' import type { ClaudeProfile } from '../hooks/useIssues'
import type { Issue, IssueColumn } from '../types' import type { Issue, IssueColumn } from '../types'
import type { PropertyGroup, RowAction } from './property-grid' import type { PropertyGroup, RowAction } from './property-grid'
import { ArrowRightLeft, CircleSlash, Download, ExternalLink, GitMerge, Loader2, Play, RotateCcw, Terminal, Trash2, X } from 'lucide-react' import { ArrowRightLeft, CircleSlash, Download, Eraser, ExternalLink, GitMerge, Loader2, Play, RotateCcw, Terminal, Trash2, X } from 'lucide-react'
import { useMemo, useRef } from 'react' import { useMemo, useRef } from 'react'
import { isIssueLocked } from '../lib/dependencies' import { isIssueLocked } from '../lib/dependencies'
import { isIssueMine, issueOwnerLogin } from '../lib/issueOwnership' import { isIssueMine, issueOwnerLogin } from '../lib/issueOwnership'
@@ -93,6 +93,7 @@ interface IssueDetailPanelProps {
* 打进去,关了就 `claude --resume <id>` 带着提示词恢复,没会话就新开一个。 * 打进去,关了就 `claude --resume <id>` 带着提示词恢复,没会话就新开一个。
*/ */
onContinueBrainstorm: (issueNumber: number) => void onContinueBrainstorm: (issueNumber: number) => void
onClearBrainstormSession: (issueNumber: number) => 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
/** 已知 Claude profile 列表,用于「配置文件」下拉选项。 */ /** 已知 Claude profile 列表,用于「配置文件」下拉选项。 */
@@ -144,6 +145,7 @@ export function IssueDetailPanel({
onResetToTodo, onResetToTodo,
onCloseSessionTab, onCloseSessionTab,
onContinueBrainstorm, onContinueBrainstorm,
onClearBrainstormSession,
onUpdateAutoReview, onUpdateAutoReview,
profiles, profiles,
onUpdateProfilePath, onUpdateProfilePath,
@@ -236,6 +238,16 @@ export function IssueDetailPanel({
}, },
}) })
} }
if (hasSession) {
secondaryActions.push({
icon: <Eraser className="size-3.5" />,
title: '清除会话:下次续聊新开一个,不再带旧会话的历史',
onClick: () => {
if (issue)
onClearBrainstormSession(issue.number)
},
})
}
return { return {
key: 'sessionId', key: 'sessionId',
label: '头脑风暴会话id', label: '头脑风暴会话id',
@@ -523,7 +535,7 @@ export function IssueDetailPanel({
], ],
}, },
], ],
[onResumeSession, onResumeReviewSession, onResumeTestSession, onStartTestSession, onOpenFile, onImplement, onOpenPr, onGeneratePrDiffSummary, onOpenWorktree, onDeleteWorktree, onMergeBranch, onCloseSessionTab, onContinueBrainstorm, onOpenLogs, issue, locked, lockTitle, globalAutoReview, prDiffSummaryRunning, profiles], [onResumeSession, onResumeReviewSession, onResumeTestSession, onStartTestSession, onOpenFile, onImplement, onOpenPr, onGeneratePrDiffSummary, onOpenWorktree, onDeleteWorktree, onMergeBranch, onCloseSessionTab, onContinueBrainstorm, onClearBrainstormSession, onOpenLogs, issue, locked, lockTitle, globalAutoReview, prDiffSummaryRunning, profiles],
) )
// 同事的工单只读:属性表统一消毒,顶部只留查看类按钮。 // 同事的工单只读:属性表统一消毒,顶部只留查看类按钮。
@@ -617,7 +629,7 @@ export function IssueDetailPanel({
</span> </span>
) )
: null} : null}
<Tooltip label={issue.source === 'youtrack' ? '在浏览器里打开这张 YouTrack 卡' : '在浏览器里打开这个 Gitea 工单'}> <Tooltip label="在浏览器里打开">
<button <button
type="button" type="button"
onClick={() => onOpenInBrowser(issue.htmlUrl)} onClick={() => onOpenInBrowser(issue.htmlUrl)}
@@ -632,7 +644,7 @@ export function IssueDetailPanel({
{issue.source !== 'youtrack' && !readOnly && ( {issue.source !== 'youtrack' && !readOnly && (
<> <>
{issue.handoffAttachmentId && me !== undefined && (issue.assignees ?? []).includes(me) && ( {issue.handoffAttachmentId && me !== undefined && (issue.assignees ?? []).includes(me) && (
<Tooltip label={`接管 ${issue.handoffFrom ?? '?'} 移交过来的工单:拉回会话记录和 worktree`}> <Tooltip label={`接管 ${issue.handoffFrom ?? '?'} 的移交`}>
<button <button
type="button" type="button"
disabled={isHandoffRunning(issue.number)} disabled={isHandoffRunning(issue.number)}
@@ -646,7 +658,7 @@ export function IssueDetailPanel({
</Tooltip> </Tooltip>
)} )}
{!issue.handoffAttachmentId && issue.column !== 'done' && ((issue.assignees ?? []).length === 0 || (me !== undefined && (issue.assignees ?? []).includes(me))) && ( {!issue.handoffAttachmentId && issue.column !== 'done' && ((issue.assignees ?? []).length === 0 || (me !== undefined && (issue.assignees ?? []).includes(me))) && (
<Tooltip label="移交给同事:把会话记录打包传过去,对方接管后继续做"> <Tooltip label="移交给同事">
<button <button
type="button" type="button"
disabled={isHandoffRunning(issue.number)} disabled={isHandoffRunning(issue.number)}
@@ -659,14 +671,14 @@ export function IssueDetailPanel({
</Tooltip> </Tooltip>
)} )}
{issue.handoffAttachmentId && !(me !== undefined && (issue.assignees ?? []).includes(me)) && ( {issue.handoffAttachmentId && !(me !== undefined && (issue.assignees ?? []).includes(me)) && (
<Tooltip label={`${issue.handoffFrom ?? '?'} 已移交,等待 ${(issue.assignees ?? []).join(', ') || '?'} 接管`}> <Tooltip label={`${issue.handoffFrom ?? '?'} 已移交,等 ${(issue.assignees ?? []).join(', ') || '?'} 接管`}>
<span className="inline-flex shrink-0 items-center rounded border border-[var(--vscode-panel-border)] px-1.5 py-0.5 text-[10px] opacity-70"> <span className="inline-flex shrink-0 items-center rounded border border-[var(--vscode-panel-border)] px-1.5 py-0.5 text-[10px] opacity-70">
待接管 待接管
</span> </span>
</Tooltip> </Tooltip>
)} )}
{(issue.column === 'in-progress' || issue.column === 'review') && ( {(issue.column === 'in-progress' || issue.column === 'review') && (
<Tooltip label="打回待办:卡片挪回待办列,会话和 worktree 不动"> <Tooltip label="重置为待办(停会话、删 worktree 和未合并 PR)">
<button <button
type="button" type="button"
onClick={() => onResetToTodo(issue.number)} onClick={() => onResetToTodo(issue.number)}
@@ -677,7 +689,7 @@ export function IssueDetailPanel({
</button> </button>
</Tooltip> </Tooltip>
)} )}
<Tooltip label="关闭工单:Gitea 上置为 closed,卡片从看板消失,可在 Gitea 里重开"> <Tooltip label="关闭工单(Gitea 里可重开)">
<button <button
type="button" type="button"
onClick={() => onCloseIssue(issue.number)} onClick={() => onCloseIssue(issue.number)}
@@ -687,7 +699,7 @@ export function IssueDetailPanel({
<CircleSlash className="size-3.5" /> <CircleSlash className="size-3.5" />
</button> </button>
</Tooltip> </Tooltip>
<Tooltip label="删除工单:从 Gitea 彻底删掉,不可撤销"> <Tooltip label="删除工单(不可撤销)">
<button <button
type="button" type="button"
onClick={() => issue && onDeleteIssue?.(issue.number)} onClick={() => issue && onDeleteIssue?.(issue.number)}
+11 -12
View File
@@ -25,14 +25,14 @@ interface TooltipProps {
* 上方放不下就翻到下方,左右钳在视口内。 * 上方放不下就翻到下方,左右钳在视口内。
*/ */
export function Tooltip({ label, children, className }: TooltipProps): ReactElement { export function Tooltip({ label, children, className }: TooltipProps): ReactElement {
const [pos, setPos] = useState<{ top: number, left: number } | null>(null) const [visible, setVisible] = useState(false)
const wrapRef = useRef<HTMLSpanElement | null>(null) const wrapRef = useRef<HTMLSpanElement | null>(null)
const bubbleRef = useRef<HTMLDivElement | null>(null) const bubbleRef = useRef<HTMLDivElement | null>(null)
const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined) const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
const hide = useCallback((): void => { const hide = useCallback((): void => {
clearTimeout(timerRef.current) clearTimeout(timerRef.current)
setPos(null) setVisible(false)
}, []) }, [])
const show = useCallback((): void => { const show = useCallback((): void => {
@@ -40,18 +40,17 @@ export function Tooltip({ label, children, className }: TooltipProps): ReactElem
return return
clearTimeout(timerRef.current) clearTimeout(timerRef.current)
timerRef.current = setTimeout(() => { timerRef.current = setTimeout(() => {
const rect = wrapRef.current?.getBoundingClientRect() if (wrapRef.current)
if (rect) setVisible(true)
setPos({ top: rect.top, left: rect.left + rect.width / 2 })
}, SHOW_DELAY_MS) }, SHOW_DELAY_MS)
}, [label]) }, [label])
useEffect(() => () => clearTimeout(timerRef.current), []) useEffect(() => () => clearTimeout(timerRef.current), [])
// 气泡渲染后才知道自身尺寸,这时才能定最终位置:默认在上方, // 气泡先在左上角量一次尺寸再落位。必须量在 left:0:fixed 元素的可用宽度是
// 上方空间不够就翻到触发元素下方;水平居中后钳进视口。 // 「视口宽 - left」,贴右边量会被挤窄、行数变多,按那个高度定位就会浮高一截。
useEffect(() => { useEffect(() => {
if (!pos) if (!visible)
return return
const bubble = bubbleRef.current const bubble = bubbleRef.current
const rect = wrapRef.current?.getBoundingClientRect() const rect = wrapRef.current?.getBoundingClientRect()
@@ -65,7 +64,7 @@ export function Tooltip({ label, children, className }: TooltipProps): ReactElem
bubble.style.top = `${top}px` bubble.style.top = `${top}px`
bubble.style.left = `${left}px` bubble.style.left = `${left}px`
bubble.style.visibility = 'visible' bubble.style.visibility = 'visible'
}, [pos]) }, [visible])
return ( return (
<> <>
@@ -80,12 +79,12 @@ export function Tooltip({ label, children, className }: TooltipProps): ReactElem
> >
{children} {children}
</span> </span>
{pos && label && createPortal( {visible && label && createPortal(
<div <div
ref={bubbleRef} ref={bubbleRef}
role="tooltip" role="tooltip"
style={{ top: pos.top, left: pos.left, visibility: 'hidden' }} style={{ top: 0, left: 0, visibility: 'hidden' }}
className="pointer-events-none fixed z-50 max-w-64 rounded border border-[var(--vscode-editorHoverWidget-border,var(--vscode-panel-border))] bg-[var(--vscode-editorHoverWidget-background,var(--vscode-editorWidget-background))] px-2 py-1 text-xs leading-snug text-[var(--vscode-editorHoverWidget-foreground,var(--vscode-foreground))] shadow-md" className="pointer-events-none fixed z-50 max-w-[22rem] rounded border border-[var(--vscode-editorHoverWidget-border,var(--vscode-panel-border))] bg-[var(--vscode-editorHoverWidget-background,var(--vscode-editorWidget-background))] px-2 py-1 text-[11px] leading-tight break-words text-[var(--vscode-editorHoverWidget-foreground,var(--vscode-foreground))] shadow-md"
> >
{label} {label}
</div>, </div>,
+9 -1
View File
@@ -230,6 +230,8 @@ export interface UseIssuesResult {
* postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。 * postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。
*/ */
updateIssueBrainstormProfilePath: (issueNumber: number, brainstormProfilePath: string) => void updateIssueBrainstormProfilePath: (issueNumber: number, brainstormProfilePath: string) => void
/** 清掉工单记的头脑风暴会话 id,下次续聊新开会话。 */
clearBrainstormSession: (issueNumber: number) => void
/** /**
* 覆盖该工单测试会话专用的 Claude 配置文件,乐观更新本地 state 后 * 覆盖该工单测试会话专用的 Claude 配置文件,乐观更新本地 state 后
* postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。 * postMessage 持久化到 state JSON。失败时扩展端 push `issue/patch` 回滚。
@@ -652,6 +654,12 @@ export function useIssues(): UseIssuesResult {
postMessage({ type: 'issue/update-brainstorm-profile-path', issueNumber, brainstormProfilePath }) postMessage({ type: 'issue/update-brainstorm-profile-path', issueNumber, brainstormProfilePath })
}, []) }, [])
// 清除头脑风暴会话 id:扩展侧先弹确认框,确认后才落库并推 issue/patch,
// 所以这里不做乐观更新。
const clearBrainstormSession = useCallback((issueNumber: number): void => {
postMessage({ type: 'issue/clear-brainstorm-session', issueNumber })
}, [])
const updateIssueTestProfilePath = useCallback((issueNumber: number, testProfilePath: string): void => { const updateIssueTestProfilePath = useCallback((issueNumber: number, testProfilePath: 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.
@@ -930,5 +938,5 @@ export function useIssues(): UseIssuesResult {
return cleanup return cleanup
}, [clearPrDiffSummaryRunning, markHandoffRunning]) }, [clearPrDiffSummaryRunning, markHandoffRunning])
return { state, settings, avatars, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, refreshing, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning } return { state, settings, avatars, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, refreshing, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, clearBrainstormSession, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning }
} }
+1
View File
@@ -244,6 +244,7 @@ export type WebviewToExtension
| { type: 'issue/update-auto-review', issueNumber: number, value: boolean } | { type: 'issue/update-auto-review', 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-brainstorm-session', issueNumber: number }
| { type: 'issue/update-test-profile-path', issueNumber: number, testProfilePath: string } | { type: 'issue/update-test-profile-path', issueNumber: number, testProfilePath: string }
| { type: 'logs/fetch' } | { type: 'logs/fetch' }
| { type: 'logs/clear' } | { type: 'logs/clear' }