nomoreide 0.1.20 → 0.1.21
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/web/client/assets/{index-CylezI98.js → index-CBZsUFdB.js} +1 -1
- package/dist/web/client/index.html +1 -1
- package/dist/web/routes/agent-routes.d.ts +3 -0
- package/dist/web/routes/agent-routes.js +40 -0
- package/dist/web/routes/agent-routes.js.map +1 -0
- package/dist/web/routes/context.d.ts +39 -0
- package/dist/web/routes/context.js +48 -0
- package/dist/web/routes/context.js.map +1 -0
- package/dist/web/routes/dashboard-routes.d.ts +3 -0
- package/dist/web/routes/dashboard-routes.js +20 -0
- package/dist/web/routes/dashboard-routes.js.map +1 -0
- package/dist/web/routes/git-routes.d.ts +3 -0
- package/dist/web/routes/git-routes.js +125 -0
- package/dist/web/routes/git-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +10 -0
- package/dist/web/routes/index.js +20 -0
- package/dist/web/routes/index.js.map +1 -0
- package/dist/web/routes/service-routes.d.ts +3 -0
- package/dist/web/routes/service-routes.js +298 -0
- package/dist/web/routes/service-routes.js.map +1 -0
- package/dist/web/routes/shell-routes.d.ts +3 -0
- package/dist/web/routes/shell-routes.js +34 -0
- package/dist/web/routes/shell-routes.js.map +1 -0
- package/dist/web/server.js +21 -538
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -20,4 +20,4 @@ https://github.com/highlightjs/highlight.js/issues/2277`),wt=ie,Xe=Ne),Ie===void
|
|
|
20
20
|
`).map(Z1):r.split(`
|
|
21
21
|
`).map(o=>{if(!o)return"";try{return Y1.highlight(o,{language:a,ignoreIllegals:!0}).value}catch{return Z1(o)}})}function Z1(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function d8({content:n,path:a}){const r=C.useMemo(()=>c8(a),[a]),o=C.useMemo(()=>u8(n,r),[n,r]),u=`${Math.max(2,String(o.length).length)}ch`;return l.jsx("div",{className:"min-w-max font-mono text-[12px] leading-[1.5]",children:o.map((f,m)=>l.jsxs("div",{className:"flex",children:[l.jsx("span",{className:"shrink-0 select-none border-r border-zinc-200 bg-zinc-100 px-2 text-right text-zinc-400",style:{minWidth:`calc(${u} + 1rem)`},children:m+1}),l.jsx("span",{className:"hljs whitespace-pre px-3 text-zinc-800",dangerouslySetInnerHTML:{__html:f||" "}})]},m))})}function f8({path:n,isModified:a,onViewDiff:r}){const[o,u]=C.useState(null),[f,m]=C.useState(null),[p,g]=C.useState(!1);return C.useEffect(()=>{if(!n){u(null);return}let h=!0;return g(!0),m(null),R_(n).then(b=>{h&&(u(b),g(!1))}).catch(b=>{h&&(m(b instanceof Error?b.message:String(b)),g(!1))}),()=>{h=!1}},[n]),n?l.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col border-l border-border bg-white",children:[l.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-1.5",children:[l.jsxs("div",{className:"min-w-0",children:[l.jsx("h2",{className:"truncate text-[13px] font-semibold tracking-tight",children:n}),l.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground",children:[l.jsx("span",{children:"Read-only view of tracked file."}),o?.truncated?l.jsx("span",{className:"text-amber-700",children:"Truncated — file exceeds 1MB."}):null,o?.binary?l.jsx("span",{className:"text-amber-700",children:"Binary file."}):null]})]}),a?l.jsx(Me,{onClick:r,size:"sm",type:"button",variant:"outline",children:"View diff"}):null]}),l.jsx("div",{className:"min-h-0 flex-1 overflow-auto bg-zinc-50",children:f?l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"destructive",children:f})}):p?l.jsx("div",{className:"p-4 text-[12px] text-muted-foreground",children:"Loading…"}):o?.binary?l.jsx("div",{className:"p-4 text-[12px] text-muted-foreground",children:"Cannot display binary content."}):o?l.jsx(d8,{content:o.content,path:n}):null})]}):l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"muted",className:"border-dashed p-12 text-center",children:"Select a file to view its contents."})})}function m8({activeHunkIndex:n,filePaths:a,hunkCount:r,pendingNextFilePath:o,selectedFile:u}){if(r>0&&n<r-1)return{kind:"hunk",activeHunkIndex:n+1};const f=a.findIndex(p=>p===u),m=a[f+1];return m?o===m?{kind:"file",filePath:m}:{kind:"confirm-next-file",filePath:m}:{kind:"none"}}const X1=["#3b82f6","#10b981","#f59e0b","#ec4899","#8b5cf6","#14b8a6","#ef4444","#84cc16"];function oo(n){return X1[n%X1.length]}function h8({lane:n,laneCount:a,edges:r,throughLanes:o,isMerge:u,height:f=28,laneWidth:m=14}){const g=Math.max(n+1,a,1)*m,h=f/2,b=lo(n,m),v=u?4:3.5;return l.jsxs("svg",{width:g,height:f,viewBox:`0 0 ${g} ${f}`,style:{flex:"0 0 auto",display:"block"},children:[o.map(x=>l.jsx("line",{x1:lo(x,m),y1:0,x2:lo(x,m),y2:f,stroke:oo(x),strokeWidth:1.5},`t-${x}`)),l.jsx("line",{x1:b,y1:0,x2:b,y2:h,stroke:oo(n),strokeWidth:1.5}),r.map((x,_)=>{const S=lo(x.fromLane,m),N=lo(x.toLane,m);if(S===N)return l.jsx("line",{x1:S,y1:h,x2:N,y2:f,stroke:oo(x.toLane),strokeWidth:1.5},`e-${_}`);const M=h+(f-h)/2;return l.jsx("path",{d:`M ${S} ${h} C ${S} ${M}, ${N} ${M}, ${N} ${f}`,fill:"none",stroke:oo(x.toLane),strokeWidth:1.5},`e-${_}`)}),l.jsx("circle",{cx:b,cy:h,r:v,fill:oo(n),stroke:"var(--background, #fff)",strokeWidth:1.5})]})}function lo(n,a){return n*a+a/2}const Q1=200,W1=28;function p8({branches:n=[]}){const[a,r]=C.useState([]),[o,u]=C.useState(Q1),[f,m]=C.useState(!0),[p,g]=C.useState(null),[h,b]=C.useState(null),[v,x]=C.useState([]),[_,S]=C.useState(null),[N,M]=C.useState(null),[R,L]=C.useState(""),[B,U]=C.useState(!1),[F,X]=C.useState(null),[I,j]=C.useState("");C.useEffect(()=>{let D=!0;return m(!0),g(null),A_(o).then(P=>{D&&(r(P),P.length>0&&!P.some(K=>K.hash===h)&&b(P[0].hash))}).catch(P=>{D&&g(P instanceof Error?P.message:String(P))}).finally(()=>{D&&m(!1)}),()=>{D=!1}},[o]),C.useEffect(()=>{if(!h){x([]),M(null);return}let D=!0;return S(null),C_(h).then(P=>{D&&(x(P),M(P[0]?.path??null))}).catch(P=>{D&&S(P instanceof Error?P.message:String(P))}),()=>{D=!1}},[h]),C.useEffect(()=>{if(!h){L("");return}let D=!0;return X(null),U(!0),M_(h,N??void 0).then(P=>{D&&L(P)}).catch(P=>{D&&X(P instanceof Error?P.message:String(P))}).finally(()=>{D&&U(!1)}),()=>{D=!1}},[h,N]);const ae=C.useMemo(()=>a.reduce((D,P)=>Math.max(D,P.laneCount),1),[a]),te=a.find(D=>D.hash===h)??null,se=C.useMemo(()=>{const D=I.trim().toLowerCase();return D?n.filter(P=>P.name.toLowerCase().includes(D)):n},[n,I]),ue=C.useMemo(()=>J1(se.filter(D=>!D.remote)),[se]),ke=C.useMemo(()=>J1(se.filter(D=>D.remote)),[se]),ne=I.trim().length>0,J=C.useRef(new Map);function O(D){const P=D.remote?"remote":"branch",K=a.find(T=>T.refs.some($=>$.kind===P&&$.name===D.name));if(!K)return;b(K.hash);const Z=J.current.get(K.hash);Z&&Z.scrollIntoView({block:"center",behavior:"smooth"})}return l.jsxs("div",{className:"grid h-full min-h-0 overflow-hidden border-0 bg-card/85 grid-cols-[220px_minmax(0,1fr)]",children:[l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden border-r border-border",children:[l.jsxs("div",{className:"flex shrink-0 flex-col gap-1 border-b border-border px-3 py-1.5",children:[l.jsx("h2",{className:"text-[13px] font-semibold tracking-tight",children:"Branches"}),l.jsx("input",{type:"search",value:I,onChange:D=>j(D.target.value),placeholder:"Search branches…",className:"w-full rounded border border-border bg-background px-2 py-1 text-[11px] outline-none focus:border-foreground"})]}),l.jsxs("div",{className:"min-h-0 flex-1 overflow-auto py-1",children:[l.jsx(ey,{label:"Local",tree:ue,onSelect:O,defaultOpen:!0,forceOpen:ne}),l.jsx(ey,{label:"Remote",tree:ke,onSelect:O,forceOpen:ne})]})]}),l.jsxs("div",{className:"grid min-h-0 min-w-0 grid-rows-[minmax(0,3fr)_minmax(0,2fr)]",children:[l.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col bg-white border-b border-border",children:[l.jsx("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-1.5",children:l.jsxs("div",{className:"min-w-0",children:[l.jsx("h2",{className:"truncate text-[13px] font-semibold tracking-tight",children:N??(te?te.subject:"Commit")}),te?l.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground",children:[l.jsx("span",{className:"font-mono",children:te.hash.slice(0,12)}),l.jsxs("span",{children:[te.author," <",te.email,">"]}),l.jsx("span",{children:new Date(te.timestamp*1e3).toLocaleString()})]}):null]})}),l.jsx("div",{className:"min-h-0 min-w-0 flex-1",children:F?l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"destructive",children:F})}):te?B?l.jsx("div",{className:"p-4 text-[12px] text-muted-foreground",children:"Loading diff…"}):R?l.jsx(Bx,{activeHunkIndex:0,diff:R}):l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"muted",className:"border-dashed p-6 text-center",children:te.parents.length>1?"Merge commit with no conflict resolution — no diff against the first parent.":"No textual changes in this commit."})}):l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"muted",className:"border-dashed p-12 text-center",children:"Select a commit to inspect its diff."})})})]}),l.jsxs("div",{className:"grid min-h-0 min-w-0 grid-cols-[minmax(0,1fr)_280px]",children:[l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden border-r border-border",children:[l.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-2 border-b border-border px-3 py-1.5",children:[l.jsxs("h2",{className:"text-[13px] font-semibold tracking-tight",children:["Commit tree",a.length?l.jsxs("span",{className:"ml-2 text-[11px] font-normal text-muted-foreground",children:[a.length," commits"]}):null]}),l.jsx(Me,{disabled:f,onClick:()=>u(D=>D+Q1),size:"sm",type:"button",variant:"outline",children:"Load more"})]}),l.jsx("div",{className:"min-h-0 flex-1 overflow-auto",children:p?l.jsx("div",{className:"p-3",children:l.jsx(yt,{variant:"destructive",children:p})}):f&&a.length===0?l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"Loading commits…"}):a.length===0?l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"No commits."}):l.jsx("ul",{className:"divide-y divide-border",children:a.map(D=>l.jsx("li",{ref:P=>{P?J.current.set(D.hash,P):J.current.delete(D.hash)},children:l.jsxs("button",{onClick:()=>b(D.hash),type:"button",className:`flex w-full items-center gap-2 px-2 py-0.5 text-left transition-colors hover:bg-muted/60 ${h===D.hash?"bg-muted":""}`,style:{minHeight:W1},title:`${D.hash}
|
|
22
22
|
${D.author} <${D.email}>
|
|
23
|
-
${D.subject}`,children:[l.jsx(h8,{lane:D.lane,laneCount:Math.max(D.laneCount,ae),edges:D.edges,throughLanes:D.throughLanes,isMerge:D.parents.length>1,height:W1}),l.jsx("span",{className:"font-mono text-[10px] text-muted-foreground",children:D.hash.slice(0,7)}),l.jsxs("span",{className:"flex min-w-0 flex-1 items-center gap-1.5",children:[D.refs.map(P=>l.jsx("span",{className:b8(P.kind),children:P.name},`${P.kind}-${P.name}`)),l.jsx("span",{className:"truncate text-[12px]",children:D.subject})]}),l.jsx("span",{className:"shrink-0 text-[10px] text-muted-foreground",children:D.author})]})},D.hash))})})]}),l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden border-r border-border",children:[l.jsx("div",{className:"flex shrink-0 items-center justify-between gap-2 border-b border-border px-3 py-1.5",children:l.jsxs("h2",{className:"text-[13px] font-semibold tracking-tight",children:["Files",v.length?l.jsx("span",{className:"ml-2 text-[11px] font-normal text-muted-foreground",children:v.length}):null]})}),l.jsx("div",{className:"min-h-0 flex-1 overflow-auto",children:_?l.jsx("div",{className:"p-3",children:l.jsx(yt,{variant:"destructive",children:_})}):h?v.length===0?l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"No file changes."}):l.jsx("ul",{className:"divide-y divide-border",children:v.map(D=>l.jsx("li",{children:l.jsxs("button",{onClick:()=>M(D.path),type:"button",title:D.path,className:`flex w-full items-center gap-2 px-2 py-1 text-left text-[12px] transition-colors hover:bg-muted/60 ${N===D.path?"bg-muted":""}`,children:[l.jsx("span",{className:g8(D.index),children:D.index.trim()||"·"}),l.jsx("span",{className:"truncate font-mono",children:D.path})]})},D.path))}):l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"Select a commit to see its files."})})]})]})]})]})}function J1(n){const a={name:"",fullPath:"",children:new Map};for(const r of n){const o=r.name.split("/");let u=a;o.forEach((f,m)=>{let p=u.children.get(f);p||(p={name:f,fullPath:o.slice(0,m+1).join("/"),children:new Map},u.children.set(f,p)),u=p}),u.branch=r}return a}function ey({label:n,tree:a,onSelect:r,defaultOpen:o,forceOpen:u}){const[f,m]=C.useState(o??!1),p=u||f,g=a.children.size===0;return l.jsxs("div",{className:"mb-1",children:[l.jsxs("button",{type:"button",onClick:()=>m(h=>!h),className:"flex w-full items-center gap-1 px-2 py-0.5 text-left text-[11px] font-semibold uppercase tracking-wide text-muted-foreground hover:text-foreground",children:[p?l.jsx(wi,{size:12}):l.jsx(is,{size:12}),n,g?null:l.jsxs("span",{className:"ml-1 text-[10px] font-normal",children:["(",a.children.size,")"]})]}),p&&!g?l.jsx("ul",{children:Array.from(a.children.values()).map(h=>l.jsx(Vx,{node:h,depth:1,onSelect:r,forceOpen:u},h.fullPath))}):null]})}function Vx({node:n,depth:a,onSelect:r,forceOpen:o}){const[u,f]=C.useState(!0),m=o||u,p=n.children.size>0,g=n.branch,h={paddingLeft:`${a*10}px`};return!p&&g?l.jsx("li",{children:l.jsxs("button",{type:"button",onClick:()=>r(g),style:h,title:g.name,className:`flex w-full items-center gap-1.5 py-0.5 pr-2 text-left text-[12px] hover:bg-muted/60 ${g.current?"font-semibold text-emerald-700":""}`,children:[l.jsx(bo,{size:11,className:"shrink-0 opacity-70"}),l.jsx("span",{className:"truncate",children:n.name}),g.current?l.jsx("span",{className:"text-[10px]",children:"●"}):null]})}):l.jsxs("li",{children:[l.jsxs("button",{type:"button",onClick:()=>{g?r(g):f(b=>!b)},style:h,className:"flex w-full items-center gap-1 py-0.5 pr-2 text-left text-[12px] hover:bg-muted/60",children:[p?m?l.jsx(wi,{size:11}):l.jsx(is,{size:11}):l.jsx("span",{className:"inline-block w-[11px]"}),l.jsx("span",{className:"truncate",children:n.name})]}),m&&p?l.jsx("ul",{children:Array.from(n.children.values()).map(b=>l.jsx(Vx,{node:b,depth:a+1,onSelect:r,forceOpen:o},b.fullPath))}):null]})}function g8(n){const a="inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-[10px] font-bold";switch(n.trim().toUpperCase()){case"A":return`${a} bg-emerald-100 text-emerald-800`;case"D":return`${a} bg-red-100 text-red-800`;case"M":return`${a} bg-amber-100 text-amber-800`;case"R":return`${a} bg-blue-100 text-blue-800`;case"C":return`${a} bg-indigo-100 text-indigo-800`;default:return`${a} bg-slate-100 text-slate-700`}}function b8(n){const a="rounded px-1.5 py-px text-[10px] font-medium";switch(n){case"head":return`${a} bg-emerald-100 text-emerald-800`;case"branch":return`${a} bg-blue-100 text-blue-800`;case"remote":return`${a} bg-slate-100 text-slate-700`;case"tag":return`${a} bg-amber-100 text-amber-800`}}function y8({data:n}){const[a,r]=C.useState("changes"),[o,u]=C.useState("changes"),[f,m]=C.useState(n.git.status?.files[0]?.path??""),[p,g]=C.useState(""),[h,b]=C.useState([]),[v,x]=C.useState(null),[_,S]=C.useState(""),[N,M]=C.useState(null),[R,L]=C.useState(0),[B,U]=C.useState(null),F=n.git.status?.files??[],X=C.useMemo(()=>F.map(K=>K.path),[F]),I=C.useMemo(()=>QA(_),[_]);C.useEffect(()=>{const K=n.git.status?.files[0]?.path??"";m(Z=>Z&&n.git.status?.files.some(T=>T.path===Z)?Z:K)},[n.git.status?.files]),C.useEffect(()=>{if(o!=="all"||h.length>0)return;let K=!0;return x(null),k_().then(Z=>{K&&b(Z)}).catch(Z=>{K&&x(Z instanceof Error?Z.message:String(Z))}),()=>{K=!1}},[o,h.length]),C.useEffect(()=>{if(!f){S("");return}let K=!0;return M(null),O_(f).then(Z=>{K&&(S(Z),L(0),U(null))}).catch(Z=>{K&&M(Z instanceof Error?Z.message:String(Z))}),()=>{K=!1}},[f]);function j(K){L(0),U(null),m(K)}function ae(){const K=m8({activeHunkIndex:R,filePaths:X,hunkCount:I.hunks,pendingNextFilePath:B,selectedFile:f});K.kind==="hunk"?(U(null),L(K.activeHunkIndex)):K.kind==="confirm-next-file"?U(K.filePath):K.kind==="file"?j(K.filePath):U(null)}function te(){if(U(null),R>0){L(T=>T-1);return}const K=F.findIndex(T=>T.path===f),Z=F[K-1];Z&&j(Z.path)}const se=F.findIndex(K=>K.path===f),ue=!!(I.hunks&&R<I.hunks-1||F[se+1]),ke=!!(R>0||F[se-1]),ne=B?`End of file. Click Next again to open ${B}.`:null,J=K=>`rounded px-2 py-0.5 text-[11px] font-medium transition-colors ${K?"bg-foreground text-background":"text-muted-foreground hover:text-foreground"}`,O=K=>`flex-1 px-2 py-0.5 text-[11px] font-medium transition-colors ${K?"bg-foreground text-background":"text-muted-foreground hover:text-foreground"}`,D=C.useMemo(()=>new Set(F.map(K=>K.path)),[F]);function P(){p&&(u("changes"),j(p))}return l.jsxs("div",{className:"flex h-full min-h-0 flex-col overflow-hidden bg-card/85",children:[l.jsxs("div",{className:"flex shrink-0 items-center gap-1 border-b border-border bg-card/95 px-3 py-1",children:[l.jsx("button",{type:"button",className:J(a==="changes"),onClick:()=>r("changes"),children:"Changes"}),l.jsx("button",{type:"button",className:J(a==="graph"),onClick:()=>r("graph"),children:"Tree"})]}),l.jsx("div",{className:"min-h-0 flex-1",children:a==="graph"?l.jsx(p8,{branches:n.git.branches??[]}):l.jsxs("div",{className:"grid h-full min-h-0 overflow-hidden border-0 bg-card/85 xl:grid-cols-[320px_minmax(0,1fr)]",children:[l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden",children:[l.jsxs("div",{className:"flex shrink-0 gap-0.5 border-b border-border bg-card/95 p-1",children:[l.jsx("button",{className:O(o==="changes"),onClick:()=>u("changes"),type:"button",children:"Changes"}),l.jsx("button",{className:O(o==="all"),onClick:()=>u("all"),type:"button",children:"All files"})]}),o==="changes"?l.jsx(u6,{branch:n.git.status?.branch||void 0,error:n.git.error,files:n.git.status?.files??[],selectedFile:f,onSelectFile:j}):v?l.jsx(yt,{variant:"destructive",className:"m-3",children:v}):l.jsx(v6,{branch:n.git.status?.branch||void 0,onSelectFile:g,paths:h,selectedFile:p,status:n.git.status?.files??[]})]}),o==="all"?l.jsx(f8,{isModified:D.has(p),onViewDiff:P,path:p}):l.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col border-l border-border bg-white",children:[l.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-1.5",children:[l.jsxs("div",{className:"min-w-0",children:[l.jsx("h2",{className:"truncate text-[13px] font-semibold tracking-tight",children:f||"Diff"}),l.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground",children:[l.jsx("span",{children:"Long rows scroll horizontally inside the editor pane."}),I.additions||I.deletions?l.jsxs("span",{className:"flex items-center gap-1 font-mono",children:[l.jsxs("span",{className:"text-emerald-700",children:["+",I.additions]}),l.jsxs("span",{className:"text-red-700",children:["-",I.deletions]})]}):null]})]}),l.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[ne?l.jsx("span",{className:"max-w-72 truncate rounded border border-amber-200 bg-amber-50 px-2 py-1 text-[11px] text-amber-900",children:ne}):null,l.jsxs(Me,{disabled:!f||!ke,onClick:te,size:"sm",type:"button",variant:"outline",children:[l.jsx(l3,{}),"Previous"]}),l.jsxs(Me,{disabled:!f||!ue,onClick:ae,size:"sm",type:"button",variant:"outline",children:[l.jsx(r3,{}),"Next"]})]})]}),l.jsx("div",{className:"min-h-0 min-w-0 flex-1",children:N?l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"destructive",children:N})}):f?l.jsx(Bx,{activeHunkIndex:R,diff:_||"No unstaged diff for this file."}):l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"muted",className:"border-dashed p-12 text-center",children:"Select a changed file to inspect its diff."})})})]})]})})]})}function v8({initialPath:n,onSelect:a,selectedPath:r}){const[o,u]=C.useState(n),[f,m]=C.useState(null),[p,g]=C.useState(null),[h,b]=C.useState(!1),v=x8(f);return C.useEffect(()=>{u(n)},[n]),C.useEffect(()=>{let x=!0;return b(!0),g(null),j_(o).then(_=>{x&&(m(_),a(_.path))}).catch(_=>{x&&g(_ instanceof Error?_.message:String(_))}).finally(()=>{x&&b(!1)}),()=>{x=!1}},[o,a]),l.jsxs("div",{className:"rounded-md border border-border bg-background",children:[l.jsxs("div",{className:"flex items-center gap-2 border-b border-border p-2",children:[v?l.jsx(Me,{"aria-label":"Open parent folder",onClick:()=>f&&u(f.parent),size:"icon",type:"button",variant:"ghost",children:l.jsx(wi,{className:"rotate-90"})}):null,l.jsx("div",{className:"min-w-0 flex-1 truncate font-mono text-xs text-muted-foreground",children:f?.path??o}),h?l.jsx(yy,{className:"size-4 animate-spin text-muted-foreground"}):null]}),l.jsxs("div",{className:"max-h-56 overflow-auto p-1",children:[p?l.jsx(yt,{variant:"destructive",className:"m-1",children:p}):null,!p&&f?.entries.length===0?l.jsx(yt,{variant:"muted",className:"m-1 text-center",children:"No folders here."}):null,f?.entries.map(x=>l.jsxs(Me,{className:be("h-8 w-full justify-start rounded-sm px-2 text-left",r===x.path&&"bg-muted"),onClick:()=>u(x.path),title:x.path,type:"button",variant:"ghost",children:[l.jsx(nr,{className:"text-accent"}),l.jsx("span",{className:"truncate",children:x.name})]},x.path))]})]})}function x8(n){return!!(n&&n.parent!==n.path)}function ty(n){return n.split(/[\\/]/).filter(Boolean).pop()??"project"}function E8({data:n,onRefresh:a}){const[r,o]=C.useState(!1),[u,f]=C.useState(n.git.cwd),[m,p]=C.useState(null),[g,h]=C.useState(!1),[b,v]=C.useState("add"),[x,_]=C.useState(n.git.cwd),S=C.useRef(null),N=n.git.selectedRepository,M=N?.name??ty(n.git.cwd),{error:R,success:L}=ma();C.useEffect(()=>{f(n.git.cwd),_(n.git.cwd)},[n.git.cwd]),C.useEffect(()=>{if(!r)return;function X(I){S.current&&I.target instanceof Node&&!S.current.contains(I.target)&&o(!1)}return document.addEventListener("mousedown",X),()=>document.removeEventListener("mousedown",X)},[r]);async function B(X){try{await Mn("/api/git/select",{name:X}),o(!1),await a(),L(`Switched to ${X}.`)}catch(I){R(I instanceof Error?I.message:String(I))}}async function U(X){const I=X.trim();if(!_8(I)){const j="Please add an absolute path. Paths beginning with ~ are not expanded here.";return p(j),R(j),!1}try{const j=ty(I);return await Mn("/api/git/repositories",{name:j,path:I}),p(null),await a(),L(`Added Git project ${j}.`),!0}catch(j){const ae=j instanceof Error?j.message:String(j);return p(ae),R(ae),!1}}async function F(X){X.preventDefault(),await U(u)&&o(!1)}return l.jsxs("div",{className:"relative z-50 flex items-center gap-2",ref:S,children:[l.jsxs(Me,{className:"max-w-[220px] justify-start gap-2 rounded-md border-border bg-card",onClick:()=>o(X=>!X),size:"sm",type:"button",variant:"outline",children:[l.jsx(nr,{className:"text-muted-foreground"}),l.jsx("span",{className:"truncate",children:M}),l.jsx(wi,{className:be("ml-auto transition-transform",r&&"rotate-180")})]}),l.jsx(Me,{"aria-label":"Add Git project",onClick:()=>{v("add"),p(null),_(n.git.cwd),h(!0)},size:"sm",type:"button",variant:"outline",children:l.jsx(yo,{})}),r?l.jsxs("div",{className:"absolute right-0 top-10 z-50 w-[min(380px,calc(100vw-2rem))] overflow-hidden rounded-lg border border-border bg-card shadow-lg",children:[l.jsxs("div",{className:"flex items-center gap-2 border-b border-border px-3 py-2",children:[l.jsx(T3,{className:"size-3.5 text-muted-foreground"}),l.jsx("div",{className:"text-xs font-semibold",children:"Git Projects"}),l.jsx(lt,{className:"ml-auto h-5 px-1.5 text-[10px]",variant:"outline",children:n.config.gitRepositories.length})]}),l.jsx("div",{className:"max-h-72 overflow-auto",children:n.config.gitRepositories.length?l.jsx("div",{className:"divide-y divide-border",children:n.config.gitRepositories.map(X=>{const I=X.name===N?.name;return l.jsxs("button",{className:be("grid w-full grid-cols-[1fr_auto] items-center gap-2 px-3 py-1.5 text-left transition-colors hover:bg-muted",I&&"bg-muted/70"),onClick:()=>{B(X.name)},type:"button",children:[l.jsxs("span",{className:"min-w-0",children:[l.jsx("span",{className:"block truncate text-sm font-medium leading-tight",children:X.name}),l.jsx("span",{className:"block truncate font-mono text-[10px] leading-tight text-muted-foreground",children:X.path})]}),I?l.jsx(oy,{className:"size-3.5"}):null]},X.name)})}):l.jsx("div",{className:"px-3 py-6 text-center text-xs text-muted-foreground",children:"No saved Git projects yet."})}),l.jsxs("div",{className:"border-t border-border bg-muted/20 p-2",children:[l.jsxs("form",{className:"flex gap-1.5",onSubmit:F,children:[l.jsx(rn,{"aria-label":"Paste absolute path",className:"h-7 flex-1 px-2 font-mono text-[11px]",onChange:X=>{f(X.target.value),p(null)},placeholder:"/absolute/path",value:u}),l.jsxs(Me,{className:"h-7 px-2 text-[11px]",size:"sm",type:"submit",children:[l.jsx(yo,{className:"size-3"}),"Add"]}),l.jsx(Me,{"aria-label":"Browse folders",className:"h-7 px-2",onClick:()=>{v("fill"),p(null),_(u||n.git.cwd),h(!0)},size:"sm",type:"button",variant:"outline",children:l.jsx(z3,{className:"size-3"})})]}),m?l.jsx("div",{className:"mt-1.5 truncate text-[10px] text-destructive",children:m}):null]})]}):null,g?l.jsx(S8,{confirmLabel:b==="add"?"Add Git project":"Use this folder",errorMessage:b==="add"?m:null,initialPath:b==="add"?n.git.cwd:u||n.git.cwd,selectedPath:x,title:b==="add"?"Add Git Project":"Choose Git Project Folder",onCancel:()=>h(!1),onSelect:_,onUse:async()=>{b==="add"?await U(x)&&(h(!1),o(!1)):(f(x),p(null),h(!1))}}):null]})}function _8(n){return n.startsWith("/")}function S8({confirmLabel:n="Use this folder",errorMessage:a,initialPath:r,onCancel:o,onSelect:u,onUse:f,selectedPath:m,title:p="Choose Git Project Folder"}){return Rx.createPortal(l.jsx("div",{className:"fixed inset-0 z-[1000] grid place-items-center bg-black/35 px-4",children:l.jsxs("div",{className:"w-full max-w-2xl rounded-xl border border-border bg-card p-4 shadow-xl",children:[l.jsxs("div",{className:"mb-3 flex items-center gap-3",children:[l.jsx("div",{className:"flex size-8 items-center justify-center rounded-lg border border-border bg-background",children:l.jsx(nr,{className:"size-4"})}),l.jsxs("div",{className:"min-w-0 flex-1",children:[l.jsx("div",{className:"text-sm font-semibold",children:p}),l.jsx("div",{className:"truncate font-mono text-xs text-muted-foreground",children:m})]}),l.jsx(Me,{"aria-label":"Close folder picker",onClick:o,size:"icon",variant:"ghost",children:l.jsx(xc,{})})]}),l.jsx(v8,{initialPath:r,onSelect:u,selectedPath:m}),a?l.jsx("div",{className:"mt-3 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:a}):null,l.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[l.jsx(Me,{onClick:o,type:"button",variant:"outline",children:"Cancel"}),l.jsx(Me,{onClick:()=>{f()},type:"button",children:n})]})]})}),document.body)}function N8({branches:n,currentBranch:a,disabled:r,onRefresh:o}){const[u,f]=C.useState(!1),[m,p]=C.useState(""),[g,h]=C.useState(null),[b,v]=C.useState(null),[x,_]=C.useState(null),S=n.filter(U=>!U.remote),N=n.filter(U=>U.remote);async function M(U,F){h(U),_(null),v(null);try{await F(),await o()}catch(X){_(X instanceof Error?X.message:String(X))}finally{h(null)}}async function R(U){await M(`switch:${U}`,async()=>{await Mn("/api/git/branches/switch",{name:U}),f(!1)})}async function L(){await M("fetch",async()=>{await Mn("/api/git/fetch",{}),v("Fetched latest branch refs.")})}async function B(U){U.preventDefault();const F=m.trim();if(!F){_("Branch name is required.");return}await M("create",async()=>{await Mn("/api/git/branches",{name:F}),p(""),f(!1)})}return l.jsxs("div",{className:"fixed bottom-3 right-4 z-50 flex items-end",children:[u?l.jsxs("div",{"aria-label":"Switch Git branch",className:"mb-11 w-[min(460px,calc(100vw-2rem))] rounded-lg border border-border bg-card shadow-xl",role:"dialog",children:[l.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-border p-3",children:[l.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[l.jsx(bo,{className:"size-4 text-muted-foreground"}),l.jsx("span",{className:"truncate text-sm font-semibold",children:a||"Branches"})]}),l.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[l.jsx(Me,{"aria-label":"Fetch branches",disabled:r||g!==null,onClick:()=>{L()},size:"icon",title:"Fetch branches",type:"button",variant:"ghost",children:l.jsx(_y,{className:be(g==="fetch"&&"animate-spin")})}),l.jsx(Me,{"aria-label":"Close branch dialog",onClick:()=>f(!1),size:"icon",type:"button",variant:"ghost",children:l.jsx(xc,{})})]})]}),l.jsx("div",{className:"max-h-72 overflow-auto",children:n.length?l.jsxs(l.Fragment,{children:[l.jsx(ny,{branches:S,busy:g!==null,disabled:r,label:"Local",onSwitch:R}),l.jsx(ny,{branches:N,busy:g!==null,disabled:r,label:"Remote",onSwitch:R})]}):l.jsx("div",{className:"px-3 py-6 text-center text-sm text-muted-foreground",children:"No branches found."})}),l.jsxs("div",{className:"border-t border-border p-3",children:[l.jsxs("form",{className:"grid gap-2 sm:grid-cols-[1fr_auto]",onSubmit:B,children:[l.jsx(rn,{"aria-label":"New branch name",disabled:r||g!==null,onChange:U=>{p(U.target.value),_(null),v(null)},placeholder:"feature/new-work",value:m}),l.jsxs(Me,{disabled:r||g!==null,type:"submit",children:[l.jsx(H3,{}),"Create"]})]}),x||b?l.jsx(yt,{className:"mt-3 px-3 py-2 text-xs",variant:x?"destructive":"muted",children:x??b}):null]})]}):null,l.jsxs(Me,{className:"h-8 max-w-[260px] gap-2 rounded-md shadow-lg",disabled:r,onClick:()=>f(U=>!U),size:"sm",title:"Switch Git branch",type:"button",variant:"default",children:[l.jsx(bo,{className:"size-4"}),l.jsx("span",{className:"truncate font-mono text-xs",children:a||"No branch"}),l.jsx(wi,{className:be("size-4 transition-transform",u&&"rotate-180")})]})]})}function ny({branches:n,busy:a,disabled:r,label:o,onSwitch:u}){return l.jsxs("section",{children:[l.jsx("div",{className:"border-b border-border bg-muted/60 px-3 py-1.5 text-[11px] font-semibold uppercase text-muted-foreground",children:o}),n.length?n.map(f=>l.jsxs("button",{className:be("grid w-full grid-cols-[1fr_auto] items-center gap-2 border-b border-border px-3 py-2 text-left text-sm last:border-b-0 hover:bg-muted",f.current&&"bg-muted/70"),disabled:r||a||f.current,onClick:()=>{u(f.name)},type:"button",children:[l.jsxs("span",{className:"min-w-0",children:[l.jsx("span",{className:"block truncate font-medium",children:f.name}),f.upstream?l.jsxs("span",{className:"block truncate font-mono text-[11px] text-muted-foreground",children:["tracks ",f.upstream]}):null]}),l.jsx(lt,{variant:f.current?"success":f.remote?"outline":"secondary",children:f.current?"current":f.remote?"remote":"local"})]},`${f.remote?"remote":"local"}:${f.name}`)):l.jsxs("div",{className:"border-b border-border px-3 py-3 text-sm text-muted-foreground",children:["No ",o.toLowerCase()," branches."]})]})}function w8({className:n}){return l.jsxs("div",{className:be("min-w-0",n),children:[l.jsxs("div",{className:"flex items-baseline gap-1.5",children:[l.jsx("div",{className:"text-sm font-semibold",children:"NoMoreIDE"}),l.jsxs("div",{className:"font-mono text-[10px] text-muted-foreground",children:["v","0.1.20"]})]}),l.jsx("div",{className:"font-mono text-[11px] text-muted-foreground",children:"127.0.0.1 console"})]})}function T8(){const[n,a]=C.useState(()=>window.location.pathname.startsWith("/agent")?"agent":window.location.pathname.startsWith("/git")?"git":"services"),[r,o]=C.useState(null),[u,f]=C.useState(null),[m,p]=C.useState(!0),{error:g,success:h}=ma(),[b,v]=C.useState(()=>window.localStorage.getItem("nomoreide:sidebar")==="collapsed"),x=C.useCallback(async(S={})=>{S.silent||p(!0),f(null);try{o(await N_()),S.notify&&h("Dashboard refreshed.")}catch(N){const M=N instanceof Error?N.message:String(N);f(M),g(M)}finally{p(!1)}},[g,h]);C.useEffect(()=>{x()},[x]),C.useEffect(()=>{function S(){document.visibilityState==="visible"&&x({silent:!0})}const N=window.setInterval(S,5e3);return window.addEventListener("focus",S),document.addEventListener("visibilitychange",S),()=>{window.clearInterval(N),window.removeEventListener("focus",S),document.removeEventListener("visibilitychange",S)}},[n,x]),C.useEffect(()=>{const S=n==="git"?"/git":n==="agent"?"/agent":"/";window.location.pathname!==S&&window.history.pushState(null,"",S)},[n]),C.useEffect(()=>{window.localStorage.setItem("nomoreide:sidebar",b?"collapsed":"expanded")},[b]);const _=C.useMemo(()=>r?Object.values(r.runtime.services).filter(S=>S.state==="running").length:0,[r]);return l.jsxs("div",{className:"h-screen overflow-hidden",children:[l.jsxs("div",{className:"mx-auto flex h-screen max-w-[1500px]",children:[l.jsxs("aside",{className:be("hidden h-screen shrink-0 overflow-auto border-r border-border bg-card/85 px-4 py-5 backdrop-blur transition-[width] duration-200 md:block",b?"w-[76px]":"w-64"),children:[l.jsxs("div",{className:be("flex items-center px-2",b?"justify-center":"gap-3"),children:[l.jsx("div",{className:"flex size-9 items-center justify-center overflow-hidden rounded-md bg-primary",children:l.jsx("img",{alt:"NoMoreIDE",className:"size-full object-cover",src:S_})}),l.jsx(w8,{className:be(b&&"hidden")}),l.jsx(Me,{"aria-label":b?"Expand navigation":"Collapse navigation",className:be("ml-auto",b&&"hidden"),size:"icon",variant:"ghost",onClick:()=>v(S=>!S),children:l.jsx(Q3,{})})]}),l.jsx("div",{className:be("mt-4",!b&&"hidden"),children:l.jsx(Me,{"aria-label":"Expand navigation",className:"w-full",size:"icon",variant:"ghost",onClick:()=>v(S=>!S),children:l.jsx(J3,{})})}),l.jsxs("nav",{className:"mt-5 grid gap-1",children:[l.jsx(If,{active:n==="services",badge:_,collapsed:b,icon:l.jsx(f_,{}),label:"Services",onClick:()=>a("services")}),l.jsx(If,{active:n==="git",collapsed:b,icon:l.jsx(bo,{}),label:"Git Review",onClick:()=>a("git")}),l.jsx(If,{active:n==="agent",collapsed:b,icon:l.jsx(go,{}),label:"Agent",onClick:()=>a("agent")})]})]}),l.jsxs("main",{className:"flex h-screen min-w-0 flex-1 flex-col px-0 py-0",children:[l.jsxs("header",{className:be("relative z-40 flex shrink-0 flex-wrap items-center justify-between gap-3 border border-border bg-card/90 px-4 py-3 backdrop-blur","border-x-0 border-t-0 border-b"),children:[l.jsxs("div",{className:"flex items-center gap-3",children:[l.jsx(t_,{className:"size-4 text-muted-foreground md:hidden"}),l.jsxs("div",{children:[l.jsx("h1",{className:"text-lg font-semibold tracking-tight",children:n==="git"?"Git Review":n==="agent"?"Agent":"Services"}),l.jsx("p",{className:"font-mono text-xs text-muted-foreground",children:r?.git.selectedRepository?.name??r?.git.cwd??"Local workspace"})]})]}),l.jsxs("div",{className:"flex items-center gap-2",children:[u?l.jsx(lt,{variant:"danger",children:u}):null,r&&n==="git"?l.jsx(E8,{data:r,onRefresh:x}):null,l.jsxs(Me,{onClick:()=>{x({notify:!0})},size:"sm",title:"Refresh dashboard",variant:"outline",children:[l.jsx(_y,{className:be(m&&"animate-spin")}),"Refresh"]})]})]}),m&&!r?l.jsx(yt,{variant:"muted",children:"Loading NoMoreIDE state..."}):null,l.jsxs("div",{className:"min-h-0 flex-1 overflow-hidden",children:[r&&n==="services"?l.jsx(ZA,{data:r,onRefresh:x}):null,r&&n==="git"?l.jsx(y8,{data:r}):null,n==="agent"?l.jsx(L4,{}):null]})]})]}),r&&n==="git"?l.jsx(N8,{branches:r.git.branches,currentBranch:r.git.status?.branch||void 0,disabled:!r.git.status,onRefresh:x}):null]})}function If({active:n,badge:a,collapsed:r,icon:o,label:u,onClick:f}){return l.jsxs(Me,{"aria-label":u,title:r?u:void 0,className:be("w-full",r?"relative justify-center px-0":"justify-start"),variant:n?"default":"ghost",onClick:f,type:"button",children:[l.jsx("span",{className:be(r&&"[&_svg]:size-4"),children:o}),l.jsx("span",{className:be("min-w-0 flex-1 text-left",r&&"hidden"),children:u}),a!==void 0?l.jsx(lt,{appearance:a>0?"solid":"outline",className:be("min-w-6 justify-center px-1.5 font-mono shadow-none",n?"border-primary-foreground/40 bg-primary-foreground/15 text-primary-foreground":a>0?"":"border-border bg-background text-muted-foreground",r&&"absolute right-1.5 top-1.5 h-4 min-w-4 rounded-full px-1 text-[10px] leading-none shadow-none"),size:"small",variant:a>0?"success":"outline",children:a}):null]})}iy.createRoot(document.getElementById("root")).render(l.jsx(C.StrictMode,{children:l.jsx(T8,{})}));
|
|
23
|
+
${D.subject}`,children:[l.jsx(h8,{lane:D.lane,laneCount:Math.max(D.laneCount,ae),edges:D.edges,throughLanes:D.throughLanes,isMerge:D.parents.length>1,height:W1}),l.jsx("span",{className:"font-mono text-[10px] text-muted-foreground",children:D.hash.slice(0,7)}),l.jsxs("span",{className:"flex min-w-0 flex-1 items-center gap-1.5",children:[D.refs.map(P=>l.jsx("span",{className:b8(P.kind),children:P.name},`${P.kind}-${P.name}`)),l.jsx("span",{className:"truncate text-[12px]",children:D.subject})]}),l.jsx("span",{className:"shrink-0 text-[10px] text-muted-foreground",children:D.author})]})},D.hash))})})]}),l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden border-r border-border",children:[l.jsx("div",{className:"flex shrink-0 items-center justify-between gap-2 border-b border-border px-3 py-1.5",children:l.jsxs("h2",{className:"text-[13px] font-semibold tracking-tight",children:["Files",v.length?l.jsx("span",{className:"ml-2 text-[11px] font-normal text-muted-foreground",children:v.length}):null]})}),l.jsx("div",{className:"min-h-0 flex-1 overflow-auto",children:_?l.jsx("div",{className:"p-3",children:l.jsx(yt,{variant:"destructive",children:_})}):h?v.length===0?l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"No file changes."}):l.jsx("ul",{className:"divide-y divide-border",children:v.map(D=>l.jsx("li",{children:l.jsxs("button",{onClick:()=>M(D.path),type:"button",title:D.path,className:`flex w-full items-center gap-2 px-2 py-1 text-left text-[12px] transition-colors hover:bg-muted/60 ${N===D.path?"bg-muted":""}`,children:[l.jsx("span",{className:g8(D.index),children:D.index.trim()||"·"}),l.jsx("span",{className:"truncate font-mono",children:D.path})]})},D.path))}):l.jsx("div",{className:"p-3 text-[12px] text-muted-foreground",children:"Select a commit to see its files."})})]})]})]})]})}function J1(n){const a={name:"",fullPath:"",children:new Map};for(const r of n){const o=r.name.split("/");let u=a;o.forEach((f,m)=>{let p=u.children.get(f);p||(p={name:f,fullPath:o.slice(0,m+1).join("/"),children:new Map},u.children.set(f,p)),u=p}),u.branch=r}return a}function ey({label:n,tree:a,onSelect:r,defaultOpen:o,forceOpen:u}){const[f,m]=C.useState(o??!1),p=u||f,g=a.children.size===0;return l.jsxs("div",{className:"mb-1",children:[l.jsxs("button",{type:"button",onClick:()=>m(h=>!h),className:"flex w-full items-center gap-1 px-2 py-0.5 text-left text-[11px] font-semibold uppercase tracking-wide text-muted-foreground hover:text-foreground",children:[p?l.jsx(wi,{size:12}):l.jsx(is,{size:12}),n,g?null:l.jsxs("span",{className:"ml-1 text-[10px] font-normal",children:["(",a.children.size,")"]})]}),p&&!g?l.jsx("ul",{children:Array.from(a.children.values()).map(h=>l.jsx(Vx,{node:h,depth:1,onSelect:r,forceOpen:u},h.fullPath))}):null]})}function Vx({node:n,depth:a,onSelect:r,forceOpen:o}){const[u,f]=C.useState(!0),m=o||u,p=n.children.size>0,g=n.branch,h={paddingLeft:`${a*10}px`};return!p&&g?l.jsx("li",{children:l.jsxs("button",{type:"button",onClick:()=>r(g),style:h,title:g.name,className:`flex w-full items-center gap-1.5 py-0.5 pr-2 text-left text-[12px] hover:bg-muted/60 ${g.current?"font-semibold text-emerald-700":""}`,children:[l.jsx(bo,{size:11,className:"shrink-0 opacity-70"}),l.jsx("span",{className:"truncate",children:n.name}),g.current?l.jsx("span",{className:"text-[10px]",children:"●"}):null]})}):l.jsxs("li",{children:[l.jsxs("button",{type:"button",onClick:()=>{g?r(g):f(b=>!b)},style:h,className:"flex w-full items-center gap-1 py-0.5 pr-2 text-left text-[12px] hover:bg-muted/60",children:[p?m?l.jsx(wi,{size:11}):l.jsx(is,{size:11}):l.jsx("span",{className:"inline-block w-[11px]"}),l.jsx("span",{className:"truncate",children:n.name})]}),m&&p?l.jsx("ul",{children:Array.from(n.children.values()).map(b=>l.jsx(Vx,{node:b,depth:a+1,onSelect:r,forceOpen:o},b.fullPath))}):null]})}function g8(n){const a="inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-[10px] font-bold";switch(n.trim().toUpperCase()){case"A":return`${a} bg-emerald-100 text-emerald-800`;case"D":return`${a} bg-red-100 text-red-800`;case"M":return`${a} bg-amber-100 text-amber-800`;case"R":return`${a} bg-blue-100 text-blue-800`;case"C":return`${a} bg-indigo-100 text-indigo-800`;default:return`${a} bg-slate-100 text-slate-700`}}function b8(n){const a="rounded px-1.5 py-px text-[10px] font-medium";switch(n){case"head":return`${a} bg-emerald-100 text-emerald-800`;case"branch":return`${a} bg-blue-100 text-blue-800`;case"remote":return`${a} bg-slate-100 text-slate-700`;case"tag":return`${a} bg-amber-100 text-amber-800`}}function y8({data:n}){const[a,r]=C.useState("changes"),[o,u]=C.useState("changes"),[f,m]=C.useState(n.git.status?.files[0]?.path??""),[p,g]=C.useState(""),[h,b]=C.useState([]),[v,x]=C.useState(null),[_,S]=C.useState(""),[N,M]=C.useState(null),[R,L]=C.useState(0),[B,U]=C.useState(null),F=n.git.status?.files??[],X=C.useMemo(()=>F.map(K=>K.path),[F]),I=C.useMemo(()=>QA(_),[_]);C.useEffect(()=>{const K=n.git.status?.files[0]?.path??"";m(Z=>Z&&n.git.status?.files.some(T=>T.path===Z)?Z:K)},[n.git.status?.files]),C.useEffect(()=>{if(o!=="all"||h.length>0)return;let K=!0;return x(null),k_().then(Z=>{K&&b(Z)}).catch(Z=>{K&&x(Z instanceof Error?Z.message:String(Z))}),()=>{K=!1}},[o,h.length]),C.useEffect(()=>{if(!f){S("");return}let K=!0;return M(null),O_(f).then(Z=>{K&&(S(Z),L(0),U(null))}).catch(Z=>{K&&M(Z instanceof Error?Z.message:String(Z))}),()=>{K=!1}},[f]);function j(K){L(0),U(null),m(K)}function ae(){const K=m8({activeHunkIndex:R,filePaths:X,hunkCount:I.hunks,pendingNextFilePath:B,selectedFile:f});K.kind==="hunk"?(U(null),L(K.activeHunkIndex)):K.kind==="confirm-next-file"?U(K.filePath):K.kind==="file"?j(K.filePath):U(null)}function te(){if(U(null),R>0){L(T=>T-1);return}const K=F.findIndex(T=>T.path===f),Z=F[K-1];Z&&j(Z.path)}const se=F.findIndex(K=>K.path===f),ue=!!(I.hunks&&R<I.hunks-1||F[se+1]),ke=!!(R>0||F[se-1]),ne=B?`End of file. Click Next again to open ${B}.`:null,J=K=>`rounded px-2 py-0.5 text-[11px] font-medium transition-colors ${K?"bg-foreground text-background":"text-muted-foreground hover:text-foreground"}`,O=K=>`flex-1 px-2 py-0.5 text-[11px] font-medium transition-colors ${K?"bg-foreground text-background":"text-muted-foreground hover:text-foreground"}`,D=C.useMemo(()=>new Set(F.map(K=>K.path)),[F]);function P(){p&&(u("changes"),j(p))}return l.jsxs("div",{className:"flex h-full min-h-0 flex-col overflow-hidden bg-card/85",children:[l.jsxs("div",{className:"flex shrink-0 items-center gap-1 border-b border-border bg-card/95 px-3 py-1",children:[l.jsx("button",{type:"button",className:J(a==="changes"),onClick:()=>r("changes"),children:"Changes"}),l.jsx("button",{type:"button",className:J(a==="graph"),onClick:()=>r("graph"),children:"Tree"})]}),l.jsx("div",{className:"min-h-0 flex-1",children:a==="graph"?l.jsx(p8,{branches:n.git.branches??[]}):l.jsxs("div",{className:"grid h-full min-h-0 overflow-hidden border-0 bg-card/85 xl:grid-cols-[320px_minmax(0,1fr)]",children:[l.jsxs("aside",{className:"flex min-h-0 flex-col overflow-hidden",children:[l.jsxs("div",{className:"flex shrink-0 gap-0.5 border-b border-border bg-card/95 p-1",children:[l.jsx("button",{className:O(o==="changes"),onClick:()=>u("changes"),type:"button",children:"Changes"}),l.jsx("button",{className:O(o==="all"),onClick:()=>u("all"),type:"button",children:"All files"})]}),o==="changes"?l.jsx(u6,{branch:n.git.status?.branch||void 0,error:n.git.error,files:n.git.status?.files??[],selectedFile:f,onSelectFile:j}):v?l.jsx(yt,{variant:"destructive",className:"m-3",children:v}):l.jsx(v6,{branch:n.git.status?.branch||void 0,onSelectFile:g,paths:h,selectedFile:p,status:n.git.status?.files??[]})]}),o==="all"?l.jsx(f8,{isModified:D.has(p),onViewDiff:P,path:p}):l.jsxs("section",{className:"flex min-h-0 min-w-0 flex-col border-l border-border bg-white",children:[l.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-border px-3 py-1.5",children:[l.jsxs("div",{className:"min-w-0",children:[l.jsx("h2",{className:"truncate text-[13px] font-semibold tracking-tight",children:f||"Diff"}),l.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground",children:[l.jsx("span",{children:"Long rows scroll horizontally inside the editor pane."}),I.additions||I.deletions?l.jsxs("span",{className:"flex items-center gap-1 font-mono",children:[l.jsxs("span",{className:"text-emerald-700",children:["+",I.additions]}),l.jsxs("span",{className:"text-red-700",children:["-",I.deletions]})]}):null]})]}),l.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[ne?l.jsx("span",{className:"max-w-72 truncate rounded border border-amber-200 bg-amber-50 px-2 py-1 text-[11px] text-amber-900",children:ne}):null,l.jsxs(Me,{disabled:!f||!ke,onClick:te,size:"sm",type:"button",variant:"outline",children:[l.jsx(l3,{}),"Previous"]}),l.jsxs(Me,{disabled:!f||!ue,onClick:ae,size:"sm",type:"button",variant:"outline",children:[l.jsx(r3,{}),"Next"]})]})]}),l.jsx("div",{className:"min-h-0 min-w-0 flex-1",children:N?l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"destructive",children:N})}):f?l.jsx(Bx,{activeHunkIndex:R,diff:_||"No unstaged diff for this file."}):l.jsx("div",{className:"p-4",children:l.jsx(yt,{variant:"muted",className:"border-dashed p-12 text-center",children:"Select a changed file to inspect its diff."})})})]})]})})]})}function v8({initialPath:n,onSelect:a,selectedPath:r}){const[o,u]=C.useState(n),[f,m]=C.useState(null),[p,g]=C.useState(null),[h,b]=C.useState(!1),v=x8(f);return C.useEffect(()=>{u(n)},[n]),C.useEffect(()=>{let x=!0;return b(!0),g(null),j_(o).then(_=>{x&&(m(_),a(_.path))}).catch(_=>{x&&g(_ instanceof Error?_.message:String(_))}).finally(()=>{x&&b(!1)}),()=>{x=!1}},[o,a]),l.jsxs("div",{className:"rounded-md border border-border bg-background",children:[l.jsxs("div",{className:"flex items-center gap-2 border-b border-border p-2",children:[v?l.jsx(Me,{"aria-label":"Open parent folder",onClick:()=>f&&u(f.parent),size:"icon",type:"button",variant:"ghost",children:l.jsx(wi,{className:"rotate-90"})}):null,l.jsx("div",{className:"min-w-0 flex-1 truncate font-mono text-xs text-muted-foreground",children:f?.path??o}),h?l.jsx(yy,{className:"size-4 animate-spin text-muted-foreground"}):null]}),l.jsxs("div",{className:"max-h-56 overflow-auto p-1",children:[p?l.jsx(yt,{variant:"destructive",className:"m-1",children:p}):null,!p&&f?.entries.length===0?l.jsx(yt,{variant:"muted",className:"m-1 text-center",children:"No folders here."}):null,f?.entries.map(x=>l.jsxs(Me,{className:be("h-8 w-full justify-start rounded-sm px-2 text-left",r===x.path&&"bg-muted"),onClick:()=>u(x.path),title:x.path,type:"button",variant:"ghost",children:[l.jsx(nr,{className:"text-accent"}),l.jsx("span",{className:"truncate",children:x.name})]},x.path))]})]})}function x8(n){return!!(n&&n.parent!==n.path)}function ty(n){return n.split(/[\\/]/).filter(Boolean).pop()??"project"}function E8({data:n,onRefresh:a}){const[r,o]=C.useState(!1),[u,f]=C.useState(n.git.cwd),[m,p]=C.useState(null),[g,h]=C.useState(!1),[b,v]=C.useState("add"),[x,_]=C.useState(n.git.cwd),S=C.useRef(null),N=n.git.selectedRepository,M=N?.name??ty(n.git.cwd),{error:R,success:L}=ma();C.useEffect(()=>{f(n.git.cwd),_(n.git.cwd)},[n.git.cwd]),C.useEffect(()=>{if(!r)return;function X(I){S.current&&I.target instanceof Node&&!S.current.contains(I.target)&&o(!1)}return document.addEventListener("mousedown",X),()=>document.removeEventListener("mousedown",X)},[r]);async function B(X){try{await Mn("/api/git/select",{name:X}),o(!1),await a(),L(`Switched to ${X}.`)}catch(I){R(I instanceof Error?I.message:String(I))}}async function U(X){const I=X.trim();if(!_8(I)){const j="Please add an absolute path. Paths beginning with ~ are not expanded here.";return p(j),R(j),!1}try{const j=ty(I);return await Mn("/api/git/repositories",{name:j,path:I}),p(null),await a(),L(`Added Git project ${j}.`),!0}catch(j){const ae=j instanceof Error?j.message:String(j);return p(ae),R(ae),!1}}async function F(X){X.preventDefault(),await U(u)&&o(!1)}return l.jsxs("div",{className:"relative z-50 flex items-center gap-2",ref:S,children:[l.jsxs(Me,{className:"max-w-[220px] justify-start gap-2 rounded-md border-border bg-card",onClick:()=>o(X=>!X),size:"sm",type:"button",variant:"outline",children:[l.jsx(nr,{className:"text-muted-foreground"}),l.jsx("span",{className:"truncate",children:M}),l.jsx(wi,{className:be("ml-auto transition-transform",r&&"rotate-180")})]}),l.jsx(Me,{"aria-label":"Add Git project",onClick:()=>{v("add"),p(null),_(n.git.cwd),h(!0)},size:"sm",type:"button",variant:"outline",children:l.jsx(yo,{})}),r?l.jsxs("div",{className:"absolute right-0 top-10 z-50 w-[min(380px,calc(100vw-2rem))] overflow-hidden rounded-lg border border-border bg-card shadow-lg",children:[l.jsxs("div",{className:"flex items-center gap-2 border-b border-border px-3 py-2",children:[l.jsx(T3,{className:"size-3.5 text-muted-foreground"}),l.jsx("div",{className:"text-xs font-semibold",children:"Git Projects"}),l.jsx(lt,{className:"ml-auto h-5 px-1.5 text-[10px]",variant:"outline",children:n.config.gitRepositories.length})]}),l.jsx("div",{className:"max-h-72 overflow-auto",children:n.config.gitRepositories.length?l.jsx("div",{className:"divide-y divide-border",children:n.config.gitRepositories.map(X=>{const I=X.name===N?.name;return l.jsxs("button",{className:be("grid w-full grid-cols-[1fr_auto] items-center gap-2 px-3 py-1.5 text-left transition-colors hover:bg-muted",I&&"bg-muted/70"),onClick:()=>{B(X.name)},type:"button",children:[l.jsxs("span",{className:"min-w-0",children:[l.jsx("span",{className:"block truncate text-sm font-medium leading-tight",children:X.name}),l.jsx("span",{className:"block truncate font-mono text-[10px] leading-tight text-muted-foreground",children:X.path})]}),I?l.jsx(oy,{className:"size-3.5"}):null]},X.name)})}):l.jsx("div",{className:"px-3 py-6 text-center text-xs text-muted-foreground",children:"No saved Git projects yet."})}),l.jsxs("div",{className:"border-t border-border bg-muted/20 p-2",children:[l.jsxs("form",{className:"flex gap-1.5",onSubmit:F,children:[l.jsx(rn,{"aria-label":"Paste absolute path",className:"h-7 flex-1 px-2 font-mono text-[11px]",onChange:X=>{f(X.target.value),p(null)},placeholder:"/absolute/path",value:u}),l.jsxs(Me,{className:"h-7 px-2 text-[11px]",size:"sm",type:"submit",children:[l.jsx(yo,{className:"size-3"}),"Add"]}),l.jsx(Me,{"aria-label":"Browse folders",className:"h-7 px-2",onClick:()=>{v("fill"),p(null),_(u||n.git.cwd),h(!0)},size:"sm",type:"button",variant:"outline",children:l.jsx(z3,{className:"size-3"})})]}),m?l.jsx("div",{className:"mt-1.5 truncate text-[10px] text-destructive",children:m}):null]})]}):null,g?l.jsx(S8,{confirmLabel:b==="add"?"Add Git project":"Use this folder",errorMessage:b==="add"?m:null,initialPath:b==="add"?n.git.cwd:u||n.git.cwd,selectedPath:x,title:b==="add"?"Add Git Project":"Choose Git Project Folder",onCancel:()=>h(!1),onSelect:_,onUse:async()=>{b==="add"?await U(x)&&(h(!1),o(!1)):(f(x),p(null),h(!1))}}):null]})}function _8(n){return n.startsWith("/")}function S8({confirmLabel:n="Use this folder",errorMessage:a,initialPath:r,onCancel:o,onSelect:u,onUse:f,selectedPath:m,title:p="Choose Git Project Folder"}){return Rx.createPortal(l.jsx("div",{className:"fixed inset-0 z-[1000] grid place-items-center bg-black/35 px-4",children:l.jsxs("div",{className:"w-full max-w-2xl rounded-xl border border-border bg-card p-4 shadow-xl",children:[l.jsxs("div",{className:"mb-3 flex items-center gap-3",children:[l.jsx("div",{className:"flex size-8 items-center justify-center rounded-lg border border-border bg-background",children:l.jsx(nr,{className:"size-4"})}),l.jsxs("div",{className:"min-w-0 flex-1",children:[l.jsx("div",{className:"text-sm font-semibold",children:p}),l.jsx("div",{className:"truncate font-mono text-xs text-muted-foreground",children:m})]}),l.jsx(Me,{"aria-label":"Close folder picker",onClick:o,size:"icon",variant:"ghost",children:l.jsx(xc,{})})]}),l.jsx(v8,{initialPath:r,onSelect:u,selectedPath:m}),a?l.jsx("div",{className:"mt-3 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:a}):null,l.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[l.jsx(Me,{onClick:o,type:"button",variant:"outline",children:"Cancel"}),l.jsx(Me,{onClick:()=>{f()},type:"button",children:n})]})]})}),document.body)}function N8({branches:n,currentBranch:a,disabled:r,onRefresh:o}){const[u,f]=C.useState(!1),[m,p]=C.useState(""),[g,h]=C.useState(null),[b,v]=C.useState(null),[x,_]=C.useState(null),S=n.filter(U=>!U.remote),N=n.filter(U=>U.remote);async function M(U,F){h(U),_(null),v(null);try{await F(),await o()}catch(X){_(X instanceof Error?X.message:String(X))}finally{h(null)}}async function R(U){await M(`switch:${U}`,async()=>{await Mn("/api/git/branches/switch",{name:U}),f(!1)})}async function L(){await M("fetch",async()=>{await Mn("/api/git/fetch",{}),v("Fetched latest branch refs.")})}async function B(U){U.preventDefault();const F=m.trim();if(!F){_("Branch name is required.");return}await M("create",async()=>{await Mn("/api/git/branches",{name:F}),p(""),f(!1)})}return l.jsxs("div",{className:"fixed bottom-3 right-4 z-50 flex items-end",children:[u?l.jsxs("div",{"aria-label":"Switch Git branch",className:"mb-11 w-[min(460px,calc(100vw-2rem))] rounded-lg border border-border bg-card shadow-xl",role:"dialog",children:[l.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-border p-3",children:[l.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[l.jsx(bo,{className:"size-4 text-muted-foreground"}),l.jsx("span",{className:"truncate text-sm font-semibold",children:a||"Branches"})]}),l.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[l.jsx(Me,{"aria-label":"Fetch branches",disabled:r||g!==null,onClick:()=>{L()},size:"icon",title:"Fetch branches",type:"button",variant:"ghost",children:l.jsx(_y,{className:be(g==="fetch"&&"animate-spin")})}),l.jsx(Me,{"aria-label":"Close branch dialog",onClick:()=>f(!1),size:"icon",type:"button",variant:"ghost",children:l.jsx(xc,{})})]})]}),l.jsx("div",{className:"max-h-72 overflow-auto",children:n.length?l.jsxs(l.Fragment,{children:[l.jsx(ny,{branches:S,busy:g!==null,disabled:r,label:"Local",onSwitch:R}),l.jsx(ny,{branches:N,busy:g!==null,disabled:r,label:"Remote",onSwitch:R})]}):l.jsx("div",{className:"px-3 py-6 text-center text-sm text-muted-foreground",children:"No branches found."})}),l.jsxs("div",{className:"border-t border-border p-3",children:[l.jsxs("form",{className:"grid gap-2 sm:grid-cols-[1fr_auto]",onSubmit:B,children:[l.jsx(rn,{"aria-label":"New branch name",disabled:r||g!==null,onChange:U=>{p(U.target.value),_(null),v(null)},placeholder:"feature/new-work",value:m}),l.jsxs(Me,{disabled:r||g!==null,type:"submit",children:[l.jsx(H3,{}),"Create"]})]}),x||b?l.jsx(yt,{className:"mt-3 px-3 py-2 text-xs",variant:x?"destructive":"muted",children:x??b}):null]})]}):null,l.jsxs(Me,{className:"h-8 max-w-[260px] gap-2 rounded-md shadow-lg",disabled:r,onClick:()=>f(U=>!U),size:"sm",title:"Switch Git branch",type:"button",variant:"default",children:[l.jsx(bo,{className:"size-4"}),l.jsx("span",{className:"truncate font-mono text-xs",children:a||"No branch"}),l.jsx(wi,{className:be("size-4 transition-transform",u&&"rotate-180")})]})]})}function ny({branches:n,busy:a,disabled:r,label:o,onSwitch:u}){return l.jsxs("section",{children:[l.jsx("div",{className:"border-b border-border bg-muted/60 px-3 py-1.5 text-[11px] font-semibold uppercase text-muted-foreground",children:o}),n.length?n.map(f=>l.jsxs("button",{className:be("grid w-full grid-cols-[1fr_auto] items-center gap-2 border-b border-border px-3 py-2 text-left text-sm last:border-b-0 hover:bg-muted",f.current&&"bg-muted/70"),disabled:r||a||f.current,onClick:()=>{u(f.name)},type:"button",children:[l.jsxs("span",{className:"min-w-0",children:[l.jsx("span",{className:"block truncate font-medium",children:f.name}),f.upstream?l.jsxs("span",{className:"block truncate font-mono text-[11px] text-muted-foreground",children:["tracks ",f.upstream]}):null]}),l.jsx(lt,{variant:f.current?"success":f.remote?"outline":"secondary",children:f.current?"current":f.remote?"remote":"local"})]},`${f.remote?"remote":"local"}:${f.name}`)):l.jsxs("div",{className:"border-b border-border px-3 py-3 text-sm text-muted-foreground",children:["No ",o.toLowerCase()," branches."]})]})}function w8({className:n}){return l.jsxs("div",{className:be("min-w-0",n),children:[l.jsxs("div",{className:"flex items-baseline gap-1.5",children:[l.jsx("div",{className:"text-sm font-semibold",children:"NoMoreIDE"}),l.jsxs("div",{className:"font-mono text-[10px] text-muted-foreground",children:["v","0.1.21"]})]}),l.jsx("div",{className:"font-mono text-[11px] text-muted-foreground",children:"127.0.0.1 console"})]})}function T8(){const[n,a]=C.useState(()=>window.location.pathname.startsWith("/agent")?"agent":window.location.pathname.startsWith("/git")?"git":"services"),[r,o]=C.useState(null),[u,f]=C.useState(null),[m,p]=C.useState(!0),{error:g,success:h}=ma(),[b,v]=C.useState(()=>window.localStorage.getItem("nomoreide:sidebar")==="collapsed"),x=C.useCallback(async(S={})=>{S.silent||p(!0),f(null);try{o(await N_()),S.notify&&h("Dashboard refreshed.")}catch(N){const M=N instanceof Error?N.message:String(N);f(M),g(M)}finally{p(!1)}},[g,h]);C.useEffect(()=>{x()},[x]),C.useEffect(()=>{function S(){document.visibilityState==="visible"&&x({silent:!0})}const N=window.setInterval(S,5e3);return window.addEventListener("focus",S),document.addEventListener("visibilitychange",S),()=>{window.clearInterval(N),window.removeEventListener("focus",S),document.removeEventListener("visibilitychange",S)}},[n,x]),C.useEffect(()=>{const S=n==="git"?"/git":n==="agent"?"/agent":"/";window.location.pathname!==S&&window.history.pushState(null,"",S)},[n]),C.useEffect(()=>{window.localStorage.setItem("nomoreide:sidebar",b?"collapsed":"expanded")},[b]);const _=C.useMemo(()=>r?Object.values(r.runtime.services).filter(S=>S.state==="running").length:0,[r]);return l.jsxs("div",{className:"h-screen overflow-hidden",children:[l.jsxs("div",{className:"mx-auto flex h-screen max-w-[1500px]",children:[l.jsxs("aside",{className:be("hidden h-screen shrink-0 overflow-auto border-r border-border bg-card/85 px-4 py-5 backdrop-blur transition-[width] duration-200 md:block",b?"w-[76px]":"w-64"),children:[l.jsxs("div",{className:be("flex items-center px-2",b?"justify-center":"gap-3"),children:[l.jsx("div",{className:"flex size-9 items-center justify-center overflow-hidden rounded-md bg-primary",children:l.jsx("img",{alt:"NoMoreIDE",className:"size-full object-cover",src:S_})}),l.jsx(w8,{className:be(b&&"hidden")}),l.jsx(Me,{"aria-label":b?"Expand navigation":"Collapse navigation",className:be("ml-auto",b&&"hidden"),size:"icon",variant:"ghost",onClick:()=>v(S=>!S),children:l.jsx(Q3,{})})]}),l.jsx("div",{className:be("mt-4",!b&&"hidden"),children:l.jsx(Me,{"aria-label":"Expand navigation",className:"w-full",size:"icon",variant:"ghost",onClick:()=>v(S=>!S),children:l.jsx(J3,{})})}),l.jsxs("nav",{className:"mt-5 grid gap-1",children:[l.jsx(If,{active:n==="services",badge:_,collapsed:b,icon:l.jsx(f_,{}),label:"Services",onClick:()=>a("services")}),l.jsx(If,{active:n==="git",collapsed:b,icon:l.jsx(bo,{}),label:"Git Review",onClick:()=>a("git")}),l.jsx(If,{active:n==="agent",collapsed:b,icon:l.jsx(go,{}),label:"Agent",onClick:()=>a("agent")})]})]}),l.jsxs("main",{className:"flex h-screen min-w-0 flex-1 flex-col px-0 py-0",children:[l.jsxs("header",{className:be("relative z-40 flex shrink-0 flex-wrap items-center justify-between gap-3 border border-border bg-card/90 px-4 py-3 backdrop-blur","border-x-0 border-t-0 border-b"),children:[l.jsxs("div",{className:"flex items-center gap-3",children:[l.jsx(t_,{className:"size-4 text-muted-foreground md:hidden"}),l.jsxs("div",{children:[l.jsx("h1",{className:"text-lg font-semibold tracking-tight",children:n==="git"?"Git Review":n==="agent"?"Agent":"Services"}),l.jsx("p",{className:"font-mono text-xs text-muted-foreground",children:r?.git.selectedRepository?.name??r?.git.cwd??"Local workspace"})]})]}),l.jsxs("div",{className:"flex items-center gap-2",children:[u?l.jsx(lt,{variant:"danger",children:u}):null,r&&n==="git"?l.jsx(E8,{data:r,onRefresh:x}):null,l.jsxs(Me,{onClick:()=>{x({notify:!0})},size:"sm",title:"Refresh dashboard",variant:"outline",children:[l.jsx(_y,{className:be(m&&"animate-spin")}),"Refresh"]})]})]}),m&&!r?l.jsx(yt,{variant:"muted",children:"Loading NoMoreIDE state..."}):null,l.jsxs("div",{className:"min-h-0 flex-1 overflow-hidden",children:[r&&n==="services"?l.jsx(ZA,{data:r,onRefresh:x}):null,r&&n==="git"?l.jsx(y8,{data:r}):null,n==="agent"?l.jsx(L4,{}):null]})]})]}),r&&n==="git"?l.jsx(N8,{branches:r.git.branches,currentBranch:r.git.status?.branch||void 0,disabled:!r.git.status,onRefresh:x}):null]})}function If({active:n,badge:a,collapsed:r,icon:o,label:u,onClick:f}){return l.jsxs(Me,{"aria-label":u,title:r?u:void 0,className:be("w-full",r?"relative justify-center px-0":"justify-start"),variant:n?"default":"ghost",onClick:f,type:"button",children:[l.jsx("span",{className:be(r&&"[&_svg]:size-4"),children:o}),l.jsx("span",{className:be("min-w-0 flex-1 text-left",r&&"hidden"),children:u}),a!==void 0?l.jsx(lt,{appearance:a>0?"solid":"outline",className:be("min-w-6 justify-center px-1.5 font-mono shadow-none",n?"border-primary-foreground/40 bg-primary-foreground/15 text-primary-foreground":a>0?"":"border-border bg-background text-muted-foreground",r&&"absolute right-1.5 top-1.5 h-4 min-w-4 rounded-full px-1 text-[10px] leading-none shadow-none"),size:"small",variant:a>0?"success":"outline",children:a}):null]})}iy.createRoot(document.getElementById("root")).render(l.jsx(C.StrictMode,{children:l.jsx(T8,{})}));
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/assets/nomoreide-favicon-Ds7Tgj9p.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>NoMoreIDE</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CBZsUFdB.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-y4GyM_JC.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { buildAgentInfo } from "../agent-info.js";
|
|
2
|
+
import { buildUsageInfo } from "../usage-info.js";
|
|
3
|
+
import { sendJson } from "../http-utils.js";
|
|
4
|
+
import { route } from "./context.js";
|
|
5
|
+
/** Agent introspection: identity, token usage, and the live tool-call feed. */
|
|
6
|
+
export const agentRoutes = [
|
|
7
|
+
route("GET", "/api/agent", async ({ response, cwd }) => {
|
|
8
|
+
sendJson(response, { ok: true, agent: await buildAgentInfo(cwd) });
|
|
9
|
+
}),
|
|
10
|
+
route("GET", "/api/agent/usage", async ({ response, cwd }) => {
|
|
11
|
+
sendJson(response, { ok: true, usage: await buildUsageInfo(cwd) });
|
|
12
|
+
}),
|
|
13
|
+
route("GET", "/api/agent/tool-calls", ({ response, url, toolCallStore }) => {
|
|
14
|
+
const limitParam = Number(url.searchParams.get("limit"));
|
|
15
|
+
const limit = Number.isFinite(limitParam) && limitParam > 0 ? Math.min(limitParam, 500) : 100;
|
|
16
|
+
sendJson(response, { ok: true, records: toolCallStore.recent(limit) });
|
|
17
|
+
}),
|
|
18
|
+
route("GET", "/api/agent/tool-calls/stream", ({ request, response, toolCallStore }) => {
|
|
19
|
+
response.writeHead(200, {
|
|
20
|
+
"content-type": "text/event-stream",
|
|
21
|
+
"cache-control": "no-cache, no-transform",
|
|
22
|
+
connection: "keep-alive",
|
|
23
|
+
});
|
|
24
|
+
response.write(`retry: 2000\n\n`);
|
|
25
|
+
for (const record of toolCallStore.recent(50)) {
|
|
26
|
+
response.write(`event: tool-call\ndata: ${JSON.stringify(record)}\n\n`);
|
|
27
|
+
}
|
|
28
|
+
const heartbeat = setInterval(() => {
|
|
29
|
+
response.write(`: ping\n\n`);
|
|
30
|
+
}, 15000);
|
|
31
|
+
const unsubscribe = toolCallStore.subscribe((record) => {
|
|
32
|
+
response.write(`event: tool-call\ndata: ${JSON.stringify(record)}\n\n`);
|
|
33
|
+
});
|
|
34
|
+
request.on("close", () => {
|
|
35
|
+
clearInterval(heartbeat);
|
|
36
|
+
unsubscribe();
|
|
37
|
+
});
|
|
38
|
+
}),
|
|
39
|
+
];
|
|
40
|
+
//# sourceMappingURL=agent-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-routes.js","sourceRoot":"","sources":["../../../src/web/routes/agent-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAc,MAAM,cAAc,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE;QACrD,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE;QAC3D,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,uBAAuB,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE;QACzE,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9F,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,8BAA8B,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;QACpF,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE;YACtB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,wBAAwB;YACzC,UAAU,EAAE,YAAY;SACzB,CAAC,CAAC;QACH,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9C,QAAQ,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC,EAAE,KAAK,CAAC,CAAC;QACV,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;YACrD,QAAQ,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,aAAa,CAAC,SAAS,CAAC,CAAC;YACzB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { ConfigStore } from "../../core/config-store.js";
|
|
3
|
+
import type { LogStore } from "../../core/log-store.js";
|
|
4
|
+
import type { ProcessManager } from "../../core/process-manager.js";
|
|
5
|
+
import type { TimelineStore } from "../../core/timeline-store.js";
|
|
6
|
+
import type { ToolCallStore } from "../../core/tool-call-store.js";
|
|
7
|
+
/** Shared stateful services every route handler receives. */
|
|
8
|
+
export interface RouteServices {
|
|
9
|
+
configStore: ConfigStore;
|
|
10
|
+
cwd: string;
|
|
11
|
+
logStore: LogStore;
|
|
12
|
+
manager: ProcessManager;
|
|
13
|
+
timelineStore: TimelineStore;
|
|
14
|
+
toolCallStore: ToolCallStore;
|
|
15
|
+
}
|
|
16
|
+
/** Per-request context handed to a route handler. */
|
|
17
|
+
export interface RequestContext extends RouteServices {
|
|
18
|
+
request: IncomingMessage;
|
|
19
|
+
response: ServerResponse;
|
|
20
|
+
url: URL;
|
|
21
|
+
params: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
export type RouteHandler = (ctx: RequestContext) => Promise<void> | void;
|
|
24
|
+
export interface Route {
|
|
25
|
+
/** Returns matched path params when this route handles the request, else null. */
|
|
26
|
+
match(method: string, url: URL): Record<string, string> | null;
|
|
27
|
+
handle: RouteHandler;
|
|
28
|
+
}
|
|
29
|
+
/** Exact-path route; matches only the listed method(s). */
|
|
30
|
+
export declare function route(method: string | string[], pathname: string, handle: RouteHandler): Route;
|
|
31
|
+
/**
|
|
32
|
+
* Pattern route matched on pathname only — method handling lives in the
|
|
33
|
+
* handler (mirrors the original regex blocks that return their own 405).
|
|
34
|
+
* Capture groups are exposed as params under the supplied names.
|
|
35
|
+
*/
|
|
36
|
+
export declare function patternRoute(pattern: RegExp, paramNames: string[], handle: RouteHandler): Route;
|
|
37
|
+
/** Prefix route (e.g. `/assets/*`), method-filtered. */
|
|
38
|
+
export declare function prefixRoute(method: string | string[], prefix: string, handle: RouteHandler): Route;
|
|
39
|
+
export declare function errorMessage(error: unknown): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Exact-path route; matches only the listed method(s). */
|
|
2
|
+
export function route(method, pathname, handle) {
|
|
3
|
+
const methods = Array.isArray(method) ? method : [method];
|
|
4
|
+
return {
|
|
5
|
+
match(requestMethod, url) {
|
|
6
|
+
if (!methods.includes(requestMethod))
|
|
7
|
+
return null;
|
|
8
|
+
return url.pathname === pathname ? {} : null;
|
|
9
|
+
},
|
|
10
|
+
handle,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pattern route matched on pathname only — method handling lives in the
|
|
15
|
+
* handler (mirrors the original regex blocks that return their own 405).
|
|
16
|
+
* Capture groups are exposed as params under the supplied names.
|
|
17
|
+
*/
|
|
18
|
+
export function patternRoute(pattern, paramNames, handle) {
|
|
19
|
+
return {
|
|
20
|
+
match(_method, url) {
|
|
21
|
+
const matched = pattern.exec(url.pathname);
|
|
22
|
+
if (!matched)
|
|
23
|
+
return null;
|
|
24
|
+
const params = {};
|
|
25
|
+
matched.slice(1).forEach((value, index) => {
|
|
26
|
+
params[paramNames[index] ?? String(index)] = value;
|
|
27
|
+
});
|
|
28
|
+
return params;
|
|
29
|
+
},
|
|
30
|
+
handle,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Prefix route (e.g. `/assets/*`), method-filtered. */
|
|
34
|
+
export function prefixRoute(method, prefix, handle) {
|
|
35
|
+
const methods = Array.isArray(method) ? method : [method];
|
|
36
|
+
return {
|
|
37
|
+
match(requestMethod, url) {
|
|
38
|
+
if (!methods.includes(requestMethod))
|
|
39
|
+
return null;
|
|
40
|
+
return url.pathname.startsWith(prefix) ? {} : null;
|
|
41
|
+
},
|
|
42
|
+
handle,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function errorMessage(error) {
|
|
46
|
+
return error instanceof Error ? error.message : String(error);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/web/routes/context.ts"],"names":[],"mappings":"AAiCA,2DAA2D;AAC3D,MAAM,UAAU,KAAK,CACnB,MAAyB,EACzB,QAAgB,EAChB,MAAoB;IAEpB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1D,OAAO;QACL,KAAK,CAAC,aAAa,EAAE,GAAG;YACtB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAC;YAClD,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,CAAC;QACD,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,UAAoB,EACpB,MAAoB;IAEpB,OAAO;QACL,KAAK,CAAC,OAAO,EAAE,GAAG;YAChB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC1B,MAAM,MAAM,GAA2B,EAAE,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACxC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC;YACrD,CAAC,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM;KACP,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW,CACzB,MAAyB,EACzB,MAAc,EACd,MAAoB;IAEpB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1D,OAAO;QACL,KAAK,CAAC,aAAa,EAAE,GAAG;YACtB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAC;YAClD,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,CAAC;QACD,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { buildDashboardPayload } from "../dashboard.js";
|
|
2
|
+
import { listDirectories } from "../directories.js";
|
|
3
|
+
import { sendJson } from "../http-utils.js";
|
|
4
|
+
import { route } from "./context.js";
|
|
5
|
+
/** Overview / system endpoints: dashboard, health, status, directory browse. */
|
|
6
|
+
export const dashboardRoutes = [
|
|
7
|
+
route("GET", "/api/dashboard", async ({ response, configStore, cwd, logStore, manager, timelineStore }) => {
|
|
8
|
+
sendJson(response, await buildDashboardPayload({ configStore, cwd, logStore, manager, timelineStore }));
|
|
9
|
+
}),
|
|
10
|
+
route("GET", "/api/health", ({ response }) => {
|
|
11
|
+
sendJson(response, { ok: true, app: "nomoreide" });
|
|
12
|
+
}),
|
|
13
|
+
route("GET", "/api/status", ({ response, manager }) => {
|
|
14
|
+
sendJson(response, { ok: true, status: manager.status() });
|
|
15
|
+
}),
|
|
16
|
+
route("GET", "/api/fs/directories", async ({ response, url, cwd }) => {
|
|
17
|
+
sendJson(response, await listDirectories(url.searchParams.get("path")?.trim() || cwd));
|
|
18
|
+
}),
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=dashboard-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-routes.js","sourceRoot":"","sources":["../../../src/web/routes/dashboard-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAc,MAAM,cAAc,CAAC;AAEjD,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE;QACxG,QAAQ,CACN,QAAQ,EACR,MAAM,qBAAqB,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CACpF,CAAC;IACJ,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC3C,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE;QACpD,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE;QACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { GitManager } from "../../core/git-manager.js";
|
|
2
|
+
import { getSelectedGitRepository, readGitDiff, selectedGitCwd } from "../dashboard.js";
|
|
3
|
+
import { readForm, requiredFormValue, sendJson, sendText } from "../http-utils.js";
|
|
4
|
+
import { errorMessage, route } from "./context.js";
|
|
5
|
+
/** Read-safe Git operations plus repository registration/selection. */
|
|
6
|
+
export const gitRoutes = [
|
|
7
|
+
route("GET", "/api/git/diff", async ({ response, url, configStore, cwd }) => {
|
|
8
|
+
const config = await configStore.load();
|
|
9
|
+
const selectedGitRepository = getSelectedGitRepository(config);
|
|
10
|
+
const gitCwd = selectedGitRepository?.path ?? cwd;
|
|
11
|
+
const selectedFile = url.searchParams.get("file")?.trim();
|
|
12
|
+
if (!selectedFile) {
|
|
13
|
+
sendJson(response, { ok: false, error: "file is required" }, 400);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const git = new GitManager(gitCwd);
|
|
17
|
+
const status = await git.status();
|
|
18
|
+
const selectedStatus = status.files.find((file) => file.path === selectedFile);
|
|
19
|
+
const diff = selectedStatus
|
|
20
|
+
? await git.fileDiff(selectedStatus)
|
|
21
|
+
: await readGitDiff(gitCwd, selectedFile);
|
|
22
|
+
if (diff === undefined) {
|
|
23
|
+
sendJson(response, { ok: false, error: "No changes or file not found." }, 404);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
sendText(response, diff);
|
|
27
|
+
}),
|
|
28
|
+
route("GET", "/api/git/files", async ({ response, configStore, cwd }) => {
|
|
29
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
30
|
+
try {
|
|
31
|
+
const files = await new GitManager(gitCwd).listTrackedFiles();
|
|
32
|
+
sendJson(response, { ok: true, files });
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
sendJson(response, { ok: false, error: errorMessage(error) }, 400);
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
|
+
route("GET", "/api/git/file", async ({ response, url, configStore, cwd }) => {
|
|
39
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
40
|
+
const path = url.searchParams.get("path")?.trim();
|
|
41
|
+
if (!path) {
|
|
42
|
+
sendJson(response, { ok: false, error: "path is required" }, 400);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const file = await new GitManager(gitCwd).readTrackedFile(path);
|
|
47
|
+
sendJson(response, { ok: true, ...file });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
sendJson(response, { ok: false, error: errorMessage(error) }, 404);
|
|
51
|
+
}
|
|
52
|
+
}),
|
|
53
|
+
route("GET", "/api/git/commit", async ({ response, url, configStore, cwd }) => {
|
|
54
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
55
|
+
const hash = url.searchParams.get("hash")?.trim();
|
|
56
|
+
const file = url.searchParams.get("file")?.trim() || undefined;
|
|
57
|
+
if (!hash) {
|
|
58
|
+
sendJson(response, { ok: false, error: "hash is required" }, 400);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const diff = await new GitManager(gitCwd).commitDiff(hash, file);
|
|
63
|
+
sendText(response, diff);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
sendJson(response, { ok: false, error: errorMessage(error) }, 400);
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
route("GET", "/api/git/commit/files", async ({ response, url, configStore, cwd }) => {
|
|
70
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
71
|
+
const hash = url.searchParams.get("hash")?.trim();
|
|
72
|
+
if (!hash) {
|
|
73
|
+
sendJson(response, { ok: false, error: "hash is required" }, 400);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const files = await new GitManager(gitCwd).commitFiles(hash);
|
|
78
|
+
sendJson(response, { ok: true, files });
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
sendJson(response, { ok: false, error: errorMessage(error) }, 400);
|
|
82
|
+
}
|
|
83
|
+
}),
|
|
84
|
+
route("GET", "/api/git/graph", async ({ response, url, configStore, cwd }) => {
|
|
85
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
86
|
+
const limitParam = url.searchParams.get("limit")?.trim();
|
|
87
|
+
const parsedLimit = limitParam ? Number(limitParam) : 200;
|
|
88
|
+
const limit = Number.isFinite(parsedLimit) && parsedLimit > 0
|
|
89
|
+
? Math.min(Math.floor(parsedLimit), 2000)
|
|
90
|
+
: 200;
|
|
91
|
+
const commits = await new GitManager(gitCwd).graph(limit);
|
|
92
|
+
sendJson(response, { ok: true, commits });
|
|
93
|
+
}),
|
|
94
|
+
route("POST", "/api/git/fetch", async ({ response, configStore, cwd }) => {
|
|
95
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
96
|
+
const output = await new GitManager(gitCwd).fetch();
|
|
97
|
+
sendJson(response, { ok: true, output });
|
|
98
|
+
}),
|
|
99
|
+
route("POST", "/api/git/branches", async ({ request, response, configStore, cwd }) => {
|
|
100
|
+
const form = await readForm(request);
|
|
101
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
102
|
+
const output = await new GitManager(gitCwd).createBranch(requiredFormValue(form, "name"));
|
|
103
|
+
sendJson(response, { ok: true, output });
|
|
104
|
+
}),
|
|
105
|
+
route("POST", "/api/git/branches/switch", async ({ request, response, configStore, cwd }) => {
|
|
106
|
+
const form = await readForm(request);
|
|
107
|
+
const gitCwd = await selectedGitCwd(configStore, cwd);
|
|
108
|
+
const output = await new GitManager(gitCwd).switchBranch(requiredFormValue(form, "name"));
|
|
109
|
+
sendJson(response, { ok: true, output });
|
|
110
|
+
}),
|
|
111
|
+
route("POST", "/api/git/repositories", async ({ request, response, configStore }) => {
|
|
112
|
+
const form = await readForm(request);
|
|
113
|
+
const config = await configStore.registerGitRepository({
|
|
114
|
+
name: requiredFormValue(form, "name"),
|
|
115
|
+
path: requiredFormValue(form, "path"),
|
|
116
|
+
});
|
|
117
|
+
sendJson(response, { ok: true, config });
|
|
118
|
+
}),
|
|
119
|
+
route("POST", "/api/git/select", async ({ request, response, configStore }) => {
|
|
120
|
+
const form = await readForm(request);
|
|
121
|
+
const config = await configStore.selectGitRepository(requiredFormValue(form, "name"));
|
|
122
|
+
sendJson(response, { ok: true, config });
|
|
123
|
+
}),
|
|
124
|
+
];
|
|
125
|
+
//# sourceMappingURL=git-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-routes.js","sourceRoot":"","sources":["../../../src/web/routes/git-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Route } from "./context.js";
|
|
2
|
+
/**
|
|
3
|
+
* All routes in dispatch order. `/api/*` route groups come first; the shell /
|
|
4
|
+
* static catch-alls are last so they only run when no API route matched.
|
|
5
|
+
*
|
|
6
|
+
* To add a feature: create `<feature>-routes.ts` exporting a `Route[]`, then
|
|
7
|
+
* register it here. The dispatcher in `server.ts` never needs to change.
|
|
8
|
+
*/
|
|
9
|
+
export declare const routes: Route[];
|
|
10
|
+
export type { Route, RouteServices, RequestContext, RouteHandler } from "./context.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dashboardRoutes } from "./dashboard-routes.js";
|
|
2
|
+
import { agentRoutes } from "./agent-routes.js";
|
|
3
|
+
import { gitRoutes } from "./git-routes.js";
|
|
4
|
+
import { serviceRoutes } from "./service-routes.js";
|
|
5
|
+
import { shellRoutes } from "./shell-routes.js";
|
|
6
|
+
/**
|
|
7
|
+
* All routes in dispatch order. `/api/*` route groups come first; the shell /
|
|
8
|
+
* static catch-alls are last so they only run when no API route matched.
|
|
9
|
+
*
|
|
10
|
+
* To add a feature: create `<feature>-routes.ts` exporting a `Route[]`, then
|
|
11
|
+
* register it here. The dispatcher in `server.ts` never needs to change.
|
|
12
|
+
*/
|
|
13
|
+
export const routes = [
|
|
14
|
+
...dashboardRoutes,
|
|
15
|
+
...agentRoutes,
|
|
16
|
+
...gitRoutes,
|
|
17
|
+
...serviceRoutes,
|
|
18
|
+
...shellRoutes,
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/routes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAY;IAC7B,GAAG,eAAe;IAClB,GAAG,WAAW;IACd,GAAG,SAAS;IACZ,GAAG,aAAa;IAChB,GAAG,WAAW;CACf,CAAC"}
|