feat(vscode): 头脑风暴 profile 独立 + codex 命令统一组装收尾

- 头脑风暴/实施/测试会话 profile 彻底独立,互不回退,各自空值回落默认
- 新建工单弹窗的 profile 选择改为头脑风暴专用 brainstormProfilePath
- 详情面板新增「头脑风暴配置文件」下拉
- 删除从未接线的死代码 reviewFlow.ts(runReview 全仓库无调用方)
- codexCommand 精简为仅 resume/interactive 两种终端命令形态
- 版本号 0.2.55 → 0.2.60
This commit is contained in:
2026-07-13 07:50:39 +08:00
parent 5188c23765
commit b585016cd7
22 changed files with 258 additions and 366 deletions
@@ -61,6 +61,8 @@ interface IssueDetailPanelProps {
profiles: ClaudeProfile[]
/** Persist a per-issue `profilePath` override into the state JSON. */
onUpdateProfilePath: (issueNumber: number, profilePath: string) => void
/** Persist a per-issue `brainstormProfilePath` override into the state JSON. */
onUpdateBrainstormProfilePath: (issueNumber: number, brainstormProfilePath: string) => void
/** Persist a per-issue `testProfilePath` override into the state JSON. */
onUpdateTestProfilePath: (issueNumber: number, testProfilePath: string) => void
/** Open the in-webview log modal. */
@@ -99,6 +101,7 @@ export function IssueDetailPanel({
onUpdateAutoReview,
profiles,
onUpdateProfilePath,
onUpdateBrainstormProfilePath,
onUpdateTestProfilePath,
onOpenLogs,
}: IssueDetailPanelProps) {
@@ -195,7 +198,7 @@ export function IssueDetailPanel({
return
if (!throttleBySessionId(v))
return
onResumeSession(v, issue?.profilePath, undefined, issue?.number)
onResumeSession(v, issue?.brainstormProfilePath, undefined, issue?.number)
},
secondaryActionIcon,
secondaryActionTitle,
@@ -321,40 +324,46 @@ export function IssueDetailPanel({
description: '首次开会话时随机分配的终端颜色(VS Code ThemeColor),用于该工单所有会话的终端 tab 着色',
},
{
key: 'profilePath',
label: '实施配置文件',
key: 'brainstormProfilePath',
label: '头脑风暴配置文件',
type: 'select',
options: (() => {
// 占位项:value='' 对应「未设置」。原生 select 在 value 不匹配任何
// option 时会假显示第一项且 selectedIndex=0,导致点第一项不触发
// onChange、永远存不进去;占位项让未设置态有真实匹配项。
const opts = [{ label: '(默认)', value: '' }, ...profiles.map(p => ({ label: p.name, value: p.path }))]
const current = issue?.profilePath
// 自定义路径兜底:state JSON 里存的 profile 不在已知列表时,
// 额外追加一项以免下拉显示空白、丢失当前选择。
const current = issue?.brainstormProfilePath
if (current && !opts.some(o => o.value === current))
opts.push({ label: `自定义:${current}`, value: current })
return opts
})(),
description: '实施会话使用的 Claude 配置文件;选「(默认)」用内置默认(offical),选具体 profile 则覆盖(持久化 state JSON',
description: '头脑风暴会话使用的 Claude 配置文件;选「(默认)」用内置默认,与实施/测试互不回退',
},
{
key: 'profilePath',
label: '实施配置文件',
type: 'select',
options: (() => {
const opts = [{ label: '(默认)', value: '' }, ...profiles.map(p => ({ label: p.name, value: p.path }))]
const current = issue?.profilePath
if (current && !opts.some(o => o.value === current))
opts.push({ label: `自定义:${current}`, value: current })
return opts
})(),
description: '实施会话使用的 Claude 配置文件;选「(默认)」用内置默认,与头脑风暴/测试互不回退',
},
{
key: 'testProfilePath',
label: '测试配置文件',
type: 'select',
options: (() => {
// 占位项:value='' 对应「未设置」。原生 select 在 value 不匹配任何
// option 时会假显示第一项且 selectedIndex=0,导致点第一项不触发
// onChange、永远存不进去;占位项让未设置态有真实匹配项。
const opts = [{ label: '(默认)', value: '' }, ...profiles.map(p => ({ label: p.name, value: p.path }))]
const current = issue?.testProfilePath
// 自定义路径兜底:state JSON 里存的 profile 不在已知列表时,
// 额外追加一项以免下拉显示空白、丢失当前选择。
if (current && !opts.some(o => o.value === current))
opts.push({ label: `自定义:${current}`, value: current })
return opts
})(),
description: '测试会话使用的 Claude 配置文件;留空时回退实施配置文件',
description: '测试会话使用的 Claude 配置文件;选「(默认)」用内置默认,与头脑风暴/实施互不回退',
},
{
key: 'specFile',
@@ -476,6 +485,7 @@ export function IssueDetailPanel({
testSessionId: issue.testSessionId ?? null,
autoReview: issue.autoReview ?? globalAutoReview,
color: issue.color ?? null,
brainstormProfilePath: issue.brainstormProfilePath ?? null,
profilePath: issue.profilePath ?? null,
testProfilePath: issue.testProfilePath ?? null,
specFile: issue.specFile ?? null,
@@ -582,6 +592,8 @@ export function IssueDetailPanel({
onChange={(key, value) => {
if (key === 'autoReview' && issue && typeof value === 'boolean')
onUpdateAutoReview(issue.number, value)
if (key === 'brainstormProfilePath' && issue && typeof value === 'string')
onUpdateBrainstormProfilePath(issue.number, value)
if (key === 'profilePath' && issue && typeof value === 'string')
onUpdateProfilePath(issue.number, value)
if (key === 'testProfilePath' && issue && typeof value === 'string')