zen-gitsync 2.19.5 → 2.19.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/src/peer/localAsk.js +9 -1
- package/src/ui/public/assets/AgentView-CxAsrb9l.js +15 -0
- package/src/ui/public/assets/{AgentView-BIehoDwa.css → AgentView-D5MiIZuz.css} +1 -1
- package/src/ui/public/assets/{AppVersionBadge-B-6BT87B.js → AppVersionBadge-DIzhkaZi.js} +2 -2
- package/src/ui/public/assets/{BranchSelector-C1Kct7NG.js → BranchSelector-Cf6de-E0.js} +1 -1
- package/src/ui/public/assets/{CommitForm-DoC-6rft.js → CommitForm-DB0Bthai.js} +1 -1
- package/src/ui/public/assets/{CommonDialog-D8XaOcNX.js → CommonDialog-C83HvDae.js} +1 -1
- package/src/ui/public/assets/EditorView-BX7nAElt.css +1 -0
- package/src/ui/public/assets/EditorView-D-Y2WEod.js +1 -0
- package/src/ui/public/assets/{FlowExecutionViewer-CKMH34Br.js → FlowExecutionViewer-BZSHJjqL.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-CAFDGDim.js → FlowOrchestrationWorkspace-DF0kgwRn.js} +1 -1
- package/src/ui/public/assets/{LogList-DB6A2R6o.js → LogList-DiZFQLB8.js} +1 -1
- package/src/ui/public/assets/MindmapView-CohUDqAD.css +1 -0
- package/src/ui/public/assets/MindmapView-DcG7Q07c.js +1 -0
- package/src/ui/public/assets/{MonitorView-BjUS__Ze.js → MonitorView-Dsbfq-LO.js} +1 -1
- package/src/ui/public/assets/{ProjectManagerView-CWX1sSgn.js → ProjectManagerView-8Z1wtUUN.js} +1 -1
- package/src/ui/public/assets/{ProjectStartupButton-DdMFVPYI.js → ProjectStartupButton-BJ-feAjq.js} +1 -1
- package/src/ui/public/assets/{RemoteManagerDialog-fSp9IiCs.js → RemoteManagerDialog-Bx4-EAbj.js} +1 -1
- package/src/ui/public/assets/{RemoteRepoCard-Bs01mtmx.js → RemoteRepoCard-Bq-onnB-.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-tdQu2qjL.js → SourceMapView-DP5gJQOd.js} +1 -1
- package/src/ui/public/assets/{SvgIcon-D5bT7QEj.js → SvgIcon-CvIjcHNr.js} +1 -1
- package/src/ui/public/assets/{UserInputNode-DbP3PjQX.js → UserInputNode-mZ2YRrD3.js} +1 -1
- package/src/ui/public/assets/{WorkbenchView-Ahoq6RyI.js → WorkbenchView-DYy1n0I0.js} +2 -2
- package/src/ui/public/assets/{WorkbenchView-BcG-GrWp.css → WorkbenchView-DjAMZ-KQ.css} +1 -1
- package/src/ui/public/assets/{_plugin-vue_export-helper-BRUY9DoQ.js → _plugin-vue_export-helper-CfbZLRTe.js} +4 -4
- package/src/ui/public/assets/{configStore-1qv5tdrb.js → configStore-DdpMp1OU.js} +1 -1
- package/src/ui/public/assets/{index-C4masR7z.js → index-Bnk5Un7L.js} +4 -4
- package/src/ui/public/assets/{relativeTime-nh6F0rop.js → relativeTime-BNBUCPAl.js} +1 -1
- package/src/ui/public/assets/taskExecutionExport-yVOVF_bE.js +15 -0
- package/src/ui/public/assets/{useWorkbenchProjects-CDT0eWCI.js → useWorkbenchProjects-Bqm9XLHt.js} +1 -1
- package/src/ui/public/index.html +5 -5
- package/src/ui/server/routes/fs.js +132 -0
- package/src/ui/server/routes/workbench/agentRoutes.js +253 -21
- package/src/ui/server/routes/workbench/agentSessionEvents.js +114 -0
- package/src/ui/server/routes/workbench/agentSessionEvents.test.js +56 -0
- package/src/ui/server/routes/workbench/sessionGate.js +109 -8
- package/src/ui/server/routes/workbench/sessionGate.test.js +103 -0
- package/src/ui/public/assets/AgentView-B4p1C7vE.js +0 -15
- package/src/ui/public/assets/EditorView-B666I1pz.css +0 -1
- package/src/ui/public/assets/EditorView-DrhO2YSI.js +0 -1
- package/src/ui/public/assets/MindmapView-C4L5u3S9.js +0 -1
- package/src/ui/public/assets/MindmapView-DuaVqeHO.css +0 -1
- package/src/ui/public/assets/taskExecutionExport-PEcuZQo1.js +0 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./_plugin-vue_export-helper-
|
|
1
|
+
import{n as e}from"./_plugin-vue_export-helper-CfbZLRTe.js";var t=6e4,n=60*t,r=24*n;function i(i,a=Date.now()){if(!i)return``;let o=new Date(i).getTime();if(Number.isNaN(o))return``;let s=Math.max(0,a-o);return s<t?e(`@WORKBENCH:刚刚`):s<n?e(`@WORKBENCH:N 分钟前`,{n:Math.floor(s/t)}):s<r?e(`@WORKBENCH:N 小时前`,{n:Math.floor(s/n)}):s<30*r?e(`@WORKBENCH:N 天前`,{n:Math.floor(s/r)}):new Date(o).toLocaleDateString()}function a(t){if(typeof t!=`number`||!Number.isFinite(t)||t<0)return``;let n=Math.floor(t/1e3),r=Math.floor(n/3600),i=Math.floor(n%3600/60),a=n%60;return r>0?e(`@WORKBENCH:N 小时 M 分`,{n:r,m:i}):i>0?e(`@WORKBENCH:N 分 M 秒`,{n:i,m:a}):e(`@WORKBENCH:N 秒`,{n:a})}function o(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function s(t,n=Date.now()){if(!t)return``;let r=new Date(t);if(Number.isNaN(r.getTime()))return``;let i=e=>String(e).padStart(2,`0`),a=`${i(r.getHours())}:${i(r.getMinutes())}:${i(r.getSeconds())}`,s=new Date(n);if(o(r,s))return a;if(o(r,new Date(s.getFullYear(),s.getMonth(),s.getDate()-1)))return e(`@WORKBENCH:昨天 {time}`,{time:a});let c=`${r.getMonth()+1}/${r.getDate()}`;return r.getFullYear()===s.getFullYear()?`${c} ${a}`:`${r.getFullYear()}/${c} ${a}`}export{a as n,i as r,s as t};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{An as e,Ar as t,C as n,Cn as r,Gn as i,In as a,J as o,Jr as s,Mn as c,S as l,Sn as u,Sr as d,Tn as f,Y as p,Yn as m,_n as h,et as g,gr as _,i as v,ir as y,lr as b,qn as x,w as ee,wn as S,xn as C}from"./element-plus-D8LubGQe.js";import{n as w,t as T}from"./_plugin-vue_export-helper-CfbZLRTe.js";import{d as E,f as D,m as O,p as k,t as A}from"./configStore-DdpMp1OU.js";import{O as j,_ as M,g as te,vt as N,x as P}from"./index-Bnk5Un7L.js";var F=[`png`,`jpg`,`jpeg`,`gif`,`webp`,`bmp`,`svg`],ne=/!\[([^\]]*)\]\(\s*(?:<([^<>\n]+)>|([^()\s]+))(\s+["'][^"']*["'])?\s*\)/g,re=/^\s*(`{3,}|~{3,})/,ie=/\.([a-z0-9]+)$/;function I(e){let t=e.trim().toLowerCase().match(ie);return!!t&&F.includes(t[1])}function ae(e){let t=String(e||``).trim();if(!t)return!1;if(/^[a-zA-Z]:[\\/]/.test(t))return I(t);let n=t.match(/^([a-z][a-z0-9+.-]+):/i);return n&&n[1].toLowerCase()!==`file`||t.startsWith(`//`)||t.startsWith(`/`)?!1:I(t)}function oe(e,t){return`/api/workbench/jobs/${encodeURIComponent(e)}/image?path=${encodeURIComponent(t)}`}function se(e,t){return`/api/agent/sessions/${encodeURIComponent(e)}/image?path=${encodeURIComponent(t)}`}function ce(e,t){return e.includes(`}${a||``})`:e}):e}function L(e,t){let n=typeof e==`string`?e:``;if(!n||!t||!n.includes(`![`))return n;let r=n.split(`
|
|
2
|
+
`),i=null,a=[];for(let e of r){let n=e.match(re);if(n){let t=n[1][0];i===null?i=t:i===t&&(i=null),a.push(e);continue}a.push(i===null?ce(e,t):e)}return a.join(`
|
|
3
|
+
`)}function R(e,t){return L(e,t?e=>oe(t,e):null)}function z(e,t){return L(e,t?e=>se(t,e):null)}function B(e){if(!e)return``;try{let t=new Date(e);if(Number.isNaN(t.getTime()))return e;let n=new Date,r=n.getTime()-t.getTime(),i=e=>String(e).padStart(2,`0`);if(t.toDateString()===n.toDateString())return`${i(t.getHours())}:${i(t.getMinutes())}`;if(r<6048e5){let e=Math.floor(r/864e5);return e===0?w(`@AGENT:今天`):`${e}${w(`@AGENT:天前`)}`}return`${t.getFullYear()}-${i(t.getMonth()+1)}-${i(t.getDate())}`}catch{return e}}function V(e,t){return e.map(e=>({id:e.sessionId,title:e.title||w(`@AGENT:无标题`),meta:`${B(e.updatedAt)} · ${e.messageCount??0} ${w(`@AGENT:条`)}`,generatingText:e.isGenerating||t(e.sessionId)?w(`@AGENT:正在生成中...`):``,badge:e.source===`cli`?`CLI`:e.source===`peer`?w(`@AGENT:远端`):``,searchText:e.model}))}function H(){return{newConversation:w(`@AGENT:新建会话`),searchPlaceholder:w(`@AGENT:搜索会话...`),empty:w(`@AGENT:暂无会话`),emptyHint:w(`@AGENT:点击上方按钮开始对话`),noResult:w(`@AGENT:未找到匹配的会话`),loading:w(`@AGENT:加载会话中...`),rename:w(`@AGENT:重命名`),delete:w(`@AGENT:删除`),untitled:w(`@AGENT:无标题`),collapse:w(`@AGENT:收起会话列表`),expand:w(`@AGENT:展开会话列表`)}}var U={enable:!0},W={enable:!0,items:[`duration`],visibility:`always`};function G(){return{title:w(`@AGENT:等待你的回答`),placeholder:w(`@AGENT:输入回答`),submit:w(`@AGENT:提交回答`),answered:w(`@AGENT:已回答`),expand:w(`@AGENT:展开完整问答`),collapse:w(`@AGENT:收起完整问答`)}}function le(){return{title:w(`@AGENT:文件改动`),files:w(`@AGENT:个文件`),added:w(`@AGENT:新增行`),removed:w(`@AGENT:删除行`),expand:w(`@AGENT:查看改动`),collapse:w(`@AGENT:收起改动`),writeHint:w(`@AGENT:整体写入`),empty:w(`@AGENT:无可预览的差异`)}}function ue(){return{title:w(`@AGENT:排队中`),hint:w(`@AGENT:本轮结束后依次发送`),pausedHint:w(`@AGENT:已暂停,点「立即发送」继续`),send:w(`@AGENT:加入队列`),flush:w(`@AGENT:立即发送`),remove:w(`@AGENT:移出队列`)}}b();var de=1e5;function fe(){let e=_([]),t=_([]),n=_(de),r=_([]),i=_(null),a=_(!1),o=_(!1),s=_(``),c=_({}),l=_([]),u=_(!1),d=_(!1),f=_(M);async function p(o=!1){try{let l=await fetch(`/api/workbench/orchestrator`,{cache:`no-store`}).then(e=>e.json());return l?.success?(Number.isInteger(l.maxInstructionChars)&&l.maxInstructionChars>0&&(n.value=l.maxInstructionChars),e.value=Array.isArray(l.instructions)?l.instructions:[],t.value=Array.isArray(l.activity)?l.activity:[],r.value=Array.isArray(l.running)?l.running:[],te().setRunning(r.value.length),i.value=l.updatedAt||null,s.value=typeof l.defaultPrompt==`string`?l.defaultPrompt:``,c.value=l.projectPrompts&&typeof l.projectPrompts==`object`?l.projectPrompts:{},f.value=P(l.reportIntervalMs),a.value=!0,!0):(o||v.error(l?.error||w(`@WORKBENCH:读取编排状态失败`)),!1)}catch(e){return o||v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function m(e=!1){if(u.value)return!1;u.value=!0;try{let t=await fetch(`/api/workbench/orchestrator/reports`,{cache:`no-store`}).then(e=>e.json());return t?.success?(l.value=Array.isArray(t.reports)?t.reports:[],!0):(e||v.error(t?.error||w(`@WORKBENCH:读取进度报告失败`)),!1)}catch(t){return e||v.error(w(`@WORKBENCH:网络错误: `)+(t?.message||t)),!1}finally{u.value=!1}}async function h(){if(d.value)return null;d.value=!0;try{let e=String(A().locale||``).startsWith(`en`)?`en`:`zh`,t=await fetch(`/api/workbench/orchestrator/report`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({locale:e})}).then(e=>e.json());return t?.success?t.report?(l.value=[t.report,...l.value].slice(0,20),t.report):(v.info(w(`@WORKBENCH:当前没有正在执行的任务,没有可汇报的进度`)),null):(v.error(t?.error||w(`@WORKBENCH:生成进度报告失败`)),null)}catch(e){return v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),null}finally{d.value=!1}}async function g(e){try{let t=await fetch(`/api/workbench/orchestrator/report-interval`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({intervalMs:e})}).then(e=>e.json());return t?.success?(f.value=P(t.reportIntervalMs),!0):(v.error(t?.error||w(`@WORKBENCH:保存失败`)),!1)}catch(e){return v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function y(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?(s.value=typeof t.defaultPrompt==`string`?t.defaultPrompt:``,v.success(w(`@WORKBENCH:已保存全局预设提示词`)),!0):(v.error(t?.error||w(`@WORKBENCH:保存失败`)),!1)}catch(e){return v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function b(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?(c.value=n.projectPrompts&&typeof n.projectPrompts==`object`?n.projectPrompts:{},v.success(w(`@WORKBENCH:已保存项目预设提示词`)),!0):(v.error(n?.error||w(`@WORKBENCH:保存失败`)),!1)}catch(e){return v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}}async function x(e){if(o.value)return null;o.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,imageText:e.imageText,attachments:(e.attachments||[]).map(e=>({id:e.id,ext:e.ext,originalName:e.originalName}))})}).then(e=>e.json());return t?.success?(await p(!0),{task:t.task||null,ran:!!t.ran}):(v.error(t?.error||w(`@WORKBENCH:派发失败`)),null)}catch(e){return v.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),null}finally{o.value=!1}}return{instructions:e,activity:t,running:r,updatedAt:i,loaded:a,dispatching:o,maxInstructionChars:n,defaultPrompt:s,projectPrompts:c,reports:l,loadingReports:u,generatingReport:d,reportIntervalMs:f,loadOrchestrator:p,dispatch:x,saveDefaultPrompt:y,saveProjectPrompt:b,loadReports:m,generateReport:h,setReportInterval:g}}a();function K(){let e=A(),t=N(),n=C({get:()=>e.resolvedTaskExecutor,set:t=>{D(t)&&e.setLastTaskExecutor(t)}}),r=C(()=>({claude:t.claudeAvailable,opencode:t.opencodeAvailable,codex:t.codexAvailable,codebuddy:t.codebuddyAvailable,pi:t.piAvailable,codearts:t.codeartsAvailable})),i=C(()=>E.some(e=>r.value[e.id])),a=C(()=>r.value[n.value]?n.value:Object.keys(r.value).find(e=>r.value[e])??n.value);function o(e){r.value[e]&&(n.value=e)}let s=C(()=>e.ui.dispatchExecutorPriority??[]),c=C(()=>s.value.length>0),l=C(()=>c.value?k(s.value,r.value,a.value):a.value);function u(e){return t.executorModelText(e)}function d(e){return[u(e),t.executorModelDetail(e)].filter(Boolean).join(` · `)}return{selected:n,active:a,priority:s,hasPriority:c,dispatchTarget:l,availability:r,hasAnyExecutor:i,choose:o,executorModelText:u,executorModelTitle:d}}a(),b(),t();var pe={key:0,class:`tep tep--static`},me=[`title`,`aria-label`],he={class:`tep__btn-name`},ge={class:`tep__btn-tag`},_e=[`title`,`aria-label`],ve={class:`tep__btn-name`},ye={class:`tep__item`},be={class:`tep__item-name`},xe=[`title`],Se={key:2,class:`tep__item-missing`},Ce=T(c({__name:`TaskExecutorPicker`,props:{title:{},readonly:{type:Boolean},value:{}},setup(t){let a=t,{active:c,availability:_,choose:v,executorModelText:b,executorModelTitle:T}=K(),D=C(()=>a.readonly&&a.value?a.value:c.value),k=N();i(()=>{k.fetchExecutorModels()});function A(){return[a.title,T(D.value)].filter(Boolean).join(` · `)}return(i,a)=>{let c=o,C=n,k=ee,M=l;return t.readonly?(x(),f(`span`,pe,[u(`span`,{class:`tep__btn`,title:A(),"aria-label":d(w)(`@WORKBENCH:任务执行器`)},[e(j,{executor:D.value,class:`tep__btn-icon`},null,8,[`executor`]),u(`span`,he,s(d(O)(D.value)),1),u(`span`,ge,s(d(w)(`@AGENT:按优先级`)),1)],8,me)])):(x(),r(M,{key:1,trigger:`click`,class:`tep`,onCommand:d(v)},{dropdown:y(()=>[e(k,null,{default:y(()=>[(x(!0),f(h,null,m(d(E),t=>(x(),r(C,{key:t.id,command:t.id,disabled:!d(_)[t.id]},{default:y(()=>[u(`span`,ye,[e(j,{executor:t.id,class:`tep__item-icon`},null,8,[`executor`]),u(`span`,be,s(t.name),1),d(b)(t.id)?(x(),f(`span`,{key:0,class:`tep__item-model`,title:d(T)(t.id)},s(d(b)(t.id)),9,xe)):S(``,!0),D.value===t.id?(x(),r(c,{key:1,class:`tep__item-check`},{default:y(()=>[e(d(g))]),_:1})):d(_)[t.id]?S(``,!0):(x(),f(`span`,Se,s(d(w)(`@42BB9:未安装`)),1))])]),_:2},1032,[`command`,`disabled`]))),128))]),_:1})]),default:y(()=>[u(`button`,{type:`button`,class:`tep__btn`,title:A(),"aria-label":d(w)(`@WORKBENCH:任务执行器`)},[e(j,{executor:D.value,class:`tep__btn-icon`},null,8,[`executor`]),u(`span`,ve,s(d(O)(D.value)),1),e(c,{class:`tep__btn-caret`},{default:y(()=>[e(d(p))]),_:1})],8,_e)]),_:1},8,[`onCommand`]))}}}),[[`__scopeId`,`data-v-52969d85`]]),we=8192;function Te(e,t){return e.length>t?`…(前文已截断)\n${e.slice(-t)}`:e}function Ee(e,t){let n=e||`done`;return n!==`pending`&&n!==`running`||t===`running`||t===`pending`?n:t===`cancelled`||t===`error`?`error`:`done`}function q(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=Ee(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?Te(o,we):``,status:a,error:typeof i.error==`string`&&i.error?i.error:void 0})}return r}var De=`
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
`,Oe=`[运行环境 ·`,ke=`## 跨会话记忆库`,Ae=/\n\n---\n本任务包含 \d+ 个附件(请按文件路径读取[\s\S]*$/,J=/\n\n续接 #\d+\s*$/;function Y(e){let t=e.indexOf(De);return t===-1?0:t+7}function X(e){let t=typeof e==`string`?e:``;return t?(t.startsWith(Oe)&&(t=t.slice(Y(t))),t.startsWith(ke)&&(t=t.slice(Y(t))),t=t.replace(Ae,``).replace(J,``),t.trim()):``}function Z(e){switch(e){case`todo`:return w(`@WORKBENCH:待执行`);case`running`:return w(`@WORKBENCH:执行中`);case`done`:return w(`@WORKBENCH:已完成`);case`error`:return w(`@WORKBENCH:出错`);case`cancelled`:return w(`@WORKBENCH:已取消`);case`pending`:return w(`@WORKBENCH:排队中`);default:return e}}function je(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)`}}function Q(e){let t=e?new Date(e):new Date;if(Number.isNaN(t.getTime()))return``;let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}function Me(e,t=120){let n=e.replace(/\s+/g,` `).trim();return n.length>t?`${n.slice(0,t-1)}…`:n}function Ne(e){let t=(e.match(/`+/g)||[]).reduce((e,t)=>Math.max(e,t.length),0),n="`".repeat(Math.max(3,t+1));return`${n}\n${e}\n${n}`}function $(e,t){return`### ${e}\n\n${t.trim()}`}function Pe(e){let t=[];return e.forEach((e,n)=>{let r=e.name||w(`@WORKBENCH:工具`),i=Me(e.argsPreview||``);t.push(`${n+1}. **${r}**${i?` — \`${i}\``:``}`);let a=(e.status===`error`?e.error:e.result)||e.result||e.error||``;a.trim()&&t.push(``,Ne(a.trim()))}),t.join(`
|
|
8
|
+
`)}function Fe(e,t={},n={}){let r=Array.isArray(e)?e.filter(Boolean):[],i=n.scope===`brief`,a=[];if(r.forEach((e,t)=>{let n=[],r=X(e.prompt);if(r&&n.push($(w(`@WORKBENCH:用户提示词`),r)),!i){let t=(e.thinking||``).trim();t&&n.push($(w(`@WORKBENCH:Claude 思考`),t));let r=Pe(q(e));r&&n.push($(w(`@WORKBENCH:工具调用`),r))}let o=(e.output||``).trim();o&&n.push($(w(`@WORKBENCH:模型返回`),o));let s=(e.error||e.agentError||``).trim();if(s&&n.push($(w(`@WORKBENCH:出错`),s)),n.length===0)return;let c=[O(e.agent),Z(e.status),Q(e.startedAt)].filter(Boolean);a.push(`## ${w(`@WORKBENCH:第 {n} 轮`,{n:t+1})}\n\n*${c.join(` · `)}*\n\n${n.join(`
|
|
9
|
+
|
|
10
|
+
`)}`)}),a.length===0)return``;let o=[`# ${(t.title||``).trim()||w(`@WORKBENCH:未命名任务`)}`],s=(t.projectName||``).trim();return s&&o.push(``,`- ${w(`@WORKBENCH:项目:{name}`,{name:s})}`),o.push(`- ${w(`@WORKBENCH:导出时间:{time}`,{time:Q((t.now||new Date).toISOString())})}`),`${o.join(`
|
|
11
|
+
`)}\n\n---\n\n${a.join(`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
`)}\n`}export{z as _,X as a,K as c,U as d,H as f,V as g,ue as h,Z as i,fe as l,G as m,Q as n,q as o,le as p,je as r,Ce as s,Fe as t,W as u,R as v};
|
package/src/ui/public/assets/{useWorkbenchProjects-CDT0eWCI.js → useWorkbenchProjects-Bqm9XLHt.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./rolldown-runtime-C0FnF6B9.js";import{An as e,Ar as t,Cn as n,In as r,J as i,Jr as a,Lt as o,Mn as s,Nt as ee,Sn as c,Sr as l,Tn as u,Ur as d,Yn as f,_n as p,gn as m,gr as h,hn as g,i as _,ir as v,lr as y,on as b,qn as x,st as S,wn as C,xn as te,xt as ne}from"./element-plus-D8LubGQe.js";import{n as w,t as T}from"./_plugin-vue_export-helper-BRUY9DoQ.js";import{t as E}from"./SvgIcon-D5bT7QEj.js";import{B as D,F as re,G as O,H as ie,I as k,K as A,L as j,P as M,R as ae,U as oe,V as se,W as ce,q as le,vt as N,z as ue}from"./index-C4masR7z.js";function P(){let e=N();function t(t){return e.lastCheckedAt!==null&&!e.isToolAvailable(t)}async function n(t,n,r){if(!n)return`no-dir`;if(!await D())return _.warning(w(`@67CE7:工具检测失败,请稍后重试`)),`failed`;if(!e.isToolAvailable(t))return`install`;let i=await O(t,n,r);return i.success?(_.success(i.message||w(`@67CE7:已用 {tool} 打开目录`,{tool:j[t]})),`opened`):(_.error(`${w(`@67CE7:打开失败: `)}${i.error??``}`),`failed`)}return{toolMissing:t,tryOpenWithTool:n}}r(),y(),t(),b();var F=[`aria-label`],I=[`onKeydown`],L={class:`proj-menu__icon`},R={class:`proj-menu__label`},z=[`onKeydown`],B={class:`proj-menu__icon`},V={class:`proj-menu__label`},H=[`onKeydown`],U={class:`proj-menu__icon`},de={class:`proj-menu__label`},fe=[`onKeydown`],pe={class:`proj-menu__icon`},me={class:`proj-menu__label`},he=[`onKeydown`],ge={class:`proj-menu__icon`},_e={class:`proj-menu__label`},ve={class:`proj-menu__title`,role:`presentation`},ye=[`onClick`,`onKeydown`],be={class:`proj-menu__icon`},xe={class:`proj-menu__label`},Se={key:0,class:`proj-menu__hint`},Ce={class:`proj-menu__icon`},we=[`src`],Te={class:`proj-menu__label`},Ee={class:`proj-menu__hint`},De={class:`proj-menu__icon`},Oe=[`src`],ke={class:`proj-menu__label`},Ae={class:`proj-menu__icon`},je={class:`proj-menu__label`},Me={class:`proj-menu__icon`},Ne={class:`proj-menu__label`},Pe={key:0,class:`proj-menu__hint`},Fe={key:1,class:`proj-menu__hint`},Ie={class:`proj-menu__icon`},Le={class:`proj-menu__label`},Re={class:`proj-menu__icon`},ze={class:`proj-menu__label`},Be={class:`proj-menu__icon`},Ve={class:`proj-menu__label`},He={class:`proj-menu__title`,role:`presentation`},Ue=[`onClick`,`onKeydown`],W={class:`proj-menu__icon`},We=[`src`],Ge={class:`proj-menu__label`},Ke={class:`proj-menu__hint`},G=T(s({__name:`ProjectOpenMenuList`,props:{path:{},name:{}},emits:[`done`],setup(t,{emit:r}){let s=t,y=r,{toolMissing:b,tryOpenWithTool:T}=P(),D=N(),O=h(!1),G=h(null),K=te(()=>re.filter(e=>D.desktopAppOf(e)).map(e=>({id:e,name:j[e],icon:k.find(t=>t.id===e)?.icon??``})));async function q(e){let t=D.desktopAppOf(e);if(!t)return;if(y(`done`),!t.installed){window.open(t.downloadUrl,`_blank`,`noopener,noreferrer`);return}let n=await ie(e);n.success?_.success(n.message||w(`@67CE7:已打开 {app}`,{app:t.name})):_.error(n.error||w(`@WORKBENCH:打开桌面端失败`))}async function J(){y(`done`);let e=await oe(s.path);e.success?_.success(e.message||w(`@WORKBENCH:已在文件管理器中打开文件夹`)):_.error(e.error||w(`@WORKBENCH:打开文件夹失败`))}async function Y(){y(`done`);let e=await ce(s.path);e.success?_.success(e.message||w(`@67CE7:已在终端中打开目录`)):_.error(e.error||w(`@WORKBENCH:打开终端失败`))}async function X(){y(`done`);let e=await se(s.path);e.success?_.success(w(`@WORKBENCH:已在新标签页启动 g ui`)):_.error(e.error||w(`@WORKBENCH:启动 g ui 失败`))}async function Z(){if(y(`done`),s.name)try{await navigator.clipboard.writeText(s.name),_.success(w(`@67CE7:已复制文件夹名称`))}catch{_.error(w(`@67CE7:复制失败`))}}async function Q(){if(y(`done`),s.path)try{await navigator.clipboard.writeText(s.path),_.success(w(`@67CE7:已复制文件夹路径`))}catch{_.error(w(`@67CE7:复制失败`))}}async function $(e,t){if(await T(e,s.path,t)===`install`){G.value=e,O.value=!0;return}y(`done`)}return(t,r)=>{let s=i;return x(),u(p,null,[c(`ul`,{class:`proj-menu`,role:`menu`,"aria-label":l(w)(`@WORKBENCH:打开方式`)},[c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:J,onKeydown:[g(m(J,[`prevent`]),[`enter`]),g(m(J,[`prevent`]),[`space`])]},[c(`span`,L,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(ne))]),_:1})]),c(`span`,R,a(l(w)(`@WORKBENCH:在文件管理器中打开`)),1)],40,I),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Y,onKeydown:[g(m(Y,[`prevent`]),[`enter`]),g(m(Y,[`prevent`]),[`space`])]},[c(`span`,B,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(ee))]),_:1})]),c(`span`,V,a(l(w)(`@WORKBENCH:在终端中打开`)),1)],40,z),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:X,onKeydown:[g(m(X,[`prevent`]),[`enter`]),g(m(X,[`prevent`]),[`space`])]},[c(`span`,U,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(o))]),_:1})]),c(`span`,de,a(l(w)(`@WORKBENCH:在新标签页启动 g ui`)),1)],40,H),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Z,onKeydown:[g(m(Z,[`prevent`]),[`enter`]),g(m(Z,[`prevent`]),[`space`])]},[c(`span`,pe,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(S))]),_:1})]),c(`span`,me,a(l(w)(`@67CE7:复制文件夹名称`)),1)],40,fe),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Q,onKeydown:[g(m(Q,[`prevent`]),[`enter`]),g(m(Q,[`prevent`]),[`space`])]},[c(`span`,ge,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(S))]),_:1})]),c(`span`,_e,a(l(w)(`@67CE7:复制文件夹路径`)),1)],40,he),r[23]||=c(`li`,{class:`proj-menu__sep`,role:`separator`},null,-1),c(`li`,ve,a(l(w)(`@WORKBENCH:用工具打开`)),1),(x(!0),u(p,null,f(l(k),t=>(x(),u(`li`,{key:t.id,class:d([`proj-menu__item`,{"is-missing":l(b)(t.id)}]),role:`menuitem`,tabindex:`-1`,onClick:e=>$(t.id),onKeydown:[g(m(e=>$(t.id),[`prevent`]),[`enter`]),g(m(e=>$(t.id),[`prevent`]),[`space`])]},[c(`span`,be,[e(E,{"icon-class":t.icon,class:d({"icon-invert-dark":t.id===`codex`,"icon-outline-dark":l(M).has(t.id)})},null,8,[`icon-class`,`class`])]),c(`span`,xe,a(l(w)(t.labelKey)),1),l(b)(t.id)?(x(),u(`span`,Se,a(l(w)(`@67CE7:未安装`)),1)):C(``,!0)],42,ye))),128)),c(`li`,{class:d([`proj-menu__item`,{"is-missing":l(b)(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[0]||=e=>$(`claude`),onKeydown:[r[1]||=g(m(e=>$(`claude`),[`prevent`]),[`enter`]),r[2]||=g(m(e=>$(`claude`),[`prevent`]),[`space`])]},[c(`span`,Ce,[c(`img`,{src:l(A),alt:``,class:`proj-menu__img`},null,8,we)]),c(`span`,Te,a(l(w)(`@67CE7:用 Claude Code 打开`)),1),c(`span`,Ee,a(l(b)(`claude`)?l(w)(`@67CE7:未安装`):l(w)(`@67CE7:默认权限`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[3]||=e=>$(`claude`,`bypassPermissions`),onKeydown:[r[4]||=g(m(e=>$(`claude`,`bypassPermissions`),[`prevent`]),[`enter`]),r[5]||=g(m(e=>$(`claude`,`bypassPermissions`),[`prevent`]),[`space`])]},[c(`span`,De,[c(`img`,{src:l(A),alt:``,class:`proj-menu__img`},null,8,Oe)]),c(`span`,ke,a(l(w)(`@67CE7:用 Claude Code 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`opencode`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[6]||=e=>$(`opencode`,`auto`),onKeydown:[r[7]||=g(m(e=>$(`opencode`,`auto`),[`prevent`]),[`enter`]),r[8]||=g(m(e=>$(`opencode`,`auto`),[`prevent`]),[`space`])]},[c(`span`,Ae,[e(E,{"icon-class":`opencode`})]),c(`span`,je,a(l(w)(`@67CE7:用 OpenCode 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item`,{"is-missing":l(b)(`codex`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[9]||=e=>$(`codex`,`sandboxed`),onKeydown:[r[10]||=g(m(e=>$(`codex`,`sandboxed`),[`prevent`]),[`enter`]),r[11]||=g(m(e=>$(`codex`,`sandboxed`),[`prevent`]),[`space`])]},[c(`span`,Me,[e(E,{"icon-class":`codex`,class:`icon-invert-dark`})]),c(`span`,Ne,a(l(w)(`@67CE7:用 Codex 打开(自动批准)`)),1),l(b)(`codex`)?(x(),u(`span`,Fe,a(l(w)(`@67CE7:未安装`)),1)):(x(),u(`span`,Pe,a(l(w)(`@67CE7:沙箱内`)),1))],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`codex`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[12]||=e=>$(`codex`,`bypass`),onKeydown:[r[13]||=g(m(e=>$(`codex`,`bypass`),[`prevent`]),[`enter`]),r[14]||=g(m(e=>$(`codex`,`bypass`),[`prevent`]),[`space`])]},[c(`span`,Ie,[e(E,{"icon-class":`codex`,class:`icon-invert-dark`})]),c(`span`,Le,a(l(w)(`@67CE7:用 Codex 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`codebuddy`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[15]||=e=>$(`codebuddy`,`bypassPermissions`),onKeydown:[r[16]||=g(m(e=>$(`codebuddy`,`bypassPermissions`),[`prevent`]),[`enter`]),r[17]||=g(m(e=>$(`codebuddy`,`bypassPermissions`),[`prevent`]),[`space`])]},[c(`span`,Re,[e(E,{"icon-class":`codebuddy`})]),c(`span`,ze,a(l(w)(`@67CE7:用 CodeBuddy Code 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`kimi`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[18]||=e=>$(`kimi`,`auto`),onKeydown:[r[19]||=g(m(e=>$(`kimi`,`auto`),[`prevent`]),[`enter`]),r[20]||=g(m(e=>$(`kimi`,`auto`),[`prevent`]),[`space`])]},[c(`span`,Be,[e(E,{"icon-class":`kimi`})]),c(`span`,Ve,a(l(w)(`@67CE7:用 Kimi Code 打开(完全批准)`)),1)],34),K.value.length?(x(),u(p,{key:0},[r[22]||=c(`li`,{class:`proj-menu__sep`,role:`separator`},null,-1),c(`li`,He,a(l(w)(`@WORKBENCH:桌面端`)),1),(x(!0),u(p,null,f(K.value,e=>(x(),u(`li`,{key:`desktop-${e.id}`,class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:t=>q(e.id),onKeydown:[g(m(t=>q(e.id),[`prevent`]),[`enter`]),g(m(t=>q(e.id),[`prevent`]),[`space`])]},[c(`span`,W,[e.id===`claude`?(x(),u(`img`,{key:0,src:l(A),alt:``,class:`proj-menu__img`},null,8,We)):(x(),n(E,{key:1,"icon-class":e.icon,class:d({"icon-invert-dark":e.id===`codex`,"icon-outline-dark":l(M).has(e.id)})},null,8,[`icon-class`,`class`]))]),c(`span`,Ge,a(l(ue)(l(D).desktopAppOf(e.id))),1),c(`span`,Ke,a(l(ae)(l(D).desktopAppOf(e.id))),1)],40,Ue))),128))],64)):C(``,!0)],8,F),e(le,{modelValue:O.value,"onUpdate:modelValue":r[21]||=e=>O.value=e,tool:G.value},null,8,[`modelValue`,`tool`])],64)}}}),[[`__scopeId`,`data-v-80fde3fe`]]);y();function K(){let e=h([]),t=h([]),n=h(``),r=h(!1),i=h(!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||_.error(r?.error||w(`@WORKBENCH:读取项目列表失败`)),!1)}catch(e){return a||_.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}finally{r.value=!1}}async function o(e){if(!e)return{ok:!1,keptTasks:0};try{let t=await fetch(`/api/workbench/projects/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e})}).then(e=>e.json()).catch(()=>null);return t?.success?{ok:!0,keptTasks:Number.isFinite(t.keptTasks)?t.keptTasks:0}:(_.error(t?.error||w(`@WORKBENCH:移除项目失败`)),{ok:!1,keptTasks:0})}catch(e){return _.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),{ok:!1,keptTasks:0}}}async function s(e){if(!e)return{ok:!1,alreadyKnown:!1};try{let t=await fetch(`/api/workbench/projects/add`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e})}).then(e=>e.json()).catch(()=>null);return t?.success?{ok:!0,alreadyKnown:!!t.alreadyKnown}:(_.error(t?.error||w(`@PROJM:添加项目失败`)),{ok:!1,alreadyKnown:!1})}catch(e){return _.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),{ok:!1,alreadyKnown:!1}}}return{projects:e,boardTasks:t,currentProjectPath:n,loading:r,loaded:i,loadProjects:a,removeProject:o,addProject:s}}export{G as n,K as t};
|
|
1
|
+
import"./rolldown-runtime-C0FnF6B9.js";import{An as e,Ar as t,Cn as n,In as r,J as i,Jr as a,Lt as o,Mn as s,Nt as ee,Sn as c,Sr as l,Tn as u,Ur as d,Yn as f,_n as p,gn as m,gr as h,hn as g,i as _,ir as v,lr as y,on as b,qn as x,st as S,wn as C,xn as te,xt as ne}from"./element-plus-D8LubGQe.js";import{n as w,t as T}from"./_plugin-vue_export-helper-CfbZLRTe.js";import{t as E}from"./SvgIcon-CvIjcHNr.js";import{B as D,F as re,G as O,H as ie,I as k,K as A,L as j,P as M,R as ae,U as oe,V as se,W as ce,q as le,vt as N,z as ue}from"./index-Bnk5Un7L.js";function P(){let e=N();function t(t){return e.lastCheckedAt!==null&&!e.isToolAvailable(t)}async function n(t,n,r){if(!n)return`no-dir`;if(!await D())return _.warning(w(`@67CE7:工具检测失败,请稍后重试`)),`failed`;if(!e.isToolAvailable(t))return`install`;let i=await O(t,n,r);return i.success?(_.success(i.message||w(`@67CE7:已用 {tool} 打开目录`,{tool:j[t]})),`opened`):(_.error(`${w(`@67CE7:打开失败: `)}${i.error??``}`),`failed`)}return{toolMissing:t,tryOpenWithTool:n}}r(),y(),t(),b();var F=[`aria-label`],I=[`onKeydown`],L={class:`proj-menu__icon`},R={class:`proj-menu__label`},z=[`onKeydown`],B={class:`proj-menu__icon`},V={class:`proj-menu__label`},H=[`onKeydown`],U={class:`proj-menu__icon`},de={class:`proj-menu__label`},fe=[`onKeydown`],pe={class:`proj-menu__icon`},me={class:`proj-menu__label`},he=[`onKeydown`],ge={class:`proj-menu__icon`},_e={class:`proj-menu__label`},ve={class:`proj-menu__title`,role:`presentation`},ye=[`onClick`,`onKeydown`],be={class:`proj-menu__icon`},xe={class:`proj-menu__label`},Se={key:0,class:`proj-menu__hint`},Ce={class:`proj-menu__icon`},we=[`src`],Te={class:`proj-menu__label`},Ee={class:`proj-menu__hint`},De={class:`proj-menu__icon`},Oe=[`src`],ke={class:`proj-menu__label`},Ae={class:`proj-menu__icon`},je={class:`proj-menu__label`},Me={class:`proj-menu__icon`},Ne={class:`proj-menu__label`},Pe={key:0,class:`proj-menu__hint`},Fe={key:1,class:`proj-menu__hint`},Ie={class:`proj-menu__icon`},Le={class:`proj-menu__label`},Re={class:`proj-menu__icon`},ze={class:`proj-menu__label`},Be={class:`proj-menu__icon`},Ve={class:`proj-menu__label`},He={class:`proj-menu__title`,role:`presentation`},Ue=[`onClick`,`onKeydown`],W={class:`proj-menu__icon`},We=[`src`],Ge={class:`proj-menu__label`},Ke={class:`proj-menu__hint`},G=T(s({__name:`ProjectOpenMenuList`,props:{path:{},name:{}},emits:[`done`],setup(t,{emit:r}){let s=t,y=r,{toolMissing:b,tryOpenWithTool:T}=P(),D=N(),O=h(!1),G=h(null),K=te(()=>re.filter(e=>D.desktopAppOf(e)).map(e=>({id:e,name:j[e],icon:k.find(t=>t.id===e)?.icon??``})));async function q(e){let t=D.desktopAppOf(e);if(!t)return;if(y(`done`),!t.installed){window.open(t.downloadUrl,`_blank`,`noopener,noreferrer`);return}let n=await ie(e);n.success?_.success(n.message||w(`@67CE7:已打开 {app}`,{app:t.name})):_.error(n.error||w(`@WORKBENCH:打开桌面端失败`))}async function J(){y(`done`);let e=await oe(s.path);e.success?_.success(e.message||w(`@WORKBENCH:已在文件管理器中打开文件夹`)):_.error(e.error||w(`@WORKBENCH:打开文件夹失败`))}async function Y(){y(`done`);let e=await ce(s.path);e.success?_.success(e.message||w(`@67CE7:已在终端中打开目录`)):_.error(e.error||w(`@WORKBENCH:打开终端失败`))}async function X(){y(`done`);let e=await se(s.path);e.success?_.success(w(`@WORKBENCH:已在新标签页启动 g ui`)):_.error(e.error||w(`@WORKBENCH:启动 g ui 失败`))}async function Z(){if(y(`done`),s.name)try{await navigator.clipboard.writeText(s.name),_.success(w(`@67CE7:已复制文件夹名称`))}catch{_.error(w(`@67CE7:复制失败`))}}async function Q(){if(y(`done`),s.path)try{await navigator.clipboard.writeText(s.path),_.success(w(`@67CE7:已复制文件夹路径`))}catch{_.error(w(`@67CE7:复制失败`))}}async function $(e,t){if(await T(e,s.path,t)===`install`){G.value=e,O.value=!0;return}y(`done`)}return(t,r)=>{let s=i;return x(),u(p,null,[c(`ul`,{class:`proj-menu`,role:`menu`,"aria-label":l(w)(`@WORKBENCH:打开方式`)},[c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:J,onKeydown:[g(m(J,[`prevent`]),[`enter`]),g(m(J,[`prevent`]),[`space`])]},[c(`span`,L,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(ne))]),_:1})]),c(`span`,R,a(l(w)(`@WORKBENCH:在文件管理器中打开`)),1)],40,I),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Y,onKeydown:[g(m(Y,[`prevent`]),[`enter`]),g(m(Y,[`prevent`]),[`space`])]},[c(`span`,B,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(ee))]),_:1})]),c(`span`,V,a(l(w)(`@WORKBENCH:在终端中打开`)),1)],40,z),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:X,onKeydown:[g(m(X,[`prevent`]),[`enter`]),g(m(X,[`prevent`]),[`space`])]},[c(`span`,U,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(o))]),_:1})]),c(`span`,de,a(l(w)(`@WORKBENCH:在新标签页启动 g ui`)),1)],40,H),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Z,onKeydown:[g(m(Z,[`prevent`]),[`enter`]),g(m(Z,[`prevent`]),[`space`])]},[c(`span`,pe,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(S))]),_:1})]),c(`span`,me,a(l(w)(`@67CE7:复制文件夹名称`)),1)],40,fe),c(`li`,{class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:Q,onKeydown:[g(m(Q,[`prevent`]),[`enter`]),g(m(Q,[`prevent`]),[`space`])]},[c(`span`,ge,[e(s,{"aria-hidden":`true`},{default:v(()=>[e(l(S))]),_:1})]),c(`span`,_e,a(l(w)(`@67CE7:复制文件夹路径`)),1)],40,he),r[23]||=c(`li`,{class:`proj-menu__sep`,role:`separator`},null,-1),c(`li`,ve,a(l(w)(`@WORKBENCH:用工具打开`)),1),(x(!0),u(p,null,f(l(k),t=>(x(),u(`li`,{key:t.id,class:d([`proj-menu__item`,{"is-missing":l(b)(t.id)}]),role:`menuitem`,tabindex:`-1`,onClick:e=>$(t.id),onKeydown:[g(m(e=>$(t.id),[`prevent`]),[`enter`]),g(m(e=>$(t.id),[`prevent`]),[`space`])]},[c(`span`,be,[e(E,{"icon-class":t.icon,class:d({"icon-invert-dark":t.id===`codex`,"icon-outline-dark":l(M).has(t.id)})},null,8,[`icon-class`,`class`])]),c(`span`,xe,a(l(w)(t.labelKey)),1),l(b)(t.id)?(x(),u(`span`,Se,a(l(w)(`@67CE7:未安装`)),1)):C(``,!0)],42,ye))),128)),c(`li`,{class:d([`proj-menu__item`,{"is-missing":l(b)(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[0]||=e=>$(`claude`),onKeydown:[r[1]||=g(m(e=>$(`claude`),[`prevent`]),[`enter`]),r[2]||=g(m(e=>$(`claude`),[`prevent`]),[`space`])]},[c(`span`,Ce,[c(`img`,{src:l(A),alt:``,class:`proj-menu__img`},null,8,we)]),c(`span`,Te,a(l(w)(`@67CE7:用 Claude Code 打开`)),1),c(`span`,Ee,a(l(b)(`claude`)?l(w)(`@67CE7:未安装`):l(w)(`@67CE7:默认权限`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`claude`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[3]||=e=>$(`claude`,`bypassPermissions`),onKeydown:[r[4]||=g(m(e=>$(`claude`,`bypassPermissions`),[`prevent`]),[`enter`]),r[5]||=g(m(e=>$(`claude`,`bypassPermissions`),[`prevent`]),[`space`])]},[c(`span`,De,[c(`img`,{src:l(A),alt:``,class:`proj-menu__img`},null,8,Oe)]),c(`span`,ke,a(l(w)(`@67CE7:用 Claude Code 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`opencode`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[6]||=e=>$(`opencode`,`auto`),onKeydown:[r[7]||=g(m(e=>$(`opencode`,`auto`),[`prevent`]),[`enter`]),r[8]||=g(m(e=>$(`opencode`,`auto`),[`prevent`]),[`space`])]},[c(`span`,Ae,[e(E,{"icon-class":`opencode`})]),c(`span`,je,a(l(w)(`@67CE7:用 OpenCode 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item`,{"is-missing":l(b)(`codex`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[9]||=e=>$(`codex`,`sandboxed`),onKeydown:[r[10]||=g(m(e=>$(`codex`,`sandboxed`),[`prevent`]),[`enter`]),r[11]||=g(m(e=>$(`codex`,`sandboxed`),[`prevent`]),[`space`])]},[c(`span`,Me,[e(E,{"icon-class":`codex`,class:`icon-invert-dark`})]),c(`span`,Ne,a(l(w)(`@67CE7:用 Codex 打开(自动批准)`)),1),l(b)(`codex`)?(x(),u(`span`,Fe,a(l(w)(`@67CE7:未安装`)),1)):(x(),u(`span`,Pe,a(l(w)(`@67CE7:沙箱内`)),1))],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`codex`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[12]||=e=>$(`codex`,`bypass`),onKeydown:[r[13]||=g(m(e=>$(`codex`,`bypass`),[`prevent`]),[`enter`]),r[14]||=g(m(e=>$(`codex`,`bypass`),[`prevent`]),[`space`])]},[c(`span`,Ie,[e(E,{"icon-class":`codex`,class:`icon-invert-dark`})]),c(`span`,Le,a(l(w)(`@67CE7:用 Codex 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`codebuddy`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[15]||=e=>$(`codebuddy`,`bypassPermissions`),onKeydown:[r[16]||=g(m(e=>$(`codebuddy`,`bypassPermissions`),[`prevent`]),[`enter`]),r[17]||=g(m(e=>$(`codebuddy`,`bypassPermissions`),[`prevent`]),[`space`])]},[c(`span`,Re,[e(E,{"icon-class":`codebuddy`})]),c(`span`,ze,a(l(w)(`@67CE7:用 CodeBuddy Code 打开(完全批准)`)),1)],34),c(`li`,{class:d([`proj-menu__item proj-menu__item--danger`,{"is-missing":l(b)(`kimi`)}]),role:`menuitem`,tabindex:`-1`,onClick:r[18]||=e=>$(`kimi`,`auto`),onKeydown:[r[19]||=g(m(e=>$(`kimi`,`auto`),[`prevent`]),[`enter`]),r[20]||=g(m(e=>$(`kimi`,`auto`),[`prevent`]),[`space`])]},[c(`span`,Be,[e(E,{"icon-class":`kimi`})]),c(`span`,Ve,a(l(w)(`@67CE7:用 Kimi Code 打开(完全批准)`)),1)],34),K.value.length?(x(),u(p,{key:0},[r[22]||=c(`li`,{class:`proj-menu__sep`,role:`separator`},null,-1),c(`li`,He,a(l(w)(`@WORKBENCH:桌面端`)),1),(x(!0),u(p,null,f(K.value,e=>(x(),u(`li`,{key:`desktop-${e.id}`,class:`proj-menu__item`,role:`menuitem`,tabindex:`-1`,onClick:t=>q(e.id),onKeydown:[g(m(t=>q(e.id),[`prevent`]),[`enter`]),g(m(t=>q(e.id),[`prevent`]),[`space`])]},[c(`span`,W,[e.id===`claude`?(x(),u(`img`,{key:0,src:l(A),alt:``,class:`proj-menu__img`},null,8,We)):(x(),n(E,{key:1,"icon-class":e.icon,class:d({"icon-invert-dark":e.id===`codex`,"icon-outline-dark":l(M).has(e.id)})},null,8,[`icon-class`,`class`]))]),c(`span`,Ge,a(l(ue)(l(D).desktopAppOf(e.id))),1),c(`span`,Ke,a(l(ae)(l(D).desktopAppOf(e.id))),1)],40,Ue))),128))],64)):C(``,!0)],8,F),e(le,{modelValue:O.value,"onUpdate:modelValue":r[21]||=e=>O.value=e,tool:G.value},null,8,[`modelValue`,`tool`])],64)}}}),[[`__scopeId`,`data-v-80fde3fe`]]);y();function K(){let e=h([]),t=h([]),n=h(``),r=h(!1),i=h(!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||_.error(r?.error||w(`@WORKBENCH:读取项目列表失败`)),!1)}catch(e){return a||_.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),!1}finally{r.value=!1}}async function o(e){if(!e)return{ok:!1,keptTasks:0};try{let t=await fetch(`/api/workbench/projects/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e})}).then(e=>e.json()).catch(()=>null);return t?.success?{ok:!0,keptTasks:Number.isFinite(t.keptTasks)?t.keptTasks:0}:(_.error(t?.error||w(`@WORKBENCH:移除项目失败`)),{ok:!1,keptTasks:0})}catch(e){return _.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),{ok:!1,keptTasks:0}}}async function s(e){if(!e)return{ok:!1,alreadyKnown:!1};try{let t=await fetch(`/api/workbench/projects/add`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e})}).then(e=>e.json()).catch(()=>null);return t?.success?{ok:!0,alreadyKnown:!!t.alreadyKnown}:(_.error(t?.error||w(`@PROJM:添加项目失败`)),{ok:!1,alreadyKnown:!1})}catch(e){return _.error(w(`@WORKBENCH:网络错误: `)+(e?.message||e)),{ok:!1,alreadyKnown:!1}}}return{projects:e,boardTasks:t,currentProjectPath:n,loading:r,loaded:i,loadProjects:a,removeProject:o,addProject:s}}export{G as n,K as t};
|
package/src/ui/public/index.html
CHANGED
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
<meta name="theme-color" content="#141820" media="(prefers-color-scheme: dark)" />
|
|
11
11
|
<title>Zen GitSync</title>
|
|
12
12
|
<!-- 字体改为自托管(@font-face 见 src/main.css),不再依赖 Google Fonts 外链 -->
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-Bnk5Un7L.js"></script>
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/dagre-DcqvOjeb.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/element-plus-D8LubGQe.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-CUQALT_x.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-
|
|
19
|
-
<link rel="modulepreload" crossorigin href="/assets/SvgIcon-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-CfbZLRTe.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/SvgIcon-CvIjcHNr.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/socket-io-TBtw0msS.js">
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/assets/configStore-
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/configStore-DdpMp1OU.js">
|
|
22
22
|
<link rel="modulepreload" crossorigin href="/assets/monaco-CuYd4DgX.js">
|
|
23
23
|
<link rel="modulepreload" crossorigin href="/assets/flow-mindmap-DwG2RDXe.js">
|
|
24
|
-
<link rel="modulepreload" crossorigin href="/assets/CommonDialog-
|
|
24
|
+
<link rel="modulepreload" crossorigin href="/assets/CommonDialog-C83HvDae.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/vue-flow-BEVz6_7M.js">
|
|
26
26
|
<link rel="stylesheet" crossorigin href="/assets/element-plus-D-6gla1z.css">
|
|
27
27
|
<link rel="stylesheet" crossorigin href="/assets/vendor-CHUY5AXG.css">
|
|
@@ -675,6 +675,138 @@ export function registerFsRoutes({
|
|
|
675
675
|
});
|
|
676
676
|
}));
|
|
677
677
|
|
|
678
|
+
// ── 最近修改的文件(文件空间左栏底部的「最近修改」)─────────────────────
|
|
679
|
+
//
|
|
680
|
+
// 用户诉求:同步盘里的笔记常常是在**别的电脑**上改的,文件树按名字排序看不出
|
|
681
|
+
// 谁新谁旧。这里按磁盘 mtime 倒序 —— 明确不是"这个应用打开过哪些文件",
|
|
682
|
+
// 后者是另一套数据(本应用从不记录打开历史,也不需要记录)。
|
|
683
|
+
//
|
|
684
|
+
// 遍历代价靠边界控制(和上面的内容搜索同一套判据):跳过隐藏目录 / 依赖目录 /
|
|
685
|
+
// 软链接,最多扫 2 万个文件、8 秒兜底;结果按根目录缓存 12 秒 ——
|
|
686
|
+
// 面板展开、60s 树轮询、点刷新会连着问同一件事。
|
|
687
|
+
const RECENT_FILES_MAX_SCAN = 20000;
|
|
688
|
+
const RECENT_FILES_MAX_DIRS = 3000;
|
|
689
|
+
const RECENT_FILES_TIME_BUDGET_MS = 8000;
|
|
690
|
+
const RECENT_FILES_STAT_CONCURRENCY = 24;
|
|
691
|
+
const RECENT_FILES_CACHE_TTL_MS = 12000;
|
|
692
|
+
const RECENT_FILES_LIMIT_DEFAULT = 20;
|
|
693
|
+
const RECENT_FILES_LIMIT_MAX = 50;
|
|
694
|
+
const RECENT_FILES_DIR_BATCH = 16;
|
|
695
|
+
const recentFilesCache = new Map();
|
|
696
|
+
|
|
697
|
+
// 遍历 + stat。返回按 mtime 倒序的全量表(路由层再按 limit 切),
|
|
698
|
+
// 这样同一份缓存能服务不同的 limit,不必因为前端改条数就重扫一遍。
|
|
699
|
+
async function collectRecentFiles(rootPath, deadline) {
|
|
700
|
+
const files = [];
|
|
701
|
+
const dirQueue = [rootPath];
|
|
702
|
+
let scannedFiles = 0;
|
|
703
|
+
let scannedDirs = 0;
|
|
704
|
+
let truncated = false;
|
|
705
|
+
|
|
706
|
+
while (dirQueue.length > 0) {
|
|
707
|
+
if (Date.now() > deadline) { truncated = true; break; }
|
|
708
|
+
const batch = dirQueue.splice(0, RECENT_FILES_DIR_BATCH);
|
|
709
|
+
const listings = await Promise.all(
|
|
710
|
+
batch.map((dir) => fs.readdir(dir, { withFileTypes: true }).catch(() => []))
|
|
711
|
+
);
|
|
712
|
+
|
|
713
|
+
const pending = [];
|
|
714
|
+
for (let i = 0; i < listings.length; i += 1) {
|
|
715
|
+
for (const entry of listings[i]) {
|
|
716
|
+
// 符号链接不跟:可能指回祖先目录,直接把遍历变成死循环
|
|
717
|
+
if (entry.isSymbolicLink()) continue;
|
|
718
|
+
const fullPath = path.join(batch[i], entry.name);
|
|
719
|
+
if (entry.isDirectory()) {
|
|
720
|
+
// 隐藏目录(.git / .obsidian / .venv ...)与依赖/构建产物目录都不是"笔记"
|
|
721
|
+
if (entry.name.startsWith('.') || CONTENT_SEARCH_IGNORED_DIRS.has(entry.name)) continue;
|
|
722
|
+
if (scannedDirs >= RECENT_FILES_MAX_DIRS) { truncated = true; break; }
|
|
723
|
+
scannedDirs += 1;
|
|
724
|
+
dirQueue.push(fullPath);
|
|
725
|
+
} else if (entry.isFile()) {
|
|
726
|
+
// 隐藏文件同理:.gitignore / .DS_Store 这类会把"最近修改"榜单挤满
|
|
727
|
+
if (entry.name.startsWith('.')) continue;
|
|
728
|
+
if (scannedFiles >= RECENT_FILES_MAX_SCAN) { truncated = true; break; }
|
|
729
|
+
scannedFiles += 1;
|
|
730
|
+
pending.push(fullPath);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
if (truncated) break;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// 有界并发 stat:一次 24 个,避免 2 万个文件串行把请求拖成 10 秒
|
|
737
|
+
let cursor = 0;
|
|
738
|
+
const workers = Array.from(
|
|
739
|
+
{ length: Math.min(RECENT_FILES_STAT_CONCURRENCY, pending.length) },
|
|
740
|
+
async () => {
|
|
741
|
+
while (cursor < pending.length && Date.now() <= deadline) {
|
|
742
|
+
const filePath = pending[cursor];
|
|
743
|
+
cursor += 1;
|
|
744
|
+
try {
|
|
745
|
+
const stat = await fs.stat(filePath);
|
|
746
|
+
if (stat.isFile()) {
|
|
747
|
+
// mtimeMs 是浮点(NTFS 精度更高),取整即可 —— 前端只拿它排时间文案
|
|
748
|
+
files.push({ path: filePath, name: path.basename(filePath), mtimeMs: Math.round(stat.mtimeMs) });
|
|
749
|
+
}
|
|
750
|
+
} catch {
|
|
751
|
+
// 刚被删 / 无权限:跳过这只文件,不影响整张榜
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
);
|
|
756
|
+
await Promise.all(workers);
|
|
757
|
+
if (truncated) break;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
files.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
761
|
+
return { files, truncated, scannedFiles };
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
app.get('/api/recent_files', asyncRoute(async (req, res) => {
|
|
765
|
+
const rawRoot = req.query.path;
|
|
766
|
+
if (typeof rawRoot !== 'string' || !rawRoot.trim()) {
|
|
767
|
+
res.status(400).json({ success: false, error: '缺少 path 参数' });
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
const guard = await safePathInProject(rawRoot);
|
|
771
|
+
if (!guard) {
|
|
772
|
+
res.status(403).json({ success: false, error: '禁止读取工作目录以外的路径' });
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
const rootPath = guard.safePath;
|
|
776
|
+
const rawLimit = Number(req.query.limit);
|
|
777
|
+
const limit = Number.isFinite(rawLimit)
|
|
778
|
+
? Math.min(RECENT_FILES_LIMIT_MAX, Math.max(1, Math.floor(rawLimit)))
|
|
779
|
+
: RECENT_FILES_LIMIT_DEFAULT;
|
|
780
|
+
|
|
781
|
+
const cacheKey = process.platform === 'win32' ? rootPath.toLowerCase() : rootPath;
|
|
782
|
+
// refresh=1:用户手点刷新 / 探针刚造完文件时必须看盘上最新状态,不能吃 12s 缓存
|
|
783
|
+
const force = req.query.refresh === '1' || req.query.refresh === 'true';
|
|
784
|
+
const cached = recentFilesCache.get(cacheKey);
|
|
785
|
+
const now = Date.now();
|
|
786
|
+
let entry = !force && cached && now - cached.at < RECENT_FILES_CACHE_TTL_MS ? cached : null;
|
|
787
|
+
if (!entry) {
|
|
788
|
+
const startedAt = now;
|
|
789
|
+
const collected = await collectRecentFiles(rootPath, startedAt + RECENT_FILES_TIME_BUDGET_MS);
|
|
790
|
+
entry = { at: Date.now(), ...collected, elapsedMs: Date.now() - startedAt };
|
|
791
|
+
recentFilesCache.set(cacheKey, entry);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const items = entry.files.slice(0, limit).map((file) => {
|
|
795
|
+
const relPath = path.relative(rootPath, file.path).split(path.sep).join('/');
|
|
796
|
+
const dir = path.posix.dirname(relPath);
|
|
797
|
+
return { ...file, relPath, dir: dir === '.' ? '' : dir };
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
res.json({
|
|
801
|
+
success: true,
|
|
802
|
+
root: rootPath,
|
|
803
|
+
items,
|
|
804
|
+
truncated: entry.truncated,
|
|
805
|
+
scannedFiles: entry.scannedFiles,
|
|
806
|
+
elapsedMs: entry.elapsedMs,
|
|
807
|
+
});
|
|
808
|
+
}));
|
|
809
|
+
|
|
678
810
|
// 获取最近访问的目录列表
|
|
679
811
|
//
|
|
680
812
|
// 每条带一个 `iconUrl`(项目自己的 favicon,见 workbench/projectIcon.js)——
|