zen-gitsync 2.17.14 → 2.17.16

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.
Files changed (89) hide show
  1. package/README.md +211 -185
  2. package/package.json +2 -2
  3. package/scripts/release.js +33 -16
  4. package/src/cli/ai/agent.js +24 -2
  5. package/src/cli/ai/runtime.test.js +1 -1
  6. package/src/cli/ai/tools.js +69 -14
  7. package/src/cli/ai/tools.test.js +46 -1
  8. package/src/config.js +8 -4
  9. package/src/gitCommit.js +18 -1
  10. package/src/ui/public/assets/AgentView-DOyN97Ve.js +5 -0
  11. package/src/ui/public/assets/{AgentView-vvVhbIQ5.css → AgentView-DkM2KXuc.css} +1 -1
  12. package/src/ui/public/assets/AppVersionBadge-oON3sAj4.js +2 -0
  13. package/src/ui/public/assets/{BranchSelector-XIN87Mkw.js → BranchSelector-Cpj7eGqY.js} +1 -1
  14. package/src/ui/public/assets/CommitForm-D_ovYhVw.js +6 -0
  15. package/src/ui/public/assets/{CommonDialog-BiNTGpA-.js → CommonDialog-ChZbqfRF.js} +1 -1
  16. package/src/ui/public/assets/EditorView-BPzpI0GV.js +1 -0
  17. package/src/ui/public/assets/FileDiffViewer-B_qEKA9L.js +15 -0
  18. package/src/ui/public/assets/{FlowExecutionViewer-D9Vzgh91.js → FlowExecutionViewer-Drw4hlJG.js} +1 -1
  19. package/src/ui/public/assets/FlowOrchestrationWorkspace-C7yTD1gj.js +21 -0
  20. package/src/ui/public/assets/{IconButton-DysyaC1j.js → IconButton-DEARmMkZ.js} +1 -1
  21. package/src/ui/public/assets/{LogList-QDgok-UJ.js → LogList-BA_gowxE.js} +5 -5
  22. package/src/ui/public/assets/MindmapView-8X6z245q.css +1 -0
  23. package/src/ui/public/assets/MindmapView-K-XcLLXr.js +2 -0
  24. package/src/ui/public/assets/MonitorView-C0RL5K9W.js +1 -0
  25. package/src/ui/public/assets/ProjectStartupButton-DC36_vvU.js +1 -0
  26. package/src/ui/public/assets/RemoteManagerDialog-Bkqja660.js +4 -0
  27. package/src/ui/public/assets/{RemoteRepoCard-Bn9cKt1D.js → RemoteRepoCard-Bsm7cj_H.js} +2 -2
  28. package/src/ui/public/assets/SourceMapView-Y5NKdIk6.js +3 -0
  29. package/src/ui/public/assets/{SvgIcon-CvtoU5yo.js → SvgIcon-D_mFHXP4.js} +1 -1
  30. package/src/ui/public/assets/{TemplateManager-saqC9kdQ.js → TemplateManager-BzKVXZhy.js} +1 -1
  31. package/src/ui/public/assets/UserInputNode-BPLK4aYx.js +1 -0
  32. package/src/ui/public/assets/WorkbenchView-xbGdiVMQ.js +56 -0
  33. package/src/ui/public/assets/_plugin-vue_export-helper-dg2VUnSQ.js +19 -0
  34. package/src/ui/public/assets/configStore-DtjAc3w9.js +1 -0
  35. package/src/ui/public/assets/{css.worker-DFdt6_zu.js → css.worker-BDCmgL4U.js} +9 -9
  36. package/src/ui/public/assets/editor.worker-GCPm6rMv.js +26 -0
  37. package/src/ui/public/assets/{element-plus-Dc1iTOWq.css → element-plus-Cwwq-Gje.css} +1 -1
  38. package/src/ui/public/assets/element-plus-DxBPQwL7.js +48 -0
  39. package/src/ui/public/assets/{flow-mindmap-CHxAWdLw.js → flow-mindmap-BqFb1WO5.js} +1 -1
  40. package/src/ui/public/assets/{gitStore-BgC8OY0k.js → gitStore-BZo9_zyy.js} +5 -5
  41. package/src/ui/public/assets/{html.worker-JUzsMP-j.js → html.worker-DG8hnSJR.js} +8 -8
  42. package/src/ui/public/assets/index-CHuCYLWm.js +111 -0
  43. package/src/ui/public/assets/index-CmbatbSR.css +1 -0
  44. package/src/ui/public/assets/json.worker-CxwlJRnL.js +58 -0
  45. package/src/ui/public/assets/{monaco-DkJuNcCr.js → monaco-BScz9v63.js} +6 -6
  46. package/src/ui/public/assets/{office-docx-CmBY5bpF.js → office-docx-CZXLkCf5.js} +1 -1
  47. package/src/ui/public/assets/{office-excel-BEhsBUNX.js → office-excel-CBKszjVA.js} +1 -1
  48. package/src/ui/public/assets/{office-pptx-DWfi413x.js → office-pptx-NeUSnN3k.js} +3 -3
  49. package/src/ui/public/assets/previewSandbox-BTTTXooN.js +0 -0
  50. package/src/ui/public/assets/{ts.worker-CmEKzkmF.js → ts.worker-DgFMIcEs.js} +49 -49
  51. package/src/ui/public/assets/{useThemeObserver-DhCU3SIo.js → useThemeObserver-E7Hk50l3.js} +1 -1
  52. package/src/ui/public/assets/vendor-DnB9EJa3.css +1 -0
  53. package/src/ui/public/assets/{vendor-CZnXb2r9.js → vendor-bdHhLiED.js} +28 -28
  54. package/src/ui/public/assets/{vue-flow-7_n4vJqi.js → vue-flow-fLUQ0_kE.js} +1 -1
  55. package/src/ui/public/index.html +19 -19
  56. package/src/ui/server/index.js +4 -0
  57. package/src/ui/server/routes/explorerContextMenu.js +208 -0
  58. package/src/ui/server/routes/explorerContextMenu.test.js +180 -0
  59. package/src/ui/server/routes/workbench/agentChat.js +14 -3
  60. package/src/ui/server/routes/workbench/agentMarketplace.js +23 -9
  61. package/src/ui/server/routes/workbench/agentMarketplace.test.js +32 -0
  62. package/src/ui/server/routes/workbench/agentRoutes.js +14 -7
  63. package/src/ui/server/routes/workbench/agentRoutes.test.js +47 -1
  64. package/src/ui/server/routes/workbench/taskRunner.codex.test.js +173 -0
  65. package/src/ui/server/routes/workbench/taskRunner.js +259 -10
  66. package/src/ui/server/routes/workbench/taskRunner.opencode.test.js +4 -2
  67. package/src/ui/public/assets/AgentView-DLHlVWRg.js +0 -5
  68. package/src/ui/public/assets/AppVersionBadge-JxpMuGwP.js +0 -2
  69. package/src/ui/public/assets/CommitForm-CW53Er5m.js +0 -6
  70. package/src/ui/public/assets/EditorView-D0JoJhgt.js +0 -1
  71. package/src/ui/public/assets/FileDiffViewer-Yas2nO2U.js +0 -15
  72. package/src/ui/public/assets/FlowOrchestrationWorkspace-DQ3fg5b9.js +0 -21
  73. package/src/ui/public/assets/MindmapView-BQTqx842.css +0 -1
  74. package/src/ui/public/assets/MindmapView-CeZsQNBK.js +0 -2
  75. package/src/ui/public/assets/MonitorView-D1tgmjjS.js +0 -1
  76. package/src/ui/public/assets/ProjectStartupButton-COntA4q1.js +0 -1
  77. package/src/ui/public/assets/RemoteManagerDialog-3dihAOab.js +0 -4
  78. package/src/ui/public/assets/SourceMapView-C8UdzQXF.js +0 -3
  79. package/src/ui/public/assets/UserInputNode-CvEfvX3i.js +0 -1
  80. package/src/ui/public/assets/WorkbenchView-B7WAu1Ay.js +0 -56
  81. package/src/ui/public/assets/_plugin-vue_export-helper-BdTxl34g.js +0 -19
  82. package/src/ui/public/assets/configStore-AQMSazCM.js +0 -1
  83. package/src/ui/public/assets/editor.worker-O-CH8JUO.js +0 -26
  84. package/src/ui/public/assets/element-plus-CMSkP_w2.js +0 -48
  85. package/src/ui/public/assets/index-Dpx9Bcqn.css +0 -1
  86. package/src/ui/public/assets/index-qAmzFO10.js +0 -104
  87. package/src/ui/public/assets/json.worker-B4dEhy0e.js +0 -58
  88. package/src/ui/public/assets/previewSandbox-CyuMMYaq.js +0 -0
  89. package/src/ui/public/assets/vendor-4ojsjDYc.css +0 -1
@@ -0,0 +1,56 @@
1
+ import"./rolldown-runtime-C0FnF6B9.js";import{$r as e,Bt as t,C as n,Dn as r,E as i,En as a,F as o,Fn as s,It as c,J as l,Jn as u,K as d,Kn as f,L as p,Lt as m,M as h,Mn as g,Nn as _,On as v,P as y,Pr as b,Pt as x,Qn as S,Rt as C,S as w,Sn as T,St as E,Tn as D,Tt as ee,U as te,Un as ne,V as re,Vt as O,W as k,Wt as ie,Xn as A,Y as ae,Yr as j,_ as M,_n as oe,_r as se,a as N,ar as P,at as F,b as ce,bn as I,cr as L,ct as le,et as ue,fr as R,ft as de,gn as z,gt as fe,hn as pe,i as B,in as me,jt as V,pn as H,q as he,qr as U,qt as ge,r as _e,sr as W,st as ve,tr as ye,un as G,ut as be,v as xe,vn as K,vt as Se,w as Ce,wn as q,xt as we,y as Te,yn as J,yr as Y,zn as X}from"./element-plus-DxBPQwL7.js";import{a as Ee,i as De,n as Oe,t as ke}from"./vendor-bdHhLiED.js";import{n as Z,t as Q}from"./_plugin-vue_export-helper-dg2VUnSQ.js";import{t as Ae}from"./SvgIcon-D_mFHXP4.js";import{a as je,i as Me,o as Ne,r as Pe,t as Fe}from"./configStore-DtjAc3w9.js";import{t as Ie}from"./CommonDialog-ChZbqfRF.js";import{C as $,S as Le,a as Re,c as ze,d as Be,f as Ve,i as He,l as Ue,m as We,o as Ge,p as Ke,s as qe,u as Je}from"./index-CHuCYLWm.js";X(),R();var Ye=s({__name:`AttachmentZone`,props:{attachments:{type:Array,required:!0},isImage:{type:Function,required:!0},humanSize:{type:Function,required:!0},isUploading:{type:Boolean,required:!0},isPasteHover:{type:Boolean,required:!0},maxCount:{type:Number,required:!0},onPick:{type:Function,required:!0},onRemove:{type:Function,required:!0},rawBase:{type:String,required:!1}},emits:[`paste`,`drop`,`dragover`,`dragenter`,`dragleave`],setup(e,{expose:t,emit:n}){t();let r=e;function i(e){return`${r.rawBase||`/api/workbench/attachments`}/${e.id}/raw`}let a=n,o=q(()=>r.attachments.filter(e=>r.isImage(e))),s=q(()=>o.value.map(e=>i(e))),c=Y(0),l=Y(!1);function u(e){if(r.isImage(e)){let t=o.value.findIndex(t=>t.id===e.id);c.value=t>=0?t:0,l.value=!0}else window.open(i(e),`_blank`,`noopener`)}function d(){l.value=!1}let p=Y({visible:!1,x:0,y:0,att:null}),m=Y(!1);function h(e,t){if(!r.isImage(e))return;t.preventDefault();let n=window.innerWidth-180,i=window.innerHeight-120;p.value={visible:!0,x:Math.min(t.clientX,n),y:Math.min(t.clientY,i),att:e}}function g(){p.value.visible&&(p.value.visible=!1)}async function _(){let e=p.value.att;if(e&&!m.value){if(g(),!navigator.clipboard||typeof ClipboardItem>`u`){B({type:`warning`,message:Z(`@WORKBENCH:当前浏览器不支持复制图片`)});return}m.value=!0;try{let t=await fetch(i(e),{credentials:`same-origin`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.blob(),r=[`image/png`,`image/jpeg`,`image/webp`,`image/gif`].includes(n.type)?n.type:`image/png`,a=new ClipboardItem({[r]:n});await navigator.clipboard.write([a]),B({type:`success`,message:Z(`@WORKBENCH:图片已复制到剪贴板`),duration:1800})}catch(e){B({type:`error`,message:Z(`@WORKBENCH:复制失败 {error}`,{error:e?.message||``})})}finally{m.value=!1}}}typeof window<`u`&&(window.addEventListener(`click`,g),window.addEventListener(`scroll`,g,!0),window.addEventListener(`blur`,g)),f(()=>{typeof window>`u`||(window.removeEventListener(`click`,g),window.removeEventListener(`scroll`,g,!0),window.removeEventListener(`blur`,g))});let v={props:r,rawOf:i,emit:a,imageList:o,previewUrls:s,previewIndex:c,previewVisible:l,previewAttachment:u,closePreview:d,contextMenu:p,copyBusy:m,openContextMenu:h,closeContextMenu:g,copyImageToClipboard:_,get ElImageViewer(){return ce},get $t(){return Z}};return Object.defineProperty(v,"__isScriptSetup",{enumerable:!1,value:!0}),v}});b(),X(),G();var Xe={class:`wb-attachments__head`},Ze={class:`wb-attachments__label`},Qe={class:`wb-attachments__count`},$e=[`disabled`],et={key:0,class:`wb-attachments__paste-hint`},tt={key:1,class:`wb-attachments__list`},nt=[`title`,`onClick`,`onContextmenu`],rt=[`src`,`alt`],it={key:1},at={class:`wb-attachment__meta`},ot=[`title`],st=[`onClick`,`title`];function ct(t,n,i,o,s,c){return A(),v(I,null,[D(`div`,{class:U([`wb-attachments`,{"is-paste-hover":i.isPasteHover}]),onPaste:n[1]||=e=>o.emit(`paste`,e),onDrop:n[2]||=J(e=>o.emit(`drop`,e),[`prevent`]),onDragover:n[3]||=J(e=>o.emit(`dragover`,e),[`prevent`]),onDragenter:n[4]||=J(e=>o.emit(`dragenter`,e),[`prevent`]),onDragleave:n[5]||=e=>o.emit(`dragleave`,e)},[D(`div`,Xe,[D(`span`,Ze,[g(e(o.$t(`@WORKBENCH:附件`))+` `,1),D(`span`,Qe,e(i.attachments.length)+` / `+e(i.maxCount),1)]),D(`button`,{class:`wb-attachments__add wb-soft-btn`,disabled:i.isUploading||i.attachments.length>=i.maxCount,onClick:n[0]||=(...e)=>i.onPick&&i.onPick(...e)},e(i.isUploading?o.$t(`@WORKBENCH:上传中…`):o.$t(`@WORKBENCH:添加附件`)),9,$e)]),i.isPasteHover?(A(),v(`div`,et,e(o.$t(`@WORKBENCH:粘贴图片以快速添加`)),1)):r(`v-if`,!0),i.attachments.length>0?(A(),v(`ul`,tt,[(A(!0),v(I,null,S(i.attachments,t=>(A(),v(`li`,{key:t.id,class:`wb-attachment`},[D(`button`,{type:`button`,class:`wb-attachment__preview`,title:o.$t(`@WORKBENCH:点击预览`),onClick:e=>o.previewAttachment(t),onContextmenu:e=>o.openContextMenu(t,e)},[D(`div`,{class:U([`wb-attachment__icon`,{"wb-attachment__icon--img":i.isImage(t)}])},[i.isImage(t)?(A(),v(`img`,{key:0,src:o.rawOf(t),alt:t.originalName,loading:`lazy`},null,8,rt)):(A(),v(`span`,it,e(t.ext.toUpperCase()),1))],2),D(`div`,at,[D(`div`,{class:`wb-attachment__name`,title:`${t.originalName} (${i.humanSize(t.size)})`},e(t.originalName),9,ot)])],40,nt),D(`button`,{class:`wb-attachment__del`,onClick:J(e=>i.onRemove(t),[`stop`]),title:o.$t(`@WORKBENCH:删除`)},`×`,8,st)]))),128))])):r(`v-if`,!0)],34),r(`
2
+ el-image-viewer 自己通过内部 <Teleport to="body" :disabled="!teleported"> 把遮罩渲染到 body。
3
+ 不要在外面再包一层 <teleport to="body"> —— 嵌套 Teleport 在 element-plus 2.11.x 下会让组件
4
+ 的 v-if 容器内残留占位、且内部 Teleport 因找不到正确锚点而不挂载,导致点击图片无反应。
5
+ 显式传 :teleported="true" 是为了保证内部 Teleport 启用(默认是 undefined 关闭)。
6
+ `),o.previewVisible&&o.previewUrls.length>0?(A(),a(o.ElImageViewer,{key:0,"url-list":o.previewUrls,"initial-index":o.previewIndex,"hide-on-click-modal":!0,teleported:!0,onClose:o.closePreview},null,8,[`url-list`,`initial-index`])):r(`v-if`,!0),r(` 右键菜单:仅图片附件可用 `),(A(),a(T,{to:`body`},[o.contextMenu.visible&&o.contextMenu.att&&i.isImage(o.contextMenu.att)?(A(),v(`ul`,{key:0,class:`wb-ctx-menu`,style:j({top:o.contextMenu.y+`px`,left:o.contextMenu.x+`px`}),onContextmenu:n[6]||=J(()=>{},[`prevent`])},[D(`li`,{class:U([`wb-ctx-menu__item`,{"is-disabled":o.copyBusy}]),onClick:o.copyImageToClipboard},[n[7]||=D(`span`,{class:`wb-ctx-menu__icon`,"aria-hidden":`true`},[D(`svg`,{viewBox:`0 0 24 24`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,"stroke-width":`1.8`,"stroke-linecap":`round`,"stroke-linejoin":`round`},[D(`rect`,{x:`9`,y:`9`,width:`11`,height:`11`,rx:`2`}),D(`path`,{d:`M5 15V5a2 2 0 0 1 2-2h10`})])],-1),D(`span`,null,e(o.$t(`@WORKBENCH:复制图片`)),1)],2)],36)):r(`v-if`,!0)]))],64)}var lt=Q(Ye,[[`render`,ct],[`__scopeId`,`data-v-d2df2361`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/AttachmentZone.vue`]]),ut=Oe(`claude`),dt=Oe(`opencode`),ft=Oe(`codex`);function pt(e){return e===`opencode`?dt:e===`codex`?ft:ut}function mt(e){switch(e){case`todo`:return Z(`@WORKBENCH:待执行`);case`running`:return Z(`@WORKBENCH:执行中`);case`done`:return Z(`@WORKBENCH:已完成`);case`error`:return Z(`@WORKBENCH:出错`);case`cancelled`:return Z(`@WORKBENCH:已取消`);case`pending`:return Z(`@WORKBENCH:排队中`);default:return e}}function ht(e){switch(e){case`running`:return`var(--color-primary)`;case`done`:return`#22c55e`;case`error`:return`#ef4444`;case`cancelled`:return`#9ca3af`;case`pending`:return`#f59e0b`;default:return`var(--text-tertiary)`}}var gt=8192;function _t(e,t){return e.length>t?`…(前文已截断)\n${e.slice(-t)}`:e}function vt(e,t){let n=e||`done`;return n!==`pending`&&n!==`running`||t===`running`||t===`pending`?n:t===`cancelled`||t===`error`?`error`:`done`}function yt(e){let t=e?.toolCalls;if(!Array.isArray(t)||t.length===0)return[];let n=e?.status||`done`,r=[];for(let e=0;e<t.length;e++){let i=t[e];if(!i||typeof i!=`object`)continue;let a=vt(i.status,n),o=typeof i.result==`string`?i.result:``;r.push({id:typeof i.id==`string`&&i.id?i.id:`tool-${e}`,name:typeof i.name==`string`?i.name:``,argsPreview:typeof i.argsPreview==`string`?i.argsPreview:``,arguments:typeof i.arguments==`string`?i.arguments:``,result:o?_t(o,gt):``,status:a,error:typeof i.error==`string`&&i.error?i.error:void 0})}return r}X(),R();var bt=65536,xt=s({__name:`JobLogDetails`,props:{job:{type:Object,required:!0}},emits:[`re-execute`],setup(e,{expose:t,emit:n}){t();let r=Fe(),i=e,a=n,o=Y(!1);function s(){o.value=!o.value}let c=q(()=>i.job.status===`running`||i.job.status===`pending`);P(()=>i.job.status,(e,t)=>{t!==`running`&&t!==`pending`&&(e===`running`||e===`pending`)&&(o.value=!1)});function l(){let e=i.job.output||``;return e?e.length<=bt?e:`${Z(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}function u(){let e=i.job.thinking||``;return e?e.length<=bt?e:`${Z(`@WORKBENCH:…(前文已截断)`)}\n${e.slice(-65536)}`:``}async function d(e){try{if(navigator?.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,t.style.left=`-9999px`,document.body.appendChild(t),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}}async function f(){let e=[];if(i.job.prompt&&e.push(`## ${Z(`@WORKBENCH:用户提示词`)}\n\n${i.job.prompt}`),i.job.thinking&&e.push(`## ${Z(`@WORKBENCH:Claude 思考`)}\n\n${i.job.thinking}`),i.job.output&&e.push(`## ${Z(`@WORKBENCH:模型返回`)}\n\n${i.job.output}`),!e.length){B.warning(Z(`@WORKBENCH:暂无内容可复制`));return}await d(e.join(`
7
+
8
+ ---
9
+
10
+ `))?B.success(Z(`@WORKBENCH:已复制到剪贴板`)):B.error(Z(`@WORKBENCH:复制失败`))}let p=q(()=>{let e=i.job.status;return e===`done`||e===`error`||e===`cancelled`}),m=q(()=>i.job.status===`cancelled`?`wb-log-summary__status--cancelled`:i.job.status===`error`?`wb-log-summary__status--error`:`wb-log-summary__status--done`),h=q(()=>i.job.status===`cancelled`?`⏹`:i.job.status===`error`?`✗`:`✓`),g=q(()=>i.job.status===`cancelled`?Z(`@WORKBENCH:已停止`):i.job.status===`error`?Z(`@WORKBENCH:执行出错`):Z(`@WORKBENCH:执行完成`)),_=q(()=>Ne(i.job?.agent)),v=q(()=>pt(i.job?.agent));function y(e,t){return e===`running`||e===`pending`?t?`streaming`:`pending`:e===`error`?`error`:`done`}let b=q(()=>{let e=i.job,t=[],n=e.startedAt?new Date(e.startedAt).getTime():Date.now();e.prompt&&t.push({id:`${e.id}-u`,role:`user`,content:e.prompt,status:`done`,createdAt:n});let r=l(),a=u(),o=!!r,s=!!a,c=yt(e),d=c.length>0,f=o||s||d,p=y(e.status,f);return t.push({id:`${e.id}-a`,role:`assistant`,content:r,reasoning:s?a:void 0,reasoningStatus:s?o?`done`:p===`streaming`?`streaming`:`done`:void 0,toolCalls:d?c:void 0,status:p,error:p===`error`&&e.error||void 0,createdAt:n}),t}),x=Y(null);P(()=>i.job.status,(e,t)=>{e===`running`&&t!==`running`&&(x.value=x.value??Date.now())});let S=q(()=>{if(!x.value)return``;let e=x.value,t=i.job.endedAt?new Date(i.job.endedAt).getTime():Date.now(),n=Math.max(0,Math.floor((t-e)/1e3));return n<60?`${n}s`:`${Math.floor(n/60)}分${(n%60).toString().padStart(2,`0`)}秒`}),C=Y(!1),w=q(()=>!!(i.job.output&&i.job.output.length)),T=q(()=>i.job.output||``),E=Y(null);P(C,async e=>{e&&(await ne(),E.value&&(E.value.scrollTop=E.value.scrollHeight))}),P(()=>(i.job.output||``).length,async()=>{C.value&&(await ne(),E.value&&(E.value.scrollTop=E.value.scrollHeight))});function D(){}let ee=q(()=>p.value&&!!i.job.prompt);function te(){a(`re-execute`,i.job)}let re={configStore:r,props:i,emit:a,isCollapsed:o,toggleOpen:s,isActive:c,MAX_LOG_DISPLAY:bt,displayOutput:l,displayThinking:u,copyToClipboard:d,copyAll:f,isFinished:p,finishedStatusClass:m,finishedStatusIcon:h,finishedStatusLabel:g,assistantLabel:_,assistantAvatar:v,mapStatus:y,chatMessages:b,startedAt:x,elapsedLabel:S,fullscreenOpen:C,hasOutput:w,fullscreenSource:T,fullscreenContainerRef:E,onFullscreenClosed:D,canReExecute:ee,onReExecute:te,get ChatContainer(){return De},get MarkdownRenderer(){return ke},get $t(){return Z}};return Object.defineProperty(re,"__isScriptSetup",{enumerable:!1,value:!0}),re}});b(),X(),G();var St=[`aria-expanded`],Ct={class:`wb-log-summary__left`},wt={key:0,class:`wb-log-summary__status wb-log-summary__status--running`},Tt={class:`wb-log-summary__label`},Et={key:0,class:`wb-log-summary__elapsed`},Dt={key:1,class:`wb-log-summary__status wb-log-summary__status--pending`},Ot={class:`wb-log-summary__label`},kt={class:`wb-log-summary__icon`},At={class:`wb-log-summary__label`},jt={key:0,class:`wb-log-summary__elapsed`},Mt={key:3},Nt={class:`wb-log-summary__right`},Pt={class:`wb-log-summary__meta`},Ft=[`title`,`aria-label`],It={class:`wb-log-details__body`},Lt={key:0,class:`wb-chat__foot`},Rt=[`title`,`aria-label`],zt={ref:`fullscreenContainerRef`,class:`wb-log-fullscreen`},Bt={key:1,class:`wb-log-fullscreen__empty`};function Vt(t,n,o,s,c,l){let u=i;return A(),v(`div`,{class:U([`wb-log-details`,{"is-running":s.isActive,"is-pending":o.job.status===`pending`,"is-finished":s.isFinished}])},[D(`div`,{class:`wb-log-summary`,onClick:s.toggleOpen,role:`button`,"aria-expanded":!s.isCollapsed},[D(`span`,Ct,[o.job.status===`running`?(A(),v(`span`,wt,[D(`span`,Tt,e(s.$t(`@WORKBENCH:正在执行…`)),1),n[1]||=D(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[D(`span`,{class:`wb-log-dots__dot`}),D(`span`,{class:`wb-log-dots__dot`}),D(`span`,{class:`wb-log-dots__dot`})],-1),s.elapsedLabel?(A(),v(`span`,Et,e(s.elapsedLabel),1)):r(`v-if`,!0)])):o.job.status===`pending`?(A(),v(`span`,Dt,[D(`span`,Ot,e(s.$t(`@WORKBENCH:排队中…`)),1),n[2]||=D(`span`,{class:`wb-log-dots`,"aria-hidden":`true`},[D(`span`,{class:`wb-log-dots__dot`}),D(`span`,{class:`wb-log-dots__dot`}),D(`span`,{class:`wb-log-dots__dot`})],-1)])):s.isFinished?(A(),v(`span`,{key:2,class:U([`wb-log-summary__status`,s.finishedStatusClass])},[D(`span`,kt,e(s.finishedStatusIcon),1),D(`span`,At,e(s.finishedStatusLabel),1),s.elapsedLabel?(A(),v(`span`,jt,e(s.elapsedLabel),1)):r(`v-if`,!0)],2)):(A(),v(`span`,Mt,e(s.$t(`@WORKBENCH:查看执行日志`)),1))]),D(`span`,Nt,[D(`span`,Pt,e((o.job.output||``).length)+` `+e(s.$t(`@WORKBENCH:字符`)),1),D(`button`,{type:`button`,class:`wb-log-copy`,title:s.$t(`@WORKBENCH:复制全部(含提示词与输出)`),"aria-label":s.$t(`@WORKBENCH:复制全部`),onClick:J(s.copyAll,[`stop`])},` ⧉ `,8,Ft)])],8,St),r(`
11
+ body 容器:用 zen-ai-chat-ui 的 ChatContainer 渲染单轮对话。
12
+ 隐藏 ChatContainer 自带的输入框(acu-chat-footer),续聊输入由父组件统一承载。
13
+ 下方保留"重新执行"footer。
14
+ `),L(D(`div`,It,[_(s.ChatContainer,{messages:s.chatMessages,"assistant-name":s.assistantLabel,"assistant-avatar":s.assistantAvatar,"show-avatar":!0,theme:s.configStore.theme,"tool-calls-config":{group:!0,collapseThreshold:2},class:`wb-job-chat`},null,8,[`messages`,`assistant-name`,`assistant-avatar`,`theme`]),r(` footer:任务结束后显示"重新执行",运行中不显示 `),s.canReExecute?(A(),v(`footer`,Lt,[D(`button`,{type:`button`,class:`wb-chat__action`,title:s.$t(`@WORKBENCH:用相同的提示词重新执行此任务`),"aria-label":s.$t(`@WORKBENCH:重新执行`),onClick:s.onReExecute},` ↻ `,8,Rt)])):r(`v-if`,!0),r(` 全屏查看 dialog `),_(u,{modelValue:s.fullscreenOpen,"onUpdate:modelValue":n[0]||=e=>s.fullscreenOpen=e,title:s.$t(`@WORKBENCH:模型返回 - 全屏查看`),fullscreen:``,"close-on-click-modal":!1,class:`wb-log-fullscreen-dialog`,onClosed:s.onFullscreenClosed},{default:W(()=>[D(`div`,zt,[s.hasOutput?(A(),a(s.MarkdownRenderer,{key:0,source:s.fullscreenSource,class:`wb-log-fullscreen__render`},null,8,[`source`])):(A(),v(`div`,Bt,e(s.$t(`@WORKBENCH:(暂无输出)`)),1))],512)]),_:1},8,[`modelValue`,`title`])],512),[[oe,!s.isCollapsed]]),r(` /.wb-log-details__body `)],2)}var Ht=Q(xt,[[`render`,Vt],[`__scopeId`,`data-v-a4bb55c4`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/JobLogDetails.vue`]]);X(),R();var Ut=50,Wt=s({__name:`ExecutionLogManager`,setup(e,{expose:t}){t();function n(e){return e instanceof Error?e.message:String(e)}let r=Y([]),i=Y(0),a=se({count:0,sizeMB:0,byStatus:{}}),o=Y(!1),s=Y(new Set),c=se({q:``,status:``,page:1}),l=Y({maxCount:500,maxSizeMB:256}),d=se({maxCount:500,maxSizeMB:256}),f=Y(!1),p=[{value:`pending`,label:Z(`@WORKBENCH:排队中`)},{value:`running`,label:Z(`@WORKBENCH:执行中`)},{value:`done`,label:Z(`@WORKBENCH:已完成`)},{value:`error`,label:Z(`@WORKBENCH:出错`)},{value:`cancelled`,label:Z(`@WORKBENCH:已取消`)}],m=q(()=>r.value.length>0&&r.value.every(e=>s.value.has(e.id))),h=q(()=>r.value.some(e=>s.value.has(e.id))&&!m.value);async function g(){o.value=!0;try{let e=new URLSearchParams;c.q&&e.set(`q`,c.q),c.status&&e.set(`status`,c.status),e.set(`limit`,String(Ut)),e.set(`offset`,String((c.page-1)*Ut));let t=await fetch(`/api/workbench/jobs/list?${e.toString()}`).then(e=>e.json());if(!t.success)throw Error(t.error||`list failed`);r.value=t.jobs,i.value=t.total,a.count=t.stats.count,a.sizeMB=t.stats.sizeMB,a.byStatus=t.stats.byStatus;let n=new Set(r.value.map(e=>e.id));for(let e of Array.from(s.value))n.has(e)||s.value.delete(e)}catch(e){B.error(Z(`@WORKBENCH:加载失败`)+`: `+n(e))}finally{o.value=!1}}async function _(){try{let e=await fetch(`/api/workbench/jobs/config`).then(e=>e.json());e.success&&(l.value=e.config,d.maxCount=e.config.maxCount,d.maxSizeMB=e.config.maxSizeMB)}catch{}}async function v(){f.value=!0;try{let e=await fetch(`/api/workbench/jobs/config`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({maxCount:d.maxCount,maxSizeMB:d.maxSizeMB})}).then(e=>e.json());if(!e.success)throw Error(e.error||`save failed`);l.value=e.config,B.success(Z(`@WORKBENCH:已保存策略`)),await g()}catch(e){B.error(Z(`@WORKBENCH:保存失败`)+`: `+n(e))}finally{f.value=!1}}function y(){c.page=1,g()}function b(){c.q=``,c.status=``,c.page=1,g()}function x(e,t){t?s.value.add(e):s.value.delete(e),s.value=new Set(s.value)}function S(e){if(e)for(let e of r.value)s.value.add(e.id);else for(let e of r.value)s.value.delete(e.id);s.value=new Set(s.value)}function C(e){B.info(Z(`@WORKBENCH:请到工作台主面板的对应任务上点击「重新执行」`))}async function w(e){try{await _e.confirm(Z(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:1}),Z(`@WORKBENCH:删除`),{type:`warning`})}catch{return}try{let t=await fetch(`/api/workbench/jobs/${e}`,{method:`DELETE`}).then(e=>e.json());if(!t.success)throw Error(t.error||`delete failed`);s.value.delete(e),s.value=new Set(s.value),await g()}catch(e){B.error(Z(`@WORKBENCH:保存失败`)+`: `+n(e))}}async function T(){let e=Array.from(s.value);if(e.length!==0){try{await _e.confirm(Z(`@WORKBENCH:确定要删除所选的 {count} 条日志吗?`,{count:e.length}),Z(`@WORKBENCH:批量删除`),{type:`warning`})}catch{return}try{let t=await fetch(`/api/workbench/jobs/batch-delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({ids:e})}).then(e=>e.json());if(!t.success)throw Error(t.error||`batch delete failed`);B.success(Z(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e.length})),s.value=new Set,await g()}catch(e){B.error(Z(`@WORKBENCH:保存失败`)+`: `+n(e))}}}async function E(){let e=a.count;if(e!==0){try{await _e.confirm(Z(`@WORKBENCH:确定要清空所有 {count} 条执行日志吗?此操作不可恢复。`,{count:e}),Z(`@WORKBENCH:清空全部`),{type:`warning`,confirmButtonText:Z(`@WORKBENCH:清空全部`)})}catch{return}try{let t=await fetch(`/api/workbench/jobs/clear`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({confirm:!0})}).then(e=>e.json());if(!t.success)throw Error(t.error||`clear failed`);B.success(Z(`@WORKBENCH:成功删除 {count} 条`,{count:t.removed||e})),s.value=new Set,await g()}catch(e){B.error(Z(`@WORKBENCH:保存失败`)+`: `+n(e))}}}function D(e,t){if(!e)return``;let n=new Date(e).getTime(),r=t?new Date(t).getTime():Date.now(),i=Math.max(0,r-n);return i<1e3?`${i}ms`:i<6e4?`${(i/1e3).toFixed(1)}s`:i<36e5?`${Math.floor(i/6e4)}m ${Math.floor(i%6e4/1e3)}s`:`${Math.floor(i/36e5)}h ${Math.floor(i%36e5/6e4)}m`}u(()=>{g(),_()});let ee={errMsg:n,list:r,total:i,stats:a,loading:o,selectedIds:s,pageSize:Ut,filter:c,config:l,configDraft:d,configSaving:f,STATUS_OPTIONS:p,isAllOnPageSelected:m,isSomeOnPageSelected:h,load:g,loadConfig:_,saveConfig:v,onFilterChange:y,resetFilter:b,toggleSelect:x,toggleSelectAllOnPage:S,onReExecuteInLog:C,deleteOne:w,batchDelete:T,clearAll:E,formatDuration:D,get Document(){return de},get Refresh(){return O},get $t(){return Z},get statusLabel(){return mt},get statusColor(){return ht},JobLogDetails:Ht};return Object.defineProperty(ee,"__isScriptSetup",{enumerable:!1,value:!0}),ee}});X(),b(),G();var Gt={class:`exec-logs`},Kt={class:`exec-logs__head`},qt={class:`exec-logs__title-block`},Jt={class:`exec-logs__stats`},Yt={class:`exec-logs__head-actions`},Xt={class:`exec-logs__config`},Zt={class:`exec-logs__config-label`},Qt={class:`exec-logs__config-field`},$t={class:`exec-logs__config-name`},en={class:`exec-logs__config-field`},tn={class:`exec-logs__config-name`},nn={class:`exec-logs__filter`},rn={key:0,class:`exec-logs__batch-meta`},an={key:0,class:`exec-logs__batch`},on={class:`exec-logs__list`},sn={key:0,class:`exec-logs__empty`},cn={class:`exec-logs__empty-art`,"aria-hidden":`true`},ln={class:`exec-logs__empty-title`},un={class:`exec-logs__empty-hint`},dn={class:`exec-card__head`},fn=[`title`],pn={class:`exec-card__meta`},mn={key:0,class:`exec-card__task`},hn={key:1,class:`exec-card__time`},gn={key:2,class:`exec-card__exit`},_n=[`title`,`onClick`],vn={key:0,class:`exec-card__error`},yn={key:1,class:`exec-logs__pager`};function bn(t,n,i,a,s,c){let l=p,u=Te,f=re,m=y,b=o,x=h,C=d,w=xe,T=N;return A(),v(`div`,Gt,[r(` 头部:统计 + 刷新 + 清空。
15
+ 标题已由外层 el-dialog 提供,这里不再重复 h2。 `),D(`header`,Kt,[D(`div`,qt,[D(`span`,Jt,e(a.$t(`@WORKBENCH:共 {count} 条,占 {size} MB`,{count:a.stats.count,size:a.stats.sizeMB})),1)]),D(`div`,Yt,[_(l,{icon:a.Refresh,size:`small`,loading:a.loading,onClick:a.load},{default:W(()=>[g(e(a.$t(`@WORKBENCH:刷新`)),1)]),_:1},8,[`icon`,`loading`]),_(l,{type:`danger`,plain:``,size:`small`,disabled:a.stats.count===0,onClick:a.clearAll},{default:W(()=>[g(e(a.$t(`@WORKBENCH:清空全部`)),1)]),_:1},8,[`disabled`])])]),r(` 保留策略 `),D(`div`,Xt,[D(`span`,Zt,e(a.$t(`@WORKBENCH:保存策略`)),1),D(`span`,Qt,[D(`span`,$t,e(a.$t(`@WORKBENCH:最大条数`)),1),_(u,{modelValue:a.configDraft.maxCount,"onUpdate:modelValue":n[0]||=e=>a.configDraft.maxCount=e,min:0,max:1e4,step:50,size:`small`,"controls-position":`right`,style:{width:`130px`}},null,8,[`modelValue`])]),D(`span`,en,[D(`span`,tn,e(a.$t(`@WORKBENCH:最大体积 (MB)`)),1),_(u,{modelValue:a.configDraft.maxSizeMB,"onUpdate:modelValue":n[1]||=e=>a.configDraft.maxSizeMB=e,min:0,max:10240,step:32,size:`small`,"controls-position":`right`,style:{width:`140px`}},null,8,[`modelValue`])]),_(l,{type:`primary`,size:`small`,loading:a.configSaving,onClick:a.saveConfig},{default:W(()=>[g(e(a.$t(`@WORKBENCH:保存策略`)),1)]),_:1},8,[`loading`])]),r(` 过滤栏 `),D(`div`,nn,[_(f,{modelValue:a.filter.q,"onUpdate:modelValue":n[2]||=e=>a.filter.q=e,placeholder:a.$t(`@WORKBENCH:搜索标题 / 任务`),clearable:``,size:`small`,style:{width:`240px`},onKeyup:K(a.onFilterChange,[`enter`]),onClear:a.onFilterChange},null,8,[`modelValue`,`placeholder`]),_(b,{modelValue:a.filter.status,"onUpdate:modelValue":n[3]||=e=>a.filter.status=e,placeholder:a.$t(`@WORKBENCH:全部状态`),clearable:``,size:`small`,style:{width:`130px`},onChange:a.onFilterChange},{default:W(()=>[(A(),v(I,null,S(a.STATUS_OPTIONS,e=>_(m,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`,`placeholder`]),_(l,{size:`small`,onClick:a.resetFilter},{default:W(()=>[g(e(a.$t(`@WORKBENCH:重置`)),1)]),_:1}),n[5]||=D(`span`,{class:`exec-logs__filter-spacer`},null,-1),a.selectedIds.size>0?(A(),v(`span`,rn,e(a.$t(`@WORKBENCH:已选择 {count} 项`,{count:a.selectedIds.size})),1)):r(`v-if`,!0)]),r(` 批量操作条 `),a.selectedIds.size>0?(A(),v(`div`,an,[_(x,{"model-value":a.isAllOnPageSelected,indeterminate:a.isSomeOnPageSelected,onChange:a.toggleSelectAllOnPage},{default:W(()=>[g(e(a.isAllOnPageSelected?a.$t(`@WORKBENCH:取消全选`):a.$t(`@WORKBENCH:全选`)),1)]),_:1},8,[`model-value`,`indeterminate`]),_(l,{type:`danger`,size:`small`,onClick:a.batchDelete},{default:W(()=>[g(e(a.$t(`@WORKBENCH:批量删除`)),1)]),_:1})])):r(`v-if`,!0),r(` 列表 `),L((A(),v(`div`,on,[!a.loading&&a.list.length===0?(A(),v(`div`,sn,[D(`div`,cn,[_(C,null,{default:W(()=>[_(a.Document)]),_:1})]),D(`div`,ln,e(a.$t(`@WORKBENCH:暂无执行日志`)),1),D(`div`,un,e(a.$t(`@WORKBENCH:点击「执行任务」开始一次执行,日志会出现在这里。`)),1)])):r(`v-if`,!0),(A(!0),v(I,null,S(a.list,t=>(A(),v(`article`,{key:t.id,class:U([`exec-card`,{"is-selected":a.selectedIds.has(t.id)}])},[D(`header`,dn,[_(x,{"model-value":a.selectedIds.has(t.id),onChange:e=>a.toggleSelect(t.id,e)},null,8,[`model-value`,`onChange`]),D(`span`,{class:`exec-card__status`,style:j({color:a.statusColor(t.status),borderColor:a.statusColor(t.status)})},e(a.statusLabel(t.status)),5),D(`span`,{class:`exec-card__title`,title:t.title||a.$t(`@WORKBENCH:无标题`)},e(t.title||a.$t(`@WORKBENCH:无标题`)),9,fn),n[6]||=D(`span`,{class:`exec-card__spacer`},null,-1),D(`span`,pn,[t.taskTitle?(A(),v(`span`,mn,`📁 `+e(t.taskTitle),1)):r(`v-if`,!0),t.startedAt?(A(),v(`span`,hn,`⏱ `+e(a.formatDuration(t.startedAt,t.endedAt)),1)):r(`v-if`,!0),t.exitCode===null?r(`v-if`,!0):(A(),v(`span`,gn,`exit `+e(t.exitCode),1))]),D(`button`,{type:`button`,class:`exec-card__del`,title:a.$t(`@WORKBENCH:删除`),onClick:e=>a.deleteOne(t.id)},`×`,8,_n)]),t.error?(A(),v(`p`,vn,`⚠ `+e(t.error),1)):r(`v-if`,!0),_(a.JobLogDetails,{job:t,onReExecute:a.onReExecuteInLog},null,8,[`job`])],2))),128))])),[[T,a.loading]]),r(` 分页 `),a.total>a.pageSize?(A(),v(`footer`,yn,[_(w,{"current-page":a.filter.page,"onUpdate:currentPage":n[4]||=e=>a.filter.page=e,"page-size":a.pageSize,total:a.total,layout:`prev, pager, next, total`,background:``,small:``,onCurrentChange:a.load},null,8,[`current-page`,`total`])])):r(`v-if`,!0)])}var xn=Q(Wt,[[`render`,bn],[`__scopeId`,`data-v-d3ebe953`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/components/ExecutionLogManager.vue`]]);R();var Sn=new Set([`image/png`,`image/jpeg`,`image/jpg`,`image/gif`,`image/webp`,`image/bmp`,`image/svg+xml`,`application/pdf`,`text/plain`,`text/markdown`,`text/x-markdown`,`text/csv`,`application/json`,`text/json`,`text/x-log`]),Cn=`.png,.jpg,.jpeg,.gif,.webp,.bmp,.svg,.pdf,.txt,.md,.csv,.json,.log`,wn=20971520,Tn=3840,En=new Set([`image/png`,`image/jpeg`,`image/jpg`,`image/webp`,`image/bmp`]);function Dn(e){if(e.size<=3670016)return!1;let t=String(e.type||``).toLowerCase();return t?En.has(t):/\.(png|jpe?g|webp|bmp)$/i.test(e.name)}function On(e,t){return`${String(e||`attachment`).replace(/\.[^./\\]+$/,``)}.${t}`}async function kn(e){if(typeof createImageBitmap==`function`)try{let t=await createImageBitmap(e);return{source:t,width:t.width,height:t.height,release:()=>t.close()}}catch{}return await new Promise(t=>{let n=URL.createObjectURL(e),r=new Image;r.onload=()=>t({source:r,width:r.naturalWidth,height:r.naturalHeight,release:()=>URL.revokeObjectURL(n)}),r.onerror=()=>{URL.revokeObjectURL(n),t(null)},r.src=n})}function An(e,t,n){return new Promise(r=>{try{e.toBlob(e=>r(e&&e.type===t?e:null),t,n)}catch{r(null)}})}async function jn(e){let t=await kn(e);if(!t)return null;try{let n=[{edge:Tn,quality:.95},{edge:Tn,quality:.85},{edge:2560,quality:.85},{edge:1920,quality:.8}],r=null;for(let e of n){let n=Math.min(1,e.edge/Math.max(t.width,t.height)),i=Math.max(1,Math.round(t.width*n)),a=Math.max(1,Math.round(t.height*n)),o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);if(!s)return null;s.drawImage(t.source,0,0,i,a);let c=await An(o,`image/webp`,e.quality)||await An(o,`image/jpeg`,e.quality);if(!c)return null;if((!r||c.size<r.size)&&(r=c),c.size<=3670016)break}return!r||r.size>=e.size?null:{blob:r,ext:r.type===`image/webp`?`webp`:`jpg`}}catch{return null}finally{t.release()}}function Mn(){let e=Y({}),t=Y(null);function n(t){return!!e.value[t]}function r(e,t){if(e instanceof File)return e;let n=e.type||`application/octet-stream`;return new File([e],t,{type:n})}function i(e){return e.kind===`draft`?`draft`:`task-${e.task?.id??``}`}function a(e){if(e.kind===`draft`)return e.list;let t=e.task?.attachments;return Array.isArray(t)?t:[]}function o(e,t){if(e.kind===`draft`){e.replace(t);return}e.task&&(e.task.attachments=t)}function s(e){return e.kind===`draft`?`/api/workbench/orchestrator/attachments`:`/api/workbench/tasks/${e.task?.id??``}/attachments`}function c(e,t){return e.kind===`draft`?`/api/workbench/orchestrator/attachments/${t}`:`/api/workbench/tasks/${e.task?.id??``}/attachments/${t}`}function l(e,t){if(!e.clipboardData)return;let n=Array.from(e.clipboardData.items).filter(e=>e.kind===`file`&&e.type.startsWith(`image/`));if(n.length>0){e.preventDefault();for(let e of n){let n=e.getAsFile();if(!n)continue;let i=(n.type.split(`/`)[1]||`png`).replace(`jpeg`,`jpg`);d(t,r(n,`paste-${new Date().toISOString().replace(/[:.]/g,`-`)}.${i}`))}return}let i=Array.from(e.clipboardData.items).filter(e=>e.kind===`file`&&!e.type.startsWith(`image/`));if(i.length>0){e.preventDefault();for(let e of i){let n=e.getAsFile();n&&d(t,r(n,n.name||`pasted-file`))}}}function u(e,n){t.value=null,Array.from(e.dataTransfer?.files||[]).forEach(e=>d(n,e))}async function d(t,n){if(!Sn.has(n.type)&&!n.name.match(/\.(png|jpg|jpeg|gif|webp|bmp|svg|pdf|txt|md|markdown|csv|json|log)$/i)){B.error(`${Z(`@WORKBENCH:不支持的文件类型`)}(${n.name})`);return}let c=a(t);if(c.length>=9){B.error(Z(`@WORKBENCH:单个任务最多 9 个附件`));return}if(c.find(e=>e.originalName===n.name&&e.size===n.size)){B.info(`${n.name} ${Z(`@WORKBENCH:已存在,已复用`)}`);return}let l=i(t);e.value[l]=!0;try{let e=n;if(Dn(n)){let t=await jn(n);t&&(e=r(t.blob,On(n.name,t.ext)),B.info(Z(`@WORKBENCH:图片过大,已压缩后上传:{from} → {to}`,{from:g(n.size),to:g(e.size)})))}if(e.size>20971520){B.error(`「${n.name}」${Z(`@WORKBENCH:超过 {size} 限制`,{size:g(wn)})}`);return}let i=await fetch(s(t),{method:`POST`,headers:{"Content-Type":`application/octet-stream`,"X-Original-Name":e.name,"X-Mime-Type":e.type||`application/octet-stream`},body:e}).then(e=>e.json());if(i.success){let n=a(t);n.push(i.attachment),o(t,n),B.success(`${Z(`@WORKBENCH:已添加:`)}${e.name}`)}else B.error(i.error||Z(`@WORKBENCH:上传失败`))}catch(e){B.error(Z(`@WORKBENCH:上传失败`)+`:`+(e&&e.message||e))}finally{e.value[l]=!1}}async function f(e,t){try{await _e.confirm(Z(`@WORKBENCH:删除附件「{name}」?`,{name:t.originalName}),Z(`@WORKBENCH:确认`),{type:`warning`})}catch{return}let n=await fetch(c(e,t.id),{method:`DELETE`}).then(e=>e.json());n.success?(o(e,a(e).filter(e=>e.id!==t.id)),B.success(Z(`@WORKBENCH:已删除`))):B.error(n.error||Z(`@WORKBENCH:删除失败`))}function p(e){let t=document.createElement(`input`);t.type=`file`,t.accept=Cn,t.multiple=!0,t.onchange=()=>{Array.from(t.files||[]).forEach(t=>d(e,t))},t.click()}let m=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`bmp`,`svg`]);function h(e){let t=String(e?.ext||``).toLowerCase();if(t&&m.has(t)||String(e?.mimeType||``).toLowerCase().startsWith(`image/`))return!0;let n=String(e?.originalName||``).toLowerCase();return/\.(png|jpe?g|gif|webp|bmp|svg)$/.test(n)}function g(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(2)} MB`}return{uploadingTargets:e,pasteHoverId:t,isUploading:n,ensureFile:r,isImageAttachment:h,humanSize:g,targetKey:i,targetAttachments:a,setTargetAttachments:o,targetUploadUrl:s,targetDeleteUrl:c,onAttachmentPaste:l,onAttachmentDrop:u,uploadAttachment:d,removeAttachment:f,pickAttachmentFile:p}}X();var Nn=`__simple`,Pn=65536;function Fn(e,t){function n(t){if(!t)return[];let n=`${t.id}${Nn}`;return e.value.filter(e=>e.subId===n||e.subId.startsWith(`${n}__r`)).sort((e,t)=>{let n=e.startedAt||``,r=t.startedAt||``;return n&&r?n.localeCompare(r):n?-1:+!!r})}function r(e){if(!e)return null;let t=n(e);return t.length>0?t[t.length-1]:null}function i(e){return e?e.status===`pending`||e.status===`running`?`running`:e.status===`done`?`done`:e.status===`cancelled`?`cancelled`:`error`:`idle`}return{simpleConversationMessages:q(()=>{if(!t.value)return[];let e=n(t.value);if(e.length===0)return[];let r=[];return e.forEach((t,n)=>{let i=n===e.length-1,a=t.startedAt?new Date(t.startedAt).getTime():Date.now();t.prompt&&r.push({id:`${t.id}-u`,role:`user`,content:t.prompt,status:`done`,createdAt:a});let o=t.output||``,s=t.thinking||``,c=o.length>Pn?`\u2026(前文已截断)\n${o.slice(-65536)}`:o,l=s.length>Pn?`\u2026(前文已截断)\n${s.slice(-65536)}`:s,u=!!c,d=!!l,f=yt(t),p=f.length>0,m=u||d||p,h;if(!i)h=`done`;else{let e=t.status;h=e===`running`||e===`pending`?m?`streaming`:`pending`:e===`error`?`error`:`done`}r.push({id:`${t.id}-a`,role:`assistant`,content:c,reasoning:d?l:void 0,reasoningStatus:d?!i&&u||u?`done`:h===`streaming`?`streaming`:`done`:void 0,toolCalls:p?f:void 0,status:h,error:h===`error`&&t.error||void 0,createdAt:a})}),r}),simpleAllJobsFor:n,simpleJobFor:r,simpleJobState:i,SIMPLE_SUB_ID_SUFFIX:Nn,MAX_LOG_DISPLAY_SIMPLE:Pn}}function In(e,t,n,r){function i(){return{executor:r.getExecutor()}}async function a(e){if(!n.value||n.value.id!==e.id)return!0;let i=t.value.find(t=>t.id===e.id);return i&&i.title===n.value.title&&i.desc===n.value.desc&&i.promptId===n.value.promptId&&(i.simpleOverride||``)===(n.value.simpleOverride||``)?!0:await r.persistTask(!1)}async function o(e){if(!await a(e))return;await r.clearJobsByTask(e.id);let t=await fetch(`/api/workbench/tasks/${encodeURIComponent(e.id)}/run`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i())}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));t.success?B.success(t.message||Z(`@WORKBENCH:已加入执行队列`)):B.error(t.error||Z(`@WORKBENCH:执行失败`))}async function s(t,n){let r=e.value.filter(e=>e.taskId===t.id).slice(-1)[0];if(!r){B.error(Z(`@WORKBENCH:没有可续接的会话`));return}let i=Array.isArray(t.attachments)?t.attachments:[],a=await fetch(`/api/workbench/jobs/${r.id}/continue`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({userMessage:n,attachments:i})}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));a.success?B.success(a.message||Z(`@WORKBENCH:已加入续接队列`)):B.error(a.error||Z(`@WORKBENCH:续接失败`))}async function c(e,t){let n=t.text.trim();if(n){for(let n of t.files)await r.uploadAttachment({kind:`task`,task:e},n.file);await s(e,n)}}async function l(e){let n=t.value.find(t=>t.id===e.taskId)||t.value.find(t=>t.id===String(e.subId||``).replace(/__simple(?:__r\d+)?$/,``));if(!n){B.error(Z(`@WORKBENCH:找不到对应任务,无法重新执行`));return}await o(n)}async function u(e){try{await _e.confirm(Z(`@WORKBENCH:确认停止执行?已输出的内容会保留。`),Z(`@WORKBENCH:停止执行`),{confirmButtonText:Z(`@WORKBENCH:停止`),cancelButtonText:Z(`@WORKBENCH:取消`),type:`warning`})}catch{return}let t=await fetch(`/api/workbench/jobs/${e.id}/cancel`,{method:`POST`}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));t.success?B.success(Z(`@WORKBENCH:已发送停止信号`)):B.error(t.error||Z(`@WORKBENCH:停止失败`))}async function d(){if(!n.value)return;let t=n.value,i=e.value.filter(e=>e.taskId===t.id),a=i.filter(e=>e.status===`running`||e.status===`pending`).length,o=i.length===0?Z(`@WORKBENCH:当前任务还没有执行内容,确认仍要清空?`):Z(`@WORKBENCH:将清空 {m} 条执行记录,任务描述/附件保留。`,{m:i.length});try{await _e.confirm(o,Z(`@WORKBENCH:清空执行内容`),{confirmButtonText:Z(`@WORKBENCH:清空`),cancelButtonText:Z(`@WORKBENCH:取消`),type:`warning`})}catch{return}if(a>0){B.warning(Z(`@WORKBENCH:任务正在执行,请先停止`));return}let s=await fetch(`/api/workbench/tasks/${encodeURIComponent(t.id)}/clear-execution`,{method:`POST`,headers:{"Content-Type":`application/json`}}).then(e=>e.json()).catch(e=>({success:!1,error:e?.message||String(e)}));s?.success?(e.value=e.value.filter(e=>e.taskId!==t.id),r.syncRunningCount(),B.success(s.message||Z(`@WORKBENCH:已清空执行内容`))):B.error(s?.error||Z(`@WORKBENCH:清空失败`))}return{runTask:o,continueChat:s,onContinueSendFromChat:c,onReExecuteJob:l,cancelJob:u,clearExecutionForSelectedTask:d}}R();function Ln(){let e=Y([]),t=Y([]),n=Y([]),r=Y({path:``,name:``}),i=He();function a(){i.setRunning(n.value.filter(e=>e.status===`running`).length)}function o(e,r){if(e===`hello`){n.value=r.jobs||[],a();return}if(e===`job:update`){let e=r,t=n.value.findIndex(t=>t.id===e.id);t>=0?n.value[t]=e:n.value.push(e),a();return}if(e===`job:thinking-delta`||e===`job:output-delta`){let t=e===`job:thinking-delta`?`thinking`:`output`,i=r?.delta||``;if(!i)return;let a=n.value.findIndex(e=>e.id===r.id);if(a<0)return;let o=n.value[a][t]||``;n.value[a][t]=o+i;return}if(e===`job:toolcalls`){let e=Array.isArray(r?.updates)?r.updates:[];if(!e.length)return;let t=n.value.findIndex(e=>e.id===r.id);if(t<0)return;let i=n.value[t];for(let t of e){if(!t||!t.id)continue;Array.isArray(i.toolCalls)||(i.toolCalls=[]);let e=i.toolCalls.findIndex(e=>e.id===t.id);e>=0?i.toolCalls[e]={...i.toolCalls[e],...t}:i.toolCalls.push(t)}return}if(e===`task:update`){let e=t.value.findIndex(e=>e.id===r.id);e>=0&&(t.value[e]=r)}if(e===`tasks:reordered`){if(Array.isArray(r?.tasks)){if(r.tasks.length<t.value.length){console.warn(`[SSE tasks:reordered] 数据丢失风险:当前 ${t.value.length} 个任务,服务端只返回 ${r.tasks.length} 个,拒绝覆盖`);return}t.value=r.tasks}return}e===`task:error`&&B.error(r.error||Z(`@WORKBENCH:执行出错`))}let s=null;function c(){s&&=(s.close(),null),s=new EventSource(`/api/workbench/events`),s.onmessage=e=>{try{let t=JSON.parse(e.data);o(t.event,t.payload)}catch{}},s.onerror=()=>{s&&=(s.close(),null),setTimeout(c,3e3)}}function l(){s&&=(s.close(),null)}async function u(){let t=await fetch(`/api/workbench/prompts`).then(e=>e.json()).catch(()=>({prompts:[]}));e.value=t.prompts||[]}async function d(e){let n=await fetch(`/api/workbench/tasks`).then(e=>e.json()).catch(()=>({tasks:[]}));t.value=n.tasks||[],e?.()}async function f(){let e=await fetch(`/api/workbench/current-project`).then(e=>e.json()).catch(()=>({}));e&&typeof e.projectPath==`string`&&(r.value={path:e.projectPath,name:e.projectName||``})}async function p(){let e=await fetch(`/api/workbench/jobs`).then(e=>e.json()).catch(()=>({jobs:[]}));n.value=e.jobs||[],a()}async function m(e){try{let t=await fetch(`/api/workbench/jobs/by-task/${encodeURIComponent(e)}`,{method:`DELETE`}).then(e=>e.json());return t?.success?(n.value=n.value.filter(t=>t.taskId!==e),a(),t.removed||0):(console.warn(`[clearJobsByTask] failed:`,t?.error),0)}catch(e){return console.warn(`[clearJobsByTask] error:`,e),0}}async function h(e){let t={title:``,desc:``,promptId:null,simpleOverride:``};e&&(t.projectPath=e);try{let e=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}).then(e=>e.json());return e.success?e.task||null:(B.error(e.error||Z(`@WORKBENCH:保存失败`)),null)}catch{return B.error(Z(`@WORKBENCH:保存失败`)),null}}return{prompts:e,tasks:t,jobs:n,currentProject:r,syncRunningCount:a,applyJobEvent:o,connectSSE:c,disconnectSSE:l,loadPrompts:u,loadTasks:d,loadCurrentProject:f,loadJobs:p,clearJobsByTask:m,createTask:h}}R(),X();var Rn=`__no_project__`,zn=`wb.collapsedGroupPaths.v1`,Bn=`wb.seenGroupPaths.v1`;function Vn(e){try{let t=localStorage.getItem(e);if(!t)return new Set;let n=JSON.parse(t);return new Set(Array.isArray(n)?n.filter(e=>typeof e==`string`):[])}catch{return new Set}}function Hn(e,t){try{localStorage.setItem(e,JSON.stringify(Array.from(t)))}catch{}}function Un(e,t){let n=Y(Vn(zn)),r=Y(Vn(Bn));P(n,e=>Hn(zn,e),{deep:!1}),P(r,e=>Hn(Bn,e),{deep:!1});function i(e){return n.value.has(e)}function a(e){n.value.has(e)?n.value.delete(e):n.value.add(e),n.value=new Set(n.value);let t=new Set(r.value);t.add(e),r.value=t}let o=q(()=>{let r=e.value,i=new Map;for(let e of r){let t=$(e.projectPath)||Rn;i.has(t)||i.set(t,[]),i.get(t).push(e)}let a=$(t.value.path),o=Array.from(i.keys()).sort((e,t)=>e===a?-1:t===a||e===Rn?1:t===Rn?-1:e.localeCompare(t));return{groups:o.map(e=>({path:e,label:e===Rn?Z(`@WORKBENCH:未关联项目`):e,tasks:i.get(e)})),hasMultiple:o.length>1||o.length===1&&n.value.has(o[0])}});function s(e){if(!e||e===Rn)return e;let t=e.split(/[\\/]/).filter(Boolean);return t.length<=1?e:t.slice(-2).join(`/`)}let c=q(()=>`${$(t.value.path)}|${o.value.groups.map(e=>e.path).join(`
16
+ `)}`);return P(c,()=>{let e=$(t.value.path);if(!e)return;let i=new Set(n.value),a=new Set(r.value),s=!1;for(let t of o.value.groups)a.has(t.path)||(a.add(t.path),t.path!==e&&(i.add(t.path),s=!0));s&&(n.value=i),r.value=a},{immediate:!0}),{groupedTasksList:o,isGroupCollapsed:i,toggleGroupCollapsed:a,shortProjectLabel:s}}X(),R();var Wn=5,Gn=s({__name:`WorkbenchSidebar`,props:{tasks:{type:Array,required:!0},prompts:{type:Array,required:!0},selectedTaskId:{type:[String,null],required:!0},currentProject:{type:Object,required:!0},creatingTask:{type:Boolean,required:!0},isTaskRunning:{type:Function,required:!0}},emits:[`select-task`,`delete-task`,`copy-task`,`create-task`,`open-create-prompt`,`open-edit-prompt`,`delete-prompt`,`reorder-tasks`],setup(e,{expose:t,emit:n}){t();let r=e,i=n,a=q(()=>r.currentProject),o=q(()=>r.tasks),{groupedTasksList:s,isGroupCollapsed:c,toggleGroupCollapsed:l,shortProjectLabel:u}=Un(o,a),d=q(()=>$(r.currentProject.path));function f(e){return!!e.projectPath&&$(e.projectPath)!==d.value}let p=q(()=>{let e=d.value;return r.prompts.filter(t=>!t.projectPath||$(t.projectPath)===e)});function m(e){return(e.title||``).trim()||(e.desc||``).replace(/\s+/g,` `).trim()}function h(e){let t=m(e),n=Z(`@WORKBENCH:拖动排序提示`);return t?`${t} · ${n}`:n}function g(e){return r.isTaskRunning(e)}let _=Y(null),v=Y(null),y=Y(null),b=Y(null),x=Y(null),S=null;function w(){_.value=null,v.value=null,y.value=null,b.value=null,x.value=null,S=null}function T(e,t,n,r){e.button===0&&(S={pointerY:e.clientY,li:r,taskId:t.id,groupPath:n},window.addEventListener(`mousemove`,E),window.addEventListener(`mouseup`,D,{once:!0}))}function E(e){if(!S)return;if(_.value===null){if(Math.abs(e.clientY-S.pointerY)<Wn)return;_.value=S.taskId,v.value=S.groupPath,window.getSelection()?.removeAllRanges(),document.body.style.userSelect=`none`}let t=document.elementFromPoint(e.clientX,e.clientY);if(!t)return;let n=t.closest(`.wb-task-item`);if(!n){y.value=null,b.value=null,x.value=null;return}let r=n.getAttribute(`data-task-id`),i=n.getAttribute(`data-group-path`);if(!r||!i)return;if(i!==v.value){y.value=null,b.value=null,x.value=null;return}let a=n.getBoundingClientRect(),o=a.top+a.height/2;y.value=r,b.value=i,x.value=e.clientY<o?`before`:`after`}function D(e){if(window.removeEventListener(`mousemove`,E),document.body.style.userSelect=``,!S){w();return}let t=S.groupPath,n=S.taskId,r=y.value,a=x.value,o=b.value;if(w(),!r||!a||o!==t)return;let c=s.value.groups.find(e=>e.path===t);if(!c)return;let l=c.tasks.map(e=>e.id),u=l.indexOf(n);if(u<0)return;l.splice(u,1);let d=l.indexOf(r)+ +(a===`after`);l.splice(d,0,n),i(`reorder-tasks`,{groupPath:t,orderedIds:l})}let ee={props:r,emit:i,currentProjectRef:a,tasksRef:o,groupedTasksList:s,isGroupCollapsed:c,toggleGroupCollapsed:l,shortProjectLabel:u,currentProjectKey:d,isOtherProject:f,availablePrompts:p,taskDisplayName:m,taskTooltip:h,taskIsRunning:g,draggingTaskId:_,dragStartGroupPath:v,dragOverTaskId:y,dragOverGroupPath:b,dragPosition:x,get dragStart(){return S},set dragStart(e){S=e},DRAG_THRESHOLD_PX:Wn,resetDragState:w,onTaskMouseDown:T,onWindowMouseMove:E,onWindowMouseUp:D,get $t(){return Z},get Plus(){return C},get Close(){return F},get DocumentAdd(){return be},get Memo(){return V},get Folder(){return we},get ArrowDown(){return he},get ArrowRight(){return ae},get CopyDocument(){return ve}};return Object.defineProperty(ee,"__isScriptSetup",{enumerable:!1,value:!0}),ee}});X(),b(),G();var Kn={class:`wb-sidebar`},qn={class:`wb-section`},Jn=[`disabled`],Yn=[`aria-expanded`,`title`,`onClick`,`onKeydown`],Xn=[`title`],Zn={class:`wb-pill wb-task-group__count`},Qn=[`data-task-id`,`data-group-path`,`title`,`onClick`,`onMousedown`],$n={class:`wb-task-item__body`},er=[`title`],tr=[`title`],nr={class:`wb-task-item__action-group`},rr=[`title`,`aria-label`,`onClick`],ir=[`onClick`,`title`,`aria-label`],ar={key:0,class:`wb-empty wb-empty--rich`},or={class:`wb-empty__art`,"aria-hidden":`true`},sr={class:`wb-empty__title`},cr={class:`wb-empty__hint`},lr={class:`wb-empty__cta`},ur={class:`wb-section`},dr={class:`wb-section__head`},fr={class:`wb-section__tag wb-section__tag--accent`},pr={class:`wb-section__title`},mr={class:`wb-pill wb-section__count`},hr=[`title`,`aria-label`],gr={class:`wb-prompt-list`},_r={class:`wb-prompt-item__icon`},vr=[`onClick`,`title`],yr=[`title`],br=[`title`],xr=[`onClick`,`title`,`aria-label`],Sr={key:0,class:`wb-empty wb-empty--compact`};function Cr(t,n,i,o,s,c){let l=d,u=p;return A(),v(`aside`,Kn,[D(`section`,qn,[r(` 任务分组 header 已去掉:"任务"/"任务列表"/计数 三件套冗余,下方任务项本身已能自我说明。
17
+ 提示词分组保留 header(含 + 新建按钮 + 计数),信息密度不一对齐,后续按需统一。 `),D(`button`,{class:`wb-new-btn`,disabled:i.creatingTask,onClick:n[0]||=e=>o.emit(`create-task`)},[_(l,{class:`wb-new-btn__icon`},{default:W(()=>[_(o.Plus)]),_:1}),D(`span`,null,e(o.$t(`@WORKBENCH:新建任务`)),1),n[3]||=D(`span`,{class:`wb-new-btn__shortcut`},`N`,-1)],8,Jn),D(`ul`,{class:U([`wb-task-list`,{"is-grouped":o.groupedTasksList.hasMultiple}])},[(A(!0),v(I,null,S(o.groupedTasksList.groups,t=>(A(),v(I,{key:t.path},[o.groupedTasksList.hasMultiple?(A(),v(`li`,{key:0,class:U([`wb-task-group__head`,{"is-current":t.path===o.currentProjectKey,"is-collapsed":o.isGroupCollapsed(t.path)}]),role:`button`,tabindex:`0`,"aria-expanded":!o.isGroupCollapsed(t.path),title:o.isGroupCollapsed(t.path)?o.$t(`@WORKBENCH:展开`):o.$t(`@WORKBENCH:收起`),onClick:e=>o.toggleGroupCollapsed(t.path),onKeydown:[K(J(e=>o.toggleGroupCollapsed(t.path),[`prevent`]),[`enter`]),K(J(e=>o.toggleGroupCollapsed(t.path),[`prevent`]),[`space`])]},[_(l,{class:`wb-task-group__caret`},{default:W(()=>[(A(),a(ye(o.isGroupCollapsed(t.path)?o.ArrowRight:o.ArrowDown)))]),_:2},1024),_(l,{class:`wb-task-group__icon`},{default:W(()=>[_(o.Folder)]),_:1}),D(`span`,{class:`wb-task-group__name`,title:t.path===o.currentProjectKey?i.currentProject.path:t.label},e(t.path===o.currentProjectKey?i.currentProject.name:o.shortProjectLabel(t.label)),9,Xn),D(`span`,Zn,e(t.tasks.length),1)],42,Yn)):r(`v-if`,!0),o.isGroupCollapsed(t.path)?r(`v-if`,!0):(A(!0),v(I,{key:1},S(t.tasks,n=>(A(),v(`li`,{key:n.id,class:U([`wb-task-item`,{active:n.id===i.selectedTaskId,"is-other-project":o.isOtherProject(n),"is-running":o.taskIsRunning(n),"is-dragging":o.draggingTaskId===n.id,"is-drop-before":o.dragOverTaskId===n.id&&o.dragPosition===`before`,"is-drop-after":o.dragOverTaskId===n.id&&o.dragPosition===`after`}]),"data-task-id":n.id,"data-group-path":t.path,title:o.taskTooltip(n),onClick:e=>o.emit(`select-task`,n),onMousedown:e=>o.onTaskMouseDown(e,n,t.path,e.currentTarget)},[r(` 单行展示:只显示标题;没写标题用任务描述压平后顶上(CSS ellipsis 截断)。
18
+ 子任务数 / 附件数 等 meta 行已移除,降噪 `),D(`div`,$n,[D(`div`,{class:`wb-task-item__title`,title:o.taskDisplayName(n)},e(o.taskDisplayName(n)),9,er)]),o.taskIsRunning(n)?(A(),v(`span`,{key:0,class:`wb-task-item__running-dot`,title:o.$t(`@WORKBENCH:执行中`),"aria-hidden":`true`},null,8,tr)):r(`v-if`,!0),D(`div`,nr,[D(`button`,{class:`wb-task-item__copy`,title:o.$t(`@WORKBENCH:复制任务`),"aria-label":o.$t(`@WORKBENCH:复制任务`),onClick:J(e=>o.emit(`copy-task`,n),[`stop`])},[_(l,null,{default:W(()=>[_(o.CopyDocument)]),_:1})],8,rr),r(` 执行中不允许删除:避免误杀正在跑的实例(jobs 还在内存里,
19
+ 任务从 tasks.json 消失后,runSingleSubtask 读不到 task
20
+ 会留一堆孤儿 job)。后端 DELETE 路由也加了同样的 live-job 守卫兜底 `),o.taskIsRunning(n)?r(`v-if`,!0):(A(),v(`button`,{key:0,class:`wb-task-item__del`,onClick:J(e=>o.emit(`delete-task`,n),[`stop`]),title:o.$t(`@WORKBENCH:删除`),"aria-label":o.$t(`@WORKBENCH:删除`)},[_(l,null,{default:W(()=>[_(o.Close)]),_:1})],8,ir))])],42,Qn))),128))],64))),128)),i.tasks.length===0?(A(),v(`li`,ar,[D(`div`,or,[_(l,null,{default:W(()=>[_(o.DocumentAdd)]),_:1})]),D(`div`,sr,e(o.$t(`@WORKBENCH:暂无任务`)),1),D(`div`,cr,e(o.$t(`@WORKBENCH:点击上方按钮新建`)),1),D(`div`,lr,[_(u,{type:`primary`,size:`small`,icon:o.Plus,loading:i.creatingTask,onClick:n[1]||=e=>o.emit(`create-task`)},{default:W(()=>[g(e(o.$t(`@WORKBENCH:新建任务`)),1)]),_:1},8,[`icon`,`loading`])])])):r(`v-if`,!0)],2)]),D(`section`,ur,[D(`header`,dr,[D(`span`,fr,e(o.$t(`@WORKBENCH:提示`)),1),D(`h3`,pr,e(o.$t(`@WORKBENCH:预置提示词`)),1),D(`span`,mr,e(o.availablePrompts.length),1),D(`button`,{class:`wb-section__action`,onClick:n[2]||=e=>o.emit(`open-create-prompt`),title:o.$t(`@WORKBENCH:新建提示词`),"aria-label":o.$t(`@WORKBENCH:新建提示词`)},[_(l,null,{default:W(()=>[_(o.Plus)]),_:1})],8,hr)]),D(`ul`,gr,[(A(!0),v(I,null,S(o.availablePrompts,t=>(A(),v(`li`,{key:t.id,class:`wb-prompt-item`},[D(`div`,_r,[_(l,null,{default:W(()=>[_(o.Memo)]),_:1})]),D(`span`,{class:`wb-prompt-item__name`,onClick:e=>o.emit(`open-edit-prompt`,t),title:t.content},e(t.name),9,vr),t.projectPath?(A(),v(`span`,{key:1,class:`wb-prompt-item__tag wb-prompt-item__tag--project`,title:t.projectPath},e(o.shortProjectLabel(t.projectPath)),9,br)):(A(),v(`span`,{key:0,class:`wb-prompt-item__tag`,title:o.$t(`@WORKBENCH:全局(所有项目可用)`)},e(o.$t(`@WORKBENCH:全局(所有项目可用)`)),9,yr)),D(`button`,{class:`wb-prompt-item__del`,onClick:e=>o.emit(`delete-prompt`,t),title:o.$t(`@WORKBENCH:删除`),"aria-label":o.$t(`@WORKBENCH:删除`)},[_(l,null,{default:W(()=>[_(o.Close)]),_:1})],8,xr)]))),128)),o.availablePrompts.length===0?(A(),v(`li`,Sr,e(o.$t(`@WORKBENCH:暂无提示词`)),1)):r(`v-if`,!0)])])])}var wr=Q(Gn,[[`render`,Cr],[`__scopeId`,`data-v-458e9455`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchSidebar.vue`]]);R();function Tr(){let e=Y([]),t=Y([]),n=Y(``),r=Y(!1),i=Y(!1);async function a(a=!1){a||(r.value=!0);try{let r=await fetch(`/api/workbench/projects`,{cache:`no-store`}).then(e=>e.json());return r?.success?(e.value=Array.isArray(r.projects)?r.projects:[],t.value=Array.isArray(r.tasks)?r.tasks:[],n.value=r.currentProjectPath||``,i.value=!0,!0):(a||B.error(r?.error||Z(`@WORKBENCH:读取项目列表失败`)),!1)}catch(e){return a||B.error(Z(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}finally{r.value=!1}}return{projects:e,boardTasks:t,currentProjectPath:n,loading:r,loaded:i,loadProjects:a}}R();function Er(){let e=Y(!0),t=Y([]),n=Y([]),r=Y([]),i=Y(null),a=Y(!1),o=Y(!1),s=Y(!1),c=Y(``),l=Y({});async function u(o=!1){try{let s=await fetch(`/api/workbench/orchestrator`,{cache:`no-store`}).then(e=>e.json());return s?.success?(e.value=s.active!==!1,t.value=Array.isArray(s.instructions)?s.instructions:[],n.value=Array.isArray(s.activity)?s.activity:[],r.value=Array.isArray(s.running)?s.running:[],i.value=s.updatedAt||null,c.value=typeof s.defaultPrompt==`string`?s.defaultPrompt:``,l.value=s.projectPrompts&&typeof s.projectPrompts==`object`?s.projectPrompts:{},a.value=!0,!0):(o||B.error(s?.error||Z(`@WORKBENCH:读取编排状态失败`)),!1)}catch(e){return o||B.error(Z(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function d(e){try{let t=await fetch(`/api/workbench/orchestrator/default-prompt`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:e})}).then(e=>e.json());return t?.success?(c.value=typeof t.defaultPrompt==`string`?t.defaultPrompt:``,B.success(Z(`@WORKBENCH:已保存全局默认提示词`)),!0):(B.error(t?.error||Z(`@WORKBENCH:保存失败`)),!1)}catch(e){return B.error(Z(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function f(e,t){try{let n=await fetch(`/api/workbench/orchestrator/project-prompt`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({projectPath:e,prompt:t})}).then(e=>e.json());return n?.success?(l.value=n.projectPrompts&&typeof n.projectPrompts==`object`?n.projectPrompts:{},B.success(Z(`@WORKBENCH:已保存项目默认提示词`)),!0):(B.error(n?.error||Z(`@WORKBENCH:保存失败`)),!1)}catch(e){return B.error(Z(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function p(t){if(o.value)return!1;let n=e.value;e.value=t,o.value=!0;try{let r=await fetch(`/api/workbench/orchestrator/state`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({active:t})}).then(e=>e.json());return r?.success?(e.value=r.active!==!1,B.success(e.value?Z(`@WORKBENCH:已恢复调度`):Z(`@WORKBENCH:已暂停调度,派发将只建任务不执行`)),!0):(e.value=n,B.error(r?.error||Z(`@WORKBENCH:切换调度状态失败`)),!1)}catch(t){return e.value=n,B.error(Z(`@WORKBENCH:网络错误: `)+(t?.message||t)),!1}finally{o.value=!1}}async function m(e){if(s.value)return null;s.value=!0;try{let t=await fetch(`/api/workbench/orchestrator/dispatch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({text:e.text,projectPath:e.projectPath||``,autoRun:e.autoRun!==!1,useDefaultPrompt:e.useDefaultPrompt!==!1,executor:e.executor,attachments:(e.attachments||[]).map(e=>({id:e.id,ext:e.ext,originalName:e.originalName}))})}).then(e=>e.json());return t?.success?(await u(!0),{task:t.task||null,ran:!!t.ran}):(B.error(t?.error||Z(`@WORKBENCH:派发失败`)),null)}catch(e){return B.error(Z(`@WORKBENCH:网络错误: `)+(e?.message||e)),null}finally{s.value=!1}}return{active:e,instructions:t,activity:n,running:r,updatedAt:i,loaded:a,togglingSchedule:o,dispatching:s,defaultPrompt:c,projectPrompts:l,loadOrchestrator:u,setSchedulingActive:p,dispatch:m,saveDefaultPrompt:d,saveProjectPrompt:f}}var Dr=6e4,Or=60*Dr,kr=24*Or;function Ar(e,t=Date.now()){if(!e)return``;let n=new Date(e).getTime();if(Number.isNaN(n))return``;let r=Math.max(0,t-n);return r<Dr?Z(`@WORKBENCH:刚刚`):r<Or?Z(`@WORKBENCH:N 分钟前`,{n:Math.floor(r/Dr)}):r<kr?Z(`@WORKBENCH:N 小时前`,{n:Math.floor(r/Or)}):r<30*kr?Z(`@WORKBENCH:N 天前`,{n:Math.floor(r/kr)}):new Date(n).toLocaleDateString()}function jr(e,t,n=Date.now()){if(!e)return``;let r=new Date(e).getTime();if(Number.isNaN(r))return``;let i=t?new Date(t).getTime():n;if(Number.isNaN(i))return``;let a=Math.max(0,i-r),o=Math.floor(a/1e3),s=Math.floor(o/3600),c=Math.floor(o%3600/60),l=o%60;return s>0?Z(`@WORKBENCH:N 小时 M 分`,{n:s,m:c}):c>0?Z(`@WORKBENCH:N 分 M 秒`,{n:c,m:l}):Z(`@WORKBENCH:N 秒`,{n:l})}function Mr(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function Nr(e,t=Date.now()){if(!e)return``;let n=new Date(e);if(Number.isNaN(n.getTime()))return``;let r=e=>String(e).padStart(2,`0`),i=`${r(n.getHours())}:${r(n.getMinutes())}:${r(n.getSeconds())}`,a=new Date(t);if(Mr(n,a))return i;if(Mr(n,new Date(a.getFullYear(),a.getMonth(),a.getDate()-1)))return Z(`@WORKBENCH:昨天 {time}`,{time:i});let o=`${n.getMonth()+1}/${n.getDate()}`;return n.getFullYear()===a.getFullYear()?`${o} ${i}`:`${n.getFullYear()}/${o} ${i}`}X(),R();var Pr=s({__name:`WorkbenchProjectPanel`,props:{projects:{type:Array,required:!0},selectedKey:{type:String,required:!0},loading:{type:Boolean,required:!0}},emits:[`select`],setup(e,{expose:n,emit:r}){n();let i=e,a=r,o=q(()=>[...i.projects].sort((e,t)=>{if(e.stats.runningJobs>0!=t.stats.runningJobs>0)return e.stats.runningJobs>0?-1:1;let n=e.stats.lastActiveAt||``,r=t.stats.lastActiveAt||``;return n===r?e.name.localeCompare(t.name):r.localeCompare(n)})),s=Y(``),l=Y(!1),d=Y(!1),p=q(()=>!!s.value.trim()||l.value||d.value),m=q(()=>{let e=s.value.trim().toLowerCase();return o.value.filter(t=>l.value&&t.stats.total===0||d.value&&t.git&&t.git.isGitRepo===!1?!1:!e||t.name.toLowerCase().includes(e)||t.path.toLowerCase().includes(e))});function h(){s.value=``,l.value=!1,d.value=!1}let g=q(()=>i.projects.reduce((e,t)=>({running:e.running+t.stats.runningJobs,done:e.done+t.stats.done,total:e.total+t.stats.total}),{running:0,done:0,total:0})),_=q(()=>g.value.total>0?Math.round(g.value.done/g.value.total*100):0);function v(e){return e.git?e.git.isGitRepo===null?Z(`@WORKBENCH:未知`):e.git.isGitRepo?e.git.detached?Z(`@WORKBENCH:游离 HEAD`):e.git.branch||Z(`@WORKBENCH:未知`):``:``}function y(e){return!!(e.git&&e.git.isGitRepo&&(e.git.detached||e.git.branch))}let b=Y(null),S=Y(null);function C(e,t){if(b.value===e.key){b.value=null;return}S.value=t.currentTarget,b.value=e.key}function w(){b.value=null}function T(e){if(!b.value)return;let t=e.target;if(t&&!S.value?.contains(t)){for(let e of Array.from(document.querySelectorAll(`.proj-open-menu`)))if(e.contains(t))return;b.value=null}}u(()=>document.addEventListener(`mousedown`,T,!0)),f(()=>document.removeEventListener(`mousedown`,T,!0));let D=Le(),te=Y(!1),ne=Y(null);function re(e){return D.lastCheckedAt!==null&&!D.isToolAvailable(e)}async function O(e){w();let t=await Je(e.path);t.success?B.success(t.message||Z(`@WORKBENCH:已在文件管理器中打开文件夹`)):B.error(t.error||Z(`@WORKBENCH:打开文件夹失败`))}async function k(e){w();let t=await Be(e.path);t.success?B.success(t.message||Z(`@67CE7:已在终端中打开目录`)):B.error(t.error||Z(`@WORKBENCH:打开终端失败`))}async function A(e){w();let t=await Ue(e.path);t.success?B.success(Z(`@WORKBENCH:已在新标签页启动 g ui`)):B.error(t.error||Z(`@WORKBENCH:启动 g ui 失败`))}async function ae(e){if(w(),e.name)try{await navigator.clipboard.writeText(e.name),B.success(Z(`@67CE7:已复制文件夹名称`))}catch{B.error(Z(`@67CE7:复制失败`))}}async function j(e,t,n){if(w(),!await ze()){B.warning(Z(`@67CE7:工具检测失败,请稍后重试`));return}if(!D.isToolAvailable(t)){ne.value=t,te.value=!0;return}let r=await Ve(t,e.path,n);r.success?B.success(r.message||Z(`@67CE7:已用 {tool} 打开目录`,{tool:qe[t]})):B.error(`${Z(`@67CE7:打开失败: `)}${r.error??``}`)}let M={props:i,emit:a,ordered:o,query:s,onlyWithTasks:l,hideNonGit:d,filtering:p,visible:m,clearFilters:h,totals:g,overallProgress:_,gitLine:v,hasBranchIcon:y,openMenuKey:b,menuTriggerEl:S,toggleOpenMenu:C,closeOpenMenu:w,onDocumentMouseDown:T,toolsStore:D,installVisible:te,installTool:ne,toolMissing:re,openInFileManager:O,openInTerminal:k,launchGui:A,copyFolderName:ae,openWithTool:j,get $t(){return Z},get CopyDocument(){return ve},get Folder(){return we},get FolderOpened(){return E},get Grid(){return ee},get Monitor(){return x},get MoreFilled(){return c},get Promotion(){return t},get Search(){return ie},SvgIcon:Ae,ToolInstallDialog:We,get claudeCodeIcon(){return Ke},get OPEN_WITH_TOOLS(){return Ge},get relativeTimeFromIso(){return Ar}};return Object.defineProperty(M,"__isScriptSetup",{enumerable:!1,value:!0}),M}});b(),X(),G();var Fr={class:`proj`},Ir={class:`proj__head`},Lr={class:`proj__title`},Rr={class:`proj__count`},zr={key:0,class:`proj__tools`},Br={class:`proj__search`},Vr=[`placeholder`,`aria-label`],Hr={class:`proj__toggles`},Ur=[`aria-pressed`,`title`],Wr=[`aria-pressed`,`title`],Gr={class:`proj__list`},Kr=[`title`],qr={class:`proj-item__row1`},Jr={class:`proj-item__name`},Yr={key:0,class:`proj-item__running`,"aria-hidden":`true`},Xr={class:`proj-item__num`},Zr={class:`proj-item__row2`},Qr={key:0,class:`proj-item__running-text`},$r={key:0,class:`proj-item__row3`},ei={class:`proj-item__bar`,"aria-hidden":`true`},ti={class:`proj-item__progress-text`},ni=[`title`,`onClick`,`onKeydown`],ri={class:`proj-item__row1`},ii={class:`proj-item__name`},ai={class:`proj-item__signals`},oi={key:0,class:`proj-item__running`,"aria-hidden":`true`},si={key:1,class:`proj-item__badge`},ci={class:`proj-item__row2`},li={key:0,class:`proj-chip proj-chip--missing`},ui={key:0,class:`proj-item__branch`},di={class:`proj-item__branch-name`},fi={key:1,class:`proj-chip proj-chip--ahead`},pi={key:2,class:`proj-chip proj-chip--behind`},mi={key:3,class:`proj-chip proj-chip--dirty`},hi={class:`proj-item__time`},gi={key:0,class:`proj-item__row3`},_i={class:`proj-item__bar`,"aria-hidden":`true`},vi={class:`proj-item__progress-text`},yi={key:1,class:`proj-item__actions`},bi=[`title`,`aria-label`,`onClick`],xi=[`title`,`aria-label`,`aria-expanded`,`onClick`],Si=[`aria-label`],Ci=[`onClick`,`onKeydown`],wi={class:`proj-menu__icon`},Ti={class:`proj-menu__label`},Ei=[`onClick`,`onKeydown`],Di={class:`proj-menu__icon`},Oi={class:`proj-menu__label`},ki=[`onClick`,`onKeydown`],Ai={class:`proj-menu__icon`},ji={class:`proj-menu__label`},Mi=[`onClick`,`onKeydown`],Ni={class:`proj-menu__icon`},Pi={class:`proj-menu__label`},Fi={class:`proj-menu__title`,role:`presentation`},Ii=[`onClick`,`onKeydown`],Li={class:`proj-menu__icon`},Ri={class:`proj-menu__label`},zi={key:0,class:`proj-menu__hint`},Bi=[`onClick`,`onKeydown`],Vi={class:`proj-menu__icon`},Hi=[`src`],Ui={class:`proj-menu__label`},Wi={class:`proj-menu__hint`},Gi=[`onClick`,`onKeydown`],Ki={class:`proj-menu__icon`},qi=[`src`],Ji={class:`proj-menu__label`},Yi={key:0,class:`proj-empty`},Xi={class:`proj-empty__title`},Zi={class:`proj-empty__hint`},Qi={key:1,class:`proj-empty`},$i={class:`proj-empty__title`};function ea(t,n,i,o,s,c){let l=d,u=M;return A(),v(`section`,Fr,[D(`header`,Ir,[D(`h3`,Lr,e(o.$t(`@WORKBENCH:项目列表`)),1),D(`span`,Rr,[o.filtering?(A(),v(I,{key:0},[g(e(o.$t(`@WORKBENCH:匹配 {n}/{total} 个项目`,{n:o.visible.length,total:i.projects.length})),1)],64)):(A(),v(I,{key:1},[g(e(i.projects.length),1)],64))])]),r(` 一个项目都没有时不渲染筛选条:没有可筛的东西,这一行只是占位 `),i.projects.length>0?(A(),v(`div`,zr,[D(`div`,Br,[_(l,{class:`proj__search-icon`,"aria-hidden":`true`},{default:W(()=>[_(o.Search)]),_:1}),L(D(`input`,{"onUpdate:modelValue":n[0]||=e=>o.query=e,class:`proj__search-input`,type:`search`,placeholder:o.$t(`@WORKBENCH:搜索项目名称或路径`),"aria-label":o.$t(`@WORKBENCH:搜索项目名称或路径`),onKeydown:n[1]||=K(e=>o.query=``,[`esc`])},null,40,Vr),[[z,o.query]])]),D(`div`,Hr,[D(`button`,{type:`button`,class:U([`proj__toggle`,{"is-on":o.onlyWithTasks}]),"aria-pressed":o.onlyWithTasks,title:o.$t(`@WORKBENCH:只显示有任务的项目`),onClick:n[2]||=e=>o.onlyWithTasks=!o.onlyWithTasks},[D(`span`,null,e(o.$t(`@WORKBENCH:只看有任务`)),1)],10,Ur),D(`button`,{type:`button`,class:U([`proj__toggle`,{"is-on":o.hideNonGit}]),"aria-pressed":o.hideNonGit,title:o.$t(`@WORKBENCH:只显示 Git 仓库`),onClick:n[3]||=e=>o.hideNonGit=!o.hideNonGit},[D(`span`,null,e(o.$t(`@WORKBENCH:隐藏非 Git`)),1)],10,Wr)])])):r(`v-if`,!0),D(`ul`,Gr,[D(`li`,{class:U([`proj-item proj-item--all`,{"is-active":i.selectedKey===``}]),role:`button`,tabindex:`0`,title:o.$t(`@WORKBENCH:全部项目`),onClick:n[4]||=e=>o.emit(`select`,null),onKeydown:[n[5]||=K(J(e=>o.emit(`select`,null),[`prevent`]),[`enter`]),n[6]||=K(J(e=>o.emit(`select`,null),[`prevent`]),[`space`])]},[D(`div`,qr,[_(l,{class:`proj-item__icon`},{default:W(()=>[_(o.Grid)]),_:1}),D(`span`,Jr,e(o.$t(`@WORKBENCH:全部项目`)),1),o.totals.running>0?(A(),v(`span`,Yr)):r(`v-if`,!0),D(`span`,Xr,e(i.projects.length),1)]),D(`div`,Zr,[D(`span`,null,e(o.$t(`@WORKBENCH:{n} 个项目`,{n:i.projects.length})),1),o.totals.running>0?(A(),v(`span`,Qr,e(o.$t(`@WORKBENCH:{n} 个执行中`,{n:o.totals.running})),1)):r(`v-if`,!0)]),r(` 一个任务都没有时整行不渲染(「0/0 任务完成」+ 空进度条是纯噪声) `),o.totals.total>0?(A(),v(`div`,$r,[D(`span`,ei,[D(`i`,{class:`proj-item__bar-fill`,style:j({width:o.overallProgress+`%`})},null,4)]),D(`span`,ti,e(o.$t(`@WORKBENCH:{done}/{total} 任务完成`,{done:o.totals.done,total:o.totals.total})),1)])):r(`v-if`,!0)],42,Kr),(A(!0),v(I,null,S(o.visible,t=>(A(),v(`li`,{key:t.key,class:U([`proj-item`,{"is-active":t.key===i.selectedKey,"is-running":t.stats.runningJobs>0,"is-missing":t.exists===!1}]),role:`button`,tabindex:`0`,title:t.path,onClick:e=>o.emit(`select`,t),onKeydown:[K(J(e=>o.emit(`select`,t),[`self`,`prevent`]),[`enter`]),K(J(e=>o.emit(`select`,t),[`self`,`prevent`]),[`space`])]},[D(`div`,ri,[_(l,{class:`proj-item__icon`},{default:W(()=>[_(o.Folder)]),_:1}),D(`span`,ii,e(t.name),1),r(` 运行中 / 当前 这两个信号与 hover 才出现的操作按钮锚在同一个右端点:
21
+ hover 时整组淡出让位给按钮,而不是让图标压在徽标上 `),D(`span`,ai,[t.stats.runningJobs>0?(A(),v(`span`,oi)):r(`v-if`,!0),t.isCurrent?(A(),v(`span`,si,e(o.$t(`@WORKBENCH:当前`)),1)):r(`v-if`,!0)])]),D(`div`,ci,[t.exists===!1?(A(),v(`span`,li,e(o.$t(`@WORKBENCH:目录不存在`)),1)):(A(),v(I,{key:1},[r(` gitLine 为空即"不是 Git 仓库":不给文字,也不给图标 `),o.gitLine(t)?(A(),v(`span`,ui,[o.hasBranchIcon(t)?(A(),a(o.SvgIcon,{key:0,"icon-class":`git-branch`,"class-name":`proj-item__branch-icon`})):r(`v-if`,!0),D(`span`,di,e(o.gitLine(t)),1)])):r(`v-if`,!0),t.git&&t.git.ahead>0?(A(),v(`span`,fi,`↑`+e(t.git.ahead),1)):r(`v-if`,!0),t.git&&t.git.behind>0?(A(),v(`span`,pi,`↓`+e(t.git.behind),1)):r(`v-if`,!0),t.git&&t.git.changed>0?(A(),v(`span`,mi,`●`+e(t.git.changed),1)):r(`v-if`,!0)],64)),D(`span`,hi,e(o.relativeTimeFromIso(t.stats.lastActiveAt)),1)]),r(` 同上:这个项目一个任务都没有就不给进度行 `),t.stats.total>0?(A(),v(`div`,gi,[D(`span`,_i,[D(`i`,{class:`proj-item__bar-fill`,style:j({width:t.stats.progress+`%`})},null,4)]),D(`span`,vi,e(o.$t(`@WORKBENCH:{done}/{total} 任务完成`,{done:t.stats.done,total:t.stats.total})),1)])):r(`v-if`,!0),r(` 打开动作:与行主体平级,绝对定位锚在 row1 右端(不占位,否则「当前」徽标
22
+ 永远离右边缘一条);.stop 阻止冒泡到行的选中逻辑。目录都不存在了就不渲染——
23
+ 点了只会弹一个「无法打开目录」的报错。
24
+ 两个按钮:最常用的「打开文件夹」留一键直达,其余打开方式(终端 / 编辑器 /
25
+ AI 工具 / 新标签页跑 g ui)收进「打开方式」菜单 —— 一行放不下七个图标,
26
+ 而项目名被挤成省略号比多点一次更难受。
27
+ ⚠️ 行上的 keydown 必须带 .self:事件从按钮冒泡上来,不带 .self 时
28
+ 焦点在按钮上按回车会「选中该行 + preventDefault 掉按钮自己的激活」,
29
+ 键盘用户反而打不开文件夹。 `),t.exists===!1?r(`v-if`,!0):(A(),v(`div`,yi,[D(`button`,{type:`button`,class:`proj-item__action`,title:o.$t(`@WORKBENCH:打开文件夹`),"aria-label":`${o.$t(`@WORKBENCH:打开文件夹`)} ${t.name}`,onClick:J(e=>o.openInFileManager(t),[`stop`])},[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.FolderOpened)]),_:1})],8,bi),_(u,{visible:o.openMenuKey===t.key,trigger:`manual`,placement:`right-start`,width:272,"show-arrow":!1,offset:6,"popper-class":`proj-open-menu`},{reference:W(()=>[D(`button`,{type:`button`,class:U([`proj-item__action`,{"is-open":o.openMenuKey===t.key}]),title:o.$t(`@WORKBENCH:打开方式`),"aria-label":`${o.$t(`@WORKBENCH:打开方式`)} ${t.name}`,"aria-expanded":o.openMenuKey===t.key,"aria-haspopup":`menu`,onClick:J(e=>o.toggleOpenMenu(t,e),[`stop`])},[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.MoreFilled)]),_:1})],10,xi)]),default:W(()=>[o.openMenuKey===t.key?(A(),v(`ul`,{key:0,class:`proj-menu`,role:`menu`,"aria-label":o.$t(`@WORKBENCH:打开方式`)},[D(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:e=>o.openInFileManager(t),onKeydown:[K(J(e=>o.openInFileManager(t),[`prevent`]),[`enter`]),K(J(e=>o.openInFileManager(t),[`prevent`]),[`space`])]},[D(`span`,wi,[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.FolderOpened)]),_:1})]),D(`span`,Ti,e(o.$t(`@WORKBENCH:在文件管理器中打开`)),1)],40,Ci),D(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:e=>o.openInTerminal(t),onKeydown:[K(J(e=>o.openInTerminal(t),[`prevent`]),[`enter`]),K(J(e=>o.openInTerminal(t),[`prevent`]),[`space`])]},[D(`span`,Di,[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.Monitor)]),_:1})]),D(`span`,Oi,e(o.$t(`@WORKBENCH:在终端中打开`)),1)],40,Ei),D(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:e=>o.launchGui(t),onKeydown:[K(J(e=>o.launchGui(t),[`prevent`]),[`enter`]),K(J(e=>o.launchGui(t),[`prevent`]),[`space`])]},[D(`span`,Ai,[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.Promotion)]),_:1})]),D(`span`,ji,e(o.$t(`@WORKBENCH:在新标签页启动 g ui`)),1)],40,ki),r(` 复制文件夹名称:放在"打开"这一组里,因为它操作的是项目目录本身,
30
+ 而不是"用哪个工具打开"(下面那组有独立标题)。 `),D(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:e=>o.copyFolderName(t),onKeydown:[K(J(e=>o.copyFolderName(t),[`prevent`]),[`enter`]),K(J(e=>o.copyFolderName(t),[`prevent`]),[`space`])]},[D(`span`,Ni,[_(l,{"aria-hidden":`true`},{default:W(()=>[_(o.CopyDocument)]),_:1})]),D(`span`,Pi,e(o.$t(`@67CE7:复制文件夹名称`)),1)],40,Mi),n[8]||=D(`li`,{class:`proj-menu__sep`,role:`separator`},null,-1),D(`li`,Fi,e(o.$t(`@WORKBENCH:用工具打开`)),1),(A(!0),v(I,null,S(o.OPEN_WITH_TOOLS,n=>(A(),v(`li`,{key:n.id,class:U([`proj-menu__item`,{"is-missing":o.toolMissing(n.id)}]),role:`menuitem`,tabindex:`-1`,onClick:e=>o.openWithTool(t,n.id),onKeydown:[K(J(e=>o.openWithTool(t,n.id),[`prevent`]),[`enter`]),K(J(e=>o.openWithTool(t,n.id),[`prevent`]),[`space`])]},[D(`span`,Li,[_(o.SvgIcon,{"icon-class":n.icon},null,8,[`icon-class`])]),D(`span`,Ri,e(o.$t(n.labelKey)),1),o.toolMissing(n.id)?(A(),v(`span`,zi,e(o.$t(`@67CE7:未安装`)),1)):r(`v-if`,!0)],42,Ii))),128)),r(` claude 有两种权限模式,不混进上面的工具列表(顶栏也是单独排布的) `),D(`li`,{class:U([`proj-menu__item`,{"is-missing":o.toolMissing(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:e=>o.openWithTool(t,`claude`),onKeydown:[K(J(e=>o.openWithTool(t,`claude`),[`prevent`]),[`enter`]),K(J(e=>o.openWithTool(t,`claude`),[`prevent`]),[`space`])]},[D(`span`,Vi,[D(`img`,{src:o.claudeCodeIcon,alt:``,class:`proj-menu__img`},null,8,Hi)]),D(`span`,Ui,e(o.$t(`@67CE7:用 Claude Code 打开`)),1),D(`span`,Wi,e(o.toolMissing(`claude`)?o.$t(`@67CE7:未安装`):o.$t(`@67CE7:默认权限`)),1)],42,Bi),D(`li`,{class:U([`proj-menu__item proj-menu__item--danger`,{"is-missing":o.toolMissing(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:e=>o.openWithTool(t,`claude`,`bypassPermissions`),onKeydown:[K(J(e=>o.openWithTool(t,`claude`,`bypassPermissions`),[`prevent`]),[`enter`]),K(J(e=>o.openWithTool(t,`claude`,`bypassPermissions`),[`prevent`]),[`space`])]},[D(`span`,Ki,[D(`img`,{src:o.claudeCodeIcon,alt:``,class:`proj-menu__img`},null,8,qi)]),D(`span`,Ji,e(o.$t(`@67CE7:用 Claude Code 打开(完全批准)`)),1)],42,Gi)],8,Si)):r(`v-if`,!0)]),_:2},1032,[`visible`])]))],42,ni))),128)),!i.loading&&i.projects.length===0?(A(),v(`li`,Yi,[D(`p`,Xi,e(o.$t(`@WORKBENCH:尚无项目`)),1),D(`p`,Zi,e(o.$t(`@WORKBENCH:常用目录与建过任务的目录都会出现在这里`)),1)])):r(`v-if`,!0),r(` 有项目、只是被筛没了:这必须说出来。
31
+ 空着会让人以为项目列表坏了,而"没有匹配"和"一个项目都没有"是两件事。
32
+ 刻意写成两个互斥的 v-if(而不是 v-else-if):条件里带上了 projects.length,
33
+ 读代码时不用回头找上一段才敢确定它们不重叠。 `),!i.loading&&i.projects.length>0&&o.visible.length===0?(A(),v(`li`,Qi,[D(`p`,$i,e(o.$t(`@WORKBENCH:没有匹配的项目`)),1),D(`button`,{type:`button`,class:`proj-empty__clear`,onClick:o.clearFilters},e(o.$t(`@WORKBENCH:清除筛选`)),1)])):r(`v-if`,!0)]),r(` 未安装的工具:复用顶栏那套安装引导(同一个组件),不在这里另写一份说明。
34
+ 挂在面板根上只渲染一份,而不是每行一个 —— 同时最多只可能开一个。 `),_(o.ToolInstallDialog,{modelValue:o.installVisible,"onUpdate:modelValue":n[7]||=e=>o.installVisible=e,tool:o.installTool},null,8,[`modelValue`,`tool`])])}var ta=Q(Pr,[[`render`,ea],[`__scopeId`,`data-v-de1af726`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchProjectPanel.vue`]]);X(),R();var na=s({__name:`WorkbenchAgentPanel`,props:{running:{type:Array,required:!0}},setup(e,{expose:t}){t();let n=e,r=Y(Date.now()),i=null;function a(){i&&=(clearInterval(i),null)}function o(){if(n.running.length>0){if(i)return;r.value=Date.now(),i=setInterval(()=>{r.value=Date.now()},1e3)}else a()}P(()=>n.running.length,o,{immediate:!0}),f(a);let s={props:n,now:r,get timer(){return i},set timer(e){i=e},stopTimer:a,syncTimer:o,rows:q(()=>n.running.map(e=>({...e,elapsed:jr(e.startedAt,null,r.value)}))),get $t(){return Z}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}});b(),X();var ra={class:`agents`},ia={class:`agents__head`},aa={class:`agents__title`},oa={class:`agents__list`},sa={class:`agent-item__row1`},ca=[`title`],la={class:`agent-item__status`},ua=[`title`],da={class:`agent-item__row3`},fa={key:0,class:`agent-item__pid`},pa={class:`agent-item__elapsed`},ma={key:0,class:`agents-empty`};function ha(t,n,i,a,o,s){return A(),v(`section`,ra,[D(`header`,ia,[D(`h3`,aa,e(a.$t(`@WORKBENCH:执行监控`)),1),D(`span`,{class:U([`agents__count`,{"is-live":i.running.length>0}])},e(a.$t(`@WORKBENCH:{n} 个执行中`,{n:i.running.length})),3)]),D(`ul`,oa,[(A(!0),v(I,null,S(a.rows,t=>(A(),v(`li`,{key:t.jobId,class:`agent-item`},[D(`div`,sa,[D(`span`,{class:U([`agent-item__dot`,{"is-pending":t.status===`pending`}]),"aria-hidden":`true`},null,2),D(`span`,{class:`agent-item__project`,title:t.projectName},e(t.projectName||`—`),9,ca),D(`span`,la,e(t.status===`pending`?a.$t(`@WORKBENCH:排队中`):a.$t(`@WORKBENCH:执行中`)),1)]),D(`p`,{class:`agent-item__task`,title:t.taskTitle},e(t.taskTitle||a.$t(`@WORKBENCH:未命名任务`)),9,ua),D(`div`,da,[t.pid?(A(),v(`span`,fa,`PID `+e(t.pid),1)):r(`v-if`,!0),D(`span`,pa,e(t.elapsed),1)])]))),128)),i.running.length===0?(A(),v(`li`,ma,e(a.$t(`@WORKBENCH:暂无执行中的任务`)),1)):r(`v-if`,!0)])])}var ga=Q(na,[[`render`,ha],[`__scopeId`,`data-v-09820e5d`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchAgentPanel.vue`]]);X(),R();var _a=`wb.boardView.v1`,va=s({__name:`WorkbenchKanban`,props:{tasks:{type:Array,required:!0},projectLabels:{type:Object,required:!0},showProjectLabel:{type:Boolean,required:!0}},emits:[`open-task`,`run-task`,`delete-task`,`create-task`],setup(e,{expose:t,emit:n}){t();let r=e,i=n,a=Y((()=>{try{return localStorage.getItem(_a)===`list`?`list`:`kanban`}catch{return`kanban`}})());P(a,e=>{try{localStorage.setItem(_a,e)}catch{}});let o=Y(``),s=Y(!1),c=[{key:`todo`,labelKey:`@WORKBENCH:待处理`},{key:`doing`,labelKey:`@WORKBENCH:进行中`},{key:`done`,labelKey:`@WORKBENCH:已完成`}],l=q(()=>{let e=o.value.trim().toLowerCase();return r.tasks.filter(t=>s.value&&t.lastJobStatus!==`error`?!1:!e||(t.title||``).toLowerCase().includes(e)||(t.desc||``).toLowerCase().includes(e))}),u=q(()=>c.map(e=>e.key===`done`?{...e,tasks:l.value.filter(t=>t.column===e.key).sort(f)}:{...e,tasks:l.value.filter(t=>t.column===e.key)}));function d(e){return String(e.lastJobEndedAt||e.updatedAt||e.createdAt||``)}function f(e,t){return d(t).localeCompare(d(e))}function p(e){return e.column===`done`?d(e):e.updatedAt||e.createdAt||``}let m=q(()=>({gridTemplateColumns:`repeat(${u.value.length}, minmax(0, 1fr))`}));function h(e){return(e.title||``).trim()||(e.desc||``).replace(/\s+/g,` `).trim()}function g(e){return r.projectLabels[e.projectPath]||``}function _(e){return e.lastJobStatus===`error`}let v={props:r,emit:i,VIEW_KEY:_a,view:a,search:o,onlyErrors:s,COLUMNS:c,filtered:l,columns:u,doneAt:d,byDoneAtDesc:f,cardTime:p,columnsStyle:m,cardTitle:h,projectLabel:g,hasError:_,get $t(){return Z},get Search(){return ie},get relativeTimeFromIso(){return Ar}};return Object.defineProperty(v,"__isScriptSetup",{enumerable:!1,value:!0}),v}});b(),X(),G();var ya={class:`kb`},ba={class:`kb__toolbar`},xa={class:`kb__views`,role:`tablist`},Sa=[`aria-selected`],Ca=[`aria-selected`],wa={class:`kb__filters`},Ta=[`title`],Ea={class:`kb__search`},Da=[`placeholder`],Oa={class:`kb-col__head`},ka={class:`kb-col__title`},Aa={class:`kb-col__count`},ja={class:`kb-col__list`},Ma=[`onClick`],Na={class:`kb-card__row1`},Pa={key:0,class:`kb-card__running`,"aria-hidden":`true`},Fa={class:`kb-card__time`},Ia=[`title`],La={key:0,class:`kb-card__project`},Ra={class:`kb-card__actions`},za=[`title`,`onClick`],Ba=[`title`,`aria-label`,`onClick`],Va={key:0,class:`kb-col__empty`},Ha={key:1},Ua={class:`kb__table-wrap`},Wa={class:`kb-table`},Ga={class:`kb-table__th`},Ka={class:`kb-table__th kb-table__th--narrow`},qa={class:`kb-table__th kb-table__th--narrow`},Ja=[`onClick`],Ya={class:`kb-table__td`},Xa={class:`kb-table__name`},Za={key:0,class:`kb-table__project`},Qa={class:`kb-table__td`},$a={class:`kb-table__td kb-table__td--num`},eo={key:0},to={class:`kb-table__td kb-table__empty`,colspan:`3`};function no(t,n,i,a,o,s){let c=d;return A(),v(`div`,ya,[D(`div`,ba,[D(`div`,xa,[D(`button`,{type:`button`,role:`tab`,class:U([`kb__view-btn`,{"is-active":a.view===`kanban`}]),"aria-selected":a.view===`kanban`,onClick:n[0]||=e=>a.view=`kanban`},e(a.$t(`@WORKBENCH:看板视图`)),11,Sa),D(`button`,{type:`button`,role:`tab`,class:U([`kb__view-btn`,{"is-active":a.view===`list`}]),"aria-selected":a.view===`list`,onClick:n[1]||=e=>a.view=`list`},e(a.$t(`@WORKBENCH:列表视图`)),11,Ca)]),D(`div`,wa,[D(`label`,{class:`kb__check`,title:a.$t(`@WORKBENCH:只显示最近一次执行报错的任务`)},[L(D(`input`,{type:`checkbox`,"onUpdate:modelValue":n[2]||=e=>a.onlyErrors=e},null,512),[[H,a.onlyErrors]]),D(`span`,null,e(a.$t(`@WORKBENCH:仅看报错`)),1)],8,Ta),D(`div`,Ea,[_(c,{class:`kb__search-icon`},{default:W(()=>[_(a.Search)]),_:1}),L(D(`input`,{class:`kb__search-input`,type:`search`,"onUpdate:modelValue":n[3]||=e=>a.search=e,placeholder:a.$t(`@WORKBENCH:搜索任务标题或描述`)},null,8,Da),[[z,a.search]])])])]),r(` 看板视图 `),a.view===`kanban`?(A(),v(`div`,{key:0,class:`kb__columns`,style:j(a.columnsStyle)},[(A(!0),v(I,null,S(a.columns,t=>(A(),v(`section`,{key:t.key,class:U([`kb-col`,`kb-col--`+t.key])},[D(`header`,Oa,[n[5]||=D(`span`,{class:`kb-col__dot`,"aria-hidden":`true`},null,-1),D(`h3`,ka,e(a.$t(t.labelKey)),1),D(`span`,Aa,e(t.tasks.length),1)]),D(`ul`,ja,[(A(!0),v(I,null,S(t.tasks,t=>(A(),v(`li`,{key:t.id,class:U([`kb-card`,{"is-running":t.runningJobs>0,"has-error":a.hasError(t)}]),onClick:e=>a.emit(`open-task`,t)},[D(`div`,Na,[t.runningJobs>0?(A(),v(`span`,Pa)):r(`v-if`,!0),D(`span`,Fa,e(a.relativeTimeFromIso(a.cardTime(t))),1)]),D(`p`,{class:`kb-card__title`,title:a.cardTitle(t)},e(a.cardTitle(t)||a.$t(`@WORKBENCH:未命名任务`)),9,Ia),i.showProjectLabel&&a.projectLabel(t)?(A(),v(`p`,La,e(a.projectLabel(t)),1)):r(`v-if`,!0),D(`div`,Ra,[t.runningJobs===0?(A(),v(`button`,{key:0,type:`button`,class:`kb-card__btn`,title:a.$t(`@WORKBENCH:执行`),onClick:J(e=>a.emit(`run-task`,t),[`stop`])},e(a.$t(`@WORKBENCH:执行`)),9,za)):r(`v-if`,!0),D(`button`,{type:`button`,class:`kb-card__btn kb-card__btn--danger`,title:a.$t(`@WORKBENCH:删除`),"aria-label":a.$t(`@WORKBENCH:删除`),onClick:J(e=>a.emit(`delete-task`,t),[`stop`])},`×`,8,Ba)])],10,Ma))),128)),t.tasks.length===0?(A(),v(`li`,Va,[t.key===`todo`?(A(),v(`button`,{key:0,type:`button`,class:`kb-col__empty-btn`,onClick:n[4]||=e=>a.emit(`create-task`)},e(a.$t(`@WORKBENCH:新建任务`)),1)):(A(),v(`span`,Ha,e(a.$t(`@WORKBENCH:暂无任务`)),1))])):r(`v-if`,!0)])],2))),128))],4)):(A(),v(I,{key:1},[r(` 列表视图 `),D(`div`,Ua,[D(`table`,Wa,[D(`thead`,null,[D(`tr`,null,[D(`th`,Ga,e(a.$t(`@WORKBENCH:任务`)),1),D(`th`,Ka,e(a.$t(`@WORKBENCH:状态`)),1),D(`th`,qa,e(a.$t(`@WORKBENCH:更新时间`)),1)])]),D(`tbody`,null,[(A(!0),v(I,null,S(a.filtered,t=>(A(),v(`tr`,{key:t.id,class:`kb-table__row`,onClick:e=>a.emit(`open-task`,t)},[D(`td`,Ya,[D(`span`,Xa,e(a.cardTitle(t)||a.$t(`@WORKBENCH:未命名任务`)),1),i.showProjectLabel&&a.projectLabel(t)?(A(),v(`span`,Za,e(a.projectLabel(t)),1)):r(`v-if`,!0)]),D(`td`,Qa,[D(`span`,{class:U([`kb-table__status`,`is-`+t.column])},e(a.$t(a.COLUMNS.find(e=>e.key===t.column).labelKey)),3)]),D(`td`,$a,e(a.relativeTimeFromIso(t.updatedAt||t.createdAt)),1)],8,Ja))),128)),a.filtered.length===0?(A(),v(`tr`,eo,[D(`td`,to,e(a.$t(`@WORKBENCH:暂无任务`)),1)])):r(`v-if`,!0)])])])],2112))])}var ro=Q(va,[[`render`,no],[`__scopeId`,`data-v-0b8fc27c`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchKanban.vue`]]);X(),R();var io=`/api/workbench/orchestrator/attachments`,ao=`wb.ocInputHeight.v1`,oo=76,so=20,co=s({__name:`OrchestratorConsole`,props:{active:{type:Boolean,required:!0},activity:{type:Array,required:!0},runningCount:{type:Number,required:!0},selectedProject:{type:[Object,null],required:!0},dispatching:{type:Boolean,required:!0},togglingSchedule:{type:Boolean,required:!0},todayDone:{type:Number,required:!0},collapsed:{type:Boolean,required:!1},defaultPrompt:{type:String,required:!1},projectPrompts:{type:Object,required:!1}},emits:[`toggle-schedule`,`toggle-collapse`,`open-prompt-settings`,`dispatch`],setup(e,{expose:n,emit:r}){let i=e,a=r,o=Y(``),s=Y(!0),c=Y(!0),l=Le(),d=q(()=>({claude:l.claudeAvailable,opencode:l.opencodeAvailable,codex:l.codexAvailable})),p=Y(Me());function h(){if(d.value[p.value]){je(p.value);return}let e=Object.keys(d.value).find(e=>d.value[e]);e&&(p.value=e)}function g(e){return Ne(e)}function _(e){p.value=e,h()}let v=Y([]),y=q(()=>({kind:`draft`,list:v.value,replace:e=>{v.value=e}})),{isUploading:b,isImageAttachment:x,humanSize:S,onAttachmentPaste:C,onAttachmentDrop:w,removeAttachment:T,pickAttachmentFile:E}=Mn(),D=q(()=>b(`draft`)),ee=Y(!1);function te(e){e.stopPropagation(),C(e,y.value)}function ne(e){ee.value=!1,w(e,y.value)}function re(){E(y.value)}function O(e){T(y.value,e)}function k(){v.value=[]}n({clearAttachments:k});let ie=q(()=>i.selectedProject?.key||``),A=q(()=>(i.defaultPrompt||``).trim()),ae=q(()=>{let e=ie.value;return e?(i.projectPrompts?.[e]?.prompt||``).trim():``}),j=q(()=>Object.values(i.projectPrompts||{}).some(e=>(e?.prompt||``).trim().length>0)),M=q(()=>!!A.value||j.value),oe=q(()=>{let e=!!A.value,t=ie.value?ae.value?`project`:`none`:j.value?`target`:`none`;return Z(e&&t===`project`?`@WORKBENCH:全局 + 本项目`:e&&t===`target`?`@WORKBENCH:全局 + 落点项目`:e?`@WORKBENCH:全局`:t===`project`?`@WORKBENCH:本项目`:t===`target`?`@WORKBENCH:落点项目`:`@WORKBENCH:未设置`)}),se=q(()=>o.value.trim().length>0&&!i.dispatching&&!D.value);function N(){se.value&&(a(`dispatch`,{text:o.value.trim(),autoRun:s.value,attachments:v.value,projectPath:i.selectedProject?i.selectedProject.path:``,useDefaultPrompt:c.value,executor:p.value}),o.value=``)}function P(e){e.isComposing||e.keyCode===229||e.key!==`Enter`||e.shiftKey||(e.preventDefault(),N())}function F(){try{let e=localStorage.getItem(ao);if(!e)return null;let t=Number(e);return Number.isFinite(t)&&t>=oo?Math.round(t):null}catch{return null}}let ce=Y(null),I=Y(F()),L=q(()=>{let e={};return I.value&&(e.height=`${I.value}px`),e}),le=null,R=!1,de=!0;function z(e){let t=ce.value;if(!t)return;let n=t.getBoundingClientRect();R=n.right-e.clientX<=so&&n.bottom-e.clientY<=so}function pe(){R=!1}function B(e){let t=Math.round(e.offsetHeight);if(!(t<oo||t===I.value)){I.value=t;try{localStorage.setItem(ao,String(t))}catch{}}}u(()=>{let e=ce.value;e&&(window.addEventListener(`mouseup`,pe),!(typeof ResizeObserver>`u`)&&(le=new ResizeObserver(()=>{if(de){de=!1;return}let t=parseFloat(getComputedStyle(e).maxHeight),n=Number.isFinite(t)&&e.offsetHeight>=t-1;(R||!n)&&B(e)}),le.observe(e)))}),f(()=>{window.removeEventListener(`mouseup`,pe),le?.disconnect(),le=null});function me(e){let t=e.taskTitle||Z(`@WORKBENCH:未命名任务`),n=e.projectName||`—`;switch(e.kind){case`user`:return e.text||``;case`dispatch`:return Z(`@WORKBENCH:派发「{task}」至 {project}`,{task:t,project:n});case`done`:return Z(`@WORKBENCH:「{task}」执行完成`,{task:t});case`error`:return Z(`@WORKBENCH:「{task}」执行出错`,{task:t});case`cancelled`:return Z(`@WORKBENCH:「{task}」已取消`,{task:t});default:return t}}let V={user:`@WORKBENCH:用户派发`,dispatch:`@WORKBENCH:派发`,done:`@WORKBENCH:完成`,error:`@WORKBENCH:出错`,cancelled:`@WORKBENCH:取消`};function H(e){return e.kind===`user`?e.instructionStatus===`accepted`?Z(`@WORKBENCH:已建任务并开始执行`):e.instructionStatus===`rejected`?Z(`@WORKBENCH:被拒绝:{reason}`,{reason:e.reason||``}):e.reason||Z(`@WORKBENCH:已建任务(未执行)`):``}function U(e){switch(e.targetSource){case`mention`:return Z(`@WORKBENCH:指令里提到了它`);case`agent`:return Z(`@WORKBENCH:主 Agent 判断`);case`default`:return Z(`@WORKBENCH:没识别出项目,用了默认项目`);default:return``}}function _e(e){switch(e.promptSource){case`global`:return Z(`@WORKBENCH:附带全局默认提示词`);case`project`:return Z(`@WORKBENCH:附带项目默认提示词`);case`both`:return Z(`@WORKBENCH:附带全局 + 项目默认提示词`);default:return``}}let W={props:i,emit:a,draft:o,autoRun:s,useDefaultPrompt:c,toolsStore:l,executorAvailability:d,selectedExecutor:p,onExecutorChange:h,executorName:g,onExecutorPick:_,draftAttachments:v,DRAFT_RAW_BASE:io,attachTarget:y,isUploading:b,isImageAttachment:x,humanSize:S,onAttachmentPaste:C,onAttachmentDrop:w,removeAttachment:T,pickAttachmentFile:E,attachBusy:D,attachDragging:ee,onPaste:te,onDrop:ne,onPickAttachment:re,onRemoveAttachment:O,clearAttachments:k,projectKey:ie,globalPromptText:A,projectPromptText:ae,anyProjectPrompt:j,anyPromptConfigured:M,promptStateLabel:oe,canSend:se,send:N,onInputKeydown:P,INPUT_H_KEY:ao,OC_INPUT_MIN_H:oo,readInputH:F,inputRef:ce,inputH:I,inputStyle:L,get inputRO(){return le},set inputRO(e){le=e},get inputDragging(){return R},set inputDragging(e){R=e},get inputROFirst(){return de},set inputROFirst(e){de=e},INPUT_GRIP_PX:so,onInputMouseDown:z,onWindowMouseUp:pe,commitInputH:B,describe:me,KIND_LABEL:V,instructionNote:H,targetReason:U,promptNote:_e,gitSummary:q(()=>{let e=i.selectedProject;if(!e)return[];let t=[];if(e.exists===!1)return t.push({label:Z(`@WORKBENCH:工作区`),value:Z(`@WORKBENCH:目录不存在`),tone:`danger`}),t;let n=e.git;return!n||n.isGitRepo===null?(t.push({label:Z(`@WORKBENCH:Git 状态`),value:Z(`@WORKBENCH:未知`),tone:``}),t):n.isGitRepo?(t.push({label:Z(`@WORKBENCH:分支`),value:n.detached?Z(`@WORKBENCH:游离 HEAD`):n.branch||Z(`@WORKBENCH:未知`),tone:``}),t.push({label:Z(`@WORKBENCH:工作区`),value:n.changed>0?Z(`@WORKBENCH:未提交 {n} 项`,{n:n.changed}):Z(`@WORKBENCH:干净`),tone:n.changed>0?`warn`:``}),n.hasUpstream&&(n.ahead>0||n.behind>0)&&t.push({label:Z(`@WORKBENCH:与上游`),value:Z(`@WORKBENCH:领先 {ahead} / 落后 {behind}`,{ahead:n.ahead,behind:n.behind}),tone:n.behind>0?`warn`:``}),t):(t.push({label:Z(`@WORKBENCH:Git 状态`),value:Z(`@WORKBENCH:不是 Git 仓库`),tone:``}),t)}),get $t(){return Z},get Paperclip(){return m},get Promotion(){return t},get Expand(){return fe},get Fold(){return Se},get Setting(){return ge},get ArrowDown(){return he},get Check(){return ue},TaskExecutorIcon:Re,get clockFromIso(){return Nr},get relativeTimeFromIso(){return Ar},AttachmentZone:lt,get TASK_EXECUTOR_OPTIONS(){return Pe}};return Object.defineProperty(W,"__isScriptSetup",{enumerable:!1,value:!0}),W}});X(),b(),G();var lo=[`title`,`aria-label`],uo={class:`oc__rail-text`},fo={class:`oc__head`},po={class:`oc__title`},mo=[`disabled`,`title`],ho=[`title`,`aria-label`],go={class:`oc__state-label`},_o={class:`oc__state-value`},vo={class:`oc__state-meta`},yo={class:`oc__feed`},bo={class:`oc__feed-title`},xo={class:`oc__feed-list`},So={class:`oc-row__head`},Co={class:`oc-row__kind`},wo={class:`oc-row__time`},To={class:`oc-row__text`},Eo={key:0,class:`oc-row__note`},Do={key:1,class:`oc-row__note`},Oo={key:0},ko={key:2,class:`oc-row__note`},Ao=[`title`],jo={key:4,class:`oc-row__note`},Mo={key:0,class:`oc-empty`},No={class:`oc__git`},Po={class:`oc__feed-title`},Fo={class:`oc__git-name`},Io={class:`oc__git-list`},Lo={class:`oc__git-label`},Ro={class:`oc__git-label`},zo={class:`oc__git-value`},Bo={class:`oc__git-label`},Vo={class:`oc__git-value`},Ho=[`placeholder`],Uo={class:`oc__compose-foot`},Wo=[`disabled`,`title`,`aria-label`],Go=[`title`,`aria-label`],Ko=[`title`],qo=[`title`],Jo=[`title`,`aria-label`],Yo={class:`oc__executor-item`},Xo={class:`oc__executor-item__name`},Zo={key:1,class:`oc__executor-item__missing`},Qo=[`disabled`],$o={class:`oc__hint`};function es(t,i,o,s,c,l){let u=d,f=n,p=Ce,m=w;return A(),v(`aside`,{class:U([`oc`,{"is-collapsed":o.collapsed}])},[r(` 折叠后的收纳条:只剩一枚展开按钮 + 竖排标题,宽度收到 32px。
35
+ 折叠不是"把宽度压成 0"—— 那样就再没有能点回来的地方了。 `),o.collapsed?(A(),v(`button`,{key:0,type:`button`,class:`oc__rail`,title:s.$t(`@WORKBENCH:展开主 Agent 控制台`),"aria-label":s.$t(`@WORKBENCH:展开主 Agent 控制台`),"aria-expanded":!1,onClick:i[0]||=e=>s.emit(`toggle-collapse`)},[_(u,{class:`oc__rail-icon`},{default:W(()=>[_(s.Fold)]),_:1}),D(`span`,{class:U([`oc__rail-live`,{"is-off":!o.active}]),"aria-hidden":`true`},null,2),D(`span`,uo,e(s.$t(`@WORKBENCH:主 Agent 控制台`)),1)],8,lo)):r(`v-if`,!0),r(` 折叠时这几块整体隐藏而不是销毁(v-show 而不是 v-if):
36
+ 草稿指令和已贴的附件都还留着,展开回来能接着发 `),L(D(`header`,fo,[D(`span`,{class:U([`oc__live`,{"is-off":!o.active}]),"aria-hidden":`true`},null,2),D(`h3`,po,e(s.$t(`@WORKBENCH:主 Agent 控制台`)),1),D(`button`,{type:`button`,class:`oc__toggle`,disabled:o.togglingSchedule,title:o.active?s.$t(`@WORKBENCH:暂停后派发只建任务,不会自动执行`):s.$t(`@WORKBENCH:恢复后派发会自动执行`),onClick:i[1]||=e=>s.emit(`toggle-schedule`,!o.active)},e(o.active?s.$t(`@WORKBENCH:暂停调度`):s.$t(`@WORKBENCH:恢复调度`)),9,mo),D(`button`,{type:`button`,class:`oc__collapse`,title:s.$t(`@WORKBENCH:收起主 Agent 控制台`),"aria-label":s.$t(`@WORKBENCH:收起主 Agent 控制台`),"aria-expanded":!0,onClick:i[2]||=e=>s.emit(`toggle-collapse`)},[_(u,null,{default:W(()=>[_(s.Expand)]),_:1})],8,ho)],512),[[oe,!o.collapsed]]),L(D(`div`,{class:U([`oc__state`,{"is-paused":!o.active}])},[D(`span`,go,e(s.$t(`@WORKBENCH:调度状态`)),1),D(`span`,_o,e(o.active?s.$t(`@WORKBENCH:调度中`):s.$t(`@WORKBENCH:已暂停`)),1),D(`span`,vo,e(s.$t(`@WORKBENCH:{n} 个执行中`,{n:o.runningCount})),1)],2),[[oe,!o.collapsed]]),L(D(`div`,yo,[D(`p`,bo,e(s.$t(`@WORKBENCH:活动日志`)),1),D(`ul`,xo,[(A(!0),v(I,null,S(o.activity,t=>(A(),v(`li`,{key:t.id,class:U([`oc-row`,`oc-row--`+t.kind])},[D(`div`,So,[D(`span`,Co,e(s.$t(s.KIND_LABEL[t.kind]||`@WORKBENCH:派发`)),1),r(` 时间走 clockFromIso:非当天会带上日期前缀,避免跨天记录看起来像今天刚发生 `),D(`span`,wo,e(s.clockFromIso(t.at)),1)]),D(`p`,To,e(s.describe(t)),1),s.instructionNote(t)?(A(),v(`p`,Eo,e(s.instructionNote(t)),1)):r(`v-if`,!0),r(` 落点 + 依据。判断错了,用户至少要能看出是"没识别出来、退了默认"
37
+ 还是"模型猜的",否则只能对着一个错误项目名干瞪眼 `),t.kind===`user`&&t.projectName?(A(),v(`p`,Do,[g(e(s.$t(`@WORKBENCH:落点「{name}」`,{name:t.projectName}))+` `,1),s.targetReason(t)?(A(),v(`span`,Oo,`· `+e(s.targetReason(t)),1)):r(`v-if`,!0)])):r(`v-if`,!0),r(` 提示词单独占一行:它解释的是"任务正文里多出来的那段话是哪来的",
38
+ 和落点是两件事,挤在一行会看不清 `),t.kind===`user`&&s.promptNote(t)?(A(),v(`p`,ko,e(s.promptNote(t)),1)):r(`v-if`,!0),t.kind===`error`&&t.error?(A(),v(`p`,{key:3,class:`oc-row__error`,title:t.error},e(t.error),9,Ao)):r(`v-if`,!0),t.kind===`done`&&t.projectName?(A(),v(`p`,jo,e(t.projectName),1)):r(`v-if`,!0)],2))),128)),o.activity.length===0?(A(),v(`li`,Mo,e(s.$t(`@WORKBENCH:暂无活动记录`)),1)):r(`v-if`,!0)])],512),[[oe,!o.collapsed]]),L(D(`div`,No,[D(`p`,Po,[g(e(s.$t(`@WORKBENCH:项目概览`))+` `,1),r(` 无选中项目即「全部项目」:显式标出来,否则底下只剩「今日完成」一行,看着像数据没加载出来 `),D(`span`,Fo,e(o.selectedProject?o.selectedProject.name:s.$t(`@WORKBENCH:全部项目`)),1)]),D(`dl`,Io,[(A(!0),v(I,null,S(s.gitSummary,t=>(A(),v(I,{key:t.label},[D(`dt`,Lo,e(t.label),1),D(`dd`,{class:U([`oc__git-value`,{"is-warn":t.tone===`warn`,"is-danger":t.tone===`danger`}])},e(t.value),3)],64))),128)),D(`dt`,Ro,e(s.$t(`@WORKBENCH:今日完成`)),1),D(`dd`,zo,e(o.todayDone),1),D(`dt`,Bo,e(s.$t(`@WORKBENCH:最后活跃`)),1),D(`dd`,Vo,e(o.selectedProject&&s.relativeTimeFromIso(o.selectedProject.stats.lastActiveAt)||`—`),1)])],512),[[oe,!o.collapsed]]),L(D(`div`,{class:`oc__compose`,onPaste:s.onPaste,onDrop:J(s.onDrop,[`prevent`]),onDragover:i[10]||=J(e=>s.attachDragging=!0,[`prevent`]),onDragleave:i[11]||=e=>s.attachDragging=!1},[r(` 粘贴事件必须同时挂在 textarea 上:在输入框里按 Ctrl+V 时事件只到 textarea,
39
+ 不会冒泡经过下面的附件区 `),L(D(`textarea`,{ref:`inputRef`,class:`oc__input`,"onUpdate:modelValue":i[3]||=e=>s.draft=e,style:j(s.inputStyle),rows:`4`,placeholder:s.$t(`@WORKBENCH:给主 Agent 下一条指令,例如:把登录模块的错误处理重构一遍`),onKeydown:s.onInputKeydown,onPaste:s.onPaste,onMousedown:s.onInputMouseDown},null,44,Ho),[[z,s.draft]]),s.draftAttachments.length>0||s.attachBusy?(A(),a(s.AttachmentZone,{key:0,attachments:s.draftAttachments,"is-image":s.isImageAttachment,"human-size":s.humanSize,"is-uploading":s.attachBusy,"is-paste-hover":s.attachDragging,"max-count":9,"on-pick":s.onPickAttachment,"on-remove":s.onRemoveAttachment,"raw-base":s.DRAFT_RAW_BASE,onPaste:s.onPaste,onDrop:s.onDrop,onDragover:i[4]||=J(e=>s.attachDragging=!0,[`prevent`]),onDragenter:i[5]||=J(e=>s.attachDragging=!0,[`prevent`]),onDragleave:i[6]||=e=>s.attachDragging=!1},null,8,[`attachments`,`is-image`,`human-size`,`is-uploading`,`is-paste-hover`])):r(`v-if`,!0),D(`div`,Uo,[D(`button`,{type:`button`,class:`oc__attach`,disabled:s.attachBusy||s.draftAttachments.length>=9,title:s.$t(`@WORKBENCH:添加附件(也可直接粘贴或拖入文件)`),"aria-label":s.$t(`@WORKBENCH:添加附件`),onClick:s.onPickAttachment},[_(u,null,{default:W(()=>[_(s.Paperclip)]),_:1})],8,Wo),r(` 默认提示词设置入口:图标按钮按项目惯例不加底色,
40
+ 有没有设过看右侧"附加默认提示词"那个勾选(它是真实生效状态,这个只是入口) `),D(`button`,{type:`button`,class:U([`oc__attach`,{"is-on":s.anyPromptConfigured}]),title:s.$t(`@WORKBENCH:设置派发时自动附加的默认提示词(全局 / 各项目)`),"aria-label":s.$t(`@WORKBENCH:默认提示词设置`),onClick:i[7]||=e=>s.emit(`open-prompt-settings`)},[_(u,null,{default:W(()=>[_(s.Setting)]),_:1})],10,Go),D(`label`,{class:`oc__autorn`,title:s.$t(`@WORKBENCH:取消勾选则只建任务草稿,不自动执行`)},[L(D(`input`,{type:`checkbox`,"onUpdate:modelValue":i[8]||=e=>s.autoRun=e},null,512),[[H,s.autoRun]]),D(`span`,null,e(s.$t(`@WORKBENCH:立即执行`)),1)],8,Ko),r(` 一条都没设过时不出现:一个永远勾着、点了也没区别的开关只会占地方 `),s.anyPromptConfigured?(A(),v(`label`,{key:0,class:`oc__autorn`,title:s.$t(`@WORKBENCH:取消勾选则本次派发的任务不带默认提示词(设置本身不受影响)`)},[L(D(`input`,{type:`checkbox`,"onUpdate:modelValue":i[9]||=e=>s.useDefaultPrompt=e},null,512),[[H,s.useDefaultPrompt]]),D(`span`,null,e(s.$t(`@WORKBENCH:默认提示词({state})`,{state:s.promptStateLabel})),1)],8,qo)):r(`v-if`,!0),r(` 执行器:与执行按钮共用同一份临时选择,派发时覆盖设置里的默认值。
41
+ 不用原生 select —— option 里塞不了品牌图标,el-dropdown 才有精致度 `),_(m,{trigger:`click`,class:`oc__executor`,onCommand:s.onExecutorPick},{dropdown:W(()=>[_(p,null,{default:W(()=>[(A(!0),v(I,null,S(s.TASK_EXECUTOR_OPTIONS,t=>(A(),a(f,{key:t.id,command:t.id,disabled:!s.executorAvailability[t.id]},{default:W(()=>[D(`span`,Yo,[_(s.TaskExecutorIcon,{executor:t.id,class:`oc__executor-item__icon`},null,8,[`executor`]),D(`span`,Xo,e(t.name),1),s.selectedExecutor===t.id?(A(),a(u,{key:0,class:`oc__executor-item__check`},{default:W(()=>[_(s.Check)]),_:1})):s.executorAvailability[t.id]?r(`v-if`,!0):(A(),v(`span`,Zo,e(s.$t(`@42BB9:未安装`)),1))])]),_:2},1032,[`command`,`disabled`]))),128))]),_:1})]),default:W(()=>[D(`button`,{type:`button`,class:`oc__executor-btn`,title:s.$t(`@WORKBENCH:本次派发使用的执行器(与执行按钮的临时切换共用)`),"aria-label":s.$t(`@WORKBENCH:任务执行器`)},[_(s.TaskExecutorIcon,{executor:s.selectedExecutor,class:`oc__executor-btn__icon`},null,8,[`executor`]),D(`span`,null,e(s.executorName(s.selectedExecutor)),1),_(u,{class:`oc__executor-btn__caret`},{default:W(()=>[_(s.ArrowDown)]),_:1})],8,Jo)]),_:1}),D(`button`,{type:`button`,class:`oc__send`,disabled:!s.canSend,onClick:s.send},[_(u,{class:`oc__send-icon`},{default:W(()=>[_(s.Promotion)]),_:1}),D(`span`,null,e(o.dispatching?s.$t(`@WORKBENCH:派发中…`):s.$t(`@WORKBENCH:派发`)),1)],8,Qo)]),D(`p`,$o,[o.selectedProject?(A(),v(I,{key:0},[g(e(s.$t(`@WORKBENCH:指令会在「{name}」下新建一个任务;Enter 派发,Shift+Enter 换行`,{name:o.selectedProject.name})),1)],64)):(A(),v(I,{key:1},[g(e(s.$t(`@WORKBENCH:指令落到哪个项目由主 Agent 判断;Enter 派发,Shift+Enter 换行`)),1)],64))])],544),[[oe,!o.collapsed]])],2)}var ts=Q(co,[[`render`,es],[`__scopeId`,`data-v-4c030231`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/OrchestratorConsole.vue`]]);X(),R();var ns=4e3,rs=s({__name:`WorkbenchDefaultPromptDialog`,props:{modelValue:{type:Boolean,required:!0},defaultPrompt:{type:String,required:!0},projectPath:{type:String,required:!0},projectName:{type:String,required:!0},projectPrompt:{type:String,required:!0},saving:{type:Boolean,required:!0}},emits:[`update:modelValue`,`save`],setup(e,{expose:t,emit:n}){t();let r=e,i=n,a=Y(``),o=Y(``);P(()=>r.modelValue,e=>{e&&(a.value=r.defaultPrompt||``,o.value=r.projectPrompt||``)});let s=q(()=>!!r.projectPath),c=q(()=>a.value.trim()!==(r.defaultPrompt||``).trim()||s.value&&o.value.trim()!==(r.projectPrompt||``).trim());function l(){r.saving||i(`save`,{globalPrompt:a.value,projectPrompt:o.value})}function u(){i(`update:modelValue`,!1)}let d={props:r,emit:i,MAX_CHARS:ns,globalDraft:a,projectDraft:o,hasProject:s,dirty:c,submit:l,close:u,get $t(){return Z},CommonDialog:Ie};return Object.defineProperty(d,"__isScriptSetup",{enumerable:!1,value:!0}),d}});b(),X(),G();var is={class:`pd`},as={class:`pd__intro`},os={class:`pd__field`},ss={class:`pd__head`},cs={class:`pd__label`,for:`pd-global`},ls={class:`pd__count`},us=[`placeholder`],ds={class:`pd__field`},fs={class:`pd__head`},ps={class:`pd__label`,for:`pd-project`},ms={key:0,class:`pd__count`},hs=[`disabled`,`placeholder`],gs={class:`pd__hint`},_s={class:`pd__foot`},vs=[`disabled`];function ys(t,n,i,o,s,c){return A(),a(o.CommonDialog,{"model-value":i.modelValue,title:o.$t(`@WORKBENCH:默认提示词`),width:`min(640px, 94vw)`,"close-on-click-modal":!1,"onUpdate:modelValue":n[2]||=e=>o.emit(`update:modelValue`,e)},{footer:W(()=>[D(`div`,_s,[D(`button`,{type:`button`,class:`pd__btn`,onClick:o.close},e(o.$t(`@WORKBENCH:取消`)),1),n[3]||=D(`span`,{class:`pd__foot-spacer`},null,-1),D(`button`,{type:`button`,class:`pd__btn pd__btn--primary`,disabled:i.saving||!o.dirty,onClick:o.submit},e(i.saving?o.$t(`@WORKBENCH:保存中…`):o.$t(`@WORKBENCH:保存`)),9,vs)])]),default:W(()=>[D(`div`,is,[D(`p`,as,e(o.$t(`@WORKBENCH:派发指令时自动附加在指令之前,让每个任务都带上这些约束。只影响之后派发的任务,不会改动已经建好的任务。`)),1),D(`div`,os,[D(`div`,ss,[D(`label`,cs,e(o.$t(`@WORKBENCH:全局默认提示词`)),1),D(`span`,ls,e(o.globalDraft.length)+` / `+e(o.MAX_CHARS),1)]),L(D(`textarea`,{id:`pd-global`,"onUpdate:modelValue":n[0]||=e=>o.globalDraft=e,class:`pd__area`,rows:`5`,maxlength:o.MAX_CHARS,placeholder:o.$t(`@WORKBENCH:对所有项目生效。例如:回答用中文;改完代码必须跑一遍测试;不要动 dist 目录`)},null,8,us),[[z,o.globalDraft]])]),D(`div`,ds,[D(`div`,fs,[D(`label`,ps,e(o.hasProject?o.$t(`@WORKBENCH:「{name}」的项目提示词`,{name:i.projectName}):o.$t(`@WORKBENCH:项目提示词`)),1),o.hasProject?(A(),v(`span`,ms,e(o.projectDraft.length)+` / `+e(o.MAX_CHARS),1)):r(`v-if`,!0)]),L(D(`textarea`,{id:`pd-project`,"onUpdate:modelValue":n[1]||=e=>o.projectDraft=e,class:`pd__area`,rows:`5`,maxlength:o.MAX_CHARS,disabled:!o.hasProject,placeholder:o.hasProject?o.$t(`@WORKBENCH:只在这个项目派发时附加。例如:包管理器用 pnpm;改动集中在 src/ui 下`):o.$t(`@WORKBENCH:先在左侧选中一个具体项目,才能设置它的提示词`)},null,8,hs),[[z,o.projectDraft]]),D(`p`,gs,e(o.hasProject?o.$t(`@WORKBENCH:项目提示词追加在全局提示词之后(不覆盖全局),派发到「{name}」时一起带上`,{name:i.projectName}):o.$t(`@WORKBENCH:选中的是「全部项目」,落点由主 Agent 判断 —— 想给某个项目单设提示词,先选中它`)),1)])])]),_:1},8,[`model-value`,`title`])}var bs=Q(rs,[[`render`,ys],[`__scopeId`,`data-v-766f470f`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchDefaultPromptDialog.vue`]]);X(),R();var xs=s({__name:`WorkbenchTaskCreateDialog`,props:{modelValue:{type:Boolean,required:!0},projects:{type:Array,required:!0},defaultProjectPath:{type:String,required:!0}},emits:[`update:modelValue`,`created`],setup(e,{expose:t,emit:n}){t();let r=e,i=n,a=Y(``),o=Y(``),s=Y(``),c=Y(!1),l=Y(``);function u(e){let t=$(e);if(!t)return``;let n=r.projects.find(e=>$(e.path)===t);return n?n.path:``}P(()=>r.modelValue,e=>{e&&(a.value=``,o.value=``,s.value=u(r.defaultProjectPath),l.value=``,c.value=!1)});let d=q(()=>r.projects),f=q(()=>!c.value&&(a.value.trim().length>0||o.value.trim().length>0)),p=q(()=>{let e=$(s.value);if(!e)return``;let t=d.value.find(t=>$(t.path)===e);return t?t.name:``});async function m(e){if(f.value){c.value=!0,l.value=``;try{let t={title:a.value.trim(),desc:o.value,promptId:null,simpleOverride:``};s.value&&(t.projectPath=s.value);let n=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}).then(e=>e.json()).catch(()=>null);if(!n?.success){l.value=n?.error||Z(`@WORKBENCH:保存失败`);return}i(`update:modelValue`,!1),i(`created`,{task:n.task,openEditor:e})}finally{c.value=!1}}}let h={props:r,emit:i,title:a,desc:o,projectPath:s,submitting:c,error:l,matchOptionPath:u,projectOptions:d,canSubmit:f,projectName:p,submit:m,get $t(){return Z},CommonDialog:Ie};return Object.defineProperty(h,"__isScriptSetup",{enumerable:!1,value:!0}),h}});b(),X(),G();var Ss={class:`nc`},Cs={class:`nc__field`},ws={class:`nc__label`,for:`nc-project`},Ts={value:``},Es=[`value`],Ds=[`title`],Os={class:`nc__field`},ks={class:`nc__label`,for:`nc-title`},As=[`placeholder`],js={class:`nc__field`},Ms={class:`nc__label`,for:`nc-desc`},Ns=[`placeholder`],Ps={key:0,class:`nc__error`},Fs={class:`nc__foot`},Is=[`disabled`],Ls=[`disabled`];function Rs(t,n,i,o,s,c){return A(),a(o.CommonDialog,{"model-value":i.modelValue,title:o.$t(`@WORKBENCH:新建开发任务`),width:`min(600px, 94vw)`,"close-on-click-modal":!1,"onUpdate:modelValue":n[9]||=e=>o.emit(`update:modelValue`,e)},{footer:W(()=>[D(`div`,Fs,[D(`button`,{type:`button`,class:`nc__btn`,onClick:n[6]||=e=>o.emit(`update:modelValue`,!1)},e(o.$t(`@WORKBENCH:取消`)),1),n[10]||=D(`span`,{class:`nc__foot-spacer`},null,-1),D(`button`,{type:`button`,class:`nc__btn`,disabled:!o.canSubmit,onClick:n[7]||=e=>o.submit(!0)},e(o.$t(`@WORKBENCH:创建并打开编辑器`)),9,Is),D(`button`,{type:`button`,class:`nc__btn nc__btn--primary`,disabled:!o.canSubmit,onClick:n[8]||=e=>o.submit(!1)},e(o.submitting?o.$t(`@WORKBENCH:创建中…`):o.$t(`@WORKBENCH:创建`)),9,Ls)])]),default:W(()=>[D(`div`,Ss,[D(`div`,Cs,[D(`label`,ws,e(o.$t(`@WORKBENCH:项目`)),1),L(D(`select`,{id:`nc-project`,"onUpdate:modelValue":n[0]||=e=>o.projectPath=e,class:`nc__select`},[D(`option`,Ts,e(o.$t(`@WORKBENCH:跟随当前项目`)),1),(A(!0),v(I,null,S(o.projectOptions,t=>(A(),v(`option`,{key:t.key,value:t.path},e(t.name)+e(t.exists===!1?` · ${o.$t(`@WORKBENCH:目录不存在`)}`:``),9,Es))),128))],512),[[pe,o.projectPath]]),D(`p`,{class:`nc__hint`,title:o.projectPath},e(o.projectName?o.$t(`@WORKBENCH:任务会在「{name}」目录下执行`,{name:o.projectName}):o.$t(`@WORKBENCH:任务会跟随应用当前的工作目录`)),9,Ds)]),D(`div`,Os,[D(`label`,ks,e(o.$t(`@WORKBENCH:标题`)),1),L(D(`input`,{id:`nc-title`,"onUpdate:modelValue":n[1]||=e=>o.title=e,class:`nc__input`,type:`text`,maxlength:`200`,placeholder:o.$t(`@WORKBENCH:一句话说清要做什么`),onKeydown:n[2]||=K(J(e=>o.submit(!1),[`prevent`]),[`enter`])},null,40,As),[[z,o.title]])]),D(`div`,js,[D(`label`,Ms,e(o.$t(`@WORKBENCH:描述`)),1),L(D(`textarea`,{id:`nc-desc`,"onUpdate:modelValue":n[3]||=e=>o.desc=e,class:`nc__input nc__input--area`,rows:`6`,placeholder:o.$t(`@WORKBENCH:把背景、验收标准、相关文件路径写进来,执行时用它当上下文`),onKeydown:[n[4]||=K(J(e=>o.submit(!1),[`ctrl`,`prevent`]),[`enter`]),n[5]||=K(J(e=>o.submit(!1),[`meta`,`prevent`]),[`enter`])]},null,40,Ns),[[z,o.desc]])]),o.error?(A(),v(`p`,Ps,e(o.error),1)):r(`v-if`,!0)])]),_:1},8,[`model-value`,`title`])}var zs=Q(xs,[[`render`,Rs],[`__scopeId`,`data-v-c60e660a`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchTaskCreateDialog.vue`]]);X(),R();var Bs=`wb.boardProject.v1`,Vs=5e3,Hs=`wb.boardLayout.v1`,Us=180,Ws=420,Gs=260,Ks=900,qs=.26,Js=.46,Ys=120,Xs=560,Zs=.5,Qs=s({__name:`WorkbenchBoard`,emits:[`open-task`],setup(e,{expose:t,emit:n}){t();let r=n,{projects:i,boardTasks:a,currentProjectPath:o,loading:s,loadProjects:c}=Tr(),{active:l,activity:d,running:p,dispatching:m,togglingSchedule:h,defaultPrompt:g,projectPrompts:_,loadOrchestrator:v,setSchedulingActive:y,dispatch:b,saveDefaultPrompt:x,saveProjectPrompt:S}=Er(),w=Y((()=>{try{return localStorage.getItem(Bs)||``}catch{return``}})());P(w,e=>{try{localStorage.setItem(Bs,e)}catch{}});let T=q(()=>w.value&&i.value.find(e=>e.key===w.value)||null);P(i,e=>{w.value&&(e.some(e=>e.key===w.value)||(w.value=``))});let E=q(()=>{let e=new Map(i.value.map(e=>[e.key,e.name])),t={};for(let n of a.value)n.projectPath&&(t[n.projectPath]=e.get($(n.projectPath))||``);return t}),D=q(()=>{if(!w.value)return a.value;let e=w.value;return a.value.filter(t=>$(t.projectPath)===e)}),ee=q(()=>{let e=new Date;e.setHours(0,0,0,0);let t=e.getTime();return{projects:i.value.length,tasks:a.value.length,running:p.value.length,todayDone:d.value.filter(e=>e.kind===`done`&&e.at&&new Date(e.at).getTime()>=t).length}});function te(e){r(`open-task`,{taskId:e.id,projectPath:e.projectPath})}let ne=null,re=!1;async function k(e=!0){if(!re){re=!0;try{await Promise.all([c(e),v(e)])}finally{re=!1}}}function ie(){document.hidden||k(!0)}u(async()=>{window.addEventListener(`resize`,N),await k(!1),ne=setInterval(()=>{document.hidden||k(!0)},Vs),document.addEventListener(`visibilitychange`,ie)}),f(()=>{window.removeEventListener(`resize`,N),ne&&=(clearInterval(ne),null),document.removeEventListener(`visibilitychange`,ie)});let A=se({left:null,right:null,agentH:null,leftCollapsed:!1,rightCollapsed:!1});function ae(){try{let e=localStorage.getItem(Hs);if(!e)return;let t=JSON.parse(e);typeof t.left==`number`&&Number.isFinite(t.left)&&(A.left=t.left),typeof t.right==`number`&&Number.isFinite(t.right)&&(A.right=t.right),typeof t.agentH==`number`&&Number.isFinite(t.agentH)&&(A.agentH=t.agentH),A.leftCollapsed=t.leftCollapsed===!0,A.rightCollapsed=t.rightCollapsed===!0}catch{}}ae();function j(){try{localStorage.setItem(Hs,JSON.stringify(A))}catch{}}let M=Y(typeof window>`u`?1920:window.innerWidth),oe=Y(typeof window>`u`?1080:window.innerHeight);function N(){M.value=window.innerWidth,oe.value=window.innerHeight}let F=q(()=>M.value<=1024),ce=q(()=>M.value<=860);function I(e,t){let n=e===`left`?Us:Gs,r=Math.min(e===`left`?Ws:Ks,M.value*(e===`left`?qs:Js));return Math.round(Math.min(Math.max(t,n),Math.max(n,r)))}function L(e){let t=Math.min(Xs,oe.value*Zs);return Math.round(Math.min(Math.max(e,Ys),Math.max(Ys,t)))}let le=q(()=>{let e={};return A.left!=null&&(e[`--wb-left-w`]=I(`left`,A.left)+`px`),A.right!=null&&!ce.value&&(e[`--wb-right-w`]=I(`right`,A.right)+`px`),e}),ue=q(()=>{let e={};return A.agentH!=null&&(e[`--wb-agents-h`]=L(A.agentH)+`px`),e}),R=Y(null),de=Y(null),z=Y(null);function pe(e){return R.value?.querySelector(e===`left`?`.board__left`:`.oc`)}function me(e){window.removeEventListener(`mousemove`,e),document.body.style.userSelect=``,document.body.style.cursor=``,z.value=null,j()}function V(e,t){if(e===`left`?F.value:ce.value)return;let n=pe(e);if(!n)return;t.preventDefault();let r=t.clientX,i=n.getBoundingClientRect().width;z.value=e,document.body.style.userSelect=`none`,document.body.style.cursor=`col-resize`;let a=t=>{let n=(t.clientX-r)*(e===`left`?1:-1);A[e]=I(e,i+n)};window.addEventListener(`mousemove`,a),window.addEventListener(`mouseup`,()=>me(a),{once:!0})}function H(e){A[e]=null,j()}function he(){return de.value?.querySelector(`.agents`)}function U(e){let t=he();if(!t)return;e.preventDefault();let n=e.clientY,r=t.getBoundingClientRect().height;z.value=`agents`,document.body.style.userSelect=`none`,document.body.style.cursor=`row-resize`;let i=e=>{A.agentH=L(r+(n-e.clientY))};window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,()=>me(i),{once:!0})}function ge(){A.agentH=null,j()}let W=Y(!1),ve=q(()=>F.value?!W.value:A.leftCollapsed);function ye(){if(F.value){W.value=!W.value;return}A.leftCollapsed=!A.leftCollapsed,j()}function G(){F.value&&(W.value=!1)}let be=q(()=>A.rightCollapsed&&!ce.value);function xe(){A.rightCollapsed=!A.rightCollapsed,j()}function K(e){w.value=e?e.key:``,W.value=!1}let Ce=Y(!1);function we(){Ce.value=!0}async function Te(e){if(await k(!0),e.openEditor){r(`open-task`,{taskId:e.task.id,projectPath:e.task.projectPath||``});return}B.success(Z(`@WORKBENCH:已创建任务`))}async function J(e){if(e.runningJobs>0)return;let t=Le(),n={claude:t.claudeAvailable,opencode:t.opencodeAvailable,codex:t.codexAvailable},r=Me();n[r]||(r=Object.keys(n).find(e=>n[e])||r);let i=`/api/workbench/tasks/${encodeURIComponent(e.id)}/run`,a=await fetch(i,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({executor:r})}).then(e=>e.json()).catch(()=>null);if(!a?.success){B.error(a?.error||Z(`@WORKBENCH:执行失败`));return}B.success(Z(`@WORKBENCH:已开始执行`)),await k(!0)}async function X(e){let t=(e.title||``).trim()||Z(`@WORKBENCH:未命名任务`);try{await _e.confirm(Z(`@WORKBENCH:删除任务「{title}」?`,{title:t}),Z(`@WORKBENCH:确认`),{type:`warning`})}catch{return}let n=await fetch(`/api/workbench/tasks/${encodeURIComponent(e.id)}`,{method:`DELETE`}).then(e=>e.json()).catch(()=>null);if(n&&n.success===!1){B.error(n.error||Z(`@WORKBENCH:删除失败`));return}await k(!0)}let Ee=Y(null),De=q(()=>T.value?.path||o.value);async function Oe(e){let t=await b({text:e.text,projectPath:e.projectPath,autoRun:e.autoRun,attachments:e.attachments,useDefaultPrompt:e.useDefaultPrompt,executor:e.executor});t&&(Ee.value?.clearAttachments(),B.success(t.ran?Z(`@WORKBENCH:已派发并开始执行`):Z(`@WORKBENCH:已派发(只建任务未执行)`)),await k(!0))}async function ke(e){await y(e)}let Q=Y(!1),Ae=Y(!1),je=q(()=>{let e=T.value?.key;return e&&_.value?.[e]?.prompt||``});async function Ne(e){if(Ae.value)return;let t=e.globalPrompt.trim(),n=e.projectPrompt.trim(),r=T.value;Ae.value=!0;try{let e=!0;t!==(g.value||``).trim()&&(e=await x(t)),e&&r&&n!==je.value.trim()&&(e=await S(r.path,n)),e&&(Q.value=!1)}finally{Ae.value=!1}}let Pe={emit:r,projects:i,boardTasks:a,currentProjectPath:o,loading:s,loadProjects:c,active:l,activity:d,running:p,dispatching:m,togglingSchedule:h,defaultPrompt:g,projectPrompts:_,loadOrchestrator:v,setSchedulingActive:y,dispatch:b,saveDefaultPrompt:x,saveProjectPrompt:S,SELECTED_KEY:Bs,selectedKey:w,selectedProject:T,projectLabels:E,visibleTasks:D,headerStats:ee,onOpenTask:te,POLL_MS:Vs,get pollTimer(){return ne},set pollTimer(e){ne=e},get inFlight(){return re},set inFlight(e){re=e},refresh:k,onVisibilityChange:ie,LAYOUT_KEY:Hs,LEFT_W_MIN:Us,LEFT_W_MAX:Ws,RIGHT_W_MIN:Gs,RIGHT_W_MAX:Ks,LEFT_W_SHARE:qs,RIGHT_W_SHARE:Js,AGENT_H_MIN:Ys,AGENT_H_MAX:Xs,AGENT_H_SHARE:Zs,layout:A,readLayout:ae,saveLayout:j,viewportW:M,viewportH:oe,onWindowResize:N,isNarrow:F,isStacked:ce,clampWidth:I,clampAgentH:L,boardStyle:le,leftStyle:ue,colsRef:R,leftRef:de,dragging:z,panelEl:pe,endDrag:me,onSplitterMouseDown:V,onSplitterDblClick:H,agentEl:he,onAgentSplitterMouseDown:U,onAgentSplitterDblClick:ge,leftDrawerOpen:W,leftHidden:ve,toggleLeft:ye,onLeftEsc:G,rightHidden:be,toggleRight:xe,onSelectProject:K,createOpen:Ce,onCreateClick:we,onTaskCreated:Te,runTask:J,deleteTask:X,consoleRef:Ee,defaultProjectPath:De,onDispatch:Oe,onToggleSchedule:ke,promptDialogOpen:Q,savingPrompt:Ae,selectedProjectPrompt:je,onSavePromptDraft:Ne,get $t(){return Z},get Plus(){return C},get Refresh(){return O},get Fold(){return Se},get Expand(){return fe},WorkbenchProjectPanel:ta,WorkbenchAgentPanel:ga,WorkbenchKanban:ro,OrchestratorConsole:ts,WorkbenchDefaultPromptDialog:bs,WorkbenchTaskCreateDialog:zs};return Object.defineProperty(Pe,"__isScriptSetup",{enumerable:!1,value:!0}),Pe}});X(),b(),G();var $s={class:`board__top`},ec=[`title`,`aria-label`,`aria-expanded`],tc={class:`board__brand`},nc={class:`board__brand-text`},rc={class:`board__title`},ic={class:`board__subtitle`},ac={class:`board__stats`},oc={class:`board__stat`},sc={class:`board__stat-label`},cc={class:`board__stat-value`},lc={class:`board__stat`},uc={class:`board__stat-label`},dc={class:`board__stat-value`},fc={class:`board__stat`},pc={class:`board__stat-label`},mc={class:`board__stat`},hc={class:`board__stat-label`},gc={class:`board__stat-value`},_c={class:`board__actions`},vc=[`title`,`aria-label`],yc=[`title`],bc=[`title`],xc={class:`board__main`},Sc={class:`board__main-head`},Cc={class:`board__main-title`},wc={class:`board__project-name`},Tc=[`title`],Ec={key:1,class:`board__project-path`},Dc={key:0,class:`board__project-meta`},Oc=[`title`];function kc(t,n,i,o,s,c){let l=d,u=p;return A(),v(`div`,{class:`board`,style:j(o.boardStyle)},[D(`header`,$s,[r(` 左栏的开合。宽屏=收起/展开常驻那一栏;窄屏=抽屉 `),D(`button`,{type:`button`,class:U([`board__icon-btn board__fold-btn`,{"is-on":!o.leftHidden}]),title:o.leftHidden?o.$t(`@WORKBENCH:展开项目列表`):o.$t(`@WORKBENCH:收起项目列表`),"aria-label":o.leftHidden?o.$t(`@WORKBENCH:展开项目列表`):o.$t(`@WORKBENCH:收起项目列表`),"aria-expanded":!o.leftHidden,onClick:o.toggleLeft},[o.leftHidden?(A(),a(l,{key:1},{default:W(()=>[_(o.Expand)]),_:1})):(A(),a(l,{key:0},{default:W(()=>[_(o.Fold)]),_:1}))],10,ec),D(`div`,tc,[D(`span`,{class:U([`board__live`,{"is-off":!o.active}]),"aria-hidden":`true`},null,2),D(`div`,nc,[D(`h1`,rc,e(o.$t(`@WORKBENCH:多项目编排台`)),1),D(`p`,ic,e(o.active?o.$t(`@WORKBENCH:主 Agent 调度中`):o.$t(`@WORKBENCH:主 Agent 已暂停`)),1)])]),D(`div`,ac,[D(`span`,oc,[D(`span`,sc,e(o.$t(`@WORKBENCH:项目`)),1),D(`strong`,cc,e(o.headerStats.projects),1)]),D(`span`,lc,[D(`span`,uc,e(o.$t(`@WORKBENCH:任务`)),1),D(`strong`,dc,e(o.headerStats.tasks),1)]),D(`span`,fc,[D(`span`,pc,e(o.$t(`@WORKBENCH:活跃执行`)),1),D(`strong`,{class:U([`board__stat-value`,{"is-live":o.headerStats.running>0}])},e(o.headerStats.running),3)]),D(`span`,mc,[D(`span`,hc,e(o.$t(`@WORKBENCH:今日完成`)),1),D(`strong`,gc,e(o.headerStats.todayDone),1)])]),D(`div`,_c,[D(`button`,{type:`button`,class:`board__icon-btn`,title:o.$t(`@WORKBENCH:刷新`),"aria-label":o.$t(`@WORKBENCH:刷新`),onClick:n[0]||=e=>o.refresh(!1)},[_(l,null,{default:W(()=>[_(o.Refresh)]),_:1})],8,vc),_(u,{type:`primary`,size:`small`,icon:o.Plus,onClick:o.onCreateClick},{default:W(()=>[g(e(o.$t(`@WORKBENCH:新建开发任务`)),1)]),_:1},8,[`icon`])])]),D(`div`,{ref:`colsRef`,class:U([`board__cols`,{"is-resizing":o.dragging!==null}])},[r(` 抽屉打开时的点击捕获层:点空白处收起。
42
+ 只在窄屏 + 打开时才 display:block(见媒体查询),宽屏下是个不占位的空 div。
43
+ 不加遮罩底色而是全透明 —— 只是为了接住点击,不是为了压暗看板;
44
+ 真要压暗就得处理深色主题下半透明背景叠不实的老问题(见 NOTES §2)。 `),D(`div`,{class:U([`board__scrim`,{"is-on":o.leftDrawerOpen}]),"aria-hidden":`true`,onClick:n[1]||=e=>o.leftDrawerOpen=!1},null,2),D(`aside`,{ref:`leftRef`,class:U([`board__left`,{"is-collapsed":o.leftHidden}]),style:j(o.leftStyle),onKeydown:K(o.onLeftEsc,[`esc`])},[_(o.WorkbenchProjectPanel,{projects:o.projects,"selected-key":o.selectedKey,loading:o.loading,onSelect:o.onSelectProject},null,8,[`projects`,`selected-key`,`loading`]),r(` 项目列表 / 执行监控之间的横向分隔条:上下拖动改监控高度,双击恢复默认。
45
+ 这条同时也画出两段之间的那条 1px 分隔线(原来挂在 .agents 的 border-top 上)。 `),D(`div`,{class:`board__splitter board__splitter--h`,role:`separator`,"aria-orientation":`horizontal`,title:o.$t(`@WORKBENCH:上下拖动调整执行监控高度,双击恢复默认`),onMousedown:o.onAgentSplitterMouseDown,onDblclick:o.onAgentSplitterDblClick},null,40,yc),_(o.WorkbenchAgentPanel,{running:o.running},null,8,[`running`])],38),r(` 左栏分隔条:左栏收起 / 窄屏抽屉模式下不占位(不渲染 / 媒体查询里 display:none) `),o.leftHidden?r(`v-if`,!0):(A(),v(`div`,{key:0,class:`board__splitter board__splitter--left`,role:`separator`,"aria-orientation":`vertical`,title:o.$t(`@WORKBENCH:拖动调整项目列表宽度,双击恢复默认`),onMousedown:n[2]||=e=>o.onSplitterMouseDown(`left`,e),onDblclick:n[3]||=e=>o.onSplitterDblClick(`left`)},null,40,bc)),D(`main`,xc,[D(`div`,Sc,[D(`div`,Cc,[D(`h2`,wc,e(o.selectedProject?o.selectedProject.name:o.$t(`@WORKBENCH:全部项目`)),1),o.selectedProject?(A(),v(`span`,{key:0,class:`board__project-path`,title:o.selectedProject.path},e(o.selectedProject.path),9,Tc)):(A(),v(`span`,Ec,e(o.$t(`@WORKBENCH:共 {n} 个项目的任务`,{n:o.projects.length})),1))]),o.selectedProject?(A(),v(`span`,Dc,e(o.$t(`@WORKBENCH:{done}/{total} 任务完成`,{done:o.selectedProject.stats.done,total:o.selectedProject.stats.total})),1)):r(`v-if`,!0)]),_(o.WorkbenchKanban,{tasks:o.visibleTasks,"project-labels":o.projectLabels,"show-project-label":!o.selectedProject,onOpenTask:o.onOpenTask,onRunTask:o.runTask,onDeleteTask:o.deleteTask,onCreateTask:o.onCreateClick},null,8,[`tasks`,`project-labels`,`show-project-label`])]),r(` 右栏分隔条:右栏收起 / 竖排(≤860)时不占位 `),!o.rightHidden&&!o.isStacked?(A(),v(`div`,{key:1,class:`board__splitter board__splitter--right`,role:`separator`,"aria-orientation":`vertical`,title:o.$t(`@WORKBENCH:拖动调整主 Agent 控制台宽度,双击恢复默认`),onMousedown:n[4]||=e=>o.onSplitterMouseDown(`right`,e),onDblclick:n[5]||=e=>o.onSplitterDblClick(`right`)},null,40,Oc)):r(`v-if`,!0),_(o.OrchestratorConsole,{ref:`consoleRef`,active:o.active,activity:o.activity,"running-count":o.running.length,"selected-project":o.selectedProject,dispatching:o.dispatching,"toggling-schedule":o.togglingSchedule,"today-done":o.headerStats.todayDone,collapsed:o.rightHidden,"default-prompt":o.defaultPrompt,"project-prompts":o.projectPrompts,onToggleCollapse:o.toggleRight,onToggleSchedule:o.onToggleSchedule,onDispatch:o.onDispatch,onOpenPromptSettings:n[6]||=e=>o.promptDialogOpen=!0},null,8,[`active`,`activity`,`running-count`,`selected-project`,`dispatching`,`toggling-schedule`,`today-done`,`collapsed`,`default-prompt`,`project-prompts`])],2),r(` 派发默认提示词:全局一条 + 选中项目一条,写完即生效于之后的派发 `),_(o.WorkbenchDefaultPromptDialog,{modelValue:o.promptDialogOpen,"onUpdate:modelValue":n[7]||=e=>o.promptDialogOpen=e,"default-prompt":o.defaultPrompt,"project-path":o.selectedProject?.path||``,"project-name":o.selectedProject?.name||``,"project-prompt":o.selectedProjectPrompt,saving:o.savingPrompt,onSave:o.onSavePromptDraft},null,8,[`modelValue`,`default-prompt`,`project-path`,`project-name`,`project-prompt`,`saving`]),r(` 新建任务:弹窗里问清字段,建完就关 `),_(o.WorkbenchTaskCreateDialog,{modelValue:o.createOpen,"onUpdate:modelValue":n[8]||=e=>o.createOpen=e,projects:o.projects,"default-project-path":o.defaultProjectPath,onCreated:o.onTaskCreated},null,8,[`modelValue`,`projects`,`default-project-path`])],4)}var Ac=Q(Qs,[[`render`,kc],[`__scopeId`,`data-v-dd2dc7b4`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/components/WorkbenchBoard.vue`]]);X(),R();var jc=`wb.lastTaskByProject.v1`,Mc=`__no_project__`,Nc=`wb.sidebarWidth.v1`,Pc=200,Fc=480,Ic=268,Lc=52,Rc=320,zc=500,Bc=s({__name:`WorkbenchView`,setup(e,{expose:t}){t();let n=Fe(),r=Le(),i=Y((()=>{try{let e=parseInt(localStorage.getItem(Nc)||``,10);return Number.isFinite(e)?Math.min(Fc,Math.max(Pc,e)):Ic}catch{return Ic}})());function a(e){e.preventDefault();let t=e.clientX,n=i.value;document.body.style.userSelect=`none`,document.body.style.cursor=`col-resize`;let r=e=>{i.value=Math.min(Fc,Math.max(Pc,n+e.clientX-t))};window.addEventListener(`mousemove`,r),window.addEventListener(`mouseup`,()=>{window.removeEventListener(`mousemove`,r),document.body.style.userSelect=``,document.body.style.cursor=``;try{localStorage.setItem(Nc,String(i.value))}catch{}},{once:!0})}function o(){try{let e=localStorage.getItem(jc),t=e?JSON.parse(e):{};return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}}function s(e){try{localStorage.setItem(jc,JSON.stringify(e))}catch{}}function c(e,t){let n=o();n[e||Mc]=t,s(n)}let d=Y(!1);function p(){d.value=!1}async function m(e){await E(),O.value=e.taskId,j(),k.value&&c($(v.value.path),e.taskId),d.value=!0}let{prompts:h,tasks:g,jobs:_,currentProject:v,syncRunningCount:y,connectSSE:b,disconnectSSE:x,loadPrompts:S,loadCurrentProject:C,loadJobs:w,clearJobsByTask:T,loadTasks:E}=Ln();function D(){let e=$(v.value.path),t=g.value.filter(t=>!t.projectPath||$(t.projectPath)===e),n=o(),r=e&&n[e]||!e&&n[Mc]||``,i=r?g.value.find(e=>e.id===r):null,a=t[0]||g.value[0]||null,s=i&&i.projectPath&&$(i.projectPath)!==e?null:i?i.id:a?a.id:null;O.value=s,j()}async function ee(){let e=O.value;if(await E(),e&&g.value.some(t=>t.id===e)){j();return}D()}async function te(){await E(),D()}let re=Y(!1),O=Y(null),k=q(()=>g.value.find(e=>e.id===O.value)||null),ie=q(()=>{let e=k.value?.projectPath||``;return!e||$(e)===$(v.value.path)?null:{name:e.replace(/[\\/]+$/,``).split(/[\\/]/).pop()||e,path:e}}),A=Y({title:``,desc:``,promptId:null,simpleOverride:``});function j(){k.value?A.value={title:k.value.title,desc:k.value.desc,promptId:k.value.promptId,simpleOverride:k.value.simpleOverride||``}:A.value={title:``,desc:``,promptId:null,simpleOverride:``}}let M=Y(`idle`),oe=Y(0),N=null,F=q(()=>{if(!k.value)return!1;let e=k.value;return A.value.title!==e.title||A.value.desc!==e.desc||A.value.promptId!==e.promptId||A.value.simpleOverride!==(e.simpleOverride||``)});function ce(){N!==null&&(clearTimeout(N),N=null)}function I(e){return!(!e||(e.title||``).trim()||(e.desc||``).trim()||e.promptId||(e.simpleOverride||``).trim()||Array.isArray(e.attachments)&&e.attachments.length>0)}async function L(e){try{await fetch(`/api/workbench/tasks/${e.id}`,{method:`DELETE`})}catch{}let t=g.value.findIndex(t=>t.id===e.id);t!==-1&&g.value.splice(t,1)}async function R(){let e=g.value.filter(e=>e.id!==O.value&&I(e));for(let t of e)await L(t)}async function z(){if(!k.value)return!1;if(!F.value)return!0;if(M.value=`saving`,await Xe(!1))return oe.value=Date.now(),M.value=`saved`,setTimeout(()=>{M.value===`saved`&&Date.now()-oe.value>=4e3&&(M.value=`idle`)},4e3),!0;M.value=`error`;let e=Date.now();return setTimeout(()=>{M.value===`error`&&Date.now()-e>=4e3&&(M.value=`idle`)},4e3),!1}P(()=>k.value?{id:k.value.id,title:k.value.title,desc:k.value.desc,promptId:k.value.promptId,simpleOverride:k.value.simpleOverride||``}:null,(e,t)=>{e&&t&&e.id===t.id&&(N!==null&&clearTimeout(N),N=window.setTimeout(()=>{z()},1500))},{deep:!0}),P(O,async(e,t)=>{ce(),k.value&&F.value&&await z()}),P(v,async e=>{if(!e.path)return;let t=$(e.path),n=k.value;n&&n.projectPath&&$(n.projectPath)!==t&&await te()});function fe(e){try{let t=new Blob([JSON.stringify(e)],{type:`application/json`});navigator.sendBeacon?.(`/api/workbench/tasks`,t)}catch{}}function pe(){k.value&&F.value&&!I(k.value)&&fe(k.value)}let V=se({visible:!1,editing:null,name:``,content:``,aiLoading:!1,projectPath:``}),H=se({visible:!1,text:``,loading:!1,saving:!1}),U=Y(!0),ge=q(()=>{let e=$(v.value.path);return h.value.filter(t=>!t.projectPath||$(t.projectPath)===e)});async function W(e){try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0}catch{}try{let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.left=`-9999px`,document.body.appendChild(t),t.select();let n=document.execCommand(`copy`);return document.body.removeChild(t),n}catch{return!1}}let ye=Y(null),G=Y(null);async function be(e){if(e){if(!await W((e.title||``).trim()||Z(`@WORKBENCH:未命名任务`))){B.error(Z(`@WORKBENCH:复制失败`));return}ye.value=e.id,B.success(Z(`@WORKBENCH:已复制任务标题`)),window.setTimeout(()=>{ye.value===e.id&&(ye.value=null)},1500)}}async function xe(e){if(!e)return;let t=(e.desc||``).trim();if(!t){B.warning(Z(`@WORKBENCH:任务描述为空,无需复制`));return}if(!await W(t)){B.error(Z(`@WORKBENCH:复制失败`));return}G.value=e.id,B.success(Z(`@WORKBENCH:已复制任务描述`)),window.setTimeout(()=>{G.value===e.id&&(G.value=null)},1500)}let{simpleConversationMessages:K,simpleAllJobsFor:Se,simpleJobFor:Ce,simpleJobState:we}=Fn(_,k);function Te(e){if(!e)return!1;let t=Ce(e);return!!t&&(t.status===`running`||t.status===`pending`)}function J(){V.editing=null,V.name=``,V.content=``,V.aiLoading=!1,V.projectPath=(v.value.path||``).trim(),V.visible=!0}function X(e){V.editing=e,V.name=e.name,V.content=e.content,V.aiLoading=!1,V.projectPath=(e.projectPath||``).trim(),V.visible=!0}async function Oe(){if(!V.aiLoading){V.aiLoading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-generate`,{method:`POST`}).then(e=>e.json());e.success?(V.name=e.name||V.name,V.content=e.result||``,B.success(Z(`@WORKBENCH:已生成,可继续编辑`))):B.error(e.error||Z(`@WORKBENCH:生成失败`))}catch(e){B.error(Z(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{V.aiLoading=!1}}}async function ke(){H.visible=!0,H.loading=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`).then(e=>e.json());e.success?H.text=e.instruction||``:B.error(e.error||Z(`@WORKBENCH:读取指令失败`))}catch(e){B.error(Z(`@WORKBENCH:读取指令失败`)+`: `+(e&&e.message||e))}finally{H.loading=!1}}async function Q(){if(!H.text.trim()){B.warning(Z(`@WORKBENCH:指令内容不能为空`));return}H.saving=!0;try{let e=await fetch(`/api/workbench/prompts/ai-instruction`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({instruction:H.text})}).then(e=>e.json());e.success?(B.success(Z(`@WORKBENCH:已保存指令`)),H.visible=!1):B.error(e.error||Z(`@WORKBENCH:保存失败`))}catch(e){B.error(Z(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}finally{H.saving=!1}}async function Ae(){if(!V.name.trim()||!V.content.trim()){B.warning(Z(`@WORKBENCH:名称和内容不能为空`));return}let e={id:V.editing?.id,name:V.name.trim(),content:V.content,projectPath:(V.projectPath||``).trim()},t=await fetch(`/api/workbench/prompts`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>e.json());t.success?(B.success(Z(`@WORKBENCH:已保存`)),V.visible=!1,S()):B.error(t.error||Z(`@WORKBENCH:保存失败`))}async function ze(e){await _e.confirm(Z(`@WORKBENCH:删除提示词「{name}」?`,{name:e.name}),Z(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/prompts/${e.id}`,{method:`DELETE`}),S();for(let t of g.value)t.promptId===e.id&&(t.promptId=null,await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}));await ee()}let Be=Y(!1),Ve=Y(null),He=Y(null);function Ue(e){let t=e?.currentTarget||He.value;if(!t)return;t.style.height=`auto`;let n=document.activeElement===t?zc:Rc,r=Math.min(Math.max(t.scrollHeight,Lc),n);t.style.height=`${r}px`,t.style.overflowY=t.scrollHeight>n?`auto`:`hidden`}P(U,async e=>{e&&(await ne(),Ue())}),P(()=>k.value?.id,async()=>{U.value&&(await ne(),Ue())});async function We(){if(Be.value)return;Be.value=!0;let e={title:``,desc:``,promptId:null,simpleOverride:``};v.value.path&&(e.projectPath=v.value.path);try{let t=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>e.json());if(!t.success){B.error(t.error||Z(`@WORKBENCH:保存失败`));return}ce(),k.value&&I(k.value)?await L(k.value):k.value&&F.value&&await z(),await te(),t.task?.id&&(O.value=t.task.id,j(),B.success(Z(`@WORKBENCH:已新建任务`)),await ne(),Ve.value?.focus())}finally{Be.value=!1}}async function Ge(e){await _e.confirm(Z(`@WORKBENCH:删除任务「{title}」?`,{title:e.title}),Z(`@WORKBENCH:确认`),{type:`warning`}),await fetch(`/api/workbench/tasks/${e.id}`,{method:`DELETE`}),O.value===e.id&&(O.value=null),te()}async function Ke(e){let t=(e.title||Z(`@WORKBENCH:未命名任务`)).trim(),n={title:Z(`@WORKBENCH:{title} (副本)`,{title:t}),desc:e.desc||``,promptId:e.promptId||null,simpleOverride:e.simpleOverride||``};v.value.path&&(n.projectPath=v.value.path);try{let e=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)}).then(e=>e.json());if(!e.success){B.error(e.error||Z(`@WORKBENCH:复制失败`));return}await te(),e.task?.id&&(O.value=e.task.id,j()),B.success(Z(`@WORKBENCH:已复制任务`))}catch(e){B.error(Z(`@WORKBENCH:网络错误: `)+(e&&e.message||e))}}async function qe(e){if(O.value===e.id)return;ce();let t=k.value;t&&I(t)?await L(t):t&&F.value&&await z(),O.value=e.id,j(),c($(v.value.path),e.id)}async function Je(e){let{groupPath:t,orderedIds:n}=e;if(!Array.isArray(n)||n.length===0)return;let r=g.value.slice(),i=Ye(g.value,t,n);if(i!==g.value){g.value=i;try{let e=await fetch(`/api/workbench/tasks/reorder`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({orderedIds:n,groupPath:t})}).then(e=>e.json()).catch(()=>({success:!1,error:Z(`@WORKBENCH:排序保存失败`)}));e?.success||(g.value=r,B.error(e?.error||Z(`@WORKBENCH:排序保存失败`)))}catch(e){g.value=r,B.error(Z(`@WORKBENCH:排序保存失败`)+`: `+(e?.message||e))}}}function Ye(e,t,n){let r=e=>$(e)||Mc,i=e.filter(e=>r(e.projectPath)===t).map(e=>e.id),a=new Set(i);if(n.length!==a.size||n.some(e=>!a.has(e)))return e;let o=new Map(e.map(e=>[e.id,e])),s=n.map(e=>o.get(e)).filter(Boolean),c=[],l=0;for(let n of e)r(n.projectPath)===t?c.push(s[l++]):c.push(n);return c}async function Xe(e){if(!k.value)return!1;let t=await fetch(`/api/workbench/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(k.value)}).then(e=>e.json());return t.success?(e&&B.success(Z(`@WORKBENCH:已保存`)),await ee(),!0):(B.error(t.error||Z(`@WORKBENCH:保存失败`)),!1)}u(async()=>{await Promise.all([S(),te(),C(),w()]),await R(),b(),window.addEventListener(`beforeunload`,pe)}),f(()=>{x(),window.removeEventListener(`beforeunload`,pe),k.value&&F.value&&!I(k.value)&&fe(k.value)});let{pasteHoverId:Ze,isUploading:Qe,isImageAttachment:$e,humanSize:et,onAttachmentPaste:tt,onAttachmentDrop:nt,uploadAttachment:rt,removeAttachment:it,pickAttachmentFile:at}=Mn(),{runTask:ot,onContinueSendFromChat:st,cancelJob:ct,clearExecutionForSelectedTask:ut}=In(_,g,k,{syncRunningCount:y,clearJobsByTask:T,persistTask:Xe,uploadAttachment:rt,getExecutor:()=>dt.value}),dt=Y(Me()),ft=q(()=>({claude:r.claudeAvailable,opencode:r.opencodeAvailable,codex:r.codexAvailable})),mt=q(()=>Pe.some(e=>ft.value[e.id]));P(ft,e=>{if(e[dt.value])return;let t=Object.keys(e).find(t=>e[t]);t&&(dt.value=t)},{immediate:!0});function ht(e){ft.value[e]&&(dt.value=e,je(e))}function gt(e){return Ne(e)}let _t=q(()=>Se(k.value).slice(-1)[0]),vt={configStore:n,toolsStore:r,LAST_TASK_BY_PROJECT_KEY:jc,NO_PROJECT_KEY:Mc,SIDEBAR_WIDTH_KEY:Nc,SIDEBAR_MIN_W:Pc,SIDEBAR_MAX_W:Fc,SIDEBAR_DEFAULT_W:Ic,sidebarWidth:i,onSidebarSplitterMouseDown:a,readLastTaskMap:o,writeLastTaskMap:s,rememberLastTask:c,editorOpen:d,closeEditor:p,openTaskFromBoard:m,prompts:h,tasks:g,jobs:_,currentProject:v,syncRunningCount:y,connectSSE:b,disconnectSSE:x,loadPrompts:S,loadCurrentProject:C,loadJobs:w,clearJobsByTask:T,_loadDataTasks:E,applyRestoredSelection:D,refreshTasks:ee,loadTasks:te,logsDialogVisible:re,selectedTaskId:O,selectedTask:k,foreignRepo:ie,metaSnapshot:A,captureSnapshot:j,metaSaveState:M,metaSavedAt:oe,get metaSaveTimer(){return N},set metaSaveTimer(e){N=e},metaDirty:F,clearMetaSaveTimers:ce,isTaskBlank:I,discardBlankTask:L,pruneBlankTasks:R,flushMetaSave:z,beaconPersist:fe,onBeforeUnloadPersist:pe,promptDialog:V,instructionDialog:H,taskDescExpanded:U,availablePrompts:ge,copyToClipboard:W,copyTitleFlashId:ye,copyDescFlashId:G,copyTaskTitle:be,copyTaskDesc:xe,simpleConversationMessages:K,simpleAllJobsFor:Se,simpleJobFor:Ce,simpleJobState:we,isTaskRunning:Te,openCreatePrompt:J,openEditPrompt:X,aiGeneratePrompt:Oe,openEditInstruction:ke,saveInstruction:Q,savePrompt:Ae,deletePrompt:ze,creatingTask:Be,titleInputRef:Ve,taskDescTextareaRef:He,DESC_TEXTAREA_MIN_PX:Lc,DESC_TEXTAREA_MAX_PX:Rc,DESC_TEXTAREA_MAX_PX_FOCUS:zc,autoGrowTextarea:Ue,createTaskDirect:We,deleteTask:Ge,copyTask:Ke,selectTask:qe,reorderTasks:Je,applyLocalReorder:Ye,persistTask:Xe,pasteHoverId:Ze,isUploading:Qe,isImageAttachment:$e,humanSize:et,onAttachmentPaste:tt,onAttachmentDrop:nt,uploadAttachment:rt,removeAttachment:it,pickAttachmentFile:at,runTask:ot,onContinueSendFromChat:st,cancelJob:ct,clearExecutionForSelectedTask:ut,selectedTaskExecutor:dt,executorAvailability:ft,hasAnyExecutor:mt,pickExecutor:ht,executorLabel:gt,lastSimpleJob:_t,simpleAssistantLabel:q(()=>Ne(_t.value?.agent)),simpleAssistantAvatar:q(()=>pt(_t.value?.agent)),get $t(){return Z},get ArrowDown(){return he},get ArrowLeft(){return l},get ArrowRight(){return ae},get Check(){return ue},get Document(){return de},get Delete(){return le},get CopyDocument(){return ve},get Warning(){return me},AttachmentZone:lt,get ChatInput(){return Ee},get ChatContainer(){return De},ExecutionLogManager:xn,get ALLOWED_EXT_HINT(){return Cn},get MAX_ATTACHMENT_BYTES(){return wn},get TASK_EXECUTOR_OPTIONS(){return Pe},TaskExecutorIcon:Re,WorkbenchSidebar:wr,WorkbenchBoard:Ac,CommonDialog:Ie};return Object.defineProperty(vt,"__isScriptSetup",{enumerable:!1,value:!0}),vt}});X(),b(),G();var Vc={class:`workbench`},Hc={class:`wb-editor`},Uc={class:`wb-editor-bar`},Wc=[`title`],Gc=[`title`],Kc=[`title`],qc={class:`wb-editor-bar__hint`},Jc={class:`workbench__editor-row`},Yc=[`title`],Xc={class:`wb-split`},Zc={key:0,class:`wb-placeholder`},Qc={class:`wb-split__header`},$c={class:`wb-split__title-wrap`},el=[`placeholder`],tl=[`title`,`aria-label`],nl=[`title`],rl={key:0,class:`wb-meta-save__dot`},il={key:1,class:`wb-meta-save__check`},al={key:2,class:`wb-meta-save__bang`},ol={key:3,class:`wb-meta-save__dot`},sl={value:null},cl=[`value`],ll={class:`wb-executor-split__hint`},ul={class:`wb-executor-item`},dl={class:`wb-executor-item__name`},fl={key:1,class:`wb-executor-item__missing`},pl={key:2,class:`wb-no-claude-hint`,role:`status`},ml={class:`wb-no-claude-hint__text`},hl={class:`wb-no-claude-hint__link`,href:`https://docs.claude.com/en/docs/claude-code/setup`,target:`_blank`,rel:`noopener noreferrer`},gl=[`title`,`aria-label`],_l=[`title`,`aria-label`],vl=[`open`],yl={class:`wb-task-desc__summary`},bl={class:`wb-task-desc__label`},xl=[`title`,`aria-label`],Sl={key:0,class:`wb-task-desc__tag`},Cl={key:0},wl={key:1,class:`wb-task-desc__tag-attachment`},Tl=[`placeholder`],El={class:`wb-execution-body`},Dl={class:`wb-exec-detail`},Ol={class:`wb-form-item__label wb-simple__override-summary`},kl=[`title`],Al=[`placeholder`],jl={key:0,class:`wb-simple-chat-wrap`},Ml={key:0,class:`wb-simple-chat__footer`},Nl={style:{display:`flex`,gap:`8px`,"align-items":`center`}};function Pl(t,s,c,l,u,f){let m=d,h=n,b=Ce,x=w,C=i,T=re,E=k,ee=y,ne=o,O=p,ie=te;return A(),v(`div`,Vc,[r(` L1:多项目编排台 —— **常驻底图**,不再与编辑器互斥 `),_(l.WorkbenchBoard,{onOpenTask:l.openTaskFromBoard}),r(` L2:单任务编辑器 —— 大弹窗浮在看板之上,关掉即回到原位,全程无跳转 `),_(l.CommonDialog,{modelValue:l.editorOpen,"onUpdate:modelValue":s[21]||=e=>l.editorOpen=e,title:l.$t(`@WORKBENCH:任务执行`),type:`flex`,"height-mode":`fixed`,"height-offset":`88px`,top:`2vh`,width:`min(1520px, 96vw)`},{default:W(()=>[D(`div`,Hc,[r(` 顶部细栏:关闭入口做成独立一条,而不是塞进任务头 ——
46
+ 没选中任务时(右侧是空态占位)也需要它,塞进任务头就会出现"进了编辑器却关不掉"的死角。 `),D(`div`,Uc,[D(`button`,{type:`button`,class:`wb-back-btn`,title:l.$t(`@WORKBENCH:返回看板`),onClick:l.closeEditor},[_(m,{class:`wb-back-btn__icon`},{default:W(()=>[_(l.ArrowLeft)]),_:1}),D(`span`,null,e(l.$t(`@WORKBENCH:返回看板`)),1)],8,Wc),D(`span`,{class:`wb-editor-bar__project`,title:l.currentProject.path},e(l.currentProject.name),9,Gc),l.foreignRepo?(A(),v(`span`,{key:0,class:`wb-editor-bar__repo`,title:l.foreignRepo.path},e(l.$t(`@WORKBENCH:执行于 {name}`,{name:l.foreignRepo.name})),9,Kc)):r(`v-if`,!0),D(`span`,qc,e(l.$t(`@WORKBENCH:任务执行`)),1)]),D(`div`,Jc,[_(l.WorkbenchSidebar,{style:j({width:l.sidebarWidth+`px`}),tasks:l.tasks,prompts:l.prompts,"selected-task-id":l.selectedTaskId,"current-project":l.currentProject,"creating-task":l.creatingTask,"is-task-running":l.isTaskRunning,onSelectTask:l.selectTask,onDeleteTask:l.deleteTask,onCopyTask:l.copyTask,onCreateTask:l.createTaskDirect,onOpenCreatePrompt:l.openCreatePrompt,onOpenEditPrompt:l.openEditPrompt,onDeletePrompt:l.deletePrompt,onReorderTasks:l.reorderTasks},null,8,[`style`,`tasks`,`prompts`,`selected-task-id`,`current-project`,`creating-task`]),D(`div`,{class:`wb-splitter`,role:`separator`,"aria-orientation":`vertical`,title:l.$t(`@WORKBENCH:拖动调整侧边栏宽度`),onMousedown:l.onSidebarSplitterMouseDown},null,40,Yc),r(` 中:单任务编辑区 `),D(`section`,Xc,[l.selectedTask?(A(),v(I,{key:1},[D(`div`,Qc,[D(`div`,$c,[L(D(`input`,{ref:`titleInputRef`,class:`wb-input wb-input--title`,"onUpdate:modelValue":s[0]||=e=>l.selectedTask.title=e,placeholder:l.$t(`@WORKBENCH:任务标题`)},null,8,el),[[z,l.selectedTask.title]]),D(`button`,{type:`button`,class:U([`wb-copy-btn`,{"is-flash":l.copyTitleFlashId===l.selectedTask.id}]),title:l.$t(`@WORKBENCH:复制任务标题`),"aria-label":l.$t(`@WORKBENCH:复制任务标题`),onClick:s[1]||=e=>l.copyTaskTitle(l.selectedTask)},[l.copyTitleFlashId===l.selectedTask.id?(A(),a(m,{key:1,class:`wb-copy-btn__icon wb-copy-btn__icon--check`},{default:W(()=>[...s[31]||=[g(`✓`,-1)]]),_:1})):(A(),a(m,{key:0,class:`wb-copy-btn__icon`},{default:W(()=>[_(l.CopyDocument)]),_:1}))],10,tl)]),l.metaSaveState!==`idle`||l.metaDirty?(A(),v(`span`,{key:0,class:U([`wb-meta-save`,{"is-saving":l.metaSaveState===`saving`,"is-saved":l.metaSaveState===`saved`,"is-error":l.metaSaveState===`error`,"is-dirty":l.metaDirty&&l.metaSaveState===`idle`}]),title:l.metaSaveState===`saving`?l.$t(`@WORKBENCH:保存中…`):l.metaSaveState===`error`?l.$t(`@WORKBENCH:保存失败`):l.metaSaveState===`saved`?l.$t(`@WORKBENCH:已保存`):``},[l.metaSaveState===`saving`?(A(),v(`span`,rl)):l.metaSaveState===`saved`?(A(),v(`span`,il,`✓`)):l.metaSaveState===`error`?(A(),v(`span`,al,`!`)):(A(),v(`span`,ol)),g(` `+e(l.metaSaveState===`saving`?l.$t(`@WORKBENCH:保存中…`):l.metaSaveState===`saved`?l.$t(`@WORKBENCH:已保存`):l.metaSaveState===`error`?l.$t(`@WORKBENCH:保存失败`):l.$t(`@WORKBENCH:有未保存的更改`)),1)],10,nl)):r(`v-if`,!0),L(D(`select`,{class:`wb-select`,"onUpdate:modelValue":s[2]||=e=>l.selectedTask.promptId=e},[D(`option`,sl,e(l.$t(`@WORKBENCH:不绑定预置提示词`)),1),(A(!0),v(I,null,S(l.availablePrompts,t=>(A(),v(`option`,{key:t.id,value:t.id},e(t.name),9,cl))),128))],512),[[pe,l.selectedTask.promptId]]),r(` 执行:split button —— 主体按当前选中执行器直接跑,下拉临时切换执行器 `),l.hasAnyExecutor?(A(),a(x,{key:1,"split-button":``,type:`primary`,class:`wb-executor-split`,trigger:`click`,onClick:s[3]||=e=>l.runTask(l.selectedTask),onCommand:l.pickExecutor},{dropdown:W(()=>[_(b,null,{default:W(()=>[(A(!0),v(I,null,S(l.TASK_EXECUTOR_OPTIONS,t=>(A(),a(h,{key:t.id,command:t.id,disabled:!l.executorAvailability[t.id]},{default:W(()=>[D(`span`,ul,[_(l.TaskExecutorIcon,{executor:t.id,class:`wb-executor-item__icon`},null,8,[`executor`]),D(`span`,dl,e(t.name),1),l.selectedTaskExecutor===t.id?(A(),a(m,{key:0,class:`wb-executor-item__check`},{default:W(()=>[_(l.Check)]),_:1})):l.executorAvailability[t.id]?r(`v-if`,!0):(A(),v(`span`,fl,e(l.$t(`@42BB9:未安装`)),1))])]),_:2},1032,[`command`,`disabled`]))),128))]),_:1})]),default:W(()=>[g(e(l.$t(`@WORKBENCH:执行任务`))+` `,1),D(`span`,ll,[_(l.TaskExecutorIcon,{executor:l.selectedTaskExecutor,class:`wb-executor-split__hint-icon`},null,8,[`executor`]),g(` `+e(l.executorLabel(l.selectedTaskExecutor)),1)])]),_:1})):(A(),v(`div`,pl,[_(m,{class:`wb-no-claude-hint__icon`},{default:W(()=>[_(l.Warning)]),_:1}),D(`span`,ml,e(l.$t(`@WORKBENCH:未检测到本地 claude / opencode,无法执行任务`)),1),D(`a`,hl,e(l.$t(`@WORKBENCH:查看安装指引`)),1)])),D(`button`,{type:`button`,class:`wb-logs-inline-btn wb-logs-inline-btn--danger`,title:l.$t(`@WORKBENCH:清空当前任务的所有执行内容`),"aria-label":l.$t(`@WORKBENCH:清空当前任务的所有执行内容`),onClick:s[4]||=(...e)=>l.clearExecutionForSelectedTask&&l.clearExecutionForSelectedTask(...e)},[_(m,{class:`wb-logs-inline-btn__icon`},{default:W(()=>[_(l.Delete)]),_:1}),D(`span`,null,e(l.$t(`@WORKBENCH:清空执行`)),1)],8,gl),D(`button`,{type:`button`,class:`wb-logs-inline-btn`,title:l.$t(`@WORKBENCH:执行日志`),"aria-label":l.$t(`@WORKBENCH:执行日志`),onClick:s[5]||=e=>l.logsDialogVisible=!0},[_(m,{class:`wb-logs-inline-btn__icon`},{default:W(()=>[_(l.Document)]),_:1}),D(`span`,null,e(l.$t(`@WORKBENCH:执行日志`)),1)],8,_l)]),r(` 任务描述区域:默认折叠,节省首屏空间;展开后可编辑/上传附件 `),D(`details`,{class:`wb-task-desc`,open:l.taskDescExpanded,onToggle:s[17]||=e=>l.taskDescExpanded=e.target.open},[D(`summary`,yl,[_(m,{class:`wb-task-desc__caret`},{default:W(()=>[(A(),a(ye(l.taskDescExpanded?l.ArrowDown:l.ArrowRight)))]),_:1}),D(`span`,bl,e(l.$t(`@WORKBENCH:任务描述(可选)`)),1),D(`button`,{type:`button`,class:U([`wb-copy-btn wb-copy-btn--inline`,{"is-flash":l.copyDescFlashId===l.selectedTask.id}]),title:l.selectedTask.desc&&l.selectedTask.desc.trim()?l.$t(`@WORKBENCH:复制任务描述`):l.$t(`@WORKBENCH:任务描述为空,无需复制`),"aria-label":l.$t(`@WORKBENCH:复制任务描述`),onClick:s[6]||=J(e=>l.copyTaskDesc(l.selectedTask),[`stop`,`prevent`])},[l.copyDescFlashId===l.selectedTask.id?(A(),a(m,{key:1,class:`wb-copy-btn__icon wb-copy-btn__icon--check`},{default:W(()=>[...s[32]||=[g(`✓`,-1)]]),_:1})):(A(),a(m,{key:0,class:`wb-copy-btn__icon`},{default:W(()=>[_(l.CopyDocument)]),_:1}))],10,xl),l.selectedTask.desc&&l.selectedTask.desc.length>0||l.selectedTask.attachments&&l.selectedTask.attachments.length>0?(A(),v(`span`,Sl,[l.selectedTask.desc&&l.selectedTask.desc.length>0?(A(),v(`span`,Cl,e(l.$t(`@WORKBENCH:已填写`)),1)):r(`v-if`,!0),l.selectedTask.attachments&&l.selectedTask.attachments.length>0?(A(),v(`span`,wl,e(l.selectedTask.attachments.length),1)):r(`v-if`,!0)])):r(`v-if`,!0)]),L(D(`textarea`,{ref:`taskDescTextareaRef`,class:`wb-textarea wb-textarea--autogrow`,"onUpdate:modelValue":s[7]||=e=>l.selectedTask.desc=e,placeholder:l.$t(`@WORKBENCH:任务描述(可选)`),onInput:s[8]||=e=>l.autoGrowTextarea(e),onFocus:s[9]||=e=>l.autoGrowTextarea(e),onBlur:s[10]||=e=>l.autoGrowTextarea(e),onPaste:s[11]||=e=>l.onAttachmentPaste(e,{kind:`task`,task:l.selectedTask})},null,40,Tl),[[z,l.selectedTask.desc]]),_(l.AttachmentZone,{attachments:l.selectedTask.attachments||[],"is-image":l.isImageAttachment,"human-size":l.humanSize,"is-uploading":l.isUploading(`task-`+l.selectedTask.id),"is-paste-hover":l.pasteHoverId===`task-`+l.selectedTask.id,"max-count":9,"on-pick":()=>l.pickAttachmentFile({kind:`task`,task:l.selectedTask}),"on-remove":e=>l.removeAttachment({kind:`task`,task:l.selectedTask},e),onPaste:s[12]||=e=>l.onAttachmentPaste(e,{kind:`task`,task:l.selectedTask}),onDrop:s[13]||=J(e=>l.onAttachmentDrop(e,{kind:`task`,task:l.selectedTask}),[`prevent`]),onDragover:s[14]||=J(e=>l.pasteHoverId=`task-`+l.selectedTask.id,[`prevent`]),onDragenter:s[15]||=J(e=>l.pasteHoverId=`task-`+l.selectedTask.id,[`prevent`]),onDragleave:s[16]||=e=>l.pasteHoverId=l.pasteHoverId===`task-`+l.selectedTask.id?null:l.pasteHoverId},null,8,[`attachments`,`is-image`,`human-size`,`is-uploading`,`is-paste-hover`,`on-pick`,`on-remove`])],40,vl),r(` ── 执行主体:一条任务 = 一次会话,详情面板占满整行 ── `),D(`div`,El,[r(` 详情面板(执行内容区) `),D(`div`,Dl,[r(` ⚠️ 这一层**不要**用裸 <template> 包起来(踩过,2026-09-22):
47
+ Vue 3 只把带 v-if / v-else / v-for / v-slot 的 <template> 编译成片段,
48
+ 裸 <template> 会被当成真的 <template> 元素渲染 —— 浏览器把子节点全塞进
49
+ template.content(inert DocumentFragment),不产生任何布局盒。
50
+ 症状:任务在跑、看板「执行中」、执行监控有 PID,但对话区一片空白,
51
+ 而 innerText 里明明有内容(元素 0×0)。重构移除子任务概念时留下的空壳。 `),D(`details`,{class:U([`wb-simple__override`,{"has-content":!!(l.selectedTask.simpleOverride&&l.selectedTask.simpleOverride.trim())}])},[D(`summary`,Ol,[_(m,{class:`wb-simple__override-caret`},{default:W(()=>[_(l.ArrowRight)]),_:1}),D(`span`,null,e(l.$t(`@WORKBENCH:覆盖预置提示词(可选)`)),1),l.selectedTask.simpleOverride&&l.selectedTask.simpleOverride.trim()?(A(),v(`span`,{key:0,class:`wb-simple__override-tag`,title:l.$t(`@WORKBENCH:已填写覆盖内容`)},e(l.$t(`@WORKBENCH:已填写`)),9,kl)):r(`v-if`,!0),l.simpleJobState(l.simpleJobFor(l.selectedTask))===`running`&&l.simpleJobFor(l.selectedTask)?(A(),v(`button`,{key:1,class:`wb-simple__stop`,onClick:s[18]||=J(e=>l.cancelJob(l.simpleJobFor(l.selectedTask)),[`stop`])},e(l.$t(`@WORKBENCH:停止`)),1)):r(`v-if`,!0)]),L(D(`textarea`,{class:`wb-textarea`,"onUpdate:modelValue":s[19]||=e=>l.selectedTask.simpleOverride=e,placeholder:l.$t(`@WORKBENCH:留空则使用上方选定的「预置提示词」模板;可用变量:{{task.title}} {{task.desc}} {{repo.path}} {{branch}}`),rows:`6`},null,8,Al),[[z,l.selectedTask.simpleOverride]])],2),r(` 任务对话流:所有轮次合并到单个 ChatContainer `),l.simpleAllJobsFor(l.selectedTask).length>0?(A(),v(`div`,jl,[(A(),a(l.ChatContainer,{key:l.selectedTask.id,messages:l.simpleConversationMessages,"assistant-name":l.simpleAssistantLabel,"assistant-avatar":l.simpleAssistantAvatar,"show-avatar":!0,theme:l.configStore.theme,"tool-calls-config":{group:!0,collapseThreshold:2},class:`wb-simple-chat`},null,8,[`messages`,`assistant-name`,`assistant-avatar`,`theme`])),r(` 终态控件 `),l.simpleJobFor(l.selectedTask)&&[`done`,`error`,`cancelled`].includes(l.simpleJobState(l.simpleJobFor(l.selectedTask)))?(A(),v(`div`,Ml,[(A(),a(l.ChatInput,{key:`input-`+l.selectedTask.id,placeholder:l.$t(`@WORKBENCH:输入后续问题继续对话…(Ctrl+Enter 发送)`),"upload-config":{enabled:!0,accept:l.ALLOWED_EXT_HINT,multiple:!0,maxCount:Math.max(0,9-(l.selectedTask.attachments?.length??0)),maxSize:l.MAX_ATTACHMENT_BYTES},class:`wb-simple-chat__input`,onSend:s[20]||=e=>l.onContinueSendFromChat(l.selectedTask,e)},null,8,[`placeholder`,`upload-config`]))])):r(`v-if`,!0)])):r(`v-if`,!0)])])],64)):(A(),v(`div`,Zc,[D(`p`,null,e(l.$t(`@WORKBENCH:左侧选择任务,或新建一个任务开始`)),1)]))])])])]),_:1},8,[`modelValue`,`title`]),r(` 执行日志管理:弹窗形式承载,原本独立 tab 切换会占用首屏。
52
+
53
+ ⚠️ 必须 append-to-body。app shell 的 main.main-container 是 position:fixed + z-index:1001,
54
+ 它自成一个层叠上下文:留在这里面的弹窗 z-index 再高,也只是跟"同一个上下文里的兄弟"比,
55
+ 永远压不过挂在 body 下的 L2 编辑器弹窗(它 escape 了 1001 那层)。
56
+ 现象就是点了「执行日志」没反应 —— 其实弹窗开了,只是被编辑器整个盖住。 `),_(C,{modelValue:l.logsDialogVisible,"onUpdate:modelValue":s[22]||=e=>l.logsDialogVisible=e,title:l.$t(`@WORKBENCH:执行日志`),width:`1080px`,"close-on-click-modal":!1,top:`6vh`,class:`wb-logs-dialog`,"append-to-body":``},{default:W(()=>[_(l.ExecutionLogManager)]),_:1},8,[`modelValue`,`title`]),r(` 提示词编辑对话框:同「执行日志」,从编辑器里打开,必须 append-to-body 才压得住编辑器弹窗 `),_(C,{modelValue:l.promptDialog.visible,"onUpdate:modelValue":s[27]||=e=>l.promptDialog.visible=e,title:l.promptDialog.editing?l.$t(`@WORKBENCH:编辑提示词`):l.$t(`@WORKBENCH:新建提示词`),width:`640px`,"append-to-body":``},{footer:W(()=>[_(O,{onClick:s[26]||=e=>l.promptDialog.visible=!1},{default:W(()=>[g(e(l.$t(`@WORKBENCH:取消`)),1)]),_:1}),_(O,{type:`primary`,onClick:l.savePrompt},{default:W(()=>[g(e(l.$t(`@WORKBENCH:保存`)),1)]),_:1})]),default:W(()=>[_(ie,{"label-position":`top`},{default:W(()=>[_(E,{label:l.$t(`@WORKBENCH:名称`)},{default:W(()=>[_(T,{modelValue:l.promptDialog.name,"onUpdate:modelValue":s[23]||=e=>l.promptDialog.name=e,placeholder:l.$t(`@WORKBENCH:如:代码审查 / 写测试`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`]),_(E,{label:l.$t(`@WORKBENCH:所属项目`)},{default:W(()=>[_(ne,{modelValue:l.promptDialog.projectPath,"onUpdate:modelValue":s[24]||=e=>l.promptDialog.projectPath=e,placeholder:l.$t(`@WORKBENCH:所属项目`),style:{width:`100%`},disabled:!l.currentProject.path},{default:W(()=>[r(` 「全局」选项 = projectPath 为空串,所有项目都能看到 `),_(ee,{label:l.$t(`@WORKBENCH:全局(所有项目可用)`),value:``},null,8,[`label`]),r(` 仅当有当前项目时才允许绑定到当前项目,避免“绑到空项目”的兑犷数据 `),l.currentProject.path?(A(),a(ee,{key:l.currentProject.path,label:l.currentProject.name||l.currentProject.path,value:l.currentProject.path},null,8,[`label`,`value`])):r(`v-if`,!0)]),_:1},8,[`modelValue`,`placeholder`,`disabled`])]),_:1},8,[`label`]),_(E,null,{default:W(()=>[D(`div`,Nl,[_(O,{type:`primary`,plain:``,loading:l.promptDialog.aiLoading,onClick:l.aiGeneratePrompt},{default:W(()=>[g(e(l.$t(`@WORKBENCH:AI 生成项目架构说明`)),1)]),_:1},8,[`loading`]),_(O,{onClick:l.openEditInstruction},{default:W(()=>[g(e(l.$t(`@WORKBENCH:编辑指令`)),1)]),_:1})])]),_:1}),_(E,{label:l.$t(`@WORKBENCH:内容`)},{default:W(()=>[_(T,{modelValue:l.promptDialog.content,"onUpdate:modelValue":s[25]||=e=>l.promptDialog.content=e,type:`textarea`,rows:10,placeholder:l.$t(`@WORKBENCH:可用变量:`)+`{{task.title}} {{task.desc}} {{sub.title}} {{sub.desc}} {{repo.path}} {{branch}}`},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`]),r(` 生成指令编辑对话框 `),_(C,{modelValue:l.instructionDialog.visible,"onUpdate:modelValue":s[30]||=e=>l.instructionDialog.visible=e,title:l.$t(`@WORKBENCH:编辑生成指令`),width:`720px`,"append-to-body":``},{footer:W(()=>[_(O,{onClick:s[29]||=e=>l.instructionDialog.visible=!1},{default:W(()=>[g(e(l.$t(`@WORKBENCH:取消`)),1)]),_:1}),_(O,{type:`primary`,loading:l.instructionDialog.saving,onClick:l.saveInstruction},{default:W(()=>[g(e(l.$t(`@WORKBENCH:保存`)),1)]),_:1},8,[`loading`])]),default:W(()=>[_(ie,{"label-position":`top`},{default:W(()=>[_(E,{label:l.$t(`@WORKBENCH:指令内容`)},{default:W(()=>[_(T,{modelValue:l.instructionDialog.text,"onUpdate:modelValue":s[28]||=e=>l.instructionDialog.text=e,type:`textarea`,rows:18,placeholder:l.$t(`@WORKBENCH:指令内容`)},null,8,[`modelValue`,`placeholder`])]),_:1},8,[`label`])]),_:1})]),_:1},8,[`modelValue`,`title`])])}var Fl=Q(Bc,[[`render`,Pl],[`__scopeId`,`data-v-28f2e82b`],[`__file`,`D:/workspace/github_workspace/zen-gitsync/src/ui/client/src/views/WorkbenchView.vue`]]);export{Fl as default};