@alpacachen/dsh-simple-worktree 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # dsh-simple-worktree
1
+ # dsh-worktree
2
2
 
3
- A lightweight Git worktree plugin for DeepSeek Harness.
3
+ A Git worktree plugin for DeepSeek Harness that creates task branches, registers worktrees as DSH Workspaces, and opens isolated sessions.
4
+
5
+ > npm package: `@alpacachen/dsh-simple-worktree`
4
6
 
5
7
  [![npm version](https://img.shields.io/npm/v/@alpacachen/dsh-simple-worktree?color=5b8def&label=npm)](https://www.npmjs.com/package/@alpacachen/dsh-simple-worktree)
6
8
  ![DeepSeek Harness Plugin](https://img.shields.io/badge/DeepSeek%20Harness-Plugin-7c5cff)
@@ -9,11 +11,13 @@ A lightweight Git worktree plugin for DeepSeek Harness.
9
11
 
10
12
  [简体中文](README.zh.md) · **English**
11
13
 
14
+ ![Create a worktree from a new DSH session](docs/preview.png)
15
+
12
16
  ## Features
13
17
 
14
- - Create a Git worktree from any Git Workspace.
18
+ - Create a Git worktree from a new-session action or any Git Workspace menu.
15
19
  - Choose the current branch or the repository's main branch.
16
- - Register and open the new worktree as a DSH Workspace.
20
+ - Register and open the new worktree as a DSH Workspace with an isolated session.
17
21
  - Create task branches as `task/<name>`.
18
22
  - No additional service or project configuration.
19
23
  - Supports DSH themes, Chinese, and English.
@@ -30,13 +34,19 @@ Restart `dsh web` after installation.
30
34
 
31
35
  You can also install from GitHub with `dsh plugin --profile web add github:alpacachen/dsh-worktree`.
32
36
 
33
- ### Create a worktree
37
+ ### Create from a new session
38
+
39
+ 1. Open **New Session** in a Git Workspace.
40
+ 2. Choose **Create worktree** above the composer.
41
+ 3. Enter a task name. The repository's main branch is selected by default.
42
+ 4. Click **Create and open**.
43
+
44
+ ### Create from a Workspace menu
34
45
 
35
- 1. Open a Git Workspace.
36
- 2. Open the Workspace menu and choose **Create worktree**.
37
- 3. Enter a task name, such as `login-fix`.
38
- 4. Choose **Current branch** or **Main branch**.
39
- 5. Click **Create and open**.
46
+ 1. Open a Git Workspace menu and choose **Create worktree**.
47
+ 2. Enter a task name, such as `login-fix`.
48
+ 3. Choose **Current branch** or **Main branch**.
49
+ 4. Click **Create and open**.
40
50
 
41
51
  The worktree is created at:
42
52
 
@@ -45,4 +55,4 @@ project.worktrees/login-fix/
45
55
  └── branch: task/login-fix
46
56
  ```
47
57
 
48
- The new Workspace is named `<parent>/<task>`.
58
+ The new Workspace is named `<parent>/<task>`. Removing the worktree Workspace does not delete its Git branch.
package/README.zh.md CHANGED
@@ -1,6 +1,8 @@
1
- # dsh-simple-worktree
1
+ # dsh-worktree
2
2
 
3
- 一个轻量的 Git Worktree 插件,用于 DeepSeek Harness。
3
+ 一个用于 DeepSeek Harness 的 Git Worktree 插件:创建任务分支、注册 DSH Workspace,并打开隔离会话。
4
+
5
+ > npm 包:`@alpacachen/dsh-simple-worktree`
4
6
 
5
7
  [![npm version](https://img.shields.io/npm/v/@alpacachen/dsh-simple-worktree?color=5b8def&label=npm)](https://www.npmjs.com/package/@alpacachen/dsh-simple-worktree)
6
8
  ![DeepSeek Harness Plugin](https://img.shields.io/badge/DeepSeek%20Harness-Plugin-7c5cff)
@@ -9,11 +11,13 @@
9
11
 
10
12
  **简体中文** · [English](README.md)
11
13
 
14
+ ![从 DSH 新建对话创建 Worktree](docs/preview.png)
15
+
12
16
  ## 功能
13
17
 
14
- - 从任意 Git Workspace 创建 Worktree。
18
+ - 从新建对话入口或任意 Git Workspace 菜单创建 Worktree。
15
19
  - 支持当前分支和仓库主分支。
16
- - 将新 Worktree 注册并打开为 DSH Workspace
20
+ - 将新 Worktree 注册为 DSH Workspace,并打开隔离会话。
17
21
  - 自动创建 `task/<name>` 格式的任务分支。
18
22
  - 不需要额外服务或项目配置。
19
23
  - 支持 DSH 主题、中文和英文界面。
@@ -30,13 +34,19 @@ dsh plugin --profile web add @alpacachen/dsh-simple-worktree
30
34
 
31
35
  也可以通过 GitHub 安装:`dsh plugin --profile web add github:alpacachen/dsh-worktree`。
32
36
 
33
- ### 创建 Worktree
37
+ ### 从新建对话创建
38
+
39
+ 1. 在 Git Workspace 中打开**新建对话**。
40
+ 2. 点击输入框上方的**创建 Worktree**。
41
+ 3. 输入任务名称;此入口默认选择仓库主分支。
42
+ 4. 点击**创建并打开**。
43
+
44
+ ### 从 Workspace 菜单创建
34
45
 
35
- 1. 打开一个 Git Workspace
36
- 2. 打开 Workspace 菜单,选择 **创建 Worktree**。
37
- 3. 输入任务名称,例如 `login-fix`。
38
- 4. 选择 **当前分支** 或 **主分支**。
39
- 5. 点击 **创建并打开**。
46
+ 1. 打开 Git Workspace 菜单,选择**创建 Worktree**。
47
+ 2. 输入任务名称,例如 `login-fix`。
48
+ 3. 选择**当前分支**或**主分支**。
49
+ 4. 点击**创建并打开**。
40
50
 
41
51
  Worktree 会创建在:
42
52
 
@@ -45,4 +55,4 @@ project.worktrees/login-fix/
45
55
  └── branch: task/login-fix
46
56
  ```
47
57
 
48
- 新 Workspace 的名称为 `<父 Workspace>/<任务名称>`。
58
+ 新 Workspace 的名称为 `<父 Workspace>/<任务名称>`。删除 Worktree Workspace 不会删除对应的 Git 分支。
package/client/client.js CHANGED
@@ -148,7 +148,7 @@ window.__ModuleLoader__.load({
148
148
 
149
149
  If you want to hide the \`${a.titleName}\`, you can wrap it with our VisuallyHidden component.
150
150
 
151
- For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return w.useEffect(()=>{e&&(document.getElementById(e)||console.error(t))},[t,e]),null},kr="DialogDescriptionWarning",yr=({contentRef:e,descriptionId:a})=>{let o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Gt(kr).contentName}}.`;return w.useEffect(()=>{let r=e.current?.getAttribute("aria-describedby");a&&r&&(document.getElementById(a)||console.warn(o))},[o,e,a]),null},Vt=At;var zt=Mt,_t=Ft,Xt=Tt,Kt=qt,jt=Ut,Zt=Wt;var _=require("react/jsx-runtime");function ve({className:e="",...a}){return(0,_.jsx)("button",{className:`dswt-button ${e}`,...a})}function Jt({className:e="",...a}){return(0,_.jsx)("input",{className:`dswt-input ${e}`,...a})}function $t({children:e,...a}){return(0,_.jsx)(Vt,{...a,children:e})}function Qt({children:e}){let a=de();return(0,_.jsxs)(zt,{children:[(0,_.jsx)(_t,{className:"dswt-dialog-overlay"}),(0,_.jsxs)(Xt,{className:"dswt-dialog-content",children:[e,(0,_.jsx)(Zt,{className:"dswt-dialog-close","aria-label":a("close"),children:(0,_.jsx)(Le,{size:16})})]})]})}var Yt=Kt,eo=jt;var S=require("react/jsx-runtime");function ao({target:e,api:a,workspaces:t,sessions:o,defaultBaseChoice:r="current",onCreated:u,onClose:d}){let l=de(),[n,f]=(0,Y.useState)(null),[c,p]=(0,Y.useState)(""),[L,m]=(0,Y.useState)(r),[x,s]=(0,Y.useState)(""),[i,h]=(0,Y.useState)(!1);(0,Y.useEffect)(()=>{let D=!0;return f(null),s(""),p(""),m(r),a.list(e.path).then(F=>{D&&f(F)}).catch(F=>{D&&s(String(F?.message??F))}),()=>{D=!1}},[a,r,e.path]);let C=n?.repoPath,v=Ba(c),R=`task/${v}`,b=C?Ma(C,v):"",A=n?.worktrees.find(D=>E(D.path)===E(e.path))?.branch??"HEAD",I=n?.defaultBranch??n?.worktrees.find(D=>D.isMain)?.branch??A,W=L==="main"?I:A,j=async()=>{if(!C||!c.trim()){s(l("fillTaskName"));return}h(!0),s("");let D,F;try{let X=await a.create({repoPath:C,path:b,branch:R,baseRef:W});D=X.path,F=await t.create({path:X.path}),await t.rename(F.workspaceId,`${e.title}/${v}`);let lo=await t.connectWorkspace(F.workspaceId);u(X.path),o.open(lo),d()}catch(X){F?.workspaceId&&t.delete(F.workspaceId).catch(()=>{}),D&&a.remove({repoPath:C,path:D}).catch(()=>{}),s(`${l("operationFailed")}${String(X?.message??X)}`)}finally{h(!1)}};return(0,S.jsx)($t,{open:!0,onOpenChange:D=>{!D&&!i&&d()},children:(0,S.jsxs)(Qt,{children:[(0,S.jsx)(Yt,{className:"dswt-dialog-title",children:Da(l("dialogTitle"),{name:e.title})}),(0,S.jsx)(eo,{className:"dswt-visually-hidden",children:e.title}),x?(0,S.jsxs)("div",{className:"dswt-error",role:"alert",children:[(0,S.jsx)(Z,{size:14})," ",x]}):null,(0,S.jsxs)("label",{className:"dswt-field",children:[(0,S.jsx)("span",{className:"dswt-field-label",children:l("taskName")}),(0,S.jsx)(Jt,{"aria-label":l("taskName"),value:c,disabled:i,onChange:D=>p(D.target.value),placeholder:l("taskNamePlaceholder"),autoFocus:!0})]}),(0,S.jsxs)("fieldset",{className:"dswt-field dswt-base-fieldset",disabled:i||!n,children:[(0,S.jsx)("legend",{className:"dswt-field-label",children:l("basedOn")}),(0,S.jsxs)("div",{className:"dswt-radio-group",role:"radiogroup","aria-label":l("basedOn"),children:[(0,S.jsxs)("label",{className:"dswt-radio-option","data-selected":L==="current"?"true":void 0,children:[(0,S.jsx)("input",{className:"dswt-radio-input",type:"radio",name:"dswt-base-branch",value:"current",checked:L==="current",onChange:()=>m("current")}),(0,S.jsxs)("span",{className:"dswt-radio-copy",children:[(0,S.jsx)("span",{className:"dswt-radio-label",children:l("currentBranch")}),(0,S.jsx)("span",{className:"dswt-radio-branch",children:A})]})]}),(0,S.jsxs)("label",{className:"dswt-radio-option","data-selected":L==="main"?"true":void 0,children:[(0,S.jsx)("input",{className:"dswt-radio-input",type:"radio",name:"dswt-base-branch",value:"main",checked:L==="main",onChange:()=>m("main")}),(0,S.jsxs)("span",{className:"dswt-radio-copy",children:[(0,S.jsx)("span",{className:"dswt-radio-label",children:l("mainBranch")}),(0,S.jsx)("span",{className:"dswt-radio-branch",children:I})]})]})]})]}),(0,S.jsxs)("div",{className:"dswt-dialog-actions",children:[(0,S.jsx)(ve,{type:"button",disabled:i,onClick:d,children:l("cancel")}),(0,S.jsxs)(ve,{type:"button",className:"dswt-button-primary",disabled:i||!c.trim()||!n,onClick:j,children:[i?(0,S.jsx)(J,{size:14,className:"dswt-spin"}):null,l(i?"creating":"createAndOpen")]})]})]})})}var ue=require("react/jsx-runtime");function Pe(){return(0,ue.jsxs)("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M4 2.25v8.5a2.25 2.25 0 1 0 1.5 0V7.75h4v3a2.25 2.25 0 1 0 1.5 0V6.25H5.5v-4H4Z",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"4.75",cy:"12.75",r:"1.5",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"10.25",cy:"12.75",r:"1.5",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"4.75",cy:"2.25",r:"1.5",fill:"currentColor"})]})}var ke=require("react/jsx-runtime");function to({session:e,useWorkspaces:a,onOpen:t}){let o=de(),r=a(u=>u.items.find(d=>d.sessionIds?.includes(e.sessionId)));return!e.blank||!r?null:(0,ke.jsx)("div",{className:"dswt-new-session-action",children:(0,ke.jsxs)(ve,{type:"button",className:"dswt-new-session-button",onClick:()=>t(r),children:[(0,ke.jsx)(Pe,{}),o("createWorktree")]})})}var Rr="/dsh-simple-worktree";function oo(e){async function a(t,o){let r=await e.rpc.call(Rr,t,o);if(!r?.ok){let u=new Error(r?.error?.message??"worktree operation failed");throw u.code=r?.error?.code,u}return r.value}return{list:t=>a("worktree.list",{path:t}),classify:t=>a("worktree.classify",{path:t}),create:t=>a("worktree.create",t),remove:t=>a("worktree.remove",t)}}var ye=require("react/jsx-runtime"),ro="data-dsh-simple-worktree-style";function Ar(){if(typeof document>"u"||document.querySelector(`style[${ro}]`))return;let e=document.createElement("style");e.setAttribute(ro,""),e.textContent=wa,document.head.appendChild(e)}var uo={name:"@alpacachen/dsh-simple-worktree",inject:["slots","connection","locale","workspaces","sessions","workspaceExtensions"],apply(e){Ar(),e.effect(()=>Aa(e),"dsh-simple-worktree locale");let a=oo(e.connection),t=e.workspaces,o=e.sessions,r=e.get("locale"),u=e.workspaceExtensions,d=new Set;e.effect(()=>{if(!(!r||typeof r.subscribe!="function"))return r.subscribe(()=>u.invalidate())},"dsh-simple-worktree locale refresh");let l=new Set,n=!0,f=()=>{},c=0,p=async()=>{let m=++c,x=t.list.getSnapshot().items,s=await Promise.all(x.map(async i=>{try{return await a.classify(i.path)}catch{return}}));if(!(!n||m!==c)){d.clear(),l.clear();for(let i of s)i?.isGit&&i.path&&d.add(E(i.path)),i?.isWorktree&&i.path&&l.add(E(i.path));u.invalidate()}};e.effect(()=>u.register({id:"dsh-simple-worktree",menuItem(x){let s=E(x.path);if(!(!d.has(s)||l.has(s)))return{id:"dsh-simple-worktree.create",label:Ie("createWorktree"),icon:(0,ye.jsx)(Pe,{}),order:30,onSelect:()=>f(x)}},deleteWorkspace(x){let s=E(x.path);if(l.has(s))return(async()=>{let i=await a.classify(x.path);!i.isWorktree||!i.repoPath||(await a.remove({repoPath:i.repoPath,path:x.path}),await t.delete(x.workspaceId),d.delete(s),l.delete(s),u.invalidate())})()},icon(x){return l.has(E(x.path))?(0,ye.jsx)(Pe,{}):void 0}}),"dsh-simple-worktree workspace extensions"),e.effect(()=>{n=!0;let m=t.list.subscribe(()=>{p()});return p(),()=>{n=!1,c+=1,m()}},"dsh-simple-worktree workspace classification");function L(){let[m,x]=(0,ze.useState)(null);return(0,ze.useEffect)(()=>(f=(s,i="current")=>x({target:s,defaultBaseChoice:i}),()=>{f=()=>{}}),[]),m?(0,ye.jsx)(ao,{target:m.target,api:a,workspaces:t,sessions:o,defaultBaseChoice:m.defaultBaseChoice,onCreated:s=>{d.add(E(s)),l.add(E(s)),u.invalidate()},onClose:()=>x(null)}):null}e.slots.inject("conversation.input.dock",()=>e.slots.register({name:"conversation.input.dock",id:"dsh-simple-worktree-new-session",order:-30,locale:xe,label:()=>Ie("createWorktree")},m=>(0,ye.jsx)(to,{session:m.session,useWorkspaces:m.useWorkspaces,onOpen:x=>f(x,"main")}))),e.slots.inject("shell.overlay",()=>e.slots.register({name:"shell.overlay",id:"dsh-simple-worktree-create",order:30,locale:xe,label:()=>Ie("createWorktree")},L))}};var Dr=uo;
151
+ For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return w.useEffect(()=>{e&&(document.getElementById(e)||console.error(t))},[t,e]),null},kr="DialogDescriptionWarning",yr=({contentRef:e,descriptionId:a})=>{let o=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Gt(kr).contentName}}.`;return w.useEffect(()=>{let r=e.current?.getAttribute("aria-describedby");a&&r&&(document.getElementById(a)||console.warn(o))},[o,e,a]),null},Vt=At;var zt=Mt,_t=Ft,Xt=Tt,Kt=qt,jt=Ut,Zt=Wt;var _=require("react/jsx-runtime");function ve({className:e="",...a}){return(0,_.jsx)("button",{className:`dswt-button ${e}`,...a})}function Jt({className:e="",...a}){return(0,_.jsx)("input",{className:`dswt-input ${e}`,...a})}function $t({children:e,...a}){return(0,_.jsx)(Vt,{...a,children:e})}function Qt({children:e}){let a=de();return(0,_.jsxs)(zt,{children:[(0,_.jsx)(_t,{className:"dswt-dialog-overlay"}),(0,_.jsxs)(Xt,{className:"dswt-dialog-content",children:[e,(0,_.jsx)(Zt,{className:"dswt-dialog-close","aria-label":a("close"),children:(0,_.jsx)(Le,{size:16})})]})]})}var Yt=Kt,eo=jt;var S=require("react/jsx-runtime");function ao({target:e,api:a,workspaces:t,sessions:o,defaultBaseChoice:r="current",onCreated:u,onClose:d}){let l=de(),[n,f]=(0,Y.useState)(null),[c,p]=(0,Y.useState)(""),[L,m]=(0,Y.useState)(r),[x,s]=(0,Y.useState)(""),[i,h]=(0,Y.useState)(!1);(0,Y.useEffect)(()=>{let D=!0;return f(null),s(""),p(""),m(r),a.list(e.path).then(F=>{D&&f(F)}).catch(F=>{D&&s(String(F?.message??F))}),()=>{D=!1}},[a,r,e.path]);let C=n?.repoPath,v=Ba(c),R=`task/${v}`,b=C?Ma(C,v):"",A=n?.worktrees.find(D=>E(D.path)===E(e.path))?.branch??"HEAD",I=n?.defaultBranch??n?.worktrees.find(D=>D.isMain)?.branch??A,W=L==="main"?n?.defaultRef??I:A,j=async()=>{if(!C||!c.trim()){s(l("fillTaskName"));return}h(!0),s("");let D,F;try{let X=await a.create({repoPath:C,path:b,branch:R,baseRef:W});D=X.path,F=await t.create({path:X.path}),await t.rename(F.workspaceId,`${e.title}/${v}`);let lo=await t.connectWorkspace(F.workspaceId);u(X.path),o.open(lo),d()}catch(X){F?.workspaceId&&t.delete(F.workspaceId).catch(()=>{}),D&&a.remove({repoPath:C,path:D}).catch(()=>{}),s(`${l("operationFailed")}${String(X?.message??X)}`)}finally{h(!1)}};return(0,S.jsx)($t,{open:!0,onOpenChange:D=>{!D&&!i&&d()},children:(0,S.jsxs)(Qt,{children:[(0,S.jsx)(Yt,{className:"dswt-dialog-title",children:Da(l("dialogTitle"),{name:e.title})}),(0,S.jsx)(eo,{className:"dswt-visually-hidden",children:e.title}),x?(0,S.jsxs)("div",{className:"dswt-error",role:"alert",children:[(0,S.jsx)(Z,{size:14})," ",x]}):null,(0,S.jsxs)("label",{className:"dswt-field",children:[(0,S.jsx)("span",{className:"dswt-field-label",children:l("taskName")}),(0,S.jsx)(Jt,{"aria-label":l("taskName"),value:c,disabled:i,onChange:D=>p(D.target.value),placeholder:l("taskNamePlaceholder"),autoFocus:!0})]}),(0,S.jsxs)("fieldset",{className:"dswt-field dswt-base-fieldset",disabled:i||!n,children:[(0,S.jsx)("legend",{className:"dswt-field-label",children:l("basedOn")}),(0,S.jsxs)("div",{className:"dswt-radio-group",role:"radiogroup","aria-label":l("basedOn"),children:[(0,S.jsxs)("label",{className:"dswt-radio-option","data-selected":L==="current"?"true":void 0,children:[(0,S.jsx)("input",{className:"dswt-radio-input",type:"radio",name:"dswt-base-branch",value:"current",checked:L==="current",onChange:()=>m("current")}),(0,S.jsxs)("span",{className:"dswt-radio-copy",children:[(0,S.jsx)("span",{className:"dswt-radio-label",children:l("currentBranch")}),(0,S.jsx)("span",{className:"dswt-radio-branch",children:A})]})]}),(0,S.jsxs)("label",{className:"dswt-radio-option","data-selected":L==="main"?"true":void 0,children:[(0,S.jsx)("input",{className:"dswt-radio-input",type:"radio",name:"dswt-base-branch",value:"main",checked:L==="main",onChange:()=>m("main")}),(0,S.jsxs)("span",{className:"dswt-radio-copy",children:[(0,S.jsx)("span",{className:"dswt-radio-label",children:l("mainBranch")}),(0,S.jsx)("span",{className:"dswt-radio-branch",children:I})]})]})]})]}),(0,S.jsxs)("div",{className:"dswt-dialog-actions",children:[(0,S.jsx)(ve,{type:"button",disabled:i,onClick:d,children:l("cancel")}),(0,S.jsxs)(ve,{type:"button",className:"dswt-button-primary",disabled:i||!c.trim()||!n,onClick:j,children:[i?(0,S.jsx)(J,{size:14,className:"dswt-spin"}):null,l(i?"creating":"createAndOpen")]})]})]})})}var ue=require("react/jsx-runtime");function Pe(){return(0,ue.jsxs)("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[(0,ue.jsx)("path",{d:"M4 2.25v8.5a2.25 2.25 0 1 0 1.5 0V7.75h4v3a2.25 2.25 0 1 0 1.5 0V6.25H5.5v-4H4Z",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"4.75",cy:"12.75",r:"1.5",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"10.25",cy:"12.75",r:"1.5",fill:"currentColor"}),(0,ue.jsx)("circle",{cx:"4.75",cy:"2.25",r:"1.5",fill:"currentColor"})]})}var ke=require("react/jsx-runtime");function to({session:e,useWorkspaces:a,onOpen:t}){let o=de(),r=a(u=>u.items.find(d=>d.sessionIds?.includes(e.sessionId)));return!e.blank||!r?null:(0,ke.jsx)("div",{className:"dswt-new-session-action",children:(0,ke.jsxs)(ve,{type:"button",className:"dswt-new-session-button",onClick:()=>t(r),children:[(0,ke.jsx)(Pe,{}),o("createWorktree")]})})}var Rr="/dsh-simple-worktree";function oo(e){async function a(t,o){let r=await e.rpc.call(Rr,t,o);if(!r?.ok){let u=new Error(r?.error?.message??"worktree operation failed");throw u.code=r?.error?.code,u}return r.value}return{list:t=>a("worktree.list",{path:t}),classify:t=>a("worktree.classify",{path:t}),create:t=>a("worktree.create",t),remove:t=>a("worktree.remove",t)}}var ye=require("react/jsx-runtime"),ro="data-dsh-simple-worktree-style";function Ar(){if(typeof document>"u"||document.querySelector(`style[${ro}]`))return;let e=document.createElement("style");return e.setAttribute(ro,""),e.textContent=wa,document.head.appendChild(e),()=>e.remove()}var uo={name:"@alpacachen/dsh-simple-worktree",inject:["slots","connection","locale","workspaces","sessions","workspaceExtensions"],apply(e){e.effect(Ar,"dsh-simple-worktree styles"),e.effect(()=>Aa(e),"dsh-simple-worktree locale");let a=oo(e.connection),t=e.workspaces,o=e.sessions,r=e.get("locale"),u=e.workspaceExtensions,d=new Set;e.effect(()=>{if(!(!r||typeof r.subscribe!="function"))return r.subscribe(()=>u.invalidate())},"dsh-simple-worktree locale refresh");let l=new Set,n=!0,f=()=>{},c=0,p=async()=>{let m=++c,x=t.list.getSnapshot().items,s=await Promise.all(x.map(async i=>{try{return await a.classify(i.path)}catch{return}}));if(!(!n||m!==c)){d.clear(),l.clear();for(let i of s)i?.isGit&&i.path&&d.add(E(i.path)),i?.isWorktree&&i.path&&l.add(E(i.path));u.invalidate()}};e.effect(()=>u.register({id:"dsh-simple-worktree",menuItem(x){let s=E(x.path);if(!(!d.has(s)||l.has(s)))return{id:"dsh-simple-worktree.create",label:Ie("createWorktree"),icon:(0,ye.jsx)(Pe,{}),order:30,onSelect:()=>f(x)}},deleteWorkspace(x){let s=E(x.path);if(l.has(s))return(async()=>{let i=await a.classify(x.path);!i.isWorktree||!i.repoPath||(await a.remove({repoPath:i.repoPath,path:x.path}),await t.delete(x.workspaceId),d.delete(s),l.delete(s),u.invalidate())})()},icon(x){return l.has(E(x.path))?(0,ye.jsx)(Pe,{}):void 0}}),"dsh-simple-worktree workspace extensions"),e.effect(()=>{n=!0;let m=t.list.subscribe(()=>{p()});return p(),()=>{n=!1,c+=1,m()}},"dsh-simple-worktree workspace classification");function L(){let[m,x]=(0,ze.useState)(null);return(0,ze.useEffect)(()=>(f=(s,i="current")=>x({target:s,defaultBaseChoice:i}),()=>{f=()=>{}}),[]),m?(0,ye.jsx)(ao,{target:m.target,api:a,workspaces:t,sessions:o,defaultBaseChoice:m.defaultBaseChoice,onCreated:s=>{d.add(E(s)),l.add(E(s)),u.invalidate()},onClose:()=>x(null)}):null}e.slots.inject("conversation.input.dock",()=>e.slots.register({name:"conversation.input.dock",id:"dsh-simple-worktree-new-session",order:-30,locale:xe,label:()=>Ie("createWorktree")},m=>(0,ye.jsx)(to,{session:m.session,useWorkspaces:m.useWorkspaces,onOpen:x=>f(x,"main")}))),e.slots.inject("shell.overlay",()=>e.slots.register({name:"shell.overlay",id:"dsh-simple-worktree-create",order:30,locale:xe,label:()=>Ie("createWorktree")},L))}};var Dr=uo;
152
152
  /*! Bundled license information:
153
153
 
154
154
  lucide-react/dist/esm/shared/src/utils.js:
Binary file
package/lib/index.js CHANGED
@@ -42,18 +42,24 @@ async function tryRunGit(subprocess, cwd, args) {
42
42
  }
43
43
 
44
44
  export async function detectDefaultBranch(subprocess, repoPath, worktrees) {
45
- const remoteHead = await tryRunGit(subprocess, repoPath, ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'])
45
+ const [remoteHead, refsOutput] = await Promise.all([
46
+ tryRunGit(subprocess, repoPath, ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD']),
47
+ tryRunGit(subprocess, repoPath, ['for-each-ref', '--format=%(refname:short)', 'refs/heads', 'refs/remotes/origin']),
48
+ ])
49
+ const refs = new Set(refsOutput.split(/\r?\n/).filter(Boolean))
50
+
46
51
  if (remoteHead) {
47
52
  const separator = remoteHead.indexOf('/')
48
- if (separator >= 0 && remoteHead.slice(separator + 1)) return remoteHead.slice(separator + 1)
53
+ const name = separator >= 0 ? remoteHead.slice(separator + 1) : ''
54
+ if (name) return { name, ref: refs.has(name) ? name : remoteHead }
49
55
  }
50
56
 
51
- const refs = await tryRunGit(subprocess, repoPath, ['for-each-ref', '--format=%(refname:short)', 'refs/heads', 'refs/remotes/origin'])
52
- const branches = refs.split(/\r?\n/).filter(Boolean).map((ref) => ref.startsWith('origin/') ? ref.slice('origin/'.length) : ref)
53
- for (const preferred of ['main', 'master', 'trunk', 'develop']) {
54
- if (branches.includes(preferred)) return preferred
57
+ for (const name of ['main', 'master', 'trunk', 'develop']) {
58
+ if (refs.has(name)) return { name, ref: name }
59
+ if (refs.has(`origin/${name}`)) return { name, ref: `origin/${name}` }
55
60
  }
56
- return worktrees.find((worktree) => worktree.isMain)?.branch ?? worktrees.find((worktree) => worktree.branch)?.branch ?? 'HEAD'
61
+ const name = worktrees.find((worktree) => worktree.isMain)?.branch ?? worktrees.find((worktree) => worktree.branch)?.branch
62
+ return name ? { name, ref: name } : { name: 'HEAD', ref: 'HEAD' }
57
63
  }
58
64
 
59
65
  export function parseWorktrees(text) {
@@ -123,7 +129,7 @@ export function apply(ctx) {
123
129
  const worktrees = parseWorktrees(porcelain)
124
130
  const repoPath = worktrees.find((worktree) => worktree.isMain)?.path ?? topLevel
125
131
  const defaultBranch = await detectDefaultBranch(ctx.subprocess, repoPath, worktrees)
126
- return { repoPath, commonDir, defaultBranch, worktrees }
132
+ return { repoPath, commonDir, defaultBranch: defaultBranch.name, defaultRef: defaultBranch.ref, worktrees }
127
133
  }, classifyGitError)
128
134
 
129
135
  if (endpoint === 'worktree.classify') return recover(async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alpacachen/dsh-simple-worktree",
3
- "version": "1.0.5",
4
- "description": "A minimal worktree manager with one button and one dialog for DeepSeek Harness.",
3
+ "version": "1.0.6",
4
+ "description": "A Git worktree plugin for DeepSeek Harness that creates task branches, registers worktrees as DSH Workspaces, and opens isolated sessions.",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "deepseek-harness",
@@ -35,7 +35,8 @@
35
35
  "cordis.patch.yml",
36
36
  "package.json",
37
37
  "README.md",
38
- "README.zh.md"
38
+ "README.zh.md",
39
+ "docs/preview.png"
39
40
  ],
40
41
  "scripts": {
41
42
  "build": "node build.mjs",