feat(vscode): worktree 打开方式可选 VS Code/PyCharm,并修复 handleOpenWorktree 不展开 ~ 的打开报错

- worktree.ts: handleOpenWorktree/handleDeleteWorktree/dispatchImplTabPostCloseAsync 三处改用 resolveWorktreePath,修复带 ~ 的存量路径被拼成 <工作区>/~/... 导致打不开
- 新增全局设置 worktreeOpenWith('vscode' | 'pycharm',默认 vscode),贯穿 store/settings handler/messages/KanbanPanel 与 webview 的 messages/useIssues/App/SettingsModal「钩子」分组新增「工作树打开方式」下拉
- handleOpenWorktree 按设置分支:pycharm 走 JetBrains pycharm 启动器,ENOENT 时提示启用命令行启动器

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 05:20:22 +08:00
co-authored by Claude Opus 4.7
parent 5e7a3d20d9
commit cacc60eb0e
9 changed files with 78 additions and 4 deletions
+1
View File
@@ -446,6 +446,7 @@ export function App() {
initialDevBranch={settings?.devBranch ?? 'main'}
initialAutoBuildBranch={settings?.autoBuildBranch ?? ''}
initialWorktreeDirectory={settings?.worktreeDirectory ?? ''}
initialWorktreeOpenWith={settings?.worktreeOpenWith ?? 'vscode'}
initialWorktreePostCreateScript={settings?.worktreePostCreateScript ?? ''}
initialWorktreePreRemoveScript={settings?.worktreePreRemoveScript ?? ''}
initialImplTabPreCreateScript={settings?.implTabPreCreateScript ?? ''}
@@ -24,6 +24,7 @@ interface SubmitValues {
devBranch: string
autoBuildBranch: string
worktreeDirectory: string
worktreeOpenWith: 'vscode' | 'pycharm'
worktreePostCreateScript: string
worktreePreRemoveScript: string
implTabPreCreateScript: string
@@ -61,6 +62,7 @@ export interface SettingsModalProps {
initialDevBranch: string
initialAutoBuildBranch: string
initialWorktreeDirectory: string
initialWorktreeOpenWith: 'vscode' | 'pycharm'
initialWorktreePostCreateScript: string
initialWorktreePreRemoveScript: string
initialImplTabPreCreateScript: string
@@ -131,6 +133,7 @@ export function SettingsModal({
initialDevBranch,
initialAutoBuildBranch,
initialWorktreeDirectory,
initialWorktreeOpenWith,
initialWorktreePostCreateScript,
initialWorktreePreRemoveScript,
initialImplTabPreCreateScript,
@@ -155,6 +158,7 @@ export function SettingsModal({
const [devBranch, setDevBranch] = useState(initialDevBranch)
const [autoBuildBranch, setAutoBuildBranch] = useState(initialAutoBuildBranch)
const [worktreeDirectory, setWorktreeDirectory] = useState(initialWorktreeDirectory)
const [worktreeOpenWith, setWorktreeOpenWith] = useState(initialWorktreeOpenWith)
const [worktreePostCreateScript, setWorktreePostCreateScript] = useState(initialWorktreePostCreateScript)
const [worktreePreRemoveScript, setWorktreePreRemoveScript] = useState(initialWorktreePreRemoveScript)
const [implTabPreCreateScript, setImplTabPreCreateScript] = useState(initialImplTabPreCreateScript)
@@ -258,6 +262,7 @@ export function SettingsModal({
autoBuildBranch: autoBuildBranch.trim(),
// worktree 目录模板:trim 后留空 = 用默认模板(getSettings 读时回退)
worktreeDirectory: worktreeDirectory.trim(),
worktreeOpenWith,
// 钩子路径保持原样 trim(前后空格无意义;空串 = 用默认 .spx/*.sh
worktreePostCreateScript: worktreePostCreateScript.trim(),
worktreePreRemoveScript: worktreePreRemoveScript.trim(),
@@ -642,6 +647,28 @@ export function SettingsModal({
/>
</Field>
<Field
label="工作树打开方式"
hint={(
<>
PyCharm
{' '}
<code>pycharm</code>
{' '}
PATH JetBrains Toolbox
</>
)}
>
<select
value={worktreeOpenWith}
onChange={e => setWorktreeOpenWith(e.target.value as 'vscode' | 'pycharm')}
className={inputClass}
>
<option value="vscode">VS Code</option>
<option value="pycharm">PyCharm</option>
</select>
</Field>
<Field
label="worktree 创建后脚本"
hint={(
+4
View File
@@ -34,6 +34,7 @@ export interface SettingsValues {
devBranch: string
autoBuildBranch: string
worktreeDirectory: string
worktreeOpenWith: 'vscode' | 'pycharm'
worktreePostCreateScript: string
worktreePreRemoveScript: string
implTabPreCreateScript: string
@@ -57,6 +58,7 @@ export interface SettingsOverlayState {
devBranch: string
autoBuildBranch: string
worktreeDirectory: string
worktreeOpenWith: 'vscode' | 'pycharm'
worktreePostCreateScript: string
worktreePreRemoveScript: string
implTabPreCreateScript: string
@@ -268,6 +270,7 @@ export function useIssues(): UseIssuesResult {
devBranch: values.devBranch,
autoBuildBranch: values.autoBuildBranch,
worktreeDirectory: values.worktreeDirectory,
worktreeOpenWith: values.worktreeOpenWith,
worktreePostCreateScript: values.worktreePostCreateScript,
worktreePreRemoveScript: values.worktreePreRemoveScript,
implTabPreCreateScript: values.implTabPreCreateScript,
@@ -594,6 +597,7 @@ export function useIssues(): UseIssuesResult {
devBranch: msg.devBranch,
autoBuildBranch: msg.autoBuildBranch,
worktreeDirectory: msg.worktreeDirectory,
worktreeOpenWith: msg.worktreeOpenWith,
worktreePostCreateScript: msg.worktreePostCreateScript,
worktreePreRemoveScript: msg.worktreePreRemoveScript,
implTabPreCreateScript: msg.implTabPreCreateScript,
+2
View File
@@ -77,6 +77,7 @@ export type ExtensionToWebview
devBranch: string
autoBuildBranch: string
worktreeDirectory: string
worktreeOpenWith: 'vscode' | 'pycharm'
worktreePostCreateScript: string
worktreePreRemoveScript: string
implTabPreCreateScript: string
@@ -132,6 +133,7 @@ export type WebviewToExtension
devBranch: string
autoBuildBranch: string
worktreeDirectory: string
worktreeOpenWith: 'vscode' | 'pycharm'
worktreePostCreateScript: string
worktreePreRemoveScript: string
implTabPreCreateScript: string