@shaohui_jin/git-cockpit-mcp-server 0.1.5 → 0.1.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/dist/{chunk-ASBVWOQY.js → chunk-5CZ3BO3H.js} +33 -2
- package/dist/chunk-5CZ3BO3H.js.map +1 -0
- package/dist/{chunk-4QEU6AVI.js → chunk-CLCT6P3U.js} +6 -3
- package/dist/chunk-CLCT6P3U.js.map +1 -0
- package/dist/cli-entry.js +2 -2
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/mcpServer.d.ts +1 -1
- package/dist/{runtime-CmdOmv60.d.ts → runtime-BzkM1IAj.d.ts} +2 -0
- package/dist/web/assets/{index-CBdX3yjE.css → index-BrQ29WGx.css} +1 -1
- package/dist/web/assets/index-rh3DXMef.js +114 -0
- package/dist/web/index.html +2 -2
- package/dist/webServer.d.ts +1 -1
- package/dist/webServer.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-4QEU6AVI.js.map +0 -1
- package/dist/chunk-ASBVWOQY.js.map +0 -1
- package/dist/web/assets/index-CSq1S2W2.js +0 -4
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{az as qe,c as T,G as ae,d as ue,a6 as Nt,O as S,W as t,aj as g,aA as It,aB as Be,L as o,a0 as l,P as i,$ as h,u as A,M as b,F as P,ae as X,_ as f,Y as Ft,k as q,aq as We,Z as z,S as ve,w as ie,i as Ot,e as Fe,X as _e,ac as me,ak as Se,aC as Pt,aD as qt,aw as Bt,aE as Wt}from"./vue-CYNDxJyv.js";import{E as G,a as Ge,e as Gt}from"./element-plus-D8uC5V5h.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))y(r);new MutationObserver(r=>{for(const C of r)if(C.type==="childList")for(const E of C.addedNodes)E.tagName==="LINK"&&E.rel==="modulepreload"&&y(E)}).observe(document,{childList:!0,subtree:!0});function u(r){const C={};return r.integrity&&(C.integrity=r.integrity),r.referrerPolicy&&(C.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?C.credentials="include":r.crossOrigin==="anonymous"?C.credentials="omit":C.credentials="same-origin",C}function y(r){if(r.ep)return;r.ep=!0;const C=u(r);fetch(r.href,C)}})();class nt extends Error{constructor(s,u,y,r){super(s),this.status=u,this.code=y,this.requiredApproval=r,this.name="ApiError"}}async function K(a,s,u){let y;try{y=await fetch(s,{method:a,headers:u!==void 0?{"Content-Type":"application/json"}:void 0,body:u!==void 0?JSON.stringify(u):void 0})}catch(r){throw new nt(`无法连接后端服务(${s}):${r instanceof Error?r.message:String(r)}`,0)}if(!y.ok){let r=y.statusText,C,E;try{const L=await y.json();r=L.error??r,C=L.code,E=L.requiredApproval}catch{}throw new nt(r,y.status,C,E)}return await y.json()}function Mt(){return K("GET","/api/repos")}function Ht(a){return K("POST","/api/repos/open",{path:a})}function jt(a){return K("DELETE",`/api/repos/${a}`)}function Jt(a){return K("GET",`/api/repos/${a}/status`)}function Kt(a,s={}){const u=new URLSearchParams;s.maxCount&&u.set("maxCount",String(s.maxCount)),s.all&&u.set("all","true"),s.path&&u.set("path",s.path),s.from&&u.set("from",s.from),s.to&&u.set("to",s.to),s.author&&u.set("author",s.author);const y=u.toString();return K("GET",`/api/repos/${a}/log${y?`?${y}`:""}`)}function Xt(a,s={}){const u=new URLSearchParams;s.from&&u.set("from",s.from),s.to&&u.set("to",s.to),s.path&&u.set("path",s.path),s.staged&&u.set("staged","true");const y=u.toString();return K("GET",`/api/repos/${a}/diff${y?`?${y}`:""}`)}function Yt(a,s){return K("GET",`/api/repos/${a}/show/${encodeURIComponent(s)}`)}function at(a){return K("GET",`/api/repos/${a}/branches`)}function Zt(a){return K("GET",`/api/repos/${a}/stashes`)}function Oe(a,s,u={}){return K("POST",`/api/repos/${a}/tools/${s}`,{params:u})}function Qt(a={}){const s=new URLSearchParams;a.limit&&s.set("limit",String(a.limit)),a.tool&&s.set("tool",a.tool);const u=s.toString();return K("GET",`/api/logs${u?`?${u}`:""}`)}function el(){return K("GET","/api/settings")}function tl(a){return K("PUT","/api/settings",{permissions:a})}function ll(){return K("GET","/api/health")}function sl(a){const s=new EventSource("/api/events");return a.onRepoChanged&&s.addEventListener("repo-changed",u=>{var y;return(y=a.onRepoChanged)==null?void 0:y.call(a,JSON.parse(u.data))}),a.onLog&&s.addEventListener("log",()=>{var u;return(u=a.onLog)==null?void 0:u.call(a)}),a.onError&&(s.onerror=u=>{var y;return(y=a.onError)==null?void 0:y.call(a,u)}),()=>s.close()}const Te=qe("repos",{state:()=>({repos:[],currentId:null,loading:!1,error:null,healthOk:null}),getters:{current(a){return a.repos.find(s=>s.id===a.currentId)??null},currentPath(a){var s;return((s=a.repos.find(u=>u.id===a.currentId))==null?void 0:s.path)??null}},actions:{async checkHealth(){try{const a=await ll();this.healthOk=a.ok}catch{this.healthOk=!1}return this.healthOk===!0},async load(){var a;this.loading=!0,this.error=null;try{const{repos:s}=await Mt();this.repos=s,(!this.currentId||!s.some(u=>u.id===this.currentId))&&(this.currentId=((a=s[0])==null?void 0:a.id)??null)}catch(s){this.error=s instanceof Error?s.message:String(s)}finally{this.loading=!1}},async open(a){const{repo:s}=await Ht(a);return await this.load(),s},async remove(a){await jt(a),this.currentId===a&&(this.currentId=null),await this.load()},switchTo(a){this.currentId=a}}}),ot=qe("settings",{state:()=>({permissions:null,tools:[],loading:!1,saving:!1,error:null}),actions:{async load(){this.loading=!0,this.error=null;try{const a=await el();this.permissions=a.permissions,this.tools=a.tools}catch(a){this.error=a instanceof Error?a.message:String(a)}finally{this.loading=!1}},async save(a){if(this.permissions){this.saving=!0,this.error=null;try{await tl(a),this.permissions={...this.permissions,...a}}catch(s){throw this.error=s instanceof Error?s.message:String(s),s}finally{this.saving=!1}}}}}),it=T(0),nl=()=>{it.value+=1};function Ee(){return{revision:it,bump:nl}}const al={class:"repo-box"},ol=["title"],il={class:"menu-icon"},rl={class:"aside-footer"},ul=ae({__name:"App",setup(a){const s=Te(),u=ot(),y=It(),r=Be(),{bump:C}=Ee(),E=[{path:"/status",label:"状态",icon:"◧"},{path:"/history",label:"历史",icon:"◫"},{path:"/repos",label:"仓库管理",icon:"▤"},{path:"/logs",label:"操作日志",icon:"≡"},{path:"/settings",label:"设置",icon:"⚙"}],L=q(()=>{if(!s.currentId)return"未选择仓库";const c=s.repos.find(d=>d.id===s.currentId);return(c==null?void 0:c.path)??"未选择仓库"});let I=null;return ue(async()=>{await s.checkHealth(),await Promise.all([s.load(),u.load().catch(()=>{})]),I=sl({onRepoChanged:()=>C(),onLog:()=>C(),onError:()=>{}})}),Nt(()=>{I==null||I()}),(c,d)=>{const p=g("el-menu-item"),_=g("el-menu"),m=g("el-tag"),x=g("el-aside"),U=g("router-view"),B=g("el-main"),M=g("el-container");return o(),S(M,{class:"app-shell"},{default:t(()=>[l(x,{width:"220px",class:"app-aside"},{default:t(()=>[d[4]||(d[4]=i("div",{class:"brand"},[i("span",{class:"brand-mark"},"⌘"),i("span",{class:"brand-name"},"Git Cockpit")],-1)),i("div",al,[d[0]||(d[0]=i("div",{class:"repo-box-label"},"当前仓库",-1)),i("div",{class:"repo-box-path mono",title:L.value},h(L.value),9,ol)]),l(_,{"default-active":A(y).path,class:"nav-menu"},{default:t(()=>[(o(),b(P,null,X(E,D=>l(p,{key:D.path,index:D.path,onClick:H=>A(r).push(D.path)},{default:t(()=>[i("span",il,h(D.icon),1),i("span",null,h(D.label),1)]),_:2},1032,["index","onClick"])),64))]),_:1},8,["default-active"]),i("div",rl,[A(s).healthOk?(o(),S(m,{key:0,size:"small",type:"success"},{default:t(()=>[...d[1]||(d[1]=[f("后端已连接",-1)])]),_:1})):A(s).healthOk===!1?(o(),S(m,{key:1,size:"small",type:"danger"},{default:t(()=>[...d[2]||(d[2]=[f("后端离线",-1)])]),_:1})):(o(),S(m,{key:2,size:"small",type:"info"},{default:t(()=>[...d[3]||(d[3]=[f("连接中…",-1)])]),_:1}))])]),_:1}),l(M,{class:"app-main"},{default:t(()=>[l(B,{class:"main-content"},{default:t(()=>[l(U,null,{default:t(({Component:D})=>[(o(),S(Ft(D)))]),_:1})]),_:1})]),_:1})]),_:1})}}}),oe=(a,s)=>{const u=a.__vccOpts||a;for(const[y,r]of s)u[y]=r;return u},dl=oe(ul,[["__scopeId","data-v-b0a0ed56"]]),cl={class:"page"},pl={class:"open-row"},fl={class:"list-header"},ml={class:"repo-path mono"},vl=ae({__name:"ReposView",setup(a){const s=Te(),u=Be(),y=T(""),r=T(!1);async function C(){const d=y.value.trim();if(!d){G.warning("请输入仓库路径");return}r.value=!0;try{const p=await s.open(d);G.success(`已打开 ${p.path}`),s.switchTo(p.id),await u.push("/status")}catch(p){G.error(p instanceof Error?p.message:String(p))}finally{r.value=!1}}async function E(d,p){try{await Ge.confirm(`确定从列表移除 ${p}?注意:不会删除磁盘上的仓库文件。`,"移除仓库",{type:"warning",confirmButtonText:"移除",cancelButtonText:"取消"})}catch{return}try{await s.remove(d),G.success("已移除")}catch(_){G.error(_ instanceof Error?_.message:String(_))}}function L(d){s.switchTo(d),u.push("/status")}function I(d){const p=new Date(d);return Number.isNaN(p.getTime())?d:p.toLocaleString()}function c({row:d}){return d.id===s.currentId?"is-current":""}return ue(()=>s.load()),(d,p)=>{const _=g("el-input"),m=g("el-button"),x=g("el-card"),U=g("el-empty"),B=g("el-table-column"),M=g("el-table");return o(),b("div",cl,[p[8]||(p[8]=i("h2",{class:"page-title"},"仓库管理",-1)),l(x,{class:"open-card",shadow:"never"},{header:t(()=>[...p[2]||(p[2]=[f("打开本地仓库",-1)])]),default:t(()=>[i("div",pl,[l(_,{modelValue:y.value,"onUpdate:modelValue":p[0]||(p[0]=D=>y.value=D),placeholder:"输入本地 Git 仓库路径,例如 D:\\project\\repo 或 /Users/me/code/app",clearable:"",onKeyup:We(C,["enter"])},null,8,["modelValue"]),l(m,{type:"primary",loading:r.value,onClick:C},{default:t(()=>[...p[3]||(p[3]=[f("打开",-1)])]),_:1},8,["loading"])])]),_:1}),l(x,{shadow:"never",class:"list-card"},{header:t(()=>[i("div",fl,[p[5]||(p[5]=i("span",null,"最近打开的仓库",-1)),l(m,{text:"",type:"primary",loading:A(s).loading,onClick:p[1]||(p[1]=D=>A(s).load())},{default:t(()=>[...p[4]||(p[4]=[f("刷新",-1)])]),_:1},8,["loading"])])]),default:t(()=>[!A(s).loading&&A(s).repos.length===0?(o(),S(U,{key:0,description:"尚未打开任何仓库"})):(o(),S(M,{key:1,data:A(s).repos,size:"default","highlight-current-row":"","row-class-name":c},{default:t(()=>[l(B,{label:"路径","min-width":"320"},{default:t(({row:D})=>[i("div",ml,h(D.path),1)]),_:1}),l(B,{label:"最近打开",width:"190"},{default:t(({row:D})=>[f(h(I(D.lastOpenedAt)),1)]),_:1}),l(B,{label:"操作",width:"180",align:"right"},{default:t(({row:D})=>[l(m,{size:"small",text:"",type:"primary",onClick:H=>L(D.id)},{default:t(()=>[...p[6]||(p[6]=[f("进入",-1)])]),_:1},8,["onClick"]),l(m,{size:"small",text:"",type:"danger",onClick:H=>E(D.id,D.path)},{default:t(()=>[...p[7]||(p[7]=[f("移除",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"]))]),_:1})])}}}),_l=oe(vl,[["__scopeId","data-v-ff70c4b1"]]);function hl(a){const s=Be(),u=T(!1),y=T(null),r=T(!1),C=q(()=>a()!==null);async function E(p,_={}){const m=a();if(m===null)return G.warning("请先选择仓库"),!1;try{const x=await Oe(m,p,{..._,dryRun:!0});return x.success?(y.value={tool:p,params:_,preview:x.preview??x.result},u.value=!0,!0):(c(x),!1)}catch(x){return d(x),!1}}async function L(){const p=a(),_=y.value;if(p===null||!_)return null;r.value=!0,u.value=!1;try{const m=await Oe(p,_.tool,_.params);return m.success?(m.backupCreated?G.success(`${_.tool} 执行成功(已自动备份:${m.backupCreated.branch??"分支"}${m.backupCreated.stashRef?` / ${m.backupCreated.stashRef}`:""})`):G.success(`${_.tool} 执行成功`),m):(c(m),m)}catch(m){return d(m),null}finally{r.value=!1,y.value=null}}function I(){u.value=!1,y.value=null}function c(p){var _,m,x;if(((_=p.error)==null?void 0:_.code)==="PERMISSION_DENIED"){p.error.requiredApproval?Ge.confirm(`操作 ${p.tool} 属于高风险操作,当前默认禁用,需要在设置中开启后才能执行。是否前往设置?`,"需要审批",{confirmButtonText:"去开启",cancelButtonText:"取消",type:"warning"}).then(()=>s.push("/settings")).catch(()=>{}):G.error(((m=p.error)==null?void 0:m.message)??"操作被拒绝");return}G.error(((x=p.error)==null?void 0:x.message)??"操作失败")}function d(p){const _=p instanceof Error?p.message:String(p);G.error(_)}return{confirmVisible:u,pending:y,executing:r,canRun:C,previewAndConfirm:E,executeConfirmed:L,cancel:I}}const gl={key:2,class:"cmd-box"},yl={class:"cmd-pre mono"},bl={key:3,class:"files-box"},kl={class:"cmd-label"},wl={key:4,class:"note-text"},Cl={class:"risk-tag"},$l=ae({__name:"ConfirmDialog",props:{visible:{type:Boolean},tool:{},preview:{default:null},note:{default:""}},emits:["update:visible","confirm","cancel"],setup(a,{emit:s}){const u=a,y=s,r=q(()=>{const d=u.preview;return d&&"command"in d&&typeof d.command=="string"?d.command:""}),C=q(()=>{const d=u.preview;return d&&"risk"in d&&typeof d.risk=="string"?d.risk:"write"}),E=q(()=>{const d=u.preview;return d&&"affectedFiles"in d&&Array.isArray(d.affectedFiles)?d.affectedFiles:[]}),L=q(()=>C.value==="dangerous"?{type:"danger",label:"高风险"}:C.value==="write"?{type:"warning",label:"写操作"}:{type:"info",label:"只读"});function I(){y("confirm")}function c(){y("cancel"),y("update:visible",!1),G.info("操作已取消")}return(d,p)=>{const _=g("el-alert"),m=g("el-scrollbar"),x=g("el-tag"),U=g("el-button"),B=g("el-dialog");return o(),S(B,{"model-value":a.visible,title:`执行操作:${a.tool}`,width:"560px","close-on-click-modal":!1,onClosed:p[0]||(p[0]=M=>y("update:visible",!1))},{footer:t(()=>[i("span",Cl,[l(x,{type:L.value.type,size:"small",effect:"dark"},{default:t(()=>[f(h(L.value.label),1)]),_:1},8,["type"])]),l(U,{onClick:c},{default:t(()=>[...p[4]||(p[4]=[f("取消",-1)])]),_:1}),l(U,{type:"primary",danger:C.value==="dangerous",onClick:I},{default:t(()=>[...p[5]||(p[5]=[f("确认执行",-1)])]),_:1},8,["danger"])]),default:t(()=>[C.value==="dangerous"?(o(),S(_,{key:0,type:"error",closable:!1,"show-icon":"",class:"risk-alert"},{title:t(()=>[...p[1]||(p[1]=[f("这是",-1),i("b",null,"高风险",-1),f("操作,将自动创建备份(临时分支 + stash)",-1)])]),_:1})):C.value==="write"?(o(),S(_,{key:1,type:"warning",closable:!1,"show-icon":"",class:"risk-alert"},{title:t(()=>[...p[2]||(p[2]=[f("写操作:执行后将修改仓库状态",-1)])]),_:1})):z("",!0),r.value?(o(),b("div",gl,[p[3]||(p[3]=i("div",{class:"cmd-label"},"将执行的命令(dry-run 预览,未实际执行)",-1)),i("pre",yl,h(r.value),1)])):z("",!0),E.value.length?(o(),b("div",bl,[i("div",kl,"涉及文件("+h(E.value.length)+")",1),l(m,{"max-height":"140px"},{default:t(()=>[(o(!0),b(P,null,X(E.value,M=>(o(),b("div",{key:M,class:"file-item mono"},h(M),1))),128))]),_:1})])):z("",!0),a.note?(o(),b("div",wl,h(a.note),1)):z("",!0)]),_:1},8,["model-value","title"])}}}),xl=oe($l,[["__scopeId","data-v-0e5cd08f"]]),Vl={class:"diff-pre mono"},Sl=ae({__name:"DiffViewer",props:{patch:{}},setup(a){const s=a,u=q(()=>{const y=[];for(const r of s.patch.split(`
|
|
2
|
-
`)){const C=r.startsWith("diff --git")||r.startsWith("index ")||r.startsWith("---")||r.startsWith("+++")||r.startsWith("new file")||r.startsWith("deleted file")||r.startsWith("similarity")||r.startsWith("rename ")?"meta":r.startsWith("@@")?"hunk":r.startsWith("+")?"add":r.startsWith("-")?"del":"plain";y.push({type:C,text:r})}return y});return(y,r)=>(o(),b("pre",Vl,[(o(!0),b(P,null,X(u.value,(C,E)=>(o(),b(P,{key:E},[i("span",{class:ve(C.type)},h(C.text),3),r[0]||(r[0]=f(`
|
|
3
|
-
`,-1))],64))),128))]))}}),Pe=oe(Sl,[["__scopeId","data-v-cd09efab"]]),Tl={class:"page status-page"},El={class:"page-head"},zl={class:"head-branch"},Dl={key:0,class:"tracking mono"},Al={key:1,class:"sync ahead"},Rl={key:2,class:"sync behind"},Ll={class:"repo-path mono"},Ul={key:1,class:"empty-tip"},Nl={key:2,class:"status-layout"},Il={class:"panel-head"},Fl={class:"panel-actions"},Ol={class:"tree-scroll"},Pl={class:"group-label"},ql=["onDblclick"],Bl={class:"node-name"},Wl={class:"node-actions"},Gl=["onDblclick"],Ml={class:"node-name"},Hl={class:"node-actions"},jl={class:"status-content"},Jl={class:"toolbar"},Kl={class:"toolbar-group"},Xl={class:"card-head"},Yl={class:"card-actions"},Zl={class:"tab-label"},Ql={class:"tab-hint"},es={key:0,class:"file-empty"},ts={key:1,class:"file-list"},ls=["title"],ss={class:"card-head"},ns={class:"card-title"},as={class:"card-actions"},os={key:0,class:"file-empty"},is={key:1,class:"stash-list mono"},rs={class:"stash-main"},us={class:"stash-ref"},ds=["title"],cs={key:0,class:"stash-date"},ps={class:"stash-actions"},fs={class:"diff-wrap"},ms={class:"diff-summary"},vs={class:"add"},_s={class:"del"},hs={key:0,class:"warn"},gs={key:0,class:"file-empty"},ys={key:0,class:"stash-files"},bs={class:"stash-files-head"},ks={class:"stash-files-title"},ws={class:"card-actions"},Cs={class:"file-list compact"},$s={class:"file-path mono"},xs=ae({__name:"StatusView",setup(a){const s=Te(),{revision:u}=Ee(),y=()=>s.currentId,r=T(null),C=T([]),E=T([]),L=T(!1),I=T(""),c=Fe({visible:!1,title:"",diff:null,patch:"",loading:!1}),d=T(!1),p=T(""),_=T(!1),m=T(""),x=T(""),U=T(!1),B=T(""),M=T(!1),D=T(!1),H=T(""),w=Fe(new Set),te=q(()=>w.size),ne=T("unstaged"),{confirmVisible:W,pending:$,canRun:Q,previewAndConfirm:O,executeConfirmed:de,cancel:re}=hl(y),he=q(()=>{var n;return((n=s.current)==null?void 0:n.path)??""}),De=q(()=>{var n,e;return((n=r.value)==null?void 0:n.currentShort)??((e=r.value)==null?void 0:e.current)??""}),ge=q(()=>{var n;return((n=r.value)==null?void 0:n.ahead)??0}),ce=q(()=>{var n;return((n=r.value)==null?void 0:n.behind)??0}),Y=q(()=>{const n=r.value;if(!n)return{unstaged:[],staged:[],untracked:[],all:[]};const e=n.untracked.map(J=>({path:J,status:"??",indexStatus:"?",workTreeStatus:"?",staged:!1,untracked:!0,conflicted:!1})),N=[...n.staged,...n.unstaged,...e],k=new Set,R=N.filter(J=>k.has(J.path)?!1:(k.add(J.path),J.path!==""));return{unstaged:n.unstaged,staged:n.staged,untracked:e,all:R}}),Ae=q(()=>[{key:"unstaged",label:"未暂存",hint:"已修改,未 git add",count:Y.value.unstaged.length},{key:"staged",label:"已暂存",hint:"已 git add,未提交",count:Y.value.staged.length},{key:"untracked",label:"未跟踪",hint:"工作区新文件",count:Y.value.untracked.length},{key:"all",label:"全部",hint:"全部更改",count:Y.value.all.length}]),Re=q(()=>Y.value[ne.value]??[]),ye=q(()=>Y.value.all.length),be=q(()=>{const n=C.value.filter(R=>!R.remote),e=C.value.filter(R=>R.remote),N=new Map;for(const R of e){const J=R.name.indexOf("/"),le=J===-1?R.name:R.name.slice(0,J),ee=N.get(le)??[];ee.push(R),N.set(le,ee)}const k=[];k.push({key:"group:local",type:"group",label:`本地分支(${n.length})`,children:n.map(R=>({key:"l:"+R.name,type:"local",label:R.name,branch:R}))});for(const[R,J]of N){const le=[...J].sort((ee,Le)=>ee.name.localeCompare(Le.name));k.push({key:"group:remote:"+R,type:"group",label:`远程 · ${R}(${le.length})`,children:le.map(ee=>({key:"r:"+ee.name,type:"remote",label:ee.name.slice(R.length+1),branch:ee}))})}return k});function ke(n){if(!n||n.remote||!n.upstream)return"";const e=[];return(n.ahead??0)>0&&e.push(`↑${n.ahead}`),(n.behind??0)>0&&e.push(`↓${n.behind}`),e.join(" ")}async function we(){const n=y();if(n!==null){L.value=!0,I.value="";try{r.value=await Jt(n)}catch(e){I.value=e instanceof Error?e.message:String(e),r.value=null}finally{L.value=!1}}}async function F(){const n=y();if(n!==null)try{const{branches:e}=await at(n);C.value=e}catch{}}async function Z(){const n=y();if(n!==null)try{E.value=await Zt(n)}catch{}}async function pe(){await Promise.all([we(),F(),Z()])}async function j(n,e={}){await O(n,e)&&G.info("请在确认对话框中查看 dry-run 预览")}async function ut(){const n=await de();n!=null&&n.success&&await pe()}function Me(n){j("git_add",{paths:[n.path]})}function dt(n){j("git_unstage",{paths:[n.path]})}function ct(n){n.staged?dt(n):Me(n)}function pt(){j("git_add",{})}function ft(){var e;const n=((e=r.value)==null?void 0:e.staged.map(N=>N.path))??[];if(n.length===0){G.info("没有已暂存的文件");return}j("git_unstage",{paths:n})}async function mt(n){const e=y();if(e!==null){c.title=`${n.path}(${n.staged?"已 git add":"工作区修改"})`,c.diff=null,c.patch="",c.visible=!0,c.loading=!0;try{c.diff=await Xt(e,{path:n.path,staged:n.staged})}catch(N){G.error(N instanceof Error?N.message:String(N)),c.visible=!1}finally{c.loading=!1}}}async function vt(n){var N;const e=y();if(e!==null){c.title=`${n.ref} · ${n.message||"(无说明)"}`,c.diff=null,c.patch="",c.visible=!0,c.loading=!0;try{const k=await Oe(e,"git_stash_show",{index:n.index});if(k.success){const R=k.result??{};c.patch=R.patch??""}else G.error(((N=k.error)==null?void 0:N.message)??"查看差异失败"),c.visible=!1}catch(k){G.error(k instanceof Error?k.message:String(k)),c.visible=!1}finally{c.loading=!1}}}function He(n){w.has(n)?w.delete(n):w.add(n)}function je(n){return w.has(n)}function Je(){w.clear()}function _t(){for(const n of Re.value)w.add(n.path)}function ht(){for(const n of Ce.value)w.add(n)}const Ce=q(()=>{const n=r.value;if(!n)return[];const e=new Set;return[...n.unstaged.map(N=>N.path),...n.untracked].filter(N=>e.has(N)?!1:(e.add(N),N!==""))});function gt(){U.value=!0}function yt(){const n=Ce.value,e=[...w].filter(R=>n.includes(R)),N=e.some(R=>{var J;return((J=r.value)==null?void 0:J.untracked.includes(R))??!1}),k={};B.value.trim()&&(k.message=B.value.trim()),e.length&&(k.paths=e),(M.value||N)&&(k.includeUntracked=!0),U.value=!1,w.clear(),j("git_stash",k)}function bt(){j("git_stash",{})}function kt(n){j("git_stash_apply",{index:n.index})}function wt(n){j("git_stash_pop",{index:n.index})}function Ct(n){Ge.confirm(`确定删除 ${n.ref} 吗?删除后不可直接恢复。`,"删除 stash",{type:"warning",confirmButtonText:"继续",cancelButtonText:"取消"}).then(()=>void j("git_stash_drop",{index:n.index})).catch(()=>{})}function $e(n){n.branch&&j("git_checkout",{branch:n.branch.name})}function $t(){j("git_pull")}function xt(){j("git_push")}function Ke(){const n=p.value.trim();if(!n){G.warning("请输入提交信息");return}d.value=!1,j("git_commit",{message:n})}function Vt(){const n=m.value.trim();if(!n){G.warning("请输入分支名");return}_.value=!1,j("git_branch_create",x.value.trim()?{name:n,startPoint:x.value.trim()}:{name:n})}function St(){const n=H.value.trim()||"HEAD";D.value=!1,H.value="",j("git_reset_hard",{target:n})}function Tt(n){return n.untracked?"?":n.staged?n.indexStatus||"M":n.workTreeStatus||"M"}function Et(n){return n.untracked?"new":n.conflicted?"conflict":n.staged?"add":"mod"}function zt(n){if(!n)return"";const e=new Date(n);return Number.isNaN(e.getTime())?n:e.toLocaleString()}function Dt(n){return n.split(`
|
|
4
|
-
`)[0]??""}return ie(y,()=>{c.diff=null,c.patch="",c.visible=!1,w.clear(),pe()}),ie(u,()=>{pe()}),ue(()=>{pe()}),(n,e)=>{var Ye,Ze,Qe,et,tt;const N=g("el-tag"),k=g("el-button"),R=g("el-alert"),J=g("el-empty"),le=g("el-card"),ee=g("el-badge"),Le=g("el-tooltip"),Ue=g("el-checkbox"),At=g("el-tab-pane"),Rt=g("el-tabs"),Lt=g("el-drawer"),fe=g("el-input"),xe=g("el-dialog"),Ve=g("el-form-item"),Xe=g("el-form"),Ut=Se("loading");return o(),b("div",Tl,[i("div",El,[e[26]||(e[26]=i("h2",{class:"page-title"},"仓库状态",-1)),i("div",zl,[l(N,{type:"primary",effect:"dark",class:"branch-tag"},{default:t(()=>[f(h(De.value||"—"),1)]),_:1}),(Ye=r.value)!=null&&Ye.tracking?(o(),b("span",Dl,h(r.value.tracking),1)):z("",!0),ge.value?(o(),b("span",Al,"↑"+h(ge.value),1)):z("",!0),ce.value?(o(),b("span",Rl,"↓"+h(ce.value),1)):z("",!0),(Ze=r.value)!=null&&Ze.isClean?(o(),S(N,{key:3,type:"success",effect:"plain",size:"small"},{default:t(()=>[...e[24]||(e[24]=[f("工作区干净",-1)])]),_:1})):r.value?(o(),S(N,{key:4,type:"warning",effect:"plain",size:"small"},{default:t(()=>[f(h(ye.value)+" 处更改",1)]),_:1})):z("",!0),i("span",Ll,h(he.value),1)]),l(k,{loading:L.value,onClick:pe},{default:t(()=>[...e[25]||(e[25]=[f("刷新",-1)])]),_:1},8,["loading"])]),I.value?(o(),S(R,{key:0,title:I.value,type:"error",closable:!1,"show-icon":"",class:"mb"},null,8,["title"])):z("",!0),A(Q)?(o(),b("div",Nl,[l(le,{shadow:"never",class:"branch-panel"},{header:t(()=>[i("div",Il,[e[29]||(e[29]=i("span",{class:"panel-title"},"分支 Branch",-1)),i("div",Fl,[l(k,{size:"small",text:"",onClick:F},{default:t(()=>[...e[27]||(e[27]=[f("刷新",-1)])]),_:1}),l(k,{size:"small",text:"",type:"primary",onClick:e[0]||(e[0]=v=>_.value=!0)},{default:t(()=>[...e[28]||(e[28]=[f("+ 新建",-1)])]),_:1})])])]),default:t(()=>[i("div",Ol,[(o(!0),b(P,null,X(be.value,v=>(o(),b(P,{key:v.key},[v.type==="group"?(o(),b(P,{key:0},[i("div",Pl,h(v.label),1),(o(!0),b(P,null,X(v.children,V=>{var se,Ne,lt;return o(),b(P,{key:V.key},[V.type==="local"?(o(),b("div",{key:0,class:ve(["branch-node",{current:(se=V.branch)==null?void 0:se.current}]),onDblclick:Ie=>{var st;return((st=V.branch)==null?void 0:st.current)||$e(V)}},[i("span",Bl,h(V.label),1),i("span",{class:ve(["node-sync",{clean:!ke(V.branch)&&((Ne=V.branch)==null?void 0:Ne.upstream)}])},h(ke(V.branch)),3),i("span",Wl,[(lt=V.branch)!=null&<.current?(o(),b(P,{key:0},[l(k,{size:"small",text:"",type:"success",onClick:me($t,["stop"])},{default:t(()=>[...e[30]||(e[30]=[f("拉取",-1)])]),_:1}),l(k,{size:"small",text:"",type:"primary",onClick:me(xt,["stop"])},{default:t(()=>[...e[31]||(e[31]=[f("推送",-1)])]),_:1})],64)):(o(),S(k,{key:1,size:"small",text:"",type:"primary",onClick:me(Ie=>$e(V),["stop"])},{default:t(()=>[...e[32]||(e[32]=[f("切换",-1)])]),_:1},8,["onClick"]))])],42,ql)):z("",!0),V.type==="remote"?(o(),b("div",{key:1,class:"branch-node remote",onDblclick:Ie=>$e(V)},[i("span",Ml,h(V.label),1),i("span",Hl,[l(k,{size:"small",text:"",type:"primary",onClick:me(Ie=>$e(V),["stop"])},{default:t(()=>[...e[33]||(e[33]=[f("切换",-1)])]),_:1},8,["onClick"])])],40,Gl)):z("",!0)],64)}),128))],64)):z("",!0)],64))),128)),be.value.length===0?(o(),S(J,{key:0,description:"暂无分支","image-size":60})):z("",!0)])]),_:1}),i("div",jl,[l(le,{shadow:"never",class:"toolbar-card"},{default:t(()=>{var v;return[i("div",Jl,[i("div",Kl,[l(k,{type:"primary",onClick:e[1]||(e[1]=V=>d.value=!0)},{default:t(()=>[...e[34]||(e[34]=[f("提交 Commit",-1)])]),_:1}),l(k,{plain:"",onClick:pt},{default:t(()=>[...e[35]||(e[35]=[f("暂存全部",-1)])]),_:1}),l(k,{plain:"",disabled:(((v=r.value)==null?void 0:v.staged.length)??0)===0,onClick:ft},{default:t(()=>[...e[36]||(e[36]=[f("取消暂存全部",-1)])]),_:1},8,["disabled"]),l(ee,{value:te.value,hidden:te.value===0,offset:[2,4]},{default:t(()=>[l(k,{type:"success",plain:"",onClick:gt},{default:t(()=>[...e[37]||(e[37]=[f("暂存改动 Stash",-1)])]),_:1})]),_:1},8,["value","hidden"]),l(Le,{content:"Shelve Silently:使用默认说明,一键暂存全部更改",placement:"top"},{default:t(()=>[l(k,{plain:"",onClick:bt},{default:t(()=>[...e[38]||(e[38]=[f("静默 Stash",-1)])]),_:1})]),_:1}),l(k,{type:"danger",plain:"",onClick:e[2]||(e[2]=V=>D.value=!0)},{default:t(()=>[...e[39]||(e[39]=[f("硬重置",-1)])]),_:1}),l(k,{type:"danger",plain:"",onClick:e[3]||(e[3]=V=>j("git_clean"))},{default:t(()=>[...e[40]||(e[40]=[f("清理未跟踪",-1)])]),_:1})])])]}),_:1}),(Qe=r.value)!=null&&Qe.conflicted.length?(o(),S(R,{key:0,title:"存在合并冲突,请先解决冲突(修改文件后重新 git add 并提交)",type:"error",closable:!1,"show-icon":"",class:"mb"})):z("",!0),l(le,{shadow:"never",class:"changes-card"},{header:t(()=>[i("div",Xl,[e[43]||(e[43]=i("span",{class:"card-title"},"更改 Changes",-1)),i("div",Yl,[te.value?(o(),S(N,{key:0,size:"small",type:"primary",effect:"plain"},{default:t(()=>[f("已选 "+h(te.value),1)]),_:1})):z("",!0),l(k,{size:"small",text:"",onClick:_t},{default:t(()=>[...e[41]||(e[41]=[f("全选本组",-1)])]),_:1}),te.value?(o(),S(k,{key:1,size:"small",text:"",type:"danger",onClick:Je},{default:t(()=>[...e[42]||(e[42]=[f("清除选择",-1)])]),_:1})):z("",!0)])])]),default:t(()=>[l(Rt,{modelValue:ne.value,"onUpdate:modelValue":e[4]||(e[4]=v=>ne.value=v),class:"changes-tabs"},{default:t(()=>[(o(!0),b(P,null,X(Ae.value,v=>(o(),S(At,{key:v.key,name:v.key},{label:t(()=>[i("span",Zl,[f(h(v.label)+" ",1),l(ee,{value:v.count,hidden:v.count===0,type:"primary",class:"tab-badge"},null,8,["value","hidden"])])]),default:t(()=>[i("div",Ql,"「"+h(v.hint)+"」",1),v.count===0?(o(),b("div",es,"没有"+h(v.label)+"的文件",1)):(o(),b("div",ts,[(o(!0),b(P,null,X(Y.value[v.key],V=>(o(),b("div",{key:v.key+V.path,class:"file-row"},[l(Ue,{"model-value":je(V.path),onChange:se=>He(V.path)},null,8,["model-value","onChange"]),i("span",{class:ve(["file-status",Et(V)])},h(Tt(V)),3),i("span",{class:"file-path mono",title:V.path},h(V.path),9,ls),l(k,{size:"small",text:"",type:"primary",onClick:se=>mt(V)},{default:t(()=>[...e[44]||(e[44]=[f("查看差异",-1)])]),_:1},8,["onClick"]),V.conflicted?(o(),S(k,{key:0,size:"small",text:"",type:"warning",onClick:se=>Me(V)},{default:t(()=>[...e[45]||(e[45]=[f("标记已解决(git add)",-1)])]),_:1},8,["onClick"])):(o(),S(k,{key:1,size:"small",text:"",type:V.staged?"warning":"success",onClick:se=>ct(V)},{default:t(()=>[f(h(V.staged?"取消暂存":"暂存"),1)]),_:2},1032,["type","onClick"]))]))),128))]))]),_:2},1032,["name"]))),128))]),_:1},8,["modelValue"])]),_:1}),l(le,{shadow:"never",class:"stash-card"},{header:t(()=>[i("div",ss,[i("span",ns,"暂存列表 Stash("+h(E.value.length)+")",1),i("div",as,[l(k,{size:"small",text:"",onClick:Z},{default:t(()=>[...e[46]||(e[46]=[f("刷新",-1)])]),_:1})])])]),default:t(()=>[E.value.length===0?(o(),b("div",os,"没有暂存的更改")):(o(),b("div",is,[(o(!0),b(P,null,X(E.value,v=>(o(),b("div",{key:v.ref,class:"stash-row"},[i("div",rs,[i("span",us,h(v.ref),1),i("span",{class:"stash-msg",title:v.message},h(Dt(v.message)||"(无说明)"),9,ds),v.date?(o(),b("span",cs,h(zt(v.date)),1)):z("",!0)]),i("div",ps,[l(k,{size:"small",text:"",type:"primary",onClick:V=>vt(v)},{default:t(()=>[...e[47]||(e[47]=[f("差异",-1)])]),_:1},8,["onClick"]),l(k,{size:"small",text:"",type:"success",onClick:V=>kt(v)},{default:t(()=>[...e[48]||(e[48]=[f("应用",-1)])]),_:1},8,["onClick"]),l(k,{size:"small",text:"",type:"warning",onClick:V=>wt(v)},{default:t(()=>[...e[49]||(e[49]=[f("恢复",-1)])]),_:1},8,["onClick"]),l(k,{size:"small",text:"",type:"danger",onClick:V=>Ct(v)},{default:t(()=>[...e[50]||(e[50]=[f("删除",-1)])]),_:1},8,["onClick"])])]))),128))]))]),_:1})])])):(o(),b("div",Ul,"请先在「仓库管理」中打开一个仓库")),l(xl,{visible:A(W),"onUpdate:visible":e[5]||(e[5]=v=>Ot(W)?W.value=v:null),tool:((et=A($))==null?void 0:et.tool)??"",preview:((tt=A($))==null?void 0:tt.preview)??null,onConfirm:ut,onCancel:A(re)},null,8,["visible","tool","preview","onCancel"]),l(Lt,{modelValue:c.visible,"onUpdate:modelValue":e[6]||(e[6]=v=>c.visible=v),title:c.title,size:"56%","destroy-on-close":""},{default:t(()=>[_e((o(),b("div",fs,[c.diff?(o(),b(P,{key:0},[i("div",ms,[i("span",null,h(c.diff.files.length)+" 个文件",1),i("span",vs,"+"+h(c.diff.insertions),1),i("span",_s,"-"+h(c.diff.deletions),1),c.diff.truncated?(o(),b("span",hs,"(已截断)")):z("",!0)]),l(Pe,{patch:c.diff.rawPatch},null,8,["patch"])],64)):c.patch?(o(),b(P,{key:1},[c.patch?(o(),S(Pe,{key:1,patch:c.patch},null,8,["patch"])):(o(),b("div",gs,"无差异"))],64)):c.loading?z("",!0):(o(),S(J,{key:2,description:"无差异","image-size":60}))])),[[Ut,c.loading]])]),_:1},8,["modelValue","title"]),l(xe,{modelValue:d.value,"onUpdate:modelValue":e[9]||(e[9]=v=>d.value=v),title:"提交 Commit",width:"520px",onClosed:e[10]||(e[10]=v=>p.value="")},{footer:t(()=>[l(k,{onClick:e[8]||(e[8]=v=>d.value=!1)},{default:t(()=>[...e[51]||(e[51]=[f("取消",-1)])]),_:1}),l(k,{type:"primary",onClick:Ke},{default:t(()=>[...e[52]||(e[52]=[f("下一步(dry-run 预览)",-1)])]),_:1})]),default:t(()=>[l(fe,{modelValue:p.value,"onUpdate:modelValue":e[7]||(e[7]=v=>p.value=v),type:"textarea",rows:5,placeholder:"输入提交信息(message)",onKeydown:We(me(Ke,["ctrl"]),["enter"])},null,8,["modelValue","onKeydown"])]),_:1},8,["modelValue"]),l(xe,{modelValue:_.value,"onUpdate:modelValue":e[14]||(e[14]=v=>_.value=v),title:"新建分支",width:"480px",onClosed:e[15]||(e[15]=v=>{m.value="",x.value=""})},{footer:t(()=>[l(k,{onClick:e[13]||(e[13]=v=>_.value=!1)},{default:t(()=>[...e[53]||(e[53]=[f("取消",-1)])]),_:1}),l(k,{type:"primary",onClick:Vt},{default:t(()=>[...e[54]||(e[54]=[f("下一步(dry-run 预览)",-1)])]),_:1})]),default:t(()=>[l(Xe,{"label-width":"100px"},{default:t(()=>[l(Ve,{label:"分支名"},{default:t(()=>[l(fe,{modelValue:m.value,"onUpdate:modelValue":e[11]||(e[11]=v=>m.value=v),placeholder:"feature/xxx"},null,8,["modelValue"])]),_:1}),l(Ve,{label:"起点(可选)"},{default:t(()=>[l(fe,{modelValue:x.value,"onUpdate:modelValue":e[12]||(e[12]=v=>x.value=v),placeholder:"默认当前 HEAD,如 main 或 commit hash"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1},8,["modelValue"]),l(xe,{modelValue:U.value,"onUpdate:modelValue":e[19]||(e[19]=v=>U.value=v),title:"暂存改动 Stash",width:"560px"},{footer:t(()=>[l(k,{onClick:e[18]||(e[18]=v=>U.value=!1)},{default:t(()=>[...e[58]||(e[58]=[f("取消",-1)])]),_:1}),l(k,{type:"primary",onClick:yt},{default:t(()=>[...e[59]||(e[59]=[f("下一步(dry-run 预览)",-1)])]),_:1})]),default:t(()=>[l(R,{class:"stash-tip",title:"可勾选左侧更改列表的文件随本次 stash 一起保存;不勾选则保存全部更改。",type:"info",closable:!1,"show-icon":""}),l(Xe,{"label-width":"90px"},{default:t(()=>[l(Ve,{label:"说明(可选)"},{default:t(()=>[l(fe,{modelValue:B.value,"onUpdate:modelValue":e[16]||(e[16]=v=>B.value=v),placeholder:"留空则使用默认说明(WIP on 分支: 提交)"},null,8,["modelValue"])]),_:1}),l(Ve,{label:"包含未跟踪"},{default:t(()=>[l(Ue,{modelValue:M.value,"onUpdate:modelValue":e[17]||(e[17]=v=>M.value=v)},{default:t(()=>[...e[55]||(e[55]=[f("包含未跟踪文件(-u)。勾选文件后会自动包含其中的未跟踪文件",-1)])]),_:1},8,["modelValue"])]),_:1})]),_:1}),Ce.value.length?(o(),b("div",ys,[i("div",bs,[i("span",ks,"选择文件(已选 "+h(te.value)+")",1),i("div",ws,[l(k,{size:"small",text:"",onClick:ht},{default:t(()=>[...e[56]||(e[56]=[f("全选",-1)])]),_:1}),l(k,{size:"small",text:"",onClick:Je},{default:t(()=>[...e[57]||(e[57]=[f("清除选择",-1)])]),_:1})])]),i("div",Cs,[(o(!0),b(P,null,X(Ce.value,v=>{var V,se;return o(),b("div",{key:v,class:"file-row"},[l(Ue,{"model-value":je(v),onChange:Ne=>He(v)},null,8,["model-value","onChange"]),i("span",{class:ve(["file-status",(V=r.value)!=null&&V.untracked.includes(v)?"new":"mod"])},h((se=r.value)!=null&&se.untracked.includes(v)?"?":"M"),3),i("span",$s,h(v),1)])}),128))])])):z("",!0)]),_:1},8,["modelValue"]),l(xe,{modelValue:D.value,"onUpdate:modelValue":e[22]||(e[22]=v=>D.value=v),title:"硬重置(高风险)",width:"480px",onClosed:e[23]||(e[23]=v=>H.value="")},{footer:t(()=>[l(k,{onClick:e[21]||(e[21]=v=>D.value=!1)},{default:t(()=>[...e[60]||(e[60]=[f("取消",-1)])]),_:1}),l(k,{type:"danger",onClick:St},{default:t(()=>[...e[61]||(e[61]=[f("下一步(dry-run 预览)",-1)])]),_:1})]),default:t(()=>[l(R,{title:"将丢弃索引与工作区所有更改(不可逆),执行前会自动创建备份",type:"error",closable:!1,"show-icon":"",class:"mb"}),l(fe,{modelValue:H.value,"onUpdate:modelValue":e[20]||(e[20]=v=>H.value=v),placeholder:"重置目标,默认 HEAD,如 HEAD~1 / commit hash / main"},null,8,["modelValue"])]),_:1},8,["modelValue"])])}}}),Vs=oe(xs,[["__scopeId","data-v-950822e0"]]),Ss={class:"page"},Ts={class:"filter-bar"},Es={class:"mono hash"},zs={class:"subject"},Ds={key:0,class:"refs"},As={class:"sub"},Rs={class:"commit-head"},Ls={class:"mono commit-hash"},Us={class:"commit-subject"},Ns={class:"commit-meta"},Is={key:0},Fs={key:0,class:"commit-body"},Os={class:"diff-wrap"},Ps={class:"diff-summary"},qs={class:"add"},Bs={class:"del"},Ws={key:0,class:"warn"},Gs=ae({__name:"HistoryView",setup(a){const s=Te(),{revision:u}=Ee(),y=()=>s.currentId,r=T([]),C=T([]),E=T(!1),L=T(""),I=T("head"),c=T(""),d=T(""),p=T(50),_=T(!1),m=T(null),x=T(null),U=T(!1),B=q(()=>C.value.filter(W=>!W.remote)),M=q(()=>{var W;return((W=C.value.find($=>$.current))==null?void 0:W.name)??""});async function D(){const W=y();if(W!==null)try{const{branches:$}=await at(W);C.value=$}catch{}}async function H(){const W=y();if(W!==null){E.value=!0,L.value="";try{const $={maxCount:p.value};I.value==="all"?$.all=!0:I.value==="branch"&&c.value&&($.from=c.value),d.value.trim()&&($.path=d.value.trim()),r.value=await Kt(W,$)}catch($){L.value=$ instanceof Error?$.message:String($),r.value=[]}finally{E.value=!1}}}async function w(){await Promise.all([D(),H()])}async function te(W){const $=y();if($!==null){_.value=!0,m.value=W,x.value=null,U.value=!0;try{const{diff:Q}=await Yt($,W.hash);x.value=Q}catch(Q){G.error(Q instanceof Error?Q.message:String(Q))}finally{U.value=!1}}}function ne(W){const $=new Date(W);return Number.isNaN($.getTime())?W:$.toLocaleString()}return ie(y,()=>void w()),ie(u,()=>void H()),ie([I,c,p],()=>void H()),ue(()=>void w()),(W,$)=>{const Q=g("el-alert"),O=g("el-radio-button"),de=g("el-radio-group"),re=g("el-option"),he=g("el-select"),De=g("el-input"),ge=g("el-button"),ce=g("el-card"),Y=g("el-table-column"),Ae=g("el-tag"),Re=g("el-table"),ye=g("el-empty"),be=g("el-divider"),ke=g("el-drawer"),we=Se("loading");return o(),b("div",Ss,[$[8]||($[8]=i("h2",{class:"page-title"},"提交历史",-1)),L.value?(o(),S(Q,{key:0,title:L.value,type:"error",closable:!1,"show-icon":"",class:"mb"},null,8,["title"])):z("",!0),l(ce,{shadow:"never",class:"mb"},{default:t(()=>[i("div",Ts,[l(de,{modelValue:I.value,"onUpdate:modelValue":$[0]||($[0]=F=>I.value=F)},{default:t(()=>[l(O,{value:"head"},{default:t(()=>[f("当前分支("+h(M.value)+")",1)]),_:1}),l(O,{value:"all"},{default:t(()=>[...$[5]||($[5]=[f("全部分支",-1)])]),_:1}),l(O,{value:"branch"},{default:t(()=>[...$[6]||($[6]=[f("指定分支",-1)])]),_:1})]),_:1},8,["modelValue"]),I.value==="branch"?(o(),S(he,{key:0,modelValue:c.value,"onUpdate:modelValue":$[1]||($[1]=F=>c.value=F),filterable:"",placeholder:"选择分支",class:"branch-select"},{default:t(()=>[(o(!0),b(P,null,X(B.value,F=>(o(),S(re,{key:F.name,label:F.name,value:F.name},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])):z("",!0),l(De,{modelValue:d.value,"onUpdate:modelValue":$[2]||($[2]=F=>d.value=F),clearable:"",placeholder:"按路径过滤(可选)",class:"path-input",onKeyup:We(H,["enter"])},null,8,["modelValue"]),l(he,{modelValue:p.value,"onUpdate:modelValue":$[3]||($[3]=F=>p.value=F),class:"count-select"},{default:t(()=>[l(re,{label:"20 条",value:20}),l(re,{label:"50 条",value:50}),l(re,{label:"100 条",value:100})]),_:1},8,["modelValue"]),l(ge,{loading:E.value,onClick:H},{default:t(()=>[...$[7]||($[7]=[f("刷新",-1)])]),_:1},8,["loading"])])]),_:1}),l(ce,{shadow:"never"},{default:t(()=>[_e((o(),S(Re,{data:r.value,size:"default","highlight-current-row":"",onRowClick:te},{default:t(()=>[l(Y,{label:"提交",width:"100"},{default:t(({row:F})=>[i("span",Es,h(F.shortHash),1)]),_:1}),l(Y,{label:"信息","min-width":"300"},{default:t(({row:F})=>[i("div",zs,h(F.subject),1),F.refs?(o(),b("div",Ds,[(o(!0),b(P,null,X(F.refs.split(",").map(Z=>Z.trim()).filter(Boolean),Z=>(o(),S(Ae,{key:Z,size:"small",effect:"plain",class:"ref-tag"},{default:t(()=>[f(h(Z.startsWith("tag: ")?Z:Z.includes("/")&&!Z.startsWith("HEAD")?Z.split("/").pop():Z),1)]),_:2},1024))),128))])):z("",!0)]),_:1}),l(Y,{label:"作者",width:"170"},{default:t(({row:F})=>[i("div",null,h(F.authorName),1),i("div",As,h(F.authorEmail),1)]),_:1}),l(Y,{label:"时间",width:"180"},{default:t(({row:F})=>[f(h(ne(F.authorDate)),1)]),_:1})]),_:1},8,["data"])),[[we,E.value]]),!E.value&&r.value.length===0?(o(),S(ye,{key:0,description:"暂无提交记录"})):z("",!0)]),_:1}),l(ke,{modelValue:_.value,"onUpdate:modelValue":$[4]||($[4]=F=>_.value=F),size:"60%","destroy-on-close":""},{default:t(()=>[m.value?(o(),b(P,{key:0},[i("div",Rs,[i("div",Ls,h(m.value.hash),1),i("h3",Us,h(m.value.subject),1),i("div",Ns,[i("span",null,h(m.value.authorName)+" <"+h(m.value.authorEmail)+">",1),i("span",null,h(ne(m.value.authorDate)),1),m.value.refs?(o(),b("span",Is,"refs: "+h(m.value.refs),1)):z("",!0)]),m.value.body?(o(),b("pre",Fs,h(m.value.body),1)):z("",!0)]),l(be),_e((o(),b("div",Os,[x.value?(o(),b(P,{key:0},[i("div",Ps,[i("span",null,h(x.value.files.length)+" 个文件",1),i("span",qs,"+"+h(x.value.insertions),1),i("span",Bs,"-"+h(x.value.deletions),1),x.value.truncated?(o(),b("span",Ws,"(已截断)")):z("",!0)]),l(Pe,{patch:x.value.rawPatch},null,8,["patch"])],64)):U.value?z("",!0):(o(),S(ye,{key:1,description:"无差异","image-size":60}))])),[[we,U.value]])],64)):z("",!0)]),_:1},8,["modelValue"])])}}}),Ms=oe(Gs,[["__scopeId","data-v-2be2a7e8"]]),Hs=qe("logs",{state:()=>({logs:[],loading:!1,error:null,limit:50,toolFilter:""}),actions:{async load(){this.loading=!0,this.error=null;try{const{logs:a}=await Qt({limit:this.limit,tool:this.toolFilter||void 0});this.logs=a}catch(a){this.error=a instanceof Error?a.message:String(a)}finally{this.loading=!1}}}}),js={class:"page"},Js={class:"filter-bar"},Ks={class:"tool-cell"},Xs={class:"mono repo-path"},Ys=["title"],Zs=["title"],Qs=["title"],en=ae({__name:"LogsView",setup(a){const s=Hs(),{revision:u}=Ee(),y=q(()=>{const c=new Set;for(const d of s.logs)c.add(d.tool);return[...c].sort()}),r=c=>c.includes("reset")||c.includes("clean")||c.includes("force")||c.includes("rebase")?"dangerous":"write";function C(c){return r(c)==="dangerous"?"danger":c.startsWith("git_")?"primary":"success"}function E(c){const d=new Date(c);return Number.isNaN(d.getTime())?c:d.toLocaleString()}function L(c){return c==="mcp"?"primary":c==="web"?"success":"warning"}function I(c){if(c==null)return"";if(typeof c=="string")return c;try{const d=JSON.stringify(c);return d===void 0?"":d}catch{return String(c)}}return ie(u,()=>{s.load()}),ue(()=>{s.load()}),(c,d)=>{const p=g("el-option"),_=g("el-select"),m=g("el-button"),x=g("el-card"),U=g("el-table-column"),B=g("el-tag"),M=g("el-table"),D=g("el-empty"),H=Se("loading");return o(),b("div",js,[d[7]||(d[7]=i("h2",{class:"page-title"},"操作日志",-1)),l(x,{shadow:"never",class:"mb"},{default:t(()=>[i("div",Js,[l(_,{modelValue:A(s).toolFilter,"onUpdate:modelValue":d[0]||(d[0]=w=>A(s).toolFilter=w),clearable:"",placeholder:"按工具过滤",class:"tool-select",onChange:A(s).load},{default:t(()=>[(o(!0),b(P,null,X(y.value,w=>(o(),S(p,{key:w,label:w,value:w},null,8,["label","value"]))),128))]),_:1},8,["modelValue","onChange"]),l(_,{modelValue:A(s).limit,"onUpdate:modelValue":d[1]||(d[1]=w=>A(s).limit=w),class:"limit-select",onChange:A(s).load},{default:t(()=>[l(p,{label:"最近 20 条",value:20}),l(p,{label:"最近 50 条",value:50}),l(p,{label:"最近 100 条",value:100})]),_:1},8,["modelValue","onChange"]),l(m,{loading:A(s).loading,onClick:A(s).load},{default:t(()=>[...d[2]||(d[2]=[f("刷新",-1)])]),_:1},8,["loading","onClick"]),d[3]||(d[3]=i("span",{class:"tip"},"记录来源:Web / MCP / CLI 全部写入操作(只读操作不记录)",-1))])]),_:1}),l(x,{shadow:"never"},{default:t(()=>[_e((o(),S(M,{data:A(s).logs,size:"default"},{default:t(()=>[l(U,{label:"时间",width:"180"},{default:t(({row:w})=>[f(h(E(w.timestamp)),1)]),_:1}),l(U,{label:"来源",width:"90"},{default:t(({row:w})=>[l(B,{type:L(w.source),size:"small",effect:"plain"},{default:t(()=>[f(h(w.source.toUpperCase()),1)]),_:2},1032,["type"])]),_:1}),l(U,{label:"工具",width:"200"},{default:t(({row:w})=>[i("div",Ks,[l(B,{type:C(w.tool),size:"small",effect:"dark"},{default:t(()=>[f(h(w.tool),1)]),_:2},1032,["type"]),w.dryRun?(o(),S(B,{key:0,size:"small",type:"info",effect:"plain",class:"dry-tag"},{default:t(()=>[...d[4]||(d[4]=[f("dry-run",-1)])]),_:1})):z("",!0)])]),_:1}),l(U,{label:"仓库","min-width":"200"},{default:t(({row:w})=>[i("span",Xs,h(w.repoPath??"—"),1)]),_:1}),l(U,{label:"参数(脱敏)","min-width":"180"},{default:t(({row:w})=>[i("span",{class:"mono params",title:I(w.params)},h(I(w.params)||"—"),9,Ys)]),_:1}),l(U,{label:"结果","min-width":"150"},{default:t(({row:w})=>[w.error?(o(),b(P,{key:0},[l(B,{type:"danger",size:"small",effect:"plain",class:"result-tag"},{default:t(()=>[...d[5]||(d[5]=[f("失败",-1)])]),_:1}),i("div",{class:"err-text",title:w.error},h(w.error),9,Zs)],64)):(o(),b(P,{key:1},[l(B,{type:"success",size:"small",effect:"plain",class:"result-tag"},{default:t(()=>[...d[6]||(d[6]=[f("成功",-1)])]),_:1}),i("div",{class:"ok-text",title:w.result},h(w.result),9,Qs)],64))]),_:1}),l(U,{label:"耗时",width:"90"},{default:t(({row:w})=>[f(h(w.durationMs)+" ms",1)]),_:1})]),_:1},8,["data"])),[[H,A(s).loading]]),!A(s).loading&&A(s).logs.length===0?(o(),S(D,{key:0,description:"暂无操作日志"})):z("",!0)]),_:1})])}}}),tn=oe(en,[["__scopeId","data-v-bb89f017"]]),ln={class:"page"},sn={class:"card-head"},nn={class:"mono"},an={class:"desc"},on={key:1,class:"action-bar"},rn=ae({__name:"SettingsView",setup(a){const s=ot(),u=Fe({disabledTools:[],requireApprovalFor:[],dryRunDefault:!1}),y=T(!1),r=q(()=>{const _=s.permissions;return _?JSON.stringify([...u.disabledTools].sort())!==JSON.stringify([..._.disabledTools].sort())||JSON.stringify([...u.requireApprovalFor].sort())!==JSON.stringify([..._.requireApprovalFor].sort())||u.dryRunDefault!==_.dryRunDefault:!1}),C=q(()=>s.tools.filter(_=>_.risk==="dangerous")),E=q(()=>C.value.map(_=>_.name));function L(){const _=s.permissions;_&&(u.disabledTools=[..._.disabledTools],u.requireApprovalFor=[..._.requireApprovalFor],u.dryRunDefault=_.dryRunDefault,y.value=!0)}ie(()=>s.permissions,_=>{_&&!r.value&&L()});async function I(_,m){m?u.disabledTools=u.disabledTools.filter(x=>x!==_.name):(u.disabledTools.includes(_.name)||u.disabledTools.push(_.name),u.requireApprovalFor=u.requireApprovalFor.filter(x=>x!==_.name))}function c(_){return _==="readonly"?"success":_==="write"?"primary":"danger"}function d(_){return _==="readonly"?"只读":_==="write"?"写操作":"高风险"}async function p(){try{await s.save({disabledTools:[...u.disabledTools],requireApprovalFor:[...u.requireApprovalFor],dryRunDefault:u.dryRunDefault}),G.success("设置已保存")}catch(_){G.error(_ instanceof Error?_.message:String(_))}}return ue(async()=>{await s.load(),L()}),(_,m)=>{const x=g("el-alert"),U=g("el-switch"),B=g("el-form-item"),M=g("el-form"),D=g("el-card"),H=g("el-tag"),w=g("el-table-column"),te=g("el-table"),ne=g("el-option"),W=g("el-select"),$=g("el-button"),Q=Se("loading");return o(),b("div",ln,[m[10]||(m[10]=i("h2",{class:"page-title"},"设置",-1)),A(s).error?(o(),S(x,{key:0,title:A(s).error,type:"error",closable:!1,"show-icon":"",class:"mb"},null,8,["title"])):z("",!0),l(D,{shadow:"never",class:"mb"},{header:t(()=>[...m[2]||(m[2]=[f("默认行为",-1)])]),default:t(()=>[l(M,{"label-width":"180px","label-position":"left"},{default:t(()=>[l(B,{label:"写操作默认 dry-run 预览"},{default:t(()=>[l(U,{modelValue:u.dryRunDefault,"onUpdate:modelValue":m[0]||(m[0]=O=>u.dryRunDefault=O)},null,8,["modelValue"]),m[3]||(m[3]=i("span",{class:"form-tip"},"开启后所有写操作(MCP/CLI)默认只生成预览,不真正执行",-1))]),_:1})]),_:1})]),_:1}),l(D,{shadow:"never",class:"mb"},{header:t(()=>[i("div",sn,[m[5]||(m[5]=i("span",null,"工具开关与风险等级",-1)),l(H,{size:"small",type:"warning",effect:"plain"},{default:t(()=>[...m[4]||(m[4]=[f("高危工具默认禁用,需在下方开启",-1)])]),_:1})])]),default:t(()=>[_e((o(),S(te,{data:A(s).tools,size:"default"},{default:t(()=>[l(w,{label:"工具",width:"230"},{default:t(({row:O})=>[i("span",nn,h(O.name),1)]),_:1}),l(w,{label:"风险",width:"90"},{default:t(({row:O})=>[l(H,{type:c(O.risk),size:"small",effect:"dark"},{default:t(()=>[f(h(d(O.risk)),1)]),_:2},1032,["type"])]),_:1}),l(w,{label:"描述","min-width":"240"},{default:t(({row:O})=>[i("span",an,h(O.description),1)]),_:1}),l(w,{label:"启用",width:"100",align:"center"},{default:t(({row:O})=>[l(U,{"model-value":!u.disabledTools.includes(O.name),onChange:de=>I(O,de===!0)},null,8,["model-value","onChange"])]),_:1})]),_:1},8,["data"])),[[Q,A(s).loading]])]),_:1}),l(D,{shadow:"never",class:"mb"},{header:t(()=>[...m[6]||(m[6]=[f("审批规则",-1)])]),default:t(()=>[l(M,{"label-position":"top"},{default:t(()=>[l(B,{label:"执行前需要审批的工具(勾选后,执行时需在确认框中手工确认)"},{default:t(()=>[l(W,{modelValue:u.requireApprovalFor,"onUpdate:modelValue":m[1]||(m[1]=O=>u.requireApprovalFor=O),multiple:"",filterable:"","collapse-tags":"",placeholder:"选择需要审批的工具",style:{width:"100%"}},{default:t(()=>[(o(!0),b(P,null,X(E.value,O=>(o(),S(ne,{key:O,label:O,value:O,disabled:u.disabledTools.includes(O)},null,8,["label","value","disabled"]))),128))]),_:1},8,["modelValue"]),m[7]||(m[7]=i("span",{class:"form-tip"},"审批仅对已启用的高危工具生效;禁用后自动移除",-1))]),_:1})]),_:1})]),_:1}),y.value?(o(),b("div",on,[l($,{type:"primary",loading:A(s).saving,disabled:!r.value,onClick:p},{default:t(()=>[...m[8]||(m[8]=[f("保存设置",-1)])]),_:1},8,["loading","disabled"]),l($,{disabled:!r.value,onClick:L},{default:t(()=>[...m[9]||(m[9]=[f("放弃修改",-1)])]),_:1},8,["disabled"])])):z("",!0)])}}}),un=oe(rn,[["__scopeId","data-v-c9221e05"]]),rt=Pt({history:qt(),routes:[{path:"/",redirect:"/status"},{path:"/repos",name:"repos",component:_l,meta:{title:"仓库管理"}},{path:"/status",name:"status",component:Vs,meta:{title:"状态"}},{path:"/history",name:"history",component:Ms,meta:{title:"历史"}},{path:"/logs",name:"logs",component:tn,meta:{title:"操作日志"}},{path:"/settings",name:"settings",component:un,meta:{title:"设置"}}]});rt.afterEach(a=>{const s=a.meta.title;document.title=s?`${s} · Git Cockpit`:"Git Cockpit"});const ze=Bt(dl);ze.use(Wt());ze.use(rt);ze.use(Gt,{size:"default"});ze.mount("#app");
|