✨ feat(vscode): 改动说明 profile 可配置
This commit is contained in:
@@ -129,6 +129,7 @@ prompts 在 `prompts/*.md`,随 VSIX 一起安装,改完即生效,也可在
|
|||||||
| | `autoBuildBranch` | 空 | Jenkins 等监听的分支;空 = 与 `devBranch` 相同,分支同步按钮禁用 |
|
| | `autoBuildBranch` | 空 | Jenkins 等监听的分支;空 = 与 `devBranch` 相同,分支同步按钮禁用 |
|
||||||
| | `conflictResolutionProfilePath` | 空 | 冲突解决会话 profile |
|
| | `conflictResolutionProfilePath` | 空 | 冲突解决会话 profile |
|
||||||
| | `commitProfilePath` | `deepseek-v4-pro` | 「提交代码」用的 profile;未配置时提交直接失败 |
|
| | `commitProfilePath` | `deepseek-v4-pro` | 「提交代码」用的 profile;未配置时提交直接失败 |
|
||||||
|
| | `prDiffSummaryProfilePath` | `deepseek-v4-pro` | 「改动」说明 / PR 变更摘要用的 profile;未配置时生成失败 |
|
||||||
| | `codexModel` / `codexReasoningEffort` | 空 | 审查会话的 codex `-c` 覆盖;空 = 用 codex 自己的 config |
|
| | `codexModel` / `codexReasoningEffort` | 空 | 审查会话的 codex `-c` 覆盖;空 = 用 codex 自己的 config |
|
||||||
| 网络 | `webhookPort` | `17421` | 本机 webhook 端口 |
|
| 网络 | `webhookPort` | `17421` | 本机 webhook 端口 |
|
||||||
| | `webhookSecret` | 空 | Gitea webhook secret,空 = 不校验签名 |
|
| | `webhookSecret` | 空 | Gitea webhook secret,空 = 不校验签名 |
|
||||||
|
|||||||
+1
-1
@@ -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.100",
|
"version": "0.2.101",
|
||||||
"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",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ let profilesDirOverride: string | undefined
|
|||||||
*/
|
*/
|
||||||
export function setProfilesDirOverride(dir: string | undefined): void {
|
export function setProfilesDirOverride(dir: string | undefined): void {
|
||||||
const t = dir?.trim()
|
const t = dir?.trim()
|
||||||
profilesDirOverride = t ? t : undefined
|
profilesDirOverride = t || undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function isReadableDir(dir: string): boolean {
|
function isReadableDir(dir: string): boolean {
|
||||||
@@ -144,17 +144,3 @@ export function getDefaultProfilePath(): string {
|
|||||||
}
|
}
|
||||||
return path.join(dir, 'offical.json')
|
return path.join(dir, 'offical.json')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Profile for PR diff summaries / background content generation.
|
|
||||||
* Prefer `deepseek-v4-pro`, then `deepseek.json`.
|
|
||||||
*/
|
|
||||||
export function getPrDiffSummaryProfilePath(): string {
|
|
||||||
const dir = getProfilesDir()
|
|
||||||
for (const name of ['deepseek-v4-pro.json', 'deepseek.json']) {
|
|
||||||
const p = path.join(dir, name)
|
|
||||||
if (isReadableFile(p))
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
return path.join(dir, 'deepseek-v4-pro.json')
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { overlayLocalIssueState } from '../issues/localState'
|
|||||||
import { closeIssueByRef, mergeIssueState, readIssueState } from '../issues/stateRouter'
|
import { closeIssueByRef, mergeIssueState, readIssueState } from '../issues/stateRouter'
|
||||||
import { logger } from '../logging/logger'
|
import { logger } from '../logging/logger'
|
||||||
import { annotateReviewSessionFileExists } from '../sessions/codexSessions'
|
import { annotateReviewSessionFileExists } from '../sessions/codexSessions'
|
||||||
import { getEffectiveCommitProfilePath, getSettings } from '../settings/store'
|
import { getEffectiveCommitProfilePath, getEffectivePrDiffSummaryProfilePath, getSettings } from '../settings/store'
|
||||||
import { webhookCoordinator } from '../webhook/coordinator'
|
import { webhookCoordinator } from '../webhook/coordinator'
|
||||||
import { loadYouTrackIssues } from '../youtrack/issueLoader'
|
import { loadYouTrackIssues } from '../youtrack/issueLoader'
|
||||||
import * as handoffFlow from './handlers/handoffFlow'
|
import * as handoffFlow from './handlers/handoffFlow'
|
||||||
@@ -44,7 +44,7 @@ import { PALETTE, resolveIssueColor, themeColorIdToIconUri } from './issueColor'
|
|||||||
import { KANBAN_SCOPE_KEY } from './kanbanScope'
|
import { KANBAN_SCOPE_KEY } from './kanbanScope'
|
||||||
|
|
||||||
/** Resolved at runtime via getProfilesDir() — do not hardcode user paths. */
|
/** Resolved at runtime via getProfilesDir() — do not hardcode user paths. */
|
||||||
export { getDefaultProfilePath, getPrDiffSummaryProfilePath } from '../cc/profiles'
|
export { getDefaultProfilePath } from '../cc/profiles'
|
||||||
|
|
||||||
export class KanbanWebviewPanel {
|
export class KanbanWebviewPanel {
|
||||||
static readonly viewType = 'superpowers.kanbanPanel'
|
static readonly viewType = 'superpowers.kanbanPanel'
|
||||||
@@ -875,6 +875,7 @@ export class KanbanWebviewPanel {
|
|||||||
implTabPostCloseScript: s.implTabPostCloseScript,
|
implTabPostCloseScript: s.implTabPostCloseScript,
|
||||||
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
||||||
commitProfilePath: await getEffectiveCommitProfilePath(this.context),
|
commitProfilePath: await getEffectiveCommitProfilePath(this.context),
|
||||||
|
prDiffSummaryProfilePath: await getEffectivePrDiffSummaryProfilePath(this.context),
|
||||||
codexModel: s.codexModel,
|
codexModel: s.codexModel,
|
||||||
codexReasoningEffort: s.codexReasoningEffort,
|
codexReasoningEffort: s.codexReasoningEffort,
|
||||||
profilesDirectory: s.profilesDirectory,
|
profilesDirectory: s.profilesDirectory,
|
||||||
@@ -954,6 +955,7 @@ export class KanbanWebviewPanel {
|
|||||||
implTabPostCloseScript: s.implTabPostCloseScript,
|
implTabPostCloseScript: s.implTabPostCloseScript,
|
||||||
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
||||||
commitProfilePath: await getEffectiveCommitProfilePath(this.context),
|
commitProfilePath: await getEffectiveCommitProfilePath(this.context),
|
||||||
|
prDiffSummaryProfilePath: await getEffectivePrDiffSummaryProfilePath(this.context),
|
||||||
codexModel: s.codexModel,
|
codexModel: s.codexModel,
|
||||||
codexReasoningEffort: s.codexReasoningEffort,
|
codexReasoningEffort: s.codexReasoningEffort,
|
||||||
profilesDirectory: s.profilesDirectory,
|
profilesDirectory: s.profilesDirectory,
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import * as path from 'node:path'
|
|||||||
import { commands, env, ThemeColor, Uri, window, workspace } from 'vscode'
|
import { commands, env, ThemeColor, Uri, window, workspace } from 'vscode'
|
||||||
import { getToken } from '../../auth/secrets'
|
import { getToken } from '../../auth/secrets'
|
||||||
import { buildCcCommand } from '../../cc/ccCommand'
|
import { buildCcCommand } from '../../cc/ccCommand'
|
||||||
import { getDefaultProfilePath, getPrDiffSummaryProfilePath } from '../../cc/profiles'
|
import { resolveCommitProfileForRun } from '../../cc/commitProfile'
|
||||||
|
import { getDefaultProfilePath, resolveProfilePath } from '../../cc/profiles'
|
||||||
import { getBrainstormPrompt } from '../../cc/prompts'
|
import { getBrainstormPrompt } from '../../cc/prompts'
|
||||||
import { claudeProjectsRoot, installClaudeSession } from '../../cc/sessionBundle'
|
import { claudeProjectsRoot, installClaudeSession } from '../../cc/sessionBundle'
|
||||||
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
|
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
|
||||||
@@ -31,7 +32,7 @@ import {
|
|||||||
import { isValidSpxFilePath, loadIssues } from '../../gitea/issueLoader'
|
import { isValidSpxFilePath, loadIssues } from '../../gitea/issueLoader'
|
||||||
import { mergeStateJsonComment } from '../../gitea/stateJson'
|
import { mergeStateJsonComment } from '../../gitea/stateJson'
|
||||||
import { logger } from '../../logging/logger'
|
import { logger } from '../../logging/logger'
|
||||||
import { getSettings } from '../../settings/store'
|
import { getEffectivePrDiffSummaryProfilePath, getSettings } from '../../settings/store'
|
||||||
import { webhookCoordinator } from '../../webhook/coordinator'
|
import { webhookCoordinator } from '../../webhook/coordinator'
|
||||||
import { pickRandomIssueColor, themeColorIdToIconUri } from '../issueColor'
|
import { pickRandomIssueColor, themeColorIdToIconUri } from '../issueColor'
|
||||||
import { makeNonce } from '../KanbanPanel'
|
import { makeNonce } from '../KanbanPanel'
|
||||||
@@ -2275,7 +2276,34 @@ export async function handleGeneratePrDiffSummary(panel: KanbanWebviewPanel, iss
|
|||||||
dismissOnTimer: 5000,
|
dismissOnTimer: 5000,
|
||||||
})
|
})
|
||||||
|
|
||||||
const profilePath = getPrDiffSummaryProfilePath()
|
const rawProfile = await getEffectivePrDiffSummaryProfilePath(panel.context)
|
||||||
|
const resolution = resolveCommitProfileForRun(
|
||||||
|
rawProfile,
|
||||||
|
resolveProfilePath,
|
||||||
|
(p) => {
|
||||||
|
try {
|
||||||
|
fs.accessSync(p, fs.constants.R_OK)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (!resolution.ok) {
|
||||||
|
const message = resolution.reason === 'empty'
|
||||||
|
? '未配置改动说明 profile,请在设置中选择'
|
||||||
|
: `改动说明 profile 不可用:${resolution.profilePath}`
|
||||||
|
panel.postMessage({
|
||||||
|
type: 'toast/show',
|
||||||
|
id: randomUUID(),
|
||||||
|
level: 'error',
|
||||||
|
message,
|
||||||
|
dismissOnTimer: 8000,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const profilePath = resolution.profilePath
|
||||||
const prompt = `你在一个 VS Code 扩展启动的后台 Claude 会话中工作。\n\n硬性限制:\n- 不要修改代码。\n- 不要创建或切换分支。\n- 不要提交。\n- 不要 push。\n- 不要写任何文件。\n- 只分析当前 PR 的代码变动,并把 Markdown 摘要正文直接输出到 stdout。\n\n任务:\n- 当前工作目录是工单 #\${issueNumber} 的 worktree。\n- 分析 PR #\${pr} 与主分支的代码差异。\n- 用 git 拿差异:先 git fetch origin main,再 git diff origin/main...HEAD(概览可加 --stat)。注意 tea 没有 diff 子命令,不要尝试 tea pulls diff。\n\n输出必须是合法 Markdown,预览器要能渲染出标题层级与代码块高亮,结构如下:\n1. 第一行是一级标题:# PR #\${pr} 代码变更摘要\n2. 紧接着用 1~2 句话概述本次变更:做了什么、新增了哪些包/模块、关键依赖方向(例如「stockpool/ 是与 orders/ catalog/ 平级的新子域包,其 service 只单向依赖 orders/catalog 的 repository,无循环导入」)。\n3. 然后写一行图例:图例:\\\`+\\\` = 新建文件 \\\`✎\\\` = 修改文件\n4. 然后是一棵统一的目录树,放进单个围栏代码块(语言标注用 text):树前一行写三个反引号紧跟 text,树后一行写三个反引号。\n\n目录树规则:\n- 用 box-drawing 连线字符画树:├──、└──、│,缩进对齐,像 tree 命令的输出,不要只用纯空格缩进糊一棵没有连线的树。\n- 从仓库根开始保留真实目录层级。\n- 每个文件行以标记开头:新建文件用「+ 」、修改文件用「✎ 」,后接文件名 + 若干空格对齐 + 一句中文目的描述(简短,点出关键符号/端点/职责)。\n- 目录节点行尾可加可选的阶段/分组标签(如 [Phase N]),仅当本次变更本身有清晰阶段时才加;没有就不加,不要硬编。\n- 关键:整棵树一定要写在围栏代码块之内,否则 Markdown 预览器会折叠空白、丢掉层级与连线。\n\n排序与重点:\n- 按架构重要性排列:核心业务/领域代码(实现逻辑、入口、API routes、数据模型、service/repository)靠前。\n- alembic 数据库迁移文件、测试文件不算重点:放在各自模块或整棵树的靠后位置,照常用 +/✎ 标记列出,但不要放在最前、不要强调。\n- 测试文件判定:文件名形如 test_* / *_test.* / *.test.* / *.spec.*,或路径包含 tests/、__tests__/ 目录,或 conftest.py、fixture、mock 文件。\n- 迁移文件判定:路径在 alembic/、migrations/、versions/ 之下的文件。\n\n格式示例(请照此结构输出,不要照抄内容):\n\n# PR #123 代码变更摘要\n\nstockpool/ 是与 orders/ catalog/ 平级的新子域包,其 service 只单向依赖 orders/catalog 的 repository,无循环导入。\n\n图例:\\\`+\\\` = 新建文件 \\\`✎\\\` = 修改文件\n\n\\\`\\\`\\\`text\nbackend/\n└── src/luffy_agent/commerce/\n ├── models.py ✎ +StockPool;ProductCatalog 加 pool_id\n ├── stockpool/\n │ ├── service.py + reserve_pool_or_raise + compute_pool_views\n │ └── routes.py + /admin/commerce/stock-pools\n ├── orders/service.py ✎ create_order 绑定池分支\n └── alembic/versions/ + stock_pool 建表 + pool_id 加列\n\\\`\\\`\\\`\n\n要求:\n- 每个新增/修改文件一行,一句话说明新增/修改了什么及其目的。\n- 整棵树只用一个围栏代码块,用 box-drawing 连线保留真实目录层级。\n- 只输出上述 Markdown 正文本身,不要写文件,不要任何前导说明/寒暄/结尾总结,第一行就是 # PR #\${pr} 代码变更摘要 标题。`
|
const prompt = `你在一个 VS Code 扩展启动的后台 Claude 会话中工作。\n\n硬性限制:\n- 不要修改代码。\n- 不要创建或切换分支。\n- 不要提交。\n- 不要 push。\n- 不要写任何文件。\n- 只分析当前 PR 的代码变动,并把 Markdown 摘要正文直接输出到 stdout。\n\n任务:\n- 当前工作目录是工单 #\${issueNumber} 的 worktree。\n- 分析 PR #\${pr} 与主分支的代码差异。\n- 用 git 拿差异:先 git fetch origin main,再 git diff origin/main...HEAD(概览可加 --stat)。注意 tea 没有 diff 子命令,不要尝试 tea pulls diff。\n\n输出必须是合法 Markdown,预览器要能渲染出标题层级与代码块高亮,结构如下:\n1. 第一行是一级标题:# PR #\${pr} 代码变更摘要\n2. 紧接着用 1~2 句话概述本次变更:做了什么、新增了哪些包/模块、关键依赖方向(例如「stockpool/ 是与 orders/ catalog/ 平级的新子域包,其 service 只单向依赖 orders/catalog 的 repository,无循环导入」)。\n3. 然后写一行图例:图例:\\\`+\\\` = 新建文件 \\\`✎\\\` = 修改文件\n4. 然后是一棵统一的目录树,放进单个围栏代码块(语言标注用 text):树前一行写三个反引号紧跟 text,树后一行写三个反引号。\n\n目录树规则:\n- 用 box-drawing 连线字符画树:├──、└──、│,缩进对齐,像 tree 命令的输出,不要只用纯空格缩进糊一棵没有连线的树。\n- 从仓库根开始保留真实目录层级。\n- 每个文件行以标记开头:新建文件用「+ 」、修改文件用「✎ 」,后接文件名 + 若干空格对齐 + 一句中文目的描述(简短,点出关键符号/端点/职责)。\n- 目录节点行尾可加可选的阶段/分组标签(如 [Phase N]),仅当本次变更本身有清晰阶段时才加;没有就不加,不要硬编。\n- 关键:整棵树一定要写在围栏代码块之内,否则 Markdown 预览器会折叠空白、丢掉层级与连线。\n\n排序与重点:\n- 按架构重要性排列:核心业务/领域代码(实现逻辑、入口、API routes、数据模型、service/repository)靠前。\n- alembic 数据库迁移文件、测试文件不算重点:放在各自模块或整棵树的靠后位置,照常用 +/✎ 标记列出,但不要放在最前、不要强调。\n- 测试文件判定:文件名形如 test_* / *_test.* / *.test.* / *.spec.*,或路径包含 tests/、__tests__/ 目录,或 conftest.py、fixture、mock 文件。\n- 迁移文件判定:路径在 alembic/、migrations/、versions/ 之下的文件。\n\n格式示例(请照此结构输出,不要照抄内容):\n\n# PR #123 代码变更摘要\n\nstockpool/ 是与 orders/ catalog/ 平级的新子域包,其 service 只单向依赖 orders/catalog 的 repository,无循环导入。\n\n图例:\\\`+\\\` = 新建文件 \\\`✎\\\` = 修改文件\n\n\\\`\\\`\\\`text\nbackend/\n└── src/luffy_agent/commerce/\n ├── models.py ✎ +StockPool;ProductCatalog 加 pool_id\n ├── stockpool/\n │ ├── service.py + reserve_pool_or_raise + compute_pool_views\n │ └── routes.py + /admin/commerce/stock-pools\n ├── orders/service.py ✎ create_order 绑定池分支\n └── alembic/versions/ + stock_pool 建表 + pool_id 加列\n\\\`\\\`\\\`\n\n要求:\n- 每个新增/修改文件一行,一句话说明新增/修改了什么及其目的。\n- 整棵树只用一个围栏代码块,用 box-drawing 连线保留真实目录层级。\n- 只输出上述 Markdown 正文本身,不要写文件,不要任何前导说明/寒暄/结尾总结,第一行就是 # PR #\${pr} 代码变更摘要 标题。`
|
||||||
|
|
||||||
const result = await spawnClaude({
|
const result = await spawnClaude({
|
||||||
|
|||||||
@@ -8,18 +8,22 @@
|
|||||||
* 404 兜底空串,故新增/删除/改名天然成立。
|
* 404 兜底空串,故新增/删除/改名天然成立。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { PrDiffMode } from '../../cc/prDiffMode'
|
||||||
import type { KanbanWebviewPanel } from '../KanbanPanel'
|
import type { KanbanWebviewPanel } from '../KanbanPanel'
|
||||||
|
import { accessSync, constants } from 'node:fs'
|
||||||
import { createPatch } from 'diff'
|
import { createPatch } from 'diff'
|
||||||
import { workspace } from 'vscode'
|
import { workspace } from 'vscode'
|
||||||
import { getToken } from '../../auth/secrets'
|
import { getToken } from '../../auth/secrets'
|
||||||
import { listClaudeProfiles } from '../../cc/profiles'
|
import { resolveCommitProfileForRun } from '../../cc/commitProfile'
|
||||||
|
import { parsePrDiffMode } from '../../cc/prDiffMode'
|
||||||
|
import { resolveProfilePath } from '../../cc/profiles'
|
||||||
import { spawnClaude } from '../../cc/spawnClaude'
|
import { spawnClaude } from '../../cc/spawnClaude'
|
||||||
import { detectRepo } from '../../git/remote'
|
import { detectRepo } from '../../git/remote'
|
||||||
import { getPullRequest, getRawFile, listPullRequestFiles } from '../../gitea/api'
|
import { getPullRequest, getRawFile, listPullRequestFiles } from '../../gitea/api'
|
||||||
import { readStateJsonComment } from '../../gitea/stateJson'
|
import { readStateJsonComment } from '../../gitea/stateJson'
|
||||||
import { readFileSummaries, readSummarySession, writeFileSummary, writeSummarySession } from '../../sessions/prFileSummaryStore'
|
import { readFileSummaries, readSummarySession, writeFileSummary, writeSummarySession } from '../../sessions/prFileSummaryStore'
|
||||||
import { readConfirmedSigs, writeConfirmedSigs } from '../../sessions/prReviewStore'
|
import { readConfirmedSigs, writeConfirmedSigs } from '../../sessions/prReviewStore'
|
||||||
import { parsePrDiffMode, type PrDiffMode } from '../../cc/prDiffMode'
|
import { getEffectivePrDiffSummaryProfilePath } from '../../settings/store'
|
||||||
import { makeNonce } from '../KanbanPanel'
|
import { makeNonce } from '../KanbanPanel'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -259,7 +263,7 @@ function buildSummaryPrompt(prNumber: number, prBody: string, filePath: string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用 deepseek 给单个文件生成「一句话说明改了什么」的改动说明。增量复用同一会话:首个文件开新会话并把
|
* 给单个文件生成「一句话说明改了什么」的改动说明。增量复用同一会话:首个文件开新会话并把
|
||||||
* sessionId 记到 `.spx/pr-file-summaries.json`,后续文件 `--resume` 接上去,省去每次重新理解
|
* sessionId 记到 `.spx/pr-file-summaries.json`,后续文件 `--resume` 接上去,省去每次重新理解
|
||||||
* PR 的开销。说明也落盘,重载后仍显示。
|
* PR 的开销。说明也落盘,重载后仍显示。
|
||||||
*
|
*
|
||||||
@@ -279,18 +283,32 @@ export async function handleGeneratePrFileSummary(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// deepseek profile 与「一键提交」同一来源;缺失则提示用户创建并清掉前端 loading。
|
const raw = await getEffectivePrDiffSummaryProfilePath(panel.context)
|
||||||
const profiles = await listClaudeProfiles()
|
const resolution = resolveCommitProfileForRun(
|
||||||
const deepseek = profiles.find(p => p.name === 'deepseek-v4-pro')
|
raw,
|
||||||
if (!deepseek) {
|
resolveProfilePath,
|
||||||
|
(p) => {
|
||||||
|
try {
|
||||||
|
accessSync(p, constants.R_OK)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (!resolution.ok) {
|
||||||
|
const message = resolution.reason === 'empty'
|
||||||
|
? '未配置改动说明 profile,请在设置中选择'
|
||||||
|
: `改动说明 profile 不可用:${resolution.profilePath}`
|
||||||
panel.postMessage({
|
panel.postMessage({
|
||||||
type: 'toast/show',
|
type: 'toast/show',
|
||||||
id: makeNonce(),
|
id: makeNonce(),
|
||||||
level: 'error',
|
level: 'error',
|
||||||
message: '未找到 deepseek profile(deepseek-v4-pro / deepseek),请在 Claude profiles 目录下创建对应 .json',
|
message,
|
||||||
dismissOnTimer: 8000,
|
dismissOnTimer: 8000,
|
||||||
})
|
})
|
||||||
panel.postMessage({ type: 'pr-file-summary/show', issueNumber, path: filePath, error: '未找到 deepseek profile' })
|
panel.postMessage({ type: 'pr-file-summary/show', issueNumber, path: filePath, error: message })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +333,7 @@ export async function handleGeneratePrFileSummary(
|
|||||||
result = await spawnClaude({
|
result = await spawnClaude({
|
||||||
prompt: buildSummaryPrompt(index, pr.body, filePath, patch, !prevSession),
|
prompt: buildSummaryPrompt(index, pr.body, filePath, patch, !prevSession),
|
||||||
cwd: workspaceRoot,
|
cwd: workspaceRoot,
|
||||||
profilePath: deepseek.path,
|
profilePath: resolution.profilePath,
|
||||||
resumeSessionId: prevSession,
|
resumeSessionId: prevSession,
|
||||||
timeoutMs: 120_000,
|
timeoutMs: 120_000,
|
||||||
})
|
})
|
||||||
@@ -328,7 +346,7 @@ export async function handleGeneratePrFileSummary(
|
|||||||
result = await spawnClaude({
|
result = await spawnClaude({
|
||||||
prompt: buildSummaryPrompt(index, pr.body, filePath, patch, true),
|
prompt: buildSummaryPrompt(index, pr.body, filePath, patch, true),
|
||||||
cwd: workspaceRoot,
|
cwd: workspaceRoot,
|
||||||
profilePath: deepseek.path,
|
profilePath: resolution.profilePath,
|
||||||
timeoutMs: 120_000,
|
timeoutMs: 120_000,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -370,4 +388,3 @@ export async function handleSetPrDiffMode(
|
|||||||
const next: PrDiffMode = parsePrDiffMode(mode)
|
const next: PrDiffMode = parsePrDiffMode(mode)
|
||||||
await panel.context.workspaceState.update(PR_DIFF_MODE_KEY, next)
|
await panel.context.workspaceState.update(PR_DIFF_MODE_KEY, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { listClaudeProfiles, setProfilesDirOverride } from '../../cc/profiles'
|
|||||||
import { detectRepo } from '../../git/remote'
|
import { detectRepo } from '../../git/remote'
|
||||||
import { logger } from '../../logging/logger'
|
import { logger } from '../../logging/logger'
|
||||||
import { readProfiles, writeProfiles } from '../../profiles/store'
|
import { readProfiles, writeProfiles } from '../../profiles/store'
|
||||||
import { getEffectiveCommitProfilePath, getSettings, saveSettings } from '../../settings/store'
|
import { getEffectiveCommitProfilePath, getEffectivePrDiffSummaryProfilePath, getSettings, saveSettings } from '../../settings/store'
|
||||||
import { webhookCoordinator } from '../../webhook/coordinator'
|
import { webhookCoordinator } from '../../webhook/coordinator'
|
||||||
import { youtrackHost } from '../../youtrack/issueLoader'
|
import { youtrackHost } from '../../youtrack/issueLoader'
|
||||||
import { makeNonce } from '../KanbanPanel'
|
import { makeNonce } from '../KanbanPanel'
|
||||||
@@ -37,6 +37,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -70,6 +71,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
|||||||
const trimmedConflictProfile = payload.conflictResolutionProfilePath.trim()
|
const trimmedConflictProfile = payload.conflictResolutionProfilePath.trim()
|
||||||
// 提交代码 profile:'' 有意义(= 未配置 → 提交严格失败),只 trim。
|
// 提交代码 profile:'' 有意义(= 未配置 → 提交严格失败),只 trim。
|
||||||
const trimmedCommitProfile = payload.commitProfilePath.trim()
|
const trimmedCommitProfile = payload.commitProfilePath.trim()
|
||||||
|
const trimmedPrDiffSummaryProfile = payload.prDiffSummaryProfilePath.trim()
|
||||||
// codex 模型 / 思考级别:空串有意义(= 用 codex 默认),只 trim。
|
// codex 模型 / 思考级别:空串有意义(= 用 codex 默认),只 trim。
|
||||||
const trimmedCodexModel = payload.codexModel.trim()
|
const trimmedCodexModel = payload.codexModel.trim()
|
||||||
const trimmedCodexReasoningEffort = payload.codexReasoningEffort.trim()
|
const trimmedCodexReasoningEffort = payload.codexReasoningEffort.trim()
|
||||||
@@ -108,6 +110,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
|||||||
implTabPostCloseScript: trimmedImplPost,
|
implTabPostCloseScript: trimmedImplPost,
|
||||||
conflictResolutionProfilePath: trimmedConflictProfile,
|
conflictResolutionProfilePath: trimmedConflictProfile,
|
||||||
commitProfilePath: trimmedCommitProfile,
|
commitProfilePath: trimmedCommitProfile,
|
||||||
|
prDiffSummaryProfilePath: trimmedPrDiffSummaryProfile,
|
||||||
codexModel: trimmedCodexModel,
|
codexModel: trimmedCodexModel,
|
||||||
codexReasoningEffort: trimmedCodexReasoningEffort,
|
codexReasoningEffort: trimmedCodexReasoningEffort,
|
||||||
profilesDirectory: trimmedProfilesDirectory,
|
profilesDirectory: trimmedProfilesDirectory,
|
||||||
@@ -136,6 +139,7 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
|
|||||||
implTabPostCloseScript: trimmedImplPost,
|
implTabPostCloseScript: trimmedImplPost,
|
||||||
conflictResolutionProfilePath: trimmedConflictProfile,
|
conflictResolutionProfilePath: trimmedConflictProfile,
|
||||||
commitProfilePath: trimmedCommitProfile,
|
commitProfilePath: trimmedCommitProfile,
|
||||||
|
prDiffSummaryProfilePath: trimmedPrDiffSummaryProfile,
|
||||||
codexModel: trimmedCodexModel,
|
codexModel: trimmedCodexModel,
|
||||||
codexReasoningEffort: trimmedCodexReasoningEffort,
|
codexReasoningEffort: trimmedCodexReasoningEffort,
|
||||||
profilesDirectory: trimmedProfilesDirectory,
|
profilesDirectory: trimmedProfilesDirectory,
|
||||||
@@ -213,6 +217,7 @@ export async function handleEditSettingsRequest(panel: KanbanWebviewPanel): Prom
|
|||||||
: undefined
|
: undefined
|
||||||
// 升级 seed:key 缺失时预填 deepseek path(若有),仅展示不写回。
|
// 升级 seed:key 缺失时预填 deepseek path(若有),仅展示不写回。
|
||||||
const commitProfilePath = await getEffectiveCommitProfilePath(panel.context)
|
const commitProfilePath = await getEffectiveCommitProfilePath(panel.context)
|
||||||
|
const prDiffSummaryProfilePath = await getEffectivePrDiffSummaryProfilePath(panel.context)
|
||||||
// User clicked the gear themselves — let them back out without saving.
|
// User clicked the gear themselves — let them back out without saving.
|
||||||
panel.postMessage({
|
panel.postMessage({
|
||||||
type: 'settings/show',
|
type: 'settings/show',
|
||||||
@@ -237,6 +242,7 @@ export async function handleEditSettingsRequest(panel: KanbanWebviewPanel): Prom
|
|||||||
implTabPostCloseScript: s.implTabPostCloseScript,
|
implTabPostCloseScript: s.implTabPostCloseScript,
|
||||||
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
conflictResolutionProfilePath: s.conflictResolutionProfilePath,
|
||||||
commitProfilePath,
|
commitProfilePath,
|
||||||
|
prDiffSummaryProfilePath,
|
||||||
codexModel: s.codexModel,
|
codexModel: s.codexModel,
|
||||||
codexReasoningEffort: s.codexReasoningEffort,
|
codexReasoningEffort: s.codexReasoningEffort,
|
||||||
profilesDirectory: s.profilesDirectory,
|
profilesDirectory: s.profilesDirectory,
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ export type ExtensionToWebview
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -154,6 +155,7 @@ export type WebviewToExtension
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
|
|||||||
@@ -181,6 +181,11 @@ export interface Settings {
|
|||||||
* 空串 = 未配置 → 提交严格失败。升级时 key 缺失会 seed deepseek-v4-pro(若存在)。
|
* 空串 = 未配置 → 提交严格失败。升级时 key 缺失会 seed deepseek-v4-pro(若存在)。
|
||||||
*/
|
*/
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
/**
|
||||||
|
* 「改动」tab 单文件说明 / 工单 PR 变更摘要使用的 Claude profile 绝对路径。
|
||||||
|
* 空串 = 未配置 → 生成失败。升级时 key 缺失会 seed deepseek-v4-pro(若存在)。
|
||||||
|
*/
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
/**
|
/**
|
||||||
* codex 审查会话使用的模型(`-c model=`)。空串 = 不传,用 codex
|
* codex 审查会话使用的模型(`-c model=`)。空串 = 不传,用 codex
|
||||||
* `config.toml` 默认。
|
* `config.toml` 默认。
|
||||||
@@ -223,6 +228,7 @@ function defaults(ctx: ExtensionContext): Settings {
|
|||||||
youtrackCloseCommand: '',
|
youtrackCloseCommand: '',
|
||||||
conflictResolutionProfilePath: '',
|
conflictResolutionProfilePath: '',
|
||||||
commitProfilePath: '',
|
commitProfilePath: '',
|
||||||
|
prDiffSummaryProfilePath: '',
|
||||||
codexModel: '',
|
codexModel: '',
|
||||||
codexReasoningEffort: '',
|
codexReasoningEffort: '',
|
||||||
profilesDirectory: '',
|
profilesDirectory: '',
|
||||||
@@ -319,6 +325,9 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
|||||||
const commitProfilePath = typeof stored.commitProfilePath === 'string'
|
const commitProfilePath = typeof stored.commitProfilePath === 'string'
|
||||||
? stored.commitProfilePath
|
? stored.commitProfilePath
|
||||||
: base.commitProfilePath
|
: base.commitProfilePath
|
||||||
|
const prDiffSummaryProfilePath = typeof stored.prDiffSummaryProfilePath === 'string'
|
||||||
|
? stored.prDiffSummaryProfilePath
|
||||||
|
: base.prDiffSummaryProfilePath
|
||||||
// codex 模型 / 思考级别:'' 有意义(= 用 codex 默认),不强制回退。
|
// codex 模型 / 思考级别:'' 有意义(= 用 codex 默认),不强制回退。
|
||||||
const codexModel = typeof stored.codexModel === 'string'
|
const codexModel = typeof stored.codexModel === 'string'
|
||||||
? stored.codexModel
|
? stored.codexModel
|
||||||
@@ -353,6 +362,7 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
|||||||
youtrackCloseCommand,
|
youtrackCloseCommand,
|
||||||
conflictResolutionProfilePath,
|
conflictResolutionProfilePath,
|
||||||
commitProfilePath,
|
commitProfilePath,
|
||||||
|
prDiffSummaryProfilePath,
|
||||||
codexModel,
|
codexModel,
|
||||||
codexReasoningEffort,
|
codexReasoningEffort,
|
||||||
profilesDirectory,
|
profilesDirectory,
|
||||||
@@ -372,6 +382,17 @@ export async function getEffectiveCommitProfilePath(ctx: ExtensionContext): Prom
|
|||||||
return seedCommitProfilePath(undefined, profiles)
|
return seedCommitProfilePath(undefined, profiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取改动说明有效的 profile path。规则与提交代码相同:已有 key 原样返回,缺 key 才 seed。
|
||||||
|
*/
|
||||||
|
export async function getEffectivePrDiffSummaryProfilePath(ctx: ExtensionContext): Promise<string> {
|
||||||
|
const stored = ctx.globalState.get<Partial<Settings>>(SETTINGS_KEY) ?? {}
|
||||||
|
if (typeof stored.prDiffSummaryProfilePath === 'string')
|
||||||
|
return stored.prDiffSummaryProfilePath
|
||||||
|
const profiles = await listClaudeProfiles()
|
||||||
|
return seedCommitProfilePath(undefined, profiles)
|
||||||
|
}
|
||||||
|
|
||||||
export async function saveSettings(ctx: ExtensionContext, next: Partial<Settings>): Promise<void> {
|
export async function saveSettings(ctx: ExtensionContext, next: Partial<Settings>): Promise<void> {
|
||||||
const current = ctx.globalState.get<Partial<Settings>>(SETTINGS_KEY) ?? {}
|
const current = ctx.globalState.get<Partial<Settings>>(SETTINGS_KEY) ?? {}
|
||||||
const merged: Partial<Settings> = { ...current, ...next }
|
const merged: Partial<Settings> = { ...current, ...next }
|
||||||
|
|||||||
@@ -533,6 +533,7 @@ export function App() {
|
|||||||
initialImplTabPostCloseScript={settings?.implTabPostCloseScript ?? ''}
|
initialImplTabPostCloseScript={settings?.implTabPostCloseScript ?? ''}
|
||||||
initialConflictResolutionProfilePath={settings?.conflictResolutionProfilePath ?? ''}
|
initialConflictResolutionProfilePath={settings?.conflictResolutionProfilePath ?? ''}
|
||||||
initialCommitProfilePath={settings?.commitProfilePath ?? ''}
|
initialCommitProfilePath={settings?.commitProfilePath ?? ''}
|
||||||
|
initialPrDiffSummaryProfilePath={settings?.prDiffSummaryProfilePath ?? ''}
|
||||||
initialCodexModel={settings?.codexModel ?? ''}
|
initialCodexModel={settings?.codexModel ?? ''}
|
||||||
initialCodexReasoningEffort={settings?.codexReasoningEffort ?? ''}
|
initialCodexReasoningEffort={settings?.codexReasoningEffort ?? ''}
|
||||||
initialProfilesDirectory={settings?.profilesDirectory ?? ''}
|
initialProfilesDirectory={settings?.profilesDirectory ?? ''}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ interface SubmitValues {
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -82,6 +83,7 @@ export interface SettingsModalProps {
|
|||||||
initialImplTabPostCloseScript: string
|
initialImplTabPostCloseScript: string
|
||||||
initialConflictResolutionProfilePath: string
|
initialConflictResolutionProfilePath: string
|
||||||
initialCommitProfilePath: string
|
initialCommitProfilePath: string
|
||||||
|
initialPrDiffSummaryProfilePath: string
|
||||||
initialCodexModel: string
|
initialCodexModel: string
|
||||||
initialCodexReasoningEffort: string
|
initialCodexReasoningEffort: string
|
||||||
initialProfilesDirectory: string
|
initialProfilesDirectory: string
|
||||||
@@ -164,6 +166,7 @@ export function SettingsModal({
|
|||||||
initialImplTabPostCloseScript,
|
initialImplTabPostCloseScript,
|
||||||
initialConflictResolutionProfilePath,
|
initialConflictResolutionProfilePath,
|
||||||
initialCommitProfilePath,
|
initialCommitProfilePath,
|
||||||
|
initialPrDiffSummaryProfilePath,
|
||||||
initialCodexModel,
|
initialCodexModel,
|
||||||
initialCodexReasoningEffort,
|
initialCodexReasoningEffort,
|
||||||
initialProfilesDirectory,
|
initialProfilesDirectory,
|
||||||
@@ -198,6 +201,7 @@ export function SettingsModal({
|
|||||||
const [implTabPostCloseScript, setImplTabPostCloseScript] = useState(initialImplTabPostCloseScript)
|
const [implTabPostCloseScript, setImplTabPostCloseScript] = useState(initialImplTabPostCloseScript)
|
||||||
const [conflictResolutionProfilePath, setConflictResolutionProfilePath] = useState(initialConflictResolutionProfilePath)
|
const [conflictResolutionProfilePath, setConflictResolutionProfilePath] = useState(initialConflictResolutionProfilePath)
|
||||||
const [commitProfilePath, setCommitProfilePath] = useState(initialCommitProfilePath)
|
const [commitProfilePath, setCommitProfilePath] = useState(initialCommitProfilePath)
|
||||||
|
const [prDiffSummaryProfilePath, setPrDiffSummaryProfilePath] = useState(initialPrDiffSummaryProfilePath)
|
||||||
const [codexModel, setCodexModel] = useState(initialCodexModel)
|
const [codexModel, setCodexModel] = useState(initialCodexModel)
|
||||||
const [codexReasoningEffort, setCodexReasoningEffort] = useState(initialCodexReasoningEffort)
|
const [codexReasoningEffort, setCodexReasoningEffort] = useState(initialCodexReasoningEffort)
|
||||||
const [profilesDirectory, setProfilesDirectory] = useState(initialProfilesDirectory)
|
const [profilesDirectory, setProfilesDirectory] = useState(initialProfilesDirectory)
|
||||||
@@ -234,6 +238,7 @@ export function SettingsModal({
|
|||||||
setImplTabPostCloseScript(initialImplTabPostCloseScript)
|
setImplTabPostCloseScript(initialImplTabPostCloseScript)
|
||||||
setConflictResolutionProfilePath(initialConflictResolutionProfilePath)
|
setConflictResolutionProfilePath(initialConflictResolutionProfilePath)
|
||||||
setCommitProfilePath(initialCommitProfilePath)
|
setCommitProfilePath(initialCommitProfilePath)
|
||||||
|
setPrDiffSummaryProfilePath(initialPrDiffSummaryProfilePath)
|
||||||
setCodexModel(initialCodexModel)
|
setCodexModel(initialCodexModel)
|
||||||
setCodexReasoningEffort(initialCodexReasoningEffort)
|
setCodexReasoningEffort(initialCodexReasoningEffort)
|
||||||
setProfilesDirectory(initialProfilesDirectory)
|
setProfilesDirectory(initialProfilesDirectory)
|
||||||
@@ -324,6 +329,7 @@ export function SettingsModal({
|
|||||||
conflictResolutionProfilePath: conflictResolutionProfilePath.trim(),
|
conflictResolutionProfilePath: conflictResolutionProfilePath.trim(),
|
||||||
// 提交代码 profile:空串 = 未配置 → 提交严格失败
|
// 提交代码 profile:空串 = 未配置 → 提交严格失败
|
||||||
commitProfilePath: commitProfilePath.trim(),
|
commitProfilePath: commitProfilePath.trim(),
|
||||||
|
prDiffSummaryProfilePath: prDiffSummaryProfilePath.trim(),
|
||||||
// codex 模型 / 思考级别:trim 后留空 = 用 codex config.toml 默认
|
// codex 模型 / 思考级别:trim 后留空 = 用 codex config.toml 默认
|
||||||
codexModel: codexModel.trim(),
|
codexModel: codexModel.trim(),
|
||||||
codexReasoningEffort: codexReasoningEffort.trim(),
|
codexReasoningEffort: codexReasoningEffort.trim(),
|
||||||
@@ -528,6 +534,30 @@ export function SettingsModal({
|
|||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
|
<Field
|
||||||
|
label="改动说明 profile"
|
||||||
|
hint={(
|
||||||
|
<>
|
||||||
|
「改动」tab 单文件说明和工单 PR 变更摘要使用此 profile。留空则生成失败,不会回退默认。
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<SelectMenu
|
||||||
|
value={prDiffSummaryProfilePath}
|
||||||
|
onChange={setPrDiffSummaryProfilePath}
|
||||||
|
variant="input"
|
||||||
|
className={inputClass}
|
||||||
|
options={[
|
||||||
|
{ value: '', label: '(未配置)' },
|
||||||
|
...profiles.map(p => ({ value: p.path, label: p.name })),
|
||||||
|
...(prDiffSummaryProfilePath
|
||||||
|
&& !profiles.some(p => p.path === prDiffSummaryProfilePath)
|
||||||
|
? [{ value: prDiffSummaryProfilePath, label: `自定义:${prDiffSummaryProfilePath}` }]
|
||||||
|
: []),
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
label="codex 模型"
|
label="codex 模型"
|
||||||
hint={(
|
hint={(
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ interface FileDiffPaneProps {
|
|||||||
summary: string | undefined
|
summary: string | undefined
|
||||||
/** 是否正在为当前文件生成说明。 */
|
/** 是否正在为当前文件生成说明。 */
|
||||||
generating: boolean
|
generating: boolean
|
||||||
/** 触发 deepseek 生成当前文件说明。 */
|
/** 触发生成本文件改动说明。 */
|
||||||
onGenerate: () => void
|
onGenerate: () => void
|
||||||
/** 统一 / 分栏;由父级从 workspaceState 拉并持久化。 */
|
/** 统一 / 分栏;由父级从 workspaceState 拉并持久化。 */
|
||||||
mode: DiffModeEnum
|
mode: DiffModeEnum
|
||||||
@@ -158,12 +158,12 @@ export function FileDiffPane({
|
|||||||
>
|
>
|
||||||
<Check className="size-3.5" />
|
<Check className="size-3.5" />
|
||||||
</button>
|
</button>
|
||||||
{/* 一键调 deepseek 生成本文件改动说明 */}
|
{/* 一键生成本文件改动说明 */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onGenerate}
|
onClick={onGenerate}
|
||||||
disabled={generating}
|
disabled={generating}
|
||||||
title={generating ? '生成中…' : '用 deepseek 生成本文件改动说明'}
|
title={generating ? '生成中…' : '生成本文件改动说明'}
|
||||||
className="shrink-0 text-[var(--vscode-descriptionForeground)] hover:text-[var(--vscode-foreground)] disabled:opacity-60"
|
className="shrink-0 text-[var(--vscode-descriptionForeground)] hover:text-[var(--vscode-foreground)] disabled:opacity-60"
|
||||||
>
|
>
|
||||||
{generating ? <Loader2 className="size-3.5 animate-spin" /> : <Sparkles className="size-3.5" />}
|
{generating ? <Loader2 className="size-3.5 animate-spin" /> : <Sparkles className="size-3.5" />}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export interface SettingsValues {
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -86,6 +87,7 @@ export interface SettingsOverlayState {
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -377,6 +379,7 @@ export function useIssues(): UseIssuesResult {
|
|||||||
implTabPostCloseScript: values.implTabPostCloseScript,
|
implTabPostCloseScript: values.implTabPostCloseScript,
|
||||||
conflictResolutionProfilePath: values.conflictResolutionProfilePath,
|
conflictResolutionProfilePath: values.conflictResolutionProfilePath,
|
||||||
commitProfilePath: values.commitProfilePath,
|
commitProfilePath: values.commitProfilePath,
|
||||||
|
prDiffSummaryProfilePath: values.prDiffSummaryProfilePath,
|
||||||
codexModel: values.codexModel,
|
codexModel: values.codexModel,
|
||||||
codexReasoningEffort: values.codexReasoningEffort,
|
codexReasoningEffort: values.codexReasoningEffort,
|
||||||
profilesDirectory: values.profilesDirectory,
|
profilesDirectory: values.profilesDirectory,
|
||||||
@@ -763,6 +766,7 @@ export function useIssues(): UseIssuesResult {
|
|||||||
implTabPostCloseScript: msg.implTabPostCloseScript,
|
implTabPostCloseScript: msg.implTabPostCloseScript,
|
||||||
conflictResolutionProfilePath: msg.conflictResolutionProfilePath,
|
conflictResolutionProfilePath: msg.conflictResolutionProfilePath,
|
||||||
commitProfilePath: msg.commitProfilePath,
|
commitProfilePath: msg.commitProfilePath,
|
||||||
|
prDiffSummaryProfilePath: msg.prDiffSummaryProfilePath,
|
||||||
codexModel: msg.codexModel,
|
codexModel: msg.codexModel,
|
||||||
codexReasoningEffort: msg.codexReasoningEffort,
|
codexReasoningEffort: msg.codexReasoningEffort,
|
||||||
profilesDirectory: msg.profilesDirectory,
|
profilesDirectory: msg.profilesDirectory,
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ export type ExtensionToWebview
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
@@ -169,6 +170,7 @@ export type WebviewToExtension
|
|||||||
implTabPostCloseScript: string
|
implTabPostCloseScript: string
|
||||||
conflictResolutionProfilePath: string
|
conflictResolutionProfilePath: string
|
||||||
commitProfilePath: string
|
commitProfilePath: string
|
||||||
|
prDiffSummaryProfilePath: string
|
||||||
codexModel: string
|
codexModel: string
|
||||||
codexReasoningEffort: string
|
codexReasoningEffort: string
|
||||||
profilesDirectory: string
|
profilesDirectory: string
|
||||||
|
|||||||
Reference in New Issue
Block a user