@orion-agents/orion-code 0.3.17 → 0.3.19
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/CHANGELOG.md +87 -0
- package/README.md +7 -6
- package/README.zh-CN.md +5 -4
- package/dist/runtime/release-receipts.d.ts +9 -0
- package/dist/runtime/release-receipts.js +17 -1
- package/dist/web/git-file-source.js +1 -1
- package/dist/web/git-history-service.js +19 -13
- package/dist/web/git-patch-builder.js +5 -1
- package/dist/web/git-read-model-service.d.ts +24 -0
- package/dist/web/git-read-model-service.js +83 -3
- package/dist/web/protocol.d.ts +3 -3
- package/dist/web/server.js +10 -1
- package/dist/web-client/assets/{FilesPanel-BARQCmne.js → FilesPanel-DGWgLv6R.js} +1 -1
- package/dist/web-client/assets/GitPanel-DIuJNXoB.js +4 -0
- package/dist/web-client/assets/{ReviewPanel-YhEGlp-G.js → ReviewPanel-YWZXJdm5.js} +1 -1
- package/dist/web-client/assets/{TerminalPanel-DnWh3Vp2.js → TerminalPanel-DPSMepio.js} +1 -1
- package/dist/web-client/assets/{index-Drja0_BT.js → index-DYeu_rs7.js} +2 -2
- package/dist/web-client/assets/{useAutoNotice-DfQi4G1X.js → useAutoNotice-h7c0Iz1E.js} +1 -1
- package/dist/web-client/index.html +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/web-client/assets/GitPanel-DjB9eSiJ.js +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as l,P as _,R as M,b as N,c as $,d as j}from"./index-
|
|
1
|
+
import{r as t,j as l,P as _,R as M,b as N,c as $,d as j}from"./index-DYeu_rs7.js";function y({panelId:i,navigatorWidthPx:o,onNavigatorWidthCommit:e,contentLabel:d,navigatorLabel:h,handleLabel:s,contentClassName:r="",navigatorClassName:n="",children:p}){const[x,W]=t.Children.toArray(p),u=t.useRef(null),[E,T]=t.useState(0),[A,m]=t.useState(null);t.useEffect(()=>{const c=u.current;if(!c)return;const w=new ResizeObserver(S=>{const v=S[0]?.contentRect.width;v&&T(v)});return w.observe(c),()=>w.disconnect()},[]);const a=j(E),f=Math.min($(A??o),a),b=c=>{m(null),e(Math.min(c,a))},g=`${i}-split-content`,R=`${i}-split-navigator`;return l.jsxs("div",{ref:u,className:"resource-split-layout",style:{"--resource-navigator-width":`${f}px`},children:[l.jsx("section",{id:g,className:`resource-split-content${r?` ${r}`:""}`,"aria-label":d,children:W}),l.jsx(_,{side:"right",className:"resource-split-handle",minWidth:N,maxWidth:Math.max(N,a),defaultWidth:M,label:s,width:f,controls:R,boundsRef:u,resizingScope:"resource-split",onPreview:m,onCommit:b}),l.jsx("section",{id:R,className:`resource-split-navigator${n?` ${n}`:""}`,"aria-label":h,children:x})]})}const I=4e3;function D(){const[i,o]=t.useState(null),e=t.useRef(null);return t.useEffect(()=>()=>{e.current!==null&&window.clearTimeout(e.current)},[]),{notice:i,showNotice:(s,r="info")=>{e.current!==null&&(window.clearTimeout(e.current),e.current=null),o({text:s,tone:r}),r!=="error"&&(e.current=window.setTimeout(()=>{e.current=null,o(n=>n?.text===s?null:n)},I))},clearNotice:()=>{e.current!==null&&(window.clearTimeout(e.current),e.current=null),o(null)}}}export{y as R,D as u};
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<meta name="description" content="Orion Code local Web Workbench" />
|
|
9
9
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
10
10
|
<title>Orion Code</title>
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-DYeu_rs7.js"></script>
|
|
12
12
|
<link rel="stylesheet" crossorigin href="/assets/index--hnGXXjj.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-agents/orion-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@orion-agents/orion-code",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.19",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@clack/prompts": "^0.7.0",
|
package/package.json
CHANGED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
var $e=Object.defineProperty;var Pe=(t,s,n)=>s in t?$e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n;var ie=(t,s,n)=>Pe(t,typeof s!="symbol"?s+"":s,n);import{r,a as He,j as e,I as W}from"./index-Drja0_BT.js";import{u as Oe,R as Me}from"./useAutoNotice-DfQi4G1X.js";const Ne="orion.web.git-display.v1",ze=Object.freeze(["changes","history","compare"]),me=Object.freeze({message:"",author:"",path:"",sha:"",since:"",until:""}),xe=Object.freeze({view:"changes",group:null,query:"",selectedFileId:null,selectedSource:null,selectedFileIds:Object.freeze([]),selectedLineIds:Object.freeze([]),collapsedHunks:Object.freeze([]),anchorLineId:null,navigatorScrollTop:0,commitDraft:Object.freeze({summary:"",body:""}),historyQuery:me,selectedCommitId:null,selectedCommitParentIndex:0,selectedCommitPath:null,fileHistoryPath:null,notice:""}),pe=Object.freeze({mode:"unified",wrap:!1,showWhitespace:!1,ignoreWhitespace:!1,wordDiff:!1});function _e(t){return t||"__no-workspace__"}function Ae(){const t=new Map;return{read(s){return t.get(s)??xe},update(s,n){const i=Object.freeze({...t.get(s)??xe,...n});return t.set(s,i),i},clear(s){t.delete(s)}}}const Be=Ae();function Ge(){try{const t=globalThis.localStorage?.getItem(Ne);if(!t)return pe;const s=JSON.parse(t);return Te(s)}catch{return pe}}function We(t){try{globalThis.localStorage?.setItem(Ne,JSON.stringify(t))}catch{}}function Te(t){if(typeof t!="object"||t===null)return pe;const s=t;return Object.freeze({mode:s.mode==="side-by-side"?"side-by-side":"unified",wrap:s.wrap===!0,showWhitespace:s.showWhitespace===!0,ignoreWhitespace:s.ignoreWhitespace===!0,wordDiff:s.wordDiff===!0})}function qe(t){if(t.entries.length===0)return{fileId:null,path:null,notice:""};const s=t.entries.find(o=>o.fileId===t.previousFileId);if(s)return{fileId:s.fileId,path:s.path,notice:""};const i=t.entries.find(o=>o.path===t.previousPath)??t.entries[0];return{fileId:i.fileId,path:i.path,notice:t.previousFileId===null?"":`原选中的改动已不在此列表,已跳到 ${i.path}。`}}const Qe=350,je=30;function Ve(t){const{enabled:s,session:n,setSession:i,actions:o,refreshEpoch:f}=t,g=n.historyQuery??me,[x,a]=r.useState(null),[p,y]=r.useState(null),[b,d]=r.useState(null),[I,h]=r.useState(null),[H,D]=r.useState(null),[N,v]=r.useState(null),[T,P]=r.useState(!1),[A,L]=r.useState(!1),[q,R]=r.useState(!1),[j,F]=r.useState(""),$=r.useRef(0),c=r.useRef(0),l=r.useMemo(()=>({...g.message.trim()?{message:g.message.trim()}:{},...g.author.trim()?{author:g.author.trim()}:{},...g.path.trim()?{path:g.path.trim()}:{},...g.sha.trim()?{sha:g.sha.trim()}:{},...g.since.trim()?{since:g.since.trim()}:{},...g.until.trim()?{until:g.until.trim()}:{}}),[g]);r.useEffect(()=>{if(!s)return;const w=$.current+1;$.current=w,P(!0),F("");const z=setTimeout(()=>{(async()=>{try{const[_,G]=await Promise.all([o.gitRefs(),o.gitHistory({...l,pageSize:je})]);if(w!==$.current)return;a(_),y(G)}catch(_){if(w!==$.current)return;F(le(_))}finally{w===$.current&&P(!1)}})()},l.message||l.author||l.path||l.sha?Qe:0);return()=>clearTimeout(z)},[o,s,f,l]),r.useEffect(()=>{const w=n.selectedCommitId;if(!s||!w){d(null),h(null),D(null);return}const z=c.current+1;c.current=z;const _=n.selectedCommitParentIndex;R(!0),F(""),(async()=>{try{const[G,X]=await Promise.all([o.gitCommitDetail(w,_),o.gitCommitFiles(w,_)]);if(z!==c.current)return;d(G),h(X);const Z=X.files.find(K=>!K.sensitive&&!K.binary),te=n.selectedCommitPath&&X.files.some(K=>K.path===n.selectedCommitPath)?n.selectedCommitPath:Z?.path??null;te!==n.selectedCommitPath&&i({selectedCommitPath:te}),te||D(null)}catch(G){if(z!==c.current)return;F(le(G))}finally{z===c.current&&R(!1)}})()},[o,s,n.selectedCommitId,n.selectedCommitParentIndex]),r.useEffect(()=>{const w=n.selectedCommitId,z=n.selectedCommitPath;if(!s||!w||!z){D(null);return}const _=c.current;(async()=>{try{const G=await o.gitCommitDiff({oid:w,path:z,parentIndex:n.selectedCommitParentIndex});if(_!==c.current)return;D(G)}catch(G){if(_!==c.current)return;F(le(G)),D(null)}})()},[o,s,n.selectedCommitId,n.selectedCommitPath,n.selectedCommitParentIndex]),r.useEffect(()=>{const w=n.fileHistoryPath;if(!s||!w){v(null);return}const z=c.current;(async()=>{try{const _=await o.gitFileHistory({path:w});if(z!==c.current)return;v(_)}catch(_){if(z!==c.current)return;F(le(_))}})()},[o,s,n.fileHistoryPath]);const u=r.useCallback(w=>{i({historyQuery:{...g,...w}})},[g,i]),B=r.useCallback(()=>{i({historyQuery:me})},[i]),O=r.useCallback(w=>{i({selectedCommitId:w.id,selectedCommitParentIndex:0,selectedCommitPath:null})},[i]),U=r.useCallback(()=>{i({selectedCommitId:null,selectedCommitPath:null,selectedCommitParentIndex:0})},[i]),V=r.useCallback(w=>{i({selectedCommitParentIndex:w,selectedCommitPath:null})},[i]),Y=r.useCallback(w=>i({selectedCommitPath:w}),[i]),J=r.useCallback(()=>{const w=p?.nextCursor;if(!w||A)return;const z=$.current;L(!0),(async()=>{try{const _=await o.gitHistory({...l,cursor:w,pageSize:je});if(z!==$.current)return;y(G=>G?{..._,items:[...G.items,..._.items]}:_)}catch(_){if(z!==$.current)return;F(le(_))}finally{z===$.current&&L(!1)}})()},[o,A,p,l]),ne=r.useCallback(w=>i({fileHistoryPath:w}),[i]),E=r.useCallback(()=>i({fileHistoryPath:null}),[i]);return{query:g,refs:x,page:p,detail:b,files:I,diff:H,fileHistory:N,loading:T,loadingMore:A,loadingDetail:q,error:j,isEmptyRepository:p!==null&&p.tipOid===null,setQuery:u,resetQuery:B,selectCommit:O,closeDetail:U,setParentIndex:V,selectFile:Y,loadMore:J,openFileHistory:ne,closeFileHistory:E}}function le(t){return t?.code==="git_cursor_invalid"?"历史已变化,已重新载入列表。":t instanceof Error?t.message:"Git 历史读取失败。"}function Ke(t){if(!(t instanceof HTMLElement))return!1;const s=t.tagName.toLowerCase();return s==="input"||s==="textarea"||s==="select"||t.isContentEditable?!0:t.closest('[role="dialog"]')!==null}function Ue(t){const{enabled:s,session:n,setSession:i,fileIds:o,anchorLineIds:f,onOpenSelection:g,onEscapeFallback:x}=t;r.useEffect(()=>{if(!s)return;const a=p=>{if(Ke(p.target))return;if(p.key==="F7"&&f.length>0){p.preventDefault();const b=n.anchorLineId?f.indexOf(n.anchorLineId):-1,d=p.shiftKey?-1:1,I=b<0?d>0?0:f.length-1:Math.min(f.length-1,Math.max(0,b+d));i({anchorLineId:f[I]});return}if(p.key==="Escape"){if(n.query){p.preventDefault(),i({query:"",selectedFileId:null});return}if(n.selectedLineIds.length>0){p.preventDefault(),i({selectedLineIds:[]});return}x();return}if(o.length===0)return;const y=n.selectedFileId?o.indexOf(n.selectedFileId):-1;if(p.key==="ArrowDown"||p.key==="ArrowUp"){p.preventDefault();const b=p.key==="ArrowDown"?1:-1,d=y<0?b>0?0:o.length-1:Math.min(o.length-1,Math.max(0,y+b));i({selectedFileId:o[d],selectedSource:null,anchorLineId:null});return}if(p.key==="Enter"&&y>=0){p.preventDefault(),g();return}if(p.key===" "){if(y<0)return;p.preventDefault();const b=o[y];i({selectedFileIds:n.selectedFileIds.includes(b)?n.selectedFileIds.filter(d=>d!==b):[...n.selectedFileIds,b]})}};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[s,n.query,n.selectedFileId,n.selectedLineIds,n.anchorLineId,n.selectedFileIds,i,o,f,g,x])}class Ye{constructor(s){ie(this,"fetcher");ie(this,"freshnessMs");ie(this,"slots",new Map);this.fetcher=s.fetcher,this.freshnessMs=s.freshnessMs??3e4}getSnapshot(s){const n=this.slotFor(s);n.invalidated&&(n.inFlight=null,n.invalidated=!1);const i=n.snapshot;if(i&&Date.now()-i.fetchedAt<=this.freshnessMs)return Promise.resolve(i);if(n.inFlight)return n.inFlight;n.generation+=1;const o=n.generation,f=this.fetcher(s).then(g=>{const x=this.slots.get(s);if(!x||x.generation!==o||x.invalidated)throw new Je(s);return x.snapshot=Object.freeze({...g,fetchedAt:Date.now()}),x.inFlight=null,x.snapshot}).catch(g=>{const x=this.slots.get(s);throw x&&x.inFlight===f&&(x.inFlight=null),g});return n.inFlight=f,f}invalidate(s){const n=this.slots.get(s);if(!n)return!1;const i=!!(n.snapshot||n.inFlight);return n.invalidated=!0,n.snapshot=null,i}isStale(s,n){const i=this.slots.get(s)?.snapshot;return i?n==null?!1:i.repositoryRevision!==n:!0}cachedSnapshot(s){const n=this.slots.get(s);return!n||n.invalidated||!n.snapshot?null:n.snapshot}clear(){this.slots.clear()}slotFor(s){const n=this.slots.get(s);if(n)return n;const i={workspaceId:s,snapshot:null,inFlight:null,generation:0,invalidated:!1};return this.slots.set(s,i),i}}class Je extends Error{constructor(n){super(`Repository snapshot for ${n} is stale; refetching.`);ie(this,"code","workspace_snapshot_stale")}}const Xe=20*1024*1024,Ze=5*1024*1024;function et(t){let s=0;for(const n of t.hunks){s+=n.header.length;for(const i of n.lines)s+=i.raw.length+48}return s+t.path.length+256}function tt(t){const s=Xe,n=Ze,i=new Map;let o=0,f=0,g=0;const x=(a,p)=>`${a}\0${p}`;return{read(a,p){const y=x(a,p),b=i.get(y);return b?(i.delete(y),i.set(y,b),f+=1,b.document):(g+=1,null)},write(a,p,y){const b=et(y);if(b>n)return;const d=x(a,p),I=i.get(d);for(I&&(i.delete(d),o-=I.bytes),i.set(d,{document:y,bytes:b}),o+=b;o>s&&i.size>0;){const h=i.keys().next();if(h.done)break;const H=i.get(h.value);i.delete(h.value),o-=H?.bytes??0}},clear(){i.clear(),o=0},stats(){return{entries:i.size,bytes:o,hits:f,misses:g}}}}const st=tt(),nt=2e3;function it(t){const{workspaceId:s,refreshEpoch:n,actions:i}=t,o=t.store??Be,f=t.cache??st,g=_e(s),[x,a]=r.useState(()=>o.read(g)),[p,y]=r.useState(()=>Ge()),[b,d]=r.useState(null),[I,h]=r.useState(null),[H,D]=r.useState(null),[N,v]=r.useState(!1),[T,P]=r.useState(!1),[A,L]=r.useState(""),[q,R]=r.useState(!1),j=r.useRef(0),F=r.useRef(0),$=r.useRef(x);$.current=x;const c=r.useRef(b),l=r.useRef(p);l.current=p,c.current=b;const u=r.useCallback(m=>{a(o.update(g,m))},[g,o]),B=r.useCallback(m=>{y(k=>{const S=Object.freeze({...k,...m});return We(S),S})},[]),O=r.useCallback(async(m,k)=>{if(m===j.current){k.quiet?P(!0):v(!0),L("");try{const S=$.current,[C,M]=await Promise.all([i.gitStatus(void 0,{...S.group?{group:S.group}:{},...S.query?{query:S.query}:{}}),i.gitLog()]);if(m!==j.current)return;if(d(C),h(M),!C.isRepository){D(null),R(!1);return}const Q=ue(C);if(!k.keepSelection){D(null),u({selectedFileId:null,selectedSource:null,anchorLineId:null}),R(!1);return}const ae=S.selectedFileId,Re=Q.find(de=>de.fileId===ae)?.path??(H?H.path:null),oe=qe({entries:Q,previousFileId:ae,previousPath:Re});if(oe.fileId&&oe.fileId!==ae){u({selectedFileId:null,selectedSource:null,notice:oe.notice}),D(null),R(!1);return}if(ae){const de=H!==null&&C.repositoryRevision===H.repositoryRevision;R(!de)}else R(!1)}catch(S){if(m!==j.current)return;L(ee(S))}finally{m===j.current&&(v(!1),P(!1))}}},[i,H,u]),U=r.useCallback(()=>{const m=j.current+1;j.current=m,F.current+=1,O(m,{keepSelection:!0,quiet:b!==null})},[O,b]);r.useEffect(()=>{const m=j.current+1;j.current=m,F.current+=1,d(null),h(null),D(null),L(""),R(!1),v(!!s),a(o.read(g)),s?O(m,{keepSelection:!1}):v(!1)},[g,s,o]),r.useEffect(()=>{if(!s||n===0)return;const m=j.current+1;j.current=m,F.current+=1,O(m,{keepSelection:!0,quiet:!0})},[n]),r.useEffect(()=>{if(!s||typeof document>"u")return;let m;const k=()=>{m!==void 0&&clearInterval(m),m=void 0},S=()=>{k(),m=setInterval(()=>{const M=j.current+1;j.current=M,O(M,{keepSelection:!0,quiet:!0})},nt)},C=()=>{if(document.visibilityState==="visible"){const M=j.current+1;j.current=M,O(M,{keepSelection:!0,quiet:!0}),S()}else k()};return document.visibilityState==="visible"&&S(),document.addEventListener("visibilitychange",C),()=>{k(),document.removeEventListener("visibilitychange",C)}},[s,x.group,x.query]);const V=r.useCallback(m=>{const k=j.current,S=F.current+1;F.current=S,u({selectedLineIds:[],selectedFileId:m.fileId,selectedSource:m.source,anchorLineId:null,notice:""}),L("");const C=c.current?.repositoryRevision,M=C?f.read(C,m.fileId):null;if(M){D(M),R(!1),v(!1);return}D(null),v(!0),(async()=>{try{const Q=await i.gitDiffDocument(m.fileId,void 0,l.current.ignoreWhitespace,l.current.wordDiff);if(k!==j.current||S!==F.current)return;f.write(Q.repositoryRevision,m.fileId,Q),D(Q),R(!1)}catch(Q){if(k!==j.current||S!==F.current)return;if(rt(Q)){L("仓库已变化,已重新载入 Git 状态。"),u({selectedFileId:null,selectedSource:null});return}L(ee(Q))}finally{k===j.current&&S===F.current&&v(!1)}})()},[i,f,u]),Y=r.useCallback(()=>{const m=b?.nextCursor;if(!m)return;const k=j.current,S=b?.repositoryRevision;(async()=>{try{const C=await i.gitStatus(m,{...x.group?{group:x.group}:{},...x.query?{query:x.query}:{}});if(k!==j.current)return;if(S!==void 0&&C.repositoryRevision!==S){L("仓库已变化,已重新载入 Git 状态。");return}d(M=>M&&{...C,conflicted:re(M.conflicted,C.conflicted),staged:re(M.staged,C.staged),unstaged:re(M.unstaged,C.unstaged),untracked:re(M.untracked,C.untracked),counts:{...C.counts,loaded:M.counts.loaded+C.counts.loaded}})}catch(C){if(k!==j.current)return;L(ee(C))}})()},[i,x.group,x.query,b]),J=r.useCallback(()=>{const m=I?.nextCursor;if(!m)return;const k=j.current;(async()=>{try{const S=await i.gitLog(m);if(k!==j.current)return;h(C=>C&&{...S,items:at(C.items,S.items)})}catch(S){if(k!==j.current)return;L(ee(S))}})()},[i,I]),ne=r.useCallback(()=>{const m=H?.nextCursor,k=x.selectedFileId;if(!m||!k)return;const S=j.current,C=F.current;(async()=>{try{const M=await i.gitDiffDocument(k,m,l.current.ignoreWhitespace,l.current.wordDiff);if(S!==j.current||C!==F.current)return;D(Q=>Q?{...M,hunks:[...Q.hunks,...M.hunks]}:M)}catch(M){if(S!==j.current||C!==F.current)return;L(ee(M))}})()},[i,H,x.selectedFileId]);r.useEffect(()=>{!b||!x.selectedFileId||ue(b).some(k=>k.fileId===x.selectedFileId)||(D(null),u({selectedFileId:null,selectedSource:null,anchorLineId:null}))},[b,x.selectedFileId,u]);const E=r.useMemo(()=>!b||!x.selectedFileId?null:ue(b).find(m=>m.fileId===x.selectedFileId)??null,[b,x.selectedFileId]),[w,z]=r.useState(!1),[_,G]=r.useState(null),X=r.useRef(null);X.current===null&&(X.current=new Ye({fetcher:async m=>{const k=await i.gitStatus(void 0,{});return Object.freeze({repositoryRevision:k.repositoryRevision,branch:k.branch,counts:Object.freeze({totalChangedFiles:k.counts.total,staged:k.counts.staged,unstaged:k.counts.unstaged,untracked:k.counts.untracked,conflicted:k.counts.conflicted}),fetchedAt:Date.now()})}}));const Z=X.current,te=r.useCallback(async()=>{const m=c.current;if(m?.isRepository)try{if((await Z.getSnapshot(s)).repositoryRevision===m.repositoryRevision)return;Z.invalidate(s),await O(j.current,{keepSelection:!0,quiet:!0})}catch{}},[O,Z,s]);r.useEffect(()=>{if(!s)return;let m=!1;const k=()=>{m||document.hidden||(m=!0,te().finally(()=>{m=!1}))},S=()=>{document.hidden||k()};return window.addEventListener("focus",k),document.addEventListener("visibilitychange",S),()=>{window.removeEventListener("focus",k),document.removeEventListener("visibilitychange",S)}},[te,s]);const K=r.useCallback(async()=>{f.clear(),Z.invalidate(s);const m=j.current+1;j.current=m,F.current+=1,await O(m,{keepSelection:!0,quiet:!0})},[f,O,Z,s]),se=r.useCallback(async(m,k)=>{if(!w){z(!0),L("");try{await m(),await K(),u({notice:k})}catch(S){L(ee(S))}finally{z(!1)}}},[w,K,u]),Ce=r.useCallback(async m=>{const k=c.current?.repositoryRevision;k&&(await se(()=>i.gitStage(m,k),m.length>1?`已暂存 ${m.length} 个文件。`:"已暂存。"),u({selectedFileIds:[]}))},[i,se,u]),we=r.useCallback(async m=>{const k=c.current?.repositoryRevision;k&&(await se(()=>i.gitUnstage(m,k),m.length>1?`已取消暂存 ${m.length} 个文件。`:"已取消暂存。"),u({selectedFileIds:[]}))},[i,se,u]),Fe=r.useCallback(async m=>{const k=c.current?.repositoryRevision;k&&await se(()=>i.gitApplyPatch({...m,expectedRepositoryRevision:k}),"已应用所选改动到索引。")},[i,se]),Le=r.useCallback(async m=>{const k=c.current?.repositoryRevision;if(!k)throw new Error("Git repository is unavailable.");z(!0),L("");const S=He();try{const C=await i.gitCommit({summary:m.summary,...m.body?{body:m.body}:{},expectedRepositoryRevision:k,requestId:S});return await K(),u({commitDraft:{summary:"",body:""},notice:C.warning?`已提交 ${C.commitSha.slice(0,8)},但:${C.warning}`:`已提交 ${C.commitSha.slice(0,8)}。`}),C.commitSha}catch(C){throw L(ee(C)),C}finally{z(!1)}},[i,K,u]),Ee=r.useCallback(m=>{const k=$.current.selectedFileIds;u({selectedFileIds:k.includes(m)?k.filter(S=>S!==m):[...k,m]})},[u]),De=r.useCallback(()=>u({selectedFileIds:[]}),[u]);return r.useEffect(()=>{if(!b?.isRepository){G(null);return}let m=!1;return(async()=>{try{const k=await i.gitCommitPreview();m||G(k)}catch{m||G(null)}})(),()=>{m=!0}},[i,b?.isRepository,b?.repositoryRevision]),{session:x,display:p,status:b,log:I,diff:H,loading:N,refreshing:T,error:A,stale:q,setSession:u,setDisplay:B,openFile:V,reload:U,loadMoreStatus:Y,loadMoreLog:J,loadMoreDiff:ne,selectedEntry:E,busy:w,commitPreview:_,toggleSelection:Ee,clearSelection:De,stagePaths:Ce,unstagePaths:we,applyPatch:Fe,commit:Le}}function ue(t){return[...t.conflicted,...t.unstaged,...t.staged,...t.untracked]}function lt(t,s){return s==="conflict"?t.conflicted:s==="unstaged"?t.unstaged:s==="staged"?t.staged:t.untracked}function re(t,s){const n=new Map(t.map(i=>[i.fileId,i]));for(const i of s)n.set(i.fileId,i);return[...n.values()]}function at(t,s){const n=new Map(t.map(i=>[i.id,i]));for(const i of s)n.set(i.id,i);return[...n.values()]}function ee(t){return t instanceof Error?t.message:"Git 请求失败。"}function rt(t){return typeof t=="object"&&t!==null&&t.code==="git_revision_conflict"}function ct(t){const s=[];let n=0;const i=t.lines;for(;n<i.length;){const o=i[n];if(o.kind==="deletion"){const f=[];for(;n<i.length&&i[n].kind==="deletion";)f.push(i[n]),n+=1;const g=[];for(;n<i.length&&i[n].kind==="addition";)g.push(i[n]),n+=1;const x=Math.max(f.length,g.length);for(let a=0;a<x;a+=1){const p=f[a]??null,y=g[a]??null;s.push(Object.freeze({key:`${t.hunkId}:${p?.lineId??`-${a}`}:${y?.lineId??`-${a}`}`,left:p,right:y,changed:!0}))}continue}if(o.kind==="addition"){s.push(Object.freeze({key:`${t.hunkId}:${o.lineId}`,left:null,right:o,changed:!0})),n+=1;continue}s.push(Object.freeze({key:`${t.hunkId}:${o.lineId}`,left:o,right:o,changed:!1})),n+=1}return s}function ot(t,s,n){const i=new Set(s),o=[];for(const f of t){if(o.push(Object.freeze({kind:"hunk-header",hunk:f})),i.has(f.hunkId)){o.push(Object.freeze({kind:"folded",hunk:f}));continue}if(n==="side-by-side"){for(const g of ct(f))o.push(Object.freeze({kind:"side-by-side",hunk:f,row:g}));continue}for(const g of f.lines)o.push(Object.freeze({kind:"unified-line",hunk:f,line:g}))}return o}function ve(t){const s=[];for(const n of t){let i=!1;for(const o of n.lines){const f=o.kind==="addition"||o.kind==="deletion";f&&!i&&s.push(Object.freeze({lineId:o.lineId,hunkId:n.hunkId,oldLineNumber:o.oldLineNumber,newLineNumber:o.newLineNumber})),i=f}}return s}function dt(t,s,n=500){const i=s.trim().toLowerCase();if(!i)return[];const o=[];for(const f of t)for(const g of f.lines){if(o.length>=n)return o;g.text.toLowerCase().includes(i)&&o.push(Object.freeze({lineId:g.lineId,hunkId:f.hunkId,side:g.oldLineNumber!==null&&g.newLineNumber!==null?"both":g.oldLineNumber!==null?"old":"new"}))}return o}function ut(t){let s=0,n=0;for(const i of t)for(const o of i.lines)o.kind==="addition"?s+=1:o.kind==="deletion"&&(n+=1);return Object.freeze({additions:s,deletions:n,hunks:t.length})}function ce(t,s){return s?t.replace(/\t/gu,"→ ").replace(/ +$/gu,n=>"·".repeat(n.length)):t}function ge(t){return t==="addition"?"+":t==="deletion"?"-":t==="meta"?"\\":" "}function ht(t,s){const n={schemaVersion:2,type:"review_context",repositoryRevision:t.repositoryRevision,path:t.path,source:t.source,hunk:s.header,hunkId:s.hunkId,complete:s.complete},i=s.lines.map(o=>o.raw).join(`
|
|
2
|
-
`).slice(0,12e3);return[`请审阅 ${t.path} 的这个 diff hunk,并指出正确性、安全性和测试风险:`,"","```review_context",JSON.stringify(n,null,2),"```","","```diff",i,"```"].join(`
|
|
3
|
-
`)}function be({document:t,mode:s,wrap:n,showWhitespace:i,collapsedHunks:o,anchorLineId:f,loading:g=!1,stale:x=!1,onChangeMode:a,onToggleWrap:p,onToggleWhitespace:y,onToggleHunk:b,hunkAction:d=null,selectedLineIds:I=[],onToggleLine:h,ignoreWhitespace:H=!1,onToggleIgnoreWhitespace:D,wordDiff:N=!1,onToggleWordDiff:v,onSetAllFolded:T,onAnchorChange:P,onNotice:A,onLoadMore:L,onSendToComposer:q}){const R=r.useRef(null),[j,F]=r.useState(!1),[$,c]=r.useState(""),[l,u]=r.useState(0),B=r.useMemo(()=>ot(t.hunks,o,s),[t.hunks,o,s]),O=r.useMemo(()=>ve(t.hunks),[t.hunks]),U=r.useMemo(()=>ut(t.hunks),[t.hunks]),V=r.useMemo(()=>j?dt(t.hunks,$):[],[t.hunks,j,$]);r.useEffect(()=>{!f||!R.current||R.current.querySelector(`[data-line-id="${CSS.escape(f)}"]`)?.scrollIntoView({block:"center"})},[f]),r.useEffect(()=>{u(0)},[$]);const Y=r.useMemo(()=>f?O.findIndex(E=>E.lineId===f):-1,[O,f]),J=E=>{if(O.length===0){A("这个文件没有改动。");return}const w=Y<0?E>0?-1:0:Y,z=Math.min(O.length-1,Math.max(0,w+E));P(O[z].lineId)},ne=E=>{if(E.key==="F7"){E.preventDefault(),J(E.shiftKey?-1:1);return}if(E.key==="Escape"){j&&(E.stopPropagation(),F(!1),c(""));return}if(E.key==="Enter"&&j&&V.length>0){E.preventDefault();const w=E.shiftKey?(l-1+V.length)%V.length:(l+1)%V.length;u(w),P(V[w].lineId)}};return t.kind==="binary"||t.kind==="symlink"||t.kind==="submodule"?e.jsxs("div",{className:"diff-viewer",children:[e.jsx(he,{doc:t,stats:U,stale:x}),e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(W,{name:"code"}),e.jsx("strong",{children:xt(t.kind)}),e.jsx("p",{children:"只展示变更事实,不返回可预览内容。"}),e.jsx("ul",{className:"diff-meta-list",children:t.meta.slice(0,8).map(E=>e.jsx("li",{children:e.jsx("code",{children:E})},E))})]})]}):t.kind==="metadata"?e.jsxs("div",{className:"diff-viewer",children:[e.jsx(he,{doc:t,stats:U,stale:x}),e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(W,{name:"code"}),e.jsx("strong",{children:"仅有元数据变化"}),e.jsx("p",{children:"没有文本 Hunk,但文件确实变了。"}),e.jsx("ul",{className:"diff-meta-list",children:t.meta.slice(0,8).map(E=>e.jsx("li",{children:e.jsx("code",{children:E})},E))})]})]}):e.jsxs("div",{className:"diff-viewer",children:[e.jsx(he,{doc:t,stats:U,stale:x}),e.jsxs("div",{className:"diff-toolbar",role:"toolbar","aria-label":"Diff 显示选项",children:[e.jsxs("div",{className:"diff-mode-group",role:"group","aria-label":"Diff 布局",children:[e.jsx("button",{type:"button",className:"text-button","aria-pressed":s==="unified",onClick:()=>a("unified"),children:"统一"}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":s==="side-by-side",onClick:()=>a("side-by-side"),children:"并排"})]}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":n,onClick:p,children:"换行"}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":i,onClick:y,children:"空白字符"}),v?e.jsx("button",{type:"button",className:`text-button ${N?"diff-toggle-on":""}`,"aria-pressed":N,title:"词级差异(重新读取 Diff)",onClick:v,children:"词级"}):null,D?e.jsx("button",{type:"button",className:`text-button ${H?"diff-toggle-on":""}`,"aria-pressed":H,title:"忽略空白差异(重新读取 Diff)",onClick:D,children:"忽略空白"}):null,e.jsx("button",{type:"button",className:"text-button",onClick:()=>T(o.length===0),children:o.length===0?"折叠全部":"展开全部"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>J(-1),disabled:O.length===0,"aria-label":"上一个改动",children:"↑改动"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>J(1),disabled:O.length===0,"aria-label":"下一个改动",children:"↓改动"}),e.jsx("span",{className:"diff-anchor-count","aria-live":"polite",children:O.length===0?"无改动":`改动 ${Math.max(1,Y+1)}/${O.length}`}),e.jsx("button",{type:"button",className:"text-button","aria-pressed":j,onClick:()=>F(E=>!E),children:"查找"})]}),j?e.jsxs("div",{className:"diff-find",children:[e.jsx("input",{type:"search",value:$,autoFocus:!0,"aria-label":"在已加载的 Diff 中查找",placeholder:"在已加载内容中查找",onChange:E=>c(E.target.value)}),e.jsxs("span",{"aria-live":"polite",children:[$.trim()?V.length===0?"无命中":`${l+1}/${V.length}`:"输入以查找",t.completeness!=="complete"?" · 仅已加载内容":""]})]}):null,t.completeness==="paged"?e.jsx("p",{className:"resource-notice",role:"status",children:"当前为分页预览,未加载的 Hunk 不能执行任何写入。"}):null,e.jsx("div",{className:`diff-body diff-body-${s} ${n?"diff-wrap":""}`,ref:R,tabIndex:0,role:"region","aria-label":`Diff ${t.path}`,onKeyDown:ne,children:B.length===0?e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(W,{name:"check"}),e.jsx("strong",{children:"没有文本改动"})]}):B.map(E=>e.jsx(ft,{row:E,mode:s,showWhitespace:i,folded:o.includes(bt(E).hunkId),activeAnchor:f,onToggleHunk:b,hunkAction:d,selectedLineIds:I,onToggleLine:h,wordDiff:N},gt(E)))}),e.jsxs("footer",{className:"diff-footer",children:[q?e.jsx("button",{type:"button",className:"secondary-button",disabled:t.hunks.length===0,onClick:()=>q(ht({path:t.path,source:t.source,repositoryRevision:t.repositoryRevision},t.hunks[Math.max(0,O.findIndex(E=>E.lineId===f))]??t.hunks[0])),children:"发送当前 Hunk 到对话"}):null,t.nextCursor&&L?e.jsx("button",{type:"button",className:"text-button",onClick:L,disabled:g,children:g?"加载中…":"加载更多 Diff"}):null,e.jsxs("span",{className:"diff-footer-hint",children:[t.capabilities.stageFile?"可暂存此文件":t.capabilities.unstageFile?"可取消暂存此文件":"只读",t.capabilities.reason?` · ${t.capabilities.reason}`:""]})]})]})}function he({doc:t,stats:s,stale:n}){return e.jsxs("header",{children:[e.jsx("strong",{title:t.path,children:t.path}),e.jsx("span",{className:"diff-source",children:jt(t.source)}),e.jsxs("span",{className:"diff-stat-add",children:["+",s.additions]}),e.jsxs("span",{className:"diff-stat-del",children:["-",s.deletions]}),e.jsxs("span",{children:[s.hunks," 个 Hunk"]}),n?e.jsx("span",{className:"diff-stale",role:"status",children:"已变化"}):null]})}function ft({row:t,mode:s,showWhitespace:n,folded:i,activeAnchor:o,onToggleHunk:f,hunkAction:g=null,selectedLineIds:x=[],onToggleLine:a,wordDiff:p=!1}){if(t.kind==="hunk-header")return e.jsxs("div",{className:"diff-hunk-header",children:[e.jsx("button",{type:"button",className:"diff-fold","aria-expanded":!i,"aria-label":i?"展开 Hunk":"折叠 Hunk",onClick:()=>f(t.hunk.hunkId),children:i?"▸":"▾"}),e.jsx("code",{children:t.hunk.header}),t.hunk.complete?null:e.jsx("em",{className:"diff-incomplete",children:"未完整加载"}),g&&t.hunk.complete?e.jsx("button",{type:"button",className:"text-button diff-hunk-action","aria-label":g.label,onClick:()=>g.run(t.hunk.hunkId),children:g.label}):null]});if(t.kind==="folded")return e.jsxs("button",{type:"button",className:"diff-folded-row",onClick:()=>f(t.hunk.hunkId),children:["已折叠 ",t.hunk.lines.length," 行 · 点击展开"]});if(t.kind==="side-by-side")return e.jsx(pt,{row:t.row,showWhitespace:n});const y=t.line;return e.jsxs("div",{className:`diff-line diff-line-${y.kind} ${o===y.lineId?"diff-line-anchor":""}`,"data-line-id":y.lineId,"data-side":y.oldLineNumber!==null&&y.newLineNumber!==null?"both":y.oldLineNumber!==null?"old":"new",children:[e.jsx("span",{className:"diff-gutter",children:y.oldLineNumber??""}),e.jsx("span",{className:"diff-gutter",children:y.newLineNumber??""}),a&&(y.kind==="addition"||y.kind==="deletion")?e.jsx("input",{type:"checkbox",className:"diff-line-select","aria-label":`选择第 ${y.newLineNumber??y.oldLineNumber??""} 行`,checked:x.includes(y.lineId),onChange:()=>a(y.lineId)}):null,e.jsx("span",{className:"diff-marker","aria-hidden":"true",children:ge(y.kind)}),e.jsx("span",{className:"diff-code",children:p?mt(ce(y.text,n)):ce(y.text,n)||" "}),null]})}function mt(t){if(!t)return" ";const s=[],n=/\[-([\s\S]*?)-\]|\{\+([\s\S]*?)\+\}/gu;let i=0,o,f=0;for(;(o=n.exec(t))!==null;)o.index>i&&s.push(t.slice(i,o.index)),o[1]!==void 0?s.push(e.jsx("em",{className:"diff-word-del",children:o[1]},f++)):s.push(e.jsx("em",{className:"diff-word-add",children:o[2]},f++)),i=o.index+o[0].length;return i<t.length&&s.push(t.slice(i)),s.length>0?s:" "}function pt({row:t,showWhitespace:s}){return e.jsxs("div",{className:`diff-sbs-row ${t.changed?"diff-sbs-changed":""}`,children:[e.jsxs("div",{className:`diff-sbs-side ${t.left?.kind==="deletion"?"diff-line-deletion":""}`,"data-line-id":t.left?.lineId??void 0,children:[e.jsx("span",{className:"diff-gutter",children:t.left?.oldLineNumber??""}),e.jsx("span",{className:"diff-marker","aria-hidden":"true",children:t.left?ge(t.left.kind):" "}),e.jsx("span",{className:"diff-code",children:t.left?ce(t.left.text,s)||" ":""})]}),e.jsxs("div",{className:`diff-sbs-side ${t.right?.kind==="addition"?"diff-line-addition":""}`,"data-line-id":t.right?.lineId??void 0,children:[e.jsx("span",{className:"diff-gutter",children:t.right?.newLineNumber??""}),e.jsx("span",{className:"diff-marker","aria-hidden":"true",children:t.right?ge(t.right.kind):" "}),e.jsx("span",{className:"diff-code",children:t.right?ce(t.right.text,s)||" ":""})]})]})}function gt(t){return t.kind==="hunk-header"?`h:${t.hunk.hunkId}`:t.kind==="folded"?`f:${t.hunk.hunkId}`:t.kind==="side-by-side"?t.row.key:t.line.lineId}function bt(t){return t.hunk}function xt(t){return t==="binary"?"二进制差异":t==="symlink"?"符号链接变化":t==="submodule"?"Submodule 指针变化":"元数据变化"}function jt(t){return t==="staged"?"HEAD → 索引":t==="unstaged"?"索引 → 工作区":t==="untracked"?"空 → 未跟踪文件":"冲突版本"}const ye=Object.freeze({snapshot:"两端快照 A → B","merge-base":"共同祖先 → B"});function yt({refs:t,actions:s,display:n,collapsedHunks:i,anchorLineId:o,onDisplayChange:f,onToggleHunk:g,onSetAllFolded:x,onAnchorChange:a,onNotice:p,onSendToComposer:y}){const b=r.useMemo(()=>kt(t),[t]),d=b.find(u=>u.isBranch)?.value??b[0]?.value??"",I=t?.refs.find(u=>u.isHead)?.shortName??d,[h,H]=r.useState(d),[D,N]=r.useState(I),[v,T]=r.useState("snapshot"),[P,A]=r.useState(null),[L,q]=r.useState(null),[R,j]=r.useState(!1),[F,$]=r.useState(""),c=()=>{!h||!D||R||(j(!0),$(""),(async()=>{try{const u=await s.gitCompare({baseRef:h,headRef:D,mode:v});A(u),q(null)}catch(u){$(ke(u))}finally{j(!1)}})())},l=u=>{!P||u.sensitive||R||(j(!0),$(""),(async()=>{try{const B=await s.gitCompareFileDiff({baseOid:P.baseOid,headOid:P.headOid,path:u.path});q(B)}catch(B){$(ke(B))}finally{j(!1)}})())};return b.length===0?e.jsxs("div",{className:"resource-empty",children:[e.jsx(W,{name:"branch",size:16}),e.jsx("strong",{children:"没有可比较的 ref"}),e.jsx("p",{children:"这个仓库还没有分支或标签。"})]}):e.jsxs("div",{className:"git-compare","aria-label":"分支与版本比较",children:[e.jsxs("div",{className:"git-compare-form",children:[e.jsxs("label",{children:[e.jsx("span",{children:"基准 A"}),e.jsx("select",{value:h,"aria-label":"选择基准 A",onChange:u=>H(u.target.value),children:b.map(u=>e.jsx("option",{value:u.value,children:u.label},u.value))})]}),e.jsxs("label",{children:[e.jsx("span",{children:"目标 B"}),e.jsx("select",{value:D,"aria-label":"选择目标 B",onChange:u=>N(u.target.value),children:b.map(u=>e.jsx("option",{value:u.value,children:u.label},u.value))})]}),e.jsxs("label",{children:[e.jsx("span",{children:"模式"}),e.jsx("select",{value:v,"aria-label":"选择比较模式",onChange:u=>T(u.target.value),children:Object.keys(ye).map(u=>e.jsx("option",{value:u,children:ye[u]},u))})]}),e.jsx("button",{type:"button",className:"primary-button",disabled:R||h===D,"aria-busy":R,onClick:c,children:R?"比较中…":"比较"})]}),e.jsx("p",{className:"git-compare-hint",children:"修改选择不会立即发起查询;点「比较」或按 Enter 才执行。交换 A/B 后会取消旧的请求。"}),F?e.jsx("p",{className:"resource-error",role:"alert",children:F}):null,P?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"git-compare-range",children:[P.baseLabel," ",e.jsx("code",{children:P.baseOid.slice(0,10)})," → ",P.headLabel," ",e.jsx("code",{children:P.headOid.slice(0,10)}),P.truncated?" · 文件列表已截断":""]}),e.jsxs("p",{className:"git-compare-range",children:[P.files.length," 个文件 ·",e.jsxs("em",{className:"diff-stat-add",children:[" +",P.additions]}),e.jsxs("em",{className:"diff-stat-del",children:[" -",P.deletions]}),e.jsx("button",{type:"button",className:"text-button",onClick:c,disabled:R,children:"重新比较"})]}),e.jsx("ul",{className:"git-compare-files",children:P.files.map(u=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:L?.path===u.path?"selected":"","aria-current":L?.path===u.path?"true":void 0,disabled:u.sensitive,onClick:()=>l(u),children:[e.jsx("span",{className:"git-commit-file-stats",children:u.binary?"bin":`+${u.additions} -${u.deletions}`}),e.jsx("span",{title:u.path,children:u.renamedFrom?`${u.renamedFrom} → ${u.path}`:u.path}),u.sensitive?e.jsx("em",{className:"git-sensitive-badge",children:"受保护"}):null]})},`${u.renamedFrom??""}:${u.path}`))}),L?e.jsx(be,{document:L,mode:n.mode,wrap:n.wrap,showWhitespace:n.showWhitespace,collapsedHunks:i,anchorLineId:o,loading:R,onChangeMode:u=>f({mode:u}),onToggleWrap:()=>f({wrap:!n.wrap}),onToggleWhitespace:()=>f({showWhitespace:!n.showWhitespace}),onToggleHunk:g,onSetAllFolded:x,onAnchorChange:a,onNotice:p,onSendToComposer:y}):e.jsx("p",{className:"git-compare-hint",children:"点一个文件查看该比较下的 Diff。"})]}):null]})}function kt(t){return t?t.refs.map(s=>Object.freeze({value:s.shortName,label:s.kind==="branch"?s.shortName:`${s.shortName}(${s.kind==="tag"?"tag":s.kind==="remote"?"远程":"其他"})`,isBranch:s.kind==="branch"})):[]}function ke(t){const s=t?.code;return s==="git_merge_base_multiple"?"这两个 ref 有多个共同祖先,没有唯一分叉点;请改用「两端快照」模式。":s==="git_merge_base_missing"?"两个 ref 没有共同祖先,无法用「共同祖先」模式;请改用「两端快照」模式。":s==="git_shallow_history"?"仓库缺少完成该比较所需的对象(浅克隆?)。":s==="git_ref_not_found"?"所选 ref 无法解析为提交。":t instanceof Error?t.message:"比较失败。"}const Nt=Object.freeze({"both-modified":"双方都修改","both-added":"双方都新增","added-by-us":"我们新增 · 对方删除","added-by-them":"对方新增 · 我们删除","deleted-by-us":"我们删除 · 对方修改","deleted-by-them":"对方删除 · 我们修改","both-deleted":"双方都删除",other:"其他冲突形态"}),vt=Object.freeze({base:"base(共同祖先)",ours:"ours(当前分支)",theirs:"theirs(合入分支)",worktree:"工作区文件",revision:"该版本"});function It({path:t,actions:s}){const[n,i]=r.useState(null),[o,f]=r.useState(""),[g,x]=r.useState(!0);if(r.useEffect(()=>{let p=!1;return x(!0),f(""),(async()=>{try{const y=await s.gitConflictVersions(t);p||i(y)}catch(y){p||(i(null),f(y instanceof Error?y.message:"冲突详情读取失败。"))}finally{p||x(!1)}})(),()=>{p=!0}},[s,t]),g)return e.jsx("p",{className:"resource-loading",children:"正在读取冲突版本…"});if(o)return e.jsx("p",{className:"resource-error",role:"alert",children:o});if(!n)return null;const a=[n.base,n.ours,n.theirs,n.worktree];return e.jsxs("section",{className:"git-conflict","aria-label":"冲突版本",children:[e.jsxs("header",{className:"git-conflict-header",children:[e.jsx(W,{name:"warning",size:14}),e.jsx("strong",{children:n.path}),e.jsx("em",{className:"git-merge-badge",children:Nt[n.shape]})]}),e.jsx("p",{className:"git-compare-hint",children:"直接读 index 的 stage 1/2/3,不用普通暂存 Diff 代替完整冲突视图。缺失的版本是这种冲突形态的正常结果。"}),e.jsx("div",{className:"git-conflict-grid",children:a.map(p=>e.jsxs("article",{className:"git-conflict-version",children:[e.jsxs("header",{children:[e.jsx("span",{children:vt[p.label]}),p.exists?e.jsx("code",{children:p.oid?.slice(0,10)}):e.jsx("em",{className:"git-conflict-absent",children:"此形态下不存在"})]}),p.exists?p.lfs?e.jsxs("p",{className:"git-conflict-note",children:["LFS 指针 · oid ",p.lfs.oid.slice(0,16),"…",p.lfs.size!==null?` · ${p.lfs.size} 字节(不下载对象)`:""]}):p.binary?e.jsxs("p",{className:"git-conflict-note",children:["二进制内容(",p.byteSize," 字节),不在此处渲染。"]}):p.truncated?e.jsxs("p",{className:"git-conflict-note",children:["超过上限(",p.byteSize," 字节),未读取内容。"]}):e.jsx("pre",{className:"git-conflict-content",children:p.content??""}):e.jsx("p",{className:"git-conflict-note",children:"没有这个版本。"})]},p.label))})]})}function St({history:t,actions:s,display:n,collapsedHunks:i,anchorLineId:o,onDisplayChange:f,onToggleHunk:g,onSetAllFolded:x,onAnchorChange:a,onNotice:p,onSendToComposer:y}){const{page:b,detail:d,files:I,diff:h,fileHistory:H,error:D}=t,[N,v]=r.useState(null),[T,P]=r.useState(!1),[A,L]=r.useState(null),[q,R]=r.useState(!1),[j,F]=r.useState(null),$=r.useMemo(()=>(b?.items??[]).filter(c=>c.isMerge).length,[b]);return t.isEmptyRepository?e.jsxs("div",{className:"resource-empty",children:[e.jsx(W,{name:"branch",size:16}),e.jsx("strong",{children:"尚无提交"}),e.jsx("p",{children:"这个仓库还没有提交。新文件仍可暂存并完成首次提交。"})]}):e.jsxs("div",{className:"git-history","aria-label":"Git 历史",children:[e.jsxs("div",{className:"git-history-search",children:[e.jsx("input",{type:"search","aria-label":"搜索提交消息",placeholder:"搜索提交消息…",value:t.query.message,onChange:c=>t.setQuery({message:c.target.value})}),e.jsx("input",{type:"search","aria-label":"按作者筛选",placeholder:"作者",value:t.query.author,onChange:c=>t.setQuery({author:c.target.value})}),e.jsx("input",{type:"search","aria-label":"按文件路径筛选",placeholder:"文件路径",value:t.query.path,onChange:c=>t.setQuery({path:c.target.value})}),e.jsx("input",{type:"search","aria-label":"按提交哈希查找",placeholder:"提交哈希",value:t.query.sha,onChange:c=>t.setQuery({sha:c.target.value})}),e.jsxs("div",{className:"git-history-dates",children:[e.jsx("input",{type:"search","aria-label":"起始日期",placeholder:"自 (2026-01-01)",value:t.query.since,onChange:c=>t.setQuery({since:c.target.value})}),e.jsx("input",{type:"search","aria-label":"结束日期",placeholder:"至",value:t.query.until,onChange:c=>t.setQuery({until:c.target.value})})]}),e.jsxs("div",{className:"git-history-search-actions",children:[e.jsxs("span",{role:"status",children:[b?`已载 ${b.items.length}${b.truncated?"+":""} 个提交${$>0?` · 含 ${$} 个合并`:""}`:"读取中…",t.refs?.detached?" · detached HEAD":""]}),e.jsx("button",{type:"button",className:`text-button ${A?"diff-toggle-on":""}`,"aria-pressed":A!==null,onClick:()=>{if(A){L(null);return}R(!0),s.gitGraph().then(L).finally(()=>R(!1))},children:"拓扑"}),e.jsx("button",{type:"button",className:"text-button",onClick:t.resetQuery,children:"清除筛选"})]})]}),D?e.jsx("p",{className:"resource-error",role:"alert",children:D}):null,H?e.jsxs("section",{className:"git-file-history","aria-label":"文件历史",children:[e.jsxs("header",{children:[e.jsxs("strong",{children:["文件历史 · ",H.path]}),e.jsx("button",{type:"button",className:"text-button",onClick:t.closeFileHistory,children:"返回提交列表"})]}),e.jsx("p",{className:"git-file-history-note",children:"跟随重命名;复制与复杂合并场景的追踪可能不完整。"}),e.jsx("ul",{children:H.items.map(c=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>{t.closeFileHistory(),t.selectCommit(c)},children:[e.jsx("code",{children:c.shortId}),e.jsx("span",{children:c.subject}),e.jsx("time",{dateTime:c.authoredAt,children:fe(c.authoredAt)})]})},c.id))}),H.truncated?e.jsx("p",{className:"git-file-history-note",children:"结果已截断,仅显示最近的提交。"}):null]}):null,d?e.jsxs("section",{className:"git-commit-detail","aria-label":"提交详情",children:[e.jsxs("header",{children:[e.jsxs("div",{children:[e.jsx("code",{children:d.shortId}),d.isMerge?e.jsxs("span",{className:"git-merge-badge",children:["合并提交 · ",d.parents.length," 个父提交"]}):d.parents.length===0?e.jsx("span",{className:"git-root-badge",children:"根提交"}):null]}),e.jsx("button",{type:"button",className:"text-button",onClick:t.closeDetail,children:"关闭详情"})]}),e.jsx("p",{className:"git-commit-subject",children:d.subject}),d.message.trim()!==d.subject.trim()?e.jsx("pre",{className:"git-commit-message",children:d.message.trim()}):null,e.jsxs("p",{className:"git-commit-meta",children:[d.authorName," <",d.authorEmail,"> · ",fe(d.authoredAt),d.committerName&&d.committerName!==d.authorName?` · 提交者 ${d.committerName}`:""]}),e.jsxs("p",{className:"git-commit-base",children:["比较基准:",d.baseLabel," ",e.jsx("code",{children:d.baseOid.slice(0,10)})]}),d.isMerge?e.jsx("div",{className:"git-parent-picker",role:"group","aria-label":"选择父提交",children:d.parents.map((c,l)=>e.jsxs("button",{type:"button","aria-pressed":d.parentIndex===l,className:d.parentIndex===l?"selected":"",onClick:()=>t.setParentIndex(l),children:["父 ",l+1," ",e.jsx("code",{children:c.slice(0,8)})]},c))}):null,I?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"git-commit-stats-line",children:[I.files.length," 个文件 ·",e.jsxs("em",{className:"diff-stat-add",children:[" +",I.additions]}),e.jsxs("em",{className:"diff-stat-del",children:[" -",I.deletions]}),I.truncated?" · 已截断":""]}),e.jsx("ul",{className:"git-commit-file-list",children:I.files.map(c=>e.jsxs("li",{children:[e.jsxs("button",{type:"button",className:d&&t.diff?.path===c.path?"selected":"","aria-current":t.diff?.path===c.path?"true":void 0,onClick:()=>t.selectFile(c.path),children:[e.jsx("span",{className:"git-commit-file-stats",children:c.binary?"bin":`+${c.additions} -${c.deletions}`}),e.jsx("span",{title:c.path,children:c.renamedFrom?`${c.renamedFrom} → ${c.path}`:c.path}),c.sensitive?e.jsx("em",{className:"git-sensitive-badge",children:"受保护"}):null]}),e.jsx("button",{type:"button",className:"text-button","aria-label":`查看 ${c.path} 的文件历史`,onClick:()=>t.openFileHistory(c.path),children:"历史"}),e.jsx("button",{type:"button",className:"text-button","aria-label":`查看 ${c.path} 在该提交的版本`,onClick:()=>{d&&s.gitBlob({path:c.path,rev:d.id}).then(l=>F({path:l.path,rev:l.rev,lines:l.content,binary:l.binary,truncated:l.truncated,byteSize:l.byteSize,dataUrl:l.dataUrl})).catch(()=>F(null))},children:"该版本"}),e.jsx("button",{type:"button",className:"text-button","aria-label":`查看 ${c.path} 的 Blame`,onClick:()=>{d&&(P(!0),s.gitBlame({path:c.path,rev:d.id}).then(l=>v({...l,rev:d.id})).catch(()=>v(null)).finally(()=>P(!1)))},children:"Blame"})]},c.path))})]}):e.jsx("p",{className:"resource-loading",children:"正在读取该提交的改动…"})]}):null,h?e.jsx(be,{document:h,mode:n.mode,wrap:n.wrap,showWhitespace:n.showWhitespace,collapsedHunks:i,anchorLineId:o,loading:t.loadingDetail,onChangeMode:c=>f({mode:c}),onToggleWrap:()=>f({wrap:!n.wrap}),onToggleWhitespace:()=>f({showWhitespace:!n.showWhitespace}),onToggleHunk:g,onSetAllFolded:x,onAnchorChange:a,onNotice:p,onSendToComposer:y}):null,q?e.jsx("p",{className:"git-file-history-note",children:"正在读取拓扑…"}):null,A?e.jsxs("section",{className:"git-graph","aria-label":"提交拓扑",children:[e.jsxs("header",{children:[e.jsxs("strong",{children:["拓扑(",A.rows.length,A.truncated?"+":""," 行)"]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>L(null),children:"关闭"})]}),e.jsx("p",{className:"git-file-history-note",children:"图形列由 git 直接绘制,不由前端重算。"}),e.jsx("div",{className:"git-graph-body",children:A.rows.map((c,l)=>e.jsxs("button",{type:"button",className:c.id&&d?.id===c.id?"selected":"",disabled:!c.id,onClick:()=>{c.id&&(L(null),t.selectCommit({id:c.id}))},children:[e.jsx("code",{children:c.graph}),e.jsx("span",{children:c.id?c.subject:""})]},`${c.id??"graph"}:${l}`))})]}):null,j?e.jsxs("section",{className:"git-blob","aria-label":"该版本内容",children:[e.jsxs("header",{children:[e.jsxs("strong",{children:[j.path," @ ",j.rev.slice(0,10)]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>F(null),children:"关闭"})]}),j.truncated?e.jsxs("p",{className:"git-file-history-note",children:["文件超过上限(",j.byteSize," 字节),未读取内容。"]}):j.dataUrl?e.jsx("img",{src:j.dataUrl,alt:`${j.path} 在该提交的图像版本`,className:"git-blob-image"}):j.binary?e.jsxs("p",{className:"git-file-history-note",children:["二进制内容(",j.byteSize," 字节),不在此处渲染。"]}):e.jsx("pre",{className:"git-blob-content",children:j.lines.join(`
|
|
4
|
-
`)})]}):null,N?e.jsxs("section",{className:"git-blame","aria-label":"Blame",children:[e.jsxs("header",{children:[e.jsxs("strong",{children:["Blame · ",N.path]}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>v(null),children:"关闭"})]}),T?e.jsx("p",{className:"git-file-history-note",children:"读取中…"}):null,e.jsx("div",{className:"git-blame-table",children:N.lines.map(c=>e.jsxs("div",{className:"git-blame-row",children:[e.jsx("code",{children:c.commitShort}),e.jsx("span",{className:"git-blame-author",title:c.summary,children:c.author}),e.jsx("time",{children:c.authoredAt.slice(0,10)}),e.jsx("span",{className:"git-blame-summary",title:c.summary,children:c.summary})]},c.lineNumber))}),N.truncated?e.jsx("p",{className:"git-file-history-note",children:"结果已截断。"}):null]}):null,e.jsx("ul",{className:"git-history-list",children:(b?.items??[]).map(c=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:d?.id===c.id?"selected":"","aria-current":d?.id===c.id?"true":void 0,onClick:()=>t.selectCommit(c),children:[e.jsx("code",{children:c.shortId}),e.jsx("span",{title:c.subject,children:c.subject}),c.isMerge?e.jsx("em",{className:"git-merge-badge-inline",children:"合并"}):null,c.decoration.length>0?e.jsx("em",{className:"git-ref-badge",title:c.decoration.join(", "),children:c.decoration[0]}):null,e.jsx("time",{dateTime:c.authoredAt,children:fe(c.authoredAt)})]})},c.id))}),b&&b.items.length===0&&!t.loading?e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(W,{name:"search",size:16}),e.jsx("strong",{children:"没有匹配的提交"}),e.jsx("p",{children:"筛选在 Host 上对整个可达历史执行,不只是当前页。"})]}):null,b?.nextCursor?e.jsx("button",{type:"button",className:"text-button resource-load-more",onClick:t.loadMore,disabled:t.loadingMore,children:t.loadingMore?"加载中…":"加载更多提交"}):null]})}function fe(t){const s=new Date(t);return Number.isNaN(s.getTime())?t:s.toLocaleDateString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit"})}const Ct={changes:"变更",history:"历史",compare:"比较"},Ie={conflict:"冲突",unstaged:"未暂存",staged:"已暂存",untracked:"未跟踪"},Se=["conflict","unstaged","staged","untracked"];function wt(t,s){return s==="conflict"?t.conflicted:t[s]}function Pt({workspaceId:t,refreshEpoch:s,actions:n,onSendToComposer:i,onRevealInFiles:o,navigatorWidthPx:f,onNavigatorWidthCommit:g,store:x}){const a=it({workspaceId:t,refreshEpoch:s,actions:n,store:x}),{notice:p,showNotice:y,clearNotice:b}=Oe(),{status:d,diff:I,session:h}=a,H=()=>{if(!h.selectedFileId||h.selectedLineIds.length===0)return;const l=h.selectedFileId,u=h.selectedLineIds;a.applyPatch({fileId:l,lineIds:u}),a.setSession({selectedLineIds:[]})},D=r.useRef(null),[N,v]=r.useState(0);r.useEffect(()=>{const l=D.current;if(!l)return;const u=new ResizeObserver(B=>{for(const O of B)v(O.contentRect.width)});return u.observe(l),v(l.getBoundingClientRect().width),()=>u.disconnect()},[]);const T=N>0&&N<=620,P=N>0&&N<=959,A=N>0&&N<=640?"unified":a.display.mode,L=r.useMemo(()=>{const l=a.selectedEntry;if(!o||!l||h.view!=="changes")return null;const u=l.fileId;return()=>{n.gitFilesTarget(u).then(B=>o({path:B.path,filesToken:B.filesToken})).catch(()=>y("该文件无法在 Files 中打开。"))}},[n,a.selectedEntry,o,h.view,y]),q=r.useMemo(()=>{if(h.view!=="changes"||!h.selectedFileId||!I)return null;const l=h.selectedFileId;return I.source!=="staged"&&I.source!=="unstaged"&&I.source!=="untracked"?null:{label:I.source==="staged"?"取消暂存此 Hunk":"暂存此 Hunk",run:B=>{a.applyPatch({fileId:l,hunkIds:[B]})}}},[I,a,h.selectedFileId,h.view]),R=Ve({enabled:(h.view==="history"||h.view==="compare")&&!!t,session:h,setSession:a.setSession,actions:n,refreshEpoch:s}),j=r.useMemo(()=>d?Se.map(l=>({source:l,label:Ie[l],count:wt(d.counts,l),items:lt(d,l)})):[],[d]),F=r.useMemo(()=>h.group?j.filter(l=>l.source===h.group):j,[j,h.group]),$=r.useMemo(()=>F.flatMap(l=>l.items.map(u=>u.fileId)),[F]),c=r.useMemo(()=>I?ve(I.hunks).map(l=>l.lineId):[],[I]);return Ue({enabled:h.view==="changes",session:h,setSession:a.setSession,fileIds:$,anchorLineIds:c,onOpenSelection:()=>{const l=a.selectedEntry;l&&a.openFile(l)},onEscapeFallback:()=>{}}),a.error&&!d?e.jsxs("div",{className:"resource-empty",role:"alert",children:[e.jsx(W,{name:"warning"}),e.jsx("strong",{children:"Git 状态读取失败"}),e.jsx("p",{children:a.error}),e.jsx("button",{type:"button",className:"secondary-button",onClick:a.reload,children:"重试"})]}):a.loading&&!d?e.jsx("p",{className:"resource-loading",children:"正在读取 Git 状态…"}):d&&!d.isRepository?e.jsxs("div",{className:"resource-empty",children:[e.jsx(W,{name:"branch",size:16}),e.jsx("strong",{children:"当前项目不是 Git 仓库"}),e.jsx("p",{children:"文件和 Agent 不受影响。"})]}):e.jsxs("div",{ref:D,"data-width":T?"narrow":P?"compact":"wide","data-narrow-view":T&&h.selectedFileId?"detail":"list",className:"work-resource-panel git-panel",children:[e.jsxs("div",{className:"git-summary",children:[e.jsxs("div",{children:[e.jsx(W,{name:"branch",size:16}),e.jsx("strong",{children:d?.detached?`detached ${d.head??""}`:d?.branch||"HEAD"})]}),e.jsxs("span",{children:[d?.upstream||"无 upstream",d&&(d.ahead||d.behind)?` · ↑${d.ahead} ↓${d.behind}`:""]}),e.jsx("button",{type:"button",className:"icon-button","aria-label":"刷新 Git 状态","aria-busy":a.refreshing,onClick:()=>{b(),a.reload()},disabled:a.refreshing,children:e.jsx(W,{name:"refresh",size:16})})]}),e.jsxs("div",{className:"git-views",role:"tablist","aria-label":"Git 视图",children:[ze.map(l=>e.jsxs("button",{type:"button",role:"tab","aria-selected":h.view===l,className:h.view===l?"selected":"",onClick:()=>a.setSession({view:l}),children:[Ct[l],l==="changes"&&d&&d.counts.total>0?e.jsx("span",{className:"git-view-count",children:d.counts.total}):null]},l)),a.refreshing?e.jsx("span",{className:"git-refreshing",children:"更新中…"}):null]}),p?e.jsx("p",{className:"resource-notice",role:"status",children:p.text}):null,h.notice?e.jsx("p",{className:"resource-notice",role:"status",children:h.notice}):null,a.error?e.jsx("p",{className:"resource-error",role:"alert",children:a.error}):null,e.jsxs(Me,{panelId:"git",navigatorWidthPx:f,onNavigatorWidthCommit:g,contentLabel:"Git 内容",navigatorLabel:"Git 导航",handleLabel:"调整 Git 导航宽度",contentClassName:"git-content",navigatorClassName:"git-changes",children:[e.jsxs(e.Fragment,{children:[T&&h.selectedFileId?e.jsx("button",{type:"button",className:"git-back-to-list",onClick:()=>a.setSession({selectedFileId:null}),children:"← 返回文件列表"}):null,h.view==="changes"?e.jsx(Lt,{groups:F,activeGroup:h.group,query:h.query,total:d?.counts.total??0,clean:d?.clean??!1,busy:a.busy,selectedFileIds:h.selectedFileIds,onQueryChange:l=>a.setSession({query:l,selectedFileId:null}),onGroupChange:l=>a.setSession({group:l,selectedFileId:null}),selectedFileId:h.selectedFileId,onSelect:l=>{a.setSession({selectedLineIds:[]}),a.openFile(l)},onToggleSelection:a.toggleSelection,onClearSelection:a.clearSelection,onStage:l=>{a.stagePaths(l)},onUnstage:l=>{a.unstagePaths(l)}}):null,h.view==="history"?e.jsx("div",{className:"git-history-nav",children:e.jsx("p",{className:"git-history-nav-note",children:"提交列表与详情显示在右侧。"})}):null,h.view==="compare"?e.jsx(yt,{refs:R.refs,actions:n,display:a.display,collapsedHunks:h.collapsedHunks,anchorLineId:h.anchorLineId,onDisplayChange:l=>a.setDisplay(l),onToggleHunk:l=>a.setSession({collapsedHunks:h.collapsedHunks.includes(l)?h.collapsedHunks.filter(u=>u!==l):[...h.collapsedHunks,l]}),onSetAllFolded:l=>a.setSession({collapsedHunks:l?h.collapsedHunks:[]}),onAnchorChange:l=>a.setSession({anchorLineId:l}),onNotice:y,onSendToComposer:i}):null]}),e.jsxs(e.Fragment,{children:[h.view==="changes"?a.selectedEntry?.source==="conflict"?e.jsx(It,{path:a.selectedEntry.path,actions:n}):I?e.jsxs("div",{children:[L?e.jsx("div",{className:"git-reveal-row",children:e.jsx("button",{type:"button",className:"text-button",onClick:L,children:"在 Files 打开"})}):null,h.selectedLineIds.length>0?e.jsxs("div",{className:"git-line-actions",role:"group","aria-label":"选中的行",children:[e.jsxs("span",{children:["已选 ",h.selectedLineIds.length," 行"]}),e.jsx("button",{type:"button",className:"secondary-button",disabled:a.busy,onClick:H,children:"暂存选中行"}),e.jsx("button",{type:"button",className:"text-button",onClick:()=>a.setSession({selectedLineIds:[]}),children:"清除"})]}):null,e.jsx(be,{hunkAction:q,ignoreWhitespace:a.display.ignoreWhitespace,onToggleIgnoreWhitespace:()=>a.setDisplay({ignoreWhitespace:!a.display.ignoreWhitespace}),wordDiff:a.display.wordDiff,onToggleWordDiff:()=>a.setDisplay({wordDiff:!a.display.wordDiff}),selectedLineIds:h.selectedLineIds,onToggleLine:l=>a.setSession({selectedLineIds:h.selectedLineIds.includes(l)?h.selectedLineIds.filter(u=>u!==l):[...h.selectedLineIds,l]}),document:I,mode:A,wrap:a.display.wrap,showWhitespace:a.display.showWhitespace,collapsedHunks:h.collapsedHunks,anchorLineId:h.anchorLineId,loading:a.loading,stale:a.stale,onChangeMode:l=>a.setDisplay({mode:l}),onToggleWrap:()=>a.setDisplay({wrap:!a.display.wrap}),onToggleWhitespace:()=>a.setDisplay({showWhitespace:!a.display.showWhitespace}),onToggleHunk:l=>a.setSession({collapsedHunks:h.collapsedHunks.includes(l)?h.collapsedHunks.filter(u=>u!==l):[...h.collapsedHunks,l]}),onSetAllFolded:l=>a.setSession({collapsedHunks:l?I.hunks.map(u=>u.hunkId):[]}),onAnchorChange:l=>a.setSession({anchorLineId:l}),onNotice:y,onLoadMore:I.nextCursor?a.loadMoreDiff:void 0,onSendToComposer:i})]}):e.jsxs("div",{className:"resource-empty",children:[e.jsx(W,{name:"code",size:16}),e.jsx("strong",{children:"选择变更查看 Diff"}),e.jsx("p",{children:"同一文件的「未暂存」和「已暂存」是两个不同的比较目标。"})]}):null,h.view==="changes"?e.jsx(Ft,{preview:a.commitPreview,draft:h.commitDraft,busy:a.busy,onDraftChange:l=>a.setSession({commitDraft:l}),onCommit:l=>a.commit(l)}):null,h.view==="history"?e.jsx(St,{history:R,actions:n,display:a.display,collapsedHunks:h.collapsedHunks,anchorLineId:h.anchorLineId,onDisplayChange:l=>a.setDisplay(l),onToggleHunk:l=>a.setSession({collapsedHunks:h.collapsedHunks.includes(l)?h.collapsedHunks.filter(u=>u!==l):[...h.collapsedHunks,l]}),onSetAllFolded:l=>a.setSession({collapsedHunks:l?h.collapsedHunks:[]}),onAnchorChange:l=>a.setSession({anchorLineId:l}),onNotice:y,onSendToComposer:i}):null,h.view==="compare"?e.jsx(Et,{title:"比较结果",stage:"S5"}):null]})]})]})}function Ft({preview:t,draft:s,busy:n,onDraftChange:i,onCommit:o}){const[f,g]=r.useState(!1),[x,a]=r.useState(""),p=t?.blockedReason??"正在读取暂存区…",y=!!t?.canCommit&&s.summary.trim().length>0&&!n,b=()=>{a(""),o({summary:s.summary,...s.body.trim()?{body:s.body}:{}}).catch(d=>a(d instanceof Error?d.message:"提交失败。"))};return e.jsxs("section",{className:"git-commit","aria-label":"提交",children:[e.jsxs("button",{type:"button",className:"git-commit-toggle","aria-expanded":f,onClick:()=>g(d=>!d),children:[f?"▾":"▸"," 提交 ",t?`${t.filesChanged} 个文件`:"",t&&(t.additions>0||t.deletions>0)?e.jsxs("span",{className:"git-commit-stats",children:[e.jsxs("em",{className:"diff-stat-add",children:["+",t.additions]})," ",e.jsxs("em",{className:"diff-stat-del",children:["-",t.deletions]})]}):null]}),f?e.jsxs("div",{className:"git-commit-body",children:[t?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"git-commit-meta",children:[t.detached?"detached HEAD":t.branch||"HEAD"," ·"," ",t.identity.name??"未配置 user.name"," <",t.identity.email??"未配置 user.email",">",t.identity.signingEnabled?" · 已启用签名":" · 未启用签名",` · hooks ${t.identity.hooksPresent?"存在":"不存在"}`]}),e.jsxs("ul",{className:"git-commit-files",children:[t.entries.slice(0,40).map(d=>e.jsxs("li",{children:[e.jsx("code",{children:d.status}),e.jsx("span",{children:d.path})]},`${d.source}:${d.path}`)),t.entries.length>40?e.jsxs("li",{className:"git-commit-more",children:["…还有 ",t.entries.length-40," 个文件"]}):null]})]}):null,e.jsxs("label",{children:[e.jsx("span",{children:"摘要"}),e.jsx("input",{type:"text",value:s.summary,maxLength:2e3,disabled:n,placeholder:"本次提交做了什么",onChange:d=>i({...s,summary:d.target.value})})]}),e.jsxs("label",{children:[e.jsx("span",{children:"正文(可选)"}),e.jsx("textarea",{value:s.body,rows:3,disabled:n,placeholder:"为什么这样做",onChange:d=>i({...s,body:d.target.value})})]}),x?e.jsx("p",{className:"resource-error",role:"alert",children:x}):null,e.jsxs("div",{className:"git-commit-actions",children:[e.jsx("button",{type:"button",className:"primary-button",disabled:!y,"aria-busy":n,onClick:b,children:n?"提交中…":"提交到本地索引"}),t?.canCommit?null:e.jsx("span",{className:"git-commit-blocked",children:p})]}),e.jsx("p",{className:"git-commit-note",children:"只提交本地 index:不自动暂存、不 amend、不 push。"})]}):null]})}function Lt({groups:t,activeGroup:s,query:n,total:i,clean:o,busy:f,selectedFileIds:g,onQueryChange:x,onGroupChange:a,selectedFileId:p,onSelect:y,onToggleSelection:b,onClearSelection:d,onStage:I,onUnstage:h}){const H=new Set(g),D=g.length>0;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"git-filter",children:[e.jsx("input",{type:"search",value:n,"aria-label":"搜索文件路径",placeholder:"搜索文件…",onChange:N=>x(N.target.value)}),e.jsxs("div",{className:"git-filter-groups",role:"group","aria-label":"按分组筛选",children:[e.jsx("button",{type:"button","aria-pressed":s===null,onClick:()=>a(null),children:"全部"}),Se.map(N=>e.jsx("button",{type:"button","aria-pressed":s===N,onClick:()=>a(s===N?null:N),children:Ie[N]},N))]}),e.jsx("p",{className:"git-filter-summary",role:"status",children:i===0?n?"没有匹配的改动":"没有改动":`匹配 ${i} 个改动`}),D?e.jsxs("div",{className:"git-bulk",role:"group","aria-label":"对选中文件操作",children:[e.jsxs("span",{children:["已选 ",g.length," 个文件"]}),e.jsx("button",{type:"button",className:"secondary-button",disabled:f,onClick:()=>I(g),children:"暂存选中"}),e.jsx("button",{type:"button",className:"secondary-button",disabled:f,onClick:()=>h(g),children:"取消暂存选中"}),e.jsx("button",{type:"button",className:"text-button",onClick:d,children:"清除"})]}):null]}),o?e.jsxs("div",{className:"resource-empty compact",children:[e.jsx(W,{name:"check"}),e.jsx("strong",{children:"工作区干净"})]}):t.map(N=>N.count?e.jsxs("div",{className:"git-group",children:[e.jsxs("h3",{children:[N.label," ",e.jsx("span",{children:N.count}),N.items.length<N.count?e.jsxs("small",{className:"git-group-loaded",children:["已载 ",N.items.length]}):null,N.source==="unstaged"||N.source==="untracked"?e.jsx("button",{type:"button",className:"text-button git-group-action",disabled:f,onClick:()=>I(N.items.map(v=>v.fileId)),children:"暂存该组已载"}):null,N.source==="staged"?e.jsx("button",{type:"button",className:"text-button git-group-action",disabled:f,onClick:()=>h(N.items.map(v=>v.fileId)),children:"取消暂存该组已载"}):null]}),N.items.map(v=>e.jsxs("div",{className:`git-row ${p===v.fileId?"selected":""}`,children:[e.jsx("input",{type:"checkbox","aria-label":`选择 ${v.path}`,checked:H.has(v.fileId),onChange:()=>b(v.fileId)}),e.jsxs("button",{type:"button",className:p===v.fileId?"selected":"","aria-current":p===v.fileId?"true":void 0,onClick:()=>y(v),children:[e.jsx("span",{className:`git-status-code ${N.source}`,children:v.indexStatus.trim()||v.worktreeStatus.trim()||"?"}),e.jsx("span",{title:v.path,children:v.renamedFrom?`${v.renamedFrom} → ${v.path}`:v.path})]}),N.source==="unstaged"||N.source==="untracked"?e.jsx("button",{type:"button",className:"text-button",disabled:f,"aria-label":`暂存 ${v.path}`,onClick:()=>I([v.fileId]),children:"暂存"}):null,N.source==="staged"?e.jsx("button",{type:"button",className:"text-button",disabled:f,"aria-label":`取消暂存 ${v.path}`,onClick:()=>h([v.fileId]),children:"取消"}):null,N.source==="conflict"?e.jsx("span",{className:"git-conflict-hint",children:"需在 Files 处理"}):null]},v.fileId))]},N.source):null)]})}function Et({title:t,stage:s}){return e.jsxs("div",{className:"resource-empty",children:[e.jsx(W,{name:"info",size:16}),e.jsx("strong",{children:t}),e.jsxs("p",{children:["计划阶段 ",s," 交付,当前版本尚未实现。"]})]})}export{Pt as GitPanel};
|