@hienlh/ppm 0.1.0 → 0.1.2
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/assets/api-client-Bnf9LAt4.js +1 -0
- package/dist/web/assets/arrow-up-from-line-BXL5dtbG.js +1 -0
- package/dist/web/assets/button-BxijdhtM.js +1 -0
- package/dist/web/assets/chat-tab-BZopEuub.js +61 -0
- package/dist/web/assets/code-editor-hbllHzj7.js +2 -0
- package/dist/web/assets/createLucideIcon-Dy1wlrF7.js +1 -0
- package/dist/web/assets/dialog-RczsXsmw.js +45 -0
- package/dist/web/assets/diff-viewer-D6ixPlNB.js +4 -0
- package/dist/web/assets/dist-CSp7ir0r.js +46 -0
- package/dist/web/assets/external-link-WSiY-639.js +1 -0
- package/dist/web/assets/git-graph-DXMB_DoT.js +1 -0
- package/dist/web/assets/git-status-panel-D8ZUQrRF.js +1 -0
- package/dist/web/assets/index-DGSLw2GE.js +10 -0
- package/dist/web/assets/index-DYd_2slk.css +2 -0
- package/dist/web/assets/jsx-runtime-BnxRlLMJ.js +1 -0
- package/dist/web/assets/project-list-DWVXEimw.js +1 -0
- package/dist/web/assets/react-Uzd0zARU.js +1 -0
- package/dist/web/assets/refresh-cw-DtopuYJf.js +1 -0
- package/dist/web/assets/settings-tab-DJRzIAuP.js +1 -0
- package/dist/web/assets/terminal-tab-BrP-ENHg.css +1 -0
- package/dist/web/assets/terminal-tab-CbwaI-oq.js +36 -0
- package/dist/web/assets/trash-2-CHLebaNh.js +1 -0
- package/dist/web/assets/utils-Cgi2TYRi.js +1 -0
- package/dist/web/assets/x-BISR7bpK.js +1 -0
- package/dist/web/icon-192.svg +5 -0
- package/dist/web/icon-512.svg +5 -0
- package/dist/web/index.html +25 -0
- package/dist/web/manifest.webmanifest +1 -0
- package/dist/web/registerSW.js +1 -0
- package/dist/web/sw.js +1 -0
- package/dist/web/workbox-3e722498.js +1 -0
- package/package.json +2 -1
- package/src/server/index.ts +17 -3
- package/.claude/agent-memory/tester/MEMORY.md +0 -3
- package/.claude/agent-memory/tester/project-ppm-test-conventions.md +0 -32
- package/.github/workflows/release.yml +0 -46
- package/plans/260314-2009-ppm-implementation/phase-01-project-skeleton.md +0 -81
- package/plans/260314-2009-ppm-implementation/phase-02-backend-core.md +0 -148
- package/plans/260314-2009-ppm-implementation/phase-03-frontend-shell.md +0 -256
- package/plans/260314-2009-ppm-implementation/phase-04-file-explorer-editor.md +0 -120
- package/plans/260314-2009-ppm-implementation/phase-05-web-terminal.md +0 -174
- package/plans/260314-2009-ppm-implementation/phase-06-git-integration.md +0 -244
- package/plans/260314-2009-ppm-implementation/phase-07-ai-chat.md +0 -242
- package/plans/260314-2009-ppm-implementation/phase-08-cli-commands.md +0 -143
- package/plans/260314-2009-ppm-implementation/phase-09-pwa-build-deploy.md +0 -209
- package/plans/260314-2009-ppm-implementation/phase-10-testing.md +0 -311
- package/plans/260314-2009-ppm-implementation/plan.md +0 -202
- package/plans/260315-0356-project-scoped-api-refactor/phase-01-backend-project-router.md +0 -145
- package/plans/260315-0356-project-scoped-api-refactor/phase-02-frontend-api-migration.md +0 -107
- package/plans/260315-0356-project-scoped-api-refactor/phase-03-per-project-tabs.md +0 -100
- package/plans/260315-0356-project-scoped-api-refactor/phase-04-websocket-migration.md +0 -66
- package/plans/260315-0356-project-scoped-api-refactor/plan.md +0 -87
- package/plans/reports/brainstorm-260314-1938-final-techstack.md +0 -342
- package/plans/reports/docs-manager-260315-1314-documentation-creation.md +0 -386
- package/plans/reports/fullstack-developer-260314-2252-phase-02-backend-core.md +0 -57
- package/plans/reports/fullstack-developer-260314-2253-phase-03-frontend-shell.md +0 -70
- package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-api-terminal-ws.md +0 -49
- package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-explorer-editor-terminal.md +0 -52
- package/plans/reports/fullstack-developer-260314-2307-ai-chat-phase7.md +0 -58
- package/plans/reports/fullstack-developer-260314-2307-phase-06-git-integration.md +0 -33
- package/plans/reports/research-260314-1911-ppm-tech-stack.md +0 -318
- package/plans/reports/research-260314-1930-claude-code-integration.md +0 -293
- package/plans/reports/researcher-260314-2232-node-pty-bun-crash-analysis.md +0 -305
- package/plans/reports/researcher-260314-2232-ui-style.md +0 -942
- package/plans/reports/researcher-260315-0300-opcode-claude-interaction.md +0 -745
- package/plans/reports/researcher-260315-0303-opcode-deep-analysis.md +0 -742
- package/plans/reports/researcher-260315-0305-claude-agent-sdk-github-research.md +0 -423
- package/plans/reports/tester-260314-2053-initial-test-suite.md +0 -81
- package/repomix-output.xml +0 -23745
- package/tests/integration/api/chat-routes.test.ts +0 -95
- package/tests/integration/claude-agent-sdk-integration.test.ts +0 -228
- package/tests/integration/ws/chat-websocket.test.ts +0 -312
- package/tests/test-setup.ts +0 -5
- package/tests/unit/providers/claude-agent-sdk.test.ts +0 -339
- package/tests/unit/providers/mock-provider.test.ts +0 -143
- package/tests/unit/services/chat-service.test.ts +0 -100
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./createLucideIcon-Dy1wlrF7.js";var t=e(`external-link`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]);export{t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,t as n}from"./jsx-runtime-BnxRlLMJ.js";import{t as r}from"./button-BxijdhtM.js";import{t as i}from"./createLucideIcon-Dy1wlrF7.js";import{t as a}from"./arrow-up-from-line-BXL5dtbG.js";import{t as o}from"./external-link-WSiY-639.js";import{a as s,r as c,t as l}from"./api-client-Bnf9LAt4.js";import{t as u}from"./refresh-cw-DtopuYJf.js";import{t as d}from"./trash-2-CHLebaNh.js";import{a as f,i as p,n as m,o as h,t as g}from"./dialog-RczsXsmw.js";import{a as _,c as v,h as y,i as b,o as x,r as ee,s as S,u as te}from"./index-DGSLw2GE.js";var ne=i(`cherry`,[[`path`,{d:`M2 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z`,key:`cvxqlc`}],[`path`,{d:`M12 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z`,key:`1ostrc`}],[`path`,{d:`M7 14c3.22-2.91 4.29-8.75 5-12 1.66 2.38 4.94 9 5 12`,key:`hqx58h`}],[`path`,{d:`M22 9c-4.29 0-7.14-2.33-10-7 5.71 0 10 4.67 10 7Z`,key:`eykp1o`}]]),re=i(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]),C=i(`git-merge`,[[`circle`,{cx:`18`,cy:`18`,r:`3`,key:`1xkwt0`}],[`circle`,{cx:`6`,cy:`6`,r:`3`,key:`1lh9wr`}],[`path`,{d:`M6 21V9a9 9 0 0 0 9 9`,key:`7kw0sc`}]]),ie=i(`grip-vertical`,[[`circle`,{cx:`9`,cy:`12`,r:`1`,key:`1vctgf`}],[`circle`,{cx:`9`,cy:`5`,r:`1`,key:`hp0tcf`}],[`circle`,{cx:`9`,cy:`19`,r:`1`,key:`fkjjf6`}],[`circle`,{cx:`15`,cy:`12`,r:`1`,key:`1tmaij`}],[`circle`,{cx:`15`,cy:`5`,r:`1`,key:`19l28e`}],[`circle`,{cx:`15`,cy:`19`,r:`1`,key:`f4zoj3`}]]),ae=i(`rotate-ccw`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]),w=i(`tag`,[[`path`,{d:`M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z`,key:`vktsd0`}],[`circle`,{cx:`7.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`kqv944`}]]),T=e(t(),1),E=n(),D=[`#4fc3f7`,`#81c784`,`#ffb74d`,`#e57373`,`#ba68c8`,`#4dd0e1`,`#aed581`,`#ff8a65`,`#f06292`,`#7986cb`],O=32,k=20,oe=5;function A({metadata:e}){let t=e?.projectName,[n,i]=(0,T.useState)(null),[a,o]=(0,T.useState)(!0),[d,C]=(0,T.useState)(null),[A,j]=(0,T.useState)(!1),[M,N]=(0,T.useState)({type:null}),[P,F]=(0,T.useState)(``),[I,L]=(0,T.useState)(null),[R,z]=(0,T.useState)([]),[ce,B]=(0,T.useState)(!1),{openTab:V}=te(),H=(0,T.useCallback)(async()=>{if(t)try{o(!0),i(await l.get(`${c(t)}/git/graph?max=200`)),C(null)}catch(e){C(e instanceof Error?e.message:`Failed to fetch graph`)}finally{o(!1)}},[t]);(0,T.useEffect)(()=>{H()},[H]);let U=async(e,n)=>{if(t){j(!0);try{await l.post(`${c(t)}${e}`,n),await H()}catch(e){C(e instanceof Error?e.message:`Action failed`)}finally{j(!1)}}},W=e=>U(`/git/checkout`,{ref:e}),le=e=>U(`/git/cherry-pick`,{hash:e}),ue=e=>U(`/git/revert`,{hash:e}),de=e=>U(`/git/merge`,{source:e}),fe=e=>U(`/git/branch/delete`,{name:e}),pe=e=>U(`/git/push`,{branch:e}),G=async(e,t)=>{if(n?.branches.some(t=>t.name===e||t.name.endsWith(`/${e}`))){if(!window.confirm(`Branch "${e}" already exists.\nDelete it and recreate from this commit?`))return;await U(`/git/branch/delete`,{name:e})}await U(`/git/branch/create`,{name:e,from:t})},K=(e,t)=>U(`/git/tag`,{name:e,hash:t}),me=async e=>{if(t)try{let n=await l.get(`${c(t)}/git/pr-url?branch=${encodeURIComponent(e)}`);n.url&&window.open(n.url,`_blank`)}catch{}},q=e=>{navigator.clipboard.writeText(e)},he=async e=>{if(I?.hash===e.hash){L(null);return}L(e),B(!0);try{let n=e.parents[0]??``,r=n?`ref1=${encodeURIComponent(n)}&`:``,i=await l.get(`${c(t)}/git/diff-stat?${r}ref2=${encodeURIComponent(e.hash)}`);z(Array.isArray(i)?i:[])}catch(e){console.error(`diff-stat error:`,e),z([])}finally{B(!1)}},ge=e=>{let n=e.parents[0];V({type:`git-diff`,title:`Diff ${e.abbreviatedHash}`,closable:!0,metadata:{projectName:t,ref1:n??void 0,ref2:e.hash},projectId:t??null})},{laneMap:J,maxLane:_e}=(0,T.useMemo)(()=>{let e=new Map;if(!n)return{laneMap:e,maxLane:0};let t=0,r=new Map;for(let i of n.commits){let n=r.get(i.hash);n===void 0&&(n=t++),e.set(i.hash,n),r.delete(i.hash);for(let e=0;e<i.parents.length;e++){let a=i.parents[e];r.has(a)||r.set(a,e===0?n:t++)}}return{laneMap:e,maxLane:Math.max(t-1,0)}},[n]),Y=n?.branches.find(e=>e.current),ve=(0,T.useMemo)(()=>{let e=new Map;if(!n)return e;for(let t of n.branches){let n=e.get(t.commitHash)??[];n.push({name:t.name,type:`branch`}),e.set(t.commitHash,n)}for(let t of n.commits)for(let n of t.refs)if(n.startsWith(`tag: `)){let r=n.replace(`tag: `,``),i=e.get(t.hash)??[];i.push({name:r,type:`tag`}),e.set(t.hash,i)}return e},[n]),ye=(0,T.useMemo)(()=>{if(!n)return[];let e=[];for(let t=0;t<n.commits.length;t++){let r=n.commits[t],i=J.get(r.hash)??0,a=D[i%D.length];for(let o of r.parents){let s=n.commits.findIndex(e=>e.hash===o);if(s<0)continue;let c=J.get(o)??0,l=D[c%D.length],u=i*k+k/2,d=t*O+O/2,f=c*k+k/2,p=s*O+O/2,m,h=r.parents.indexOf(o)>0;if(u===f)m=`M ${u} ${d} L ${f} ${p}`;else if(h){let e=d+O;m=`M ${u} ${d} C ${u} ${e} ${f} ${d} ${f} ${e} L ${f} ${p}`}else{let e=p-O;m=`M ${u} ${d} L ${u} ${e} C ${u} ${p} ${f} ${e} ${f} ${p}`}let g=r.parents.indexOf(o)===0?a:l;e.push({d:m,color:g})}}return e},[n,J]);(_e+1)*k+k;let X=(n?.commits.length??0)*O,[Z,be]=(0,T.useState)((typeof window<`u`&&window.innerWidth<768?6:10)*k+k),Q=(0,T.useRef)(!1),$=(0,T.useCallback)(e=>{Q.current=!0;let t=Z,n=n=>{if(!Q.current)return;let r=`touches`in n?n.touches[0].clientX:n.clientX;be(Math.max(40,t+r-e))},r=()=>{Q.current=!1,window.removeEventListener(`mousemove`,n),window.removeEventListener(`mouseup`,r),window.removeEventListener(`touchmove`,n),window.removeEventListener(`touchend`,r)};window.addEventListener(`mousemove`,n),window.addEventListener(`mouseup`,r),window.addEventListener(`touchmove`,n,{passive:!1}),window.addEventListener(`touchend`,r)},[Z]),xe=(0,T.useCallback)(e=>{e.preventDefault(),$(e.clientX)},[$]),Se=(0,T.useCallback)(e=>{$(e.touches[0].clientX)},[$]);if(!t)return(0,E.jsx)(`div`,{className:`flex items-center justify-center h-full text-muted-foreground text-sm`,children:`No project selected.`});if(a&&!n)return(0,E.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,E.jsx)(s,{className:`size-5 animate-spin`}),(0,E.jsx)(`span`,{className:`text-sm`,children:`Loading git graph...`})]});if(d&&!n)return(0,E.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-2 text-destructive text-sm`,children:[(0,E.jsx)(`p`,{children:d}),(0,E.jsx)(r,{variant:`outline`,size:`sm`,onClick:H,children:`Retry`})]});function Ce(e){let t=new Date(e),n=new Date().getTime()-t.getTime(),r=Math.floor(n/6e4);if(r<1)return`just now`;if(r<60)return`${r}m ago`;let i=Math.floor(r/60);if(i<24)return`${i}h ago`;let a=Math.floor(i/24);if(a<30)return`${a}d ago`;let o=Math.floor(a/30);return o<12?`${o}mo ago`:`${Math.floor(o/12)}y ago`}return(0,E.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,E.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-2 border-b`,children:[(0,E.jsxs)(`span`,{className:`text-sm font-medium`,children:[`Git Graph`,Y?` - ${Y.name}`:``]}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:H,disabled:A,children:(0,E.jsx)(u,{className:a?`animate-spin`:``})})]}),d&&(0,E.jsx)(`div`,{className:`px-3 py-1.5 text-xs text-destructive bg-destructive/10`,children:d}),(0,E.jsx)(`div`,{className:`flex-1 overflow-y-auto overflow-x-auto md:overflow-x-hidden`,children:(0,E.jsxs)(`div`,{className:`flex min-w-max md:min-w-0`,style:{height:`${X}px`},children:[(0,E.jsxs)(`div`,{className:`sticky left-0 z-10 shrink-0 bg-background`,style:{width:`${Z}px`},children:[(0,E.jsxs)(`svg`,{width:Z,height:X,children:[ye.map((e,t)=>(0,E.jsx)(`path`,{d:e.d,stroke:e.color,strokeWidth:2,fill:`none`},t)),n?.commits.map((e,t)=>{let n=J.get(e.hash)??0,r=n*k+k/2,i=t*O+O/2,a=D[n%D.length];return(0,E.jsx)(`circle`,{cx:r,cy:i,r:oe,fill:a,stroke:`#0f1419`,strokeWidth:2},e.hash)})]}),(0,E.jsx)(`div`,{className:`absolute top-0 right-0 w-3 md:w-2 h-full cursor-col-resize hover:bg-primary/20 flex items-center justify-center bg-primary/10 md:bg-transparent`,onMouseDown:xe,onTouchStart:Se,children:(0,E.jsx)(ie,{className:`size-3 text-muted-foreground md:opacity-0 md:hover:opacity-100`})})]}),(0,E.jsx)(`div`,{className:`flex-1 min-w-[400px]`,children:n?.commits.map((e,t)=>{let n=D[(J.get(e.hash)??0)%D.length],r=ve.get(e.hash)??[],i=r.filter(e=>e.type===`branch`),a=r.filter(e=>e.type===`tag`);return(0,E.jsxs)(b,{children:[(0,E.jsx)(v,{asChild:!0,children:(0,E.jsx)(`div`,{className:`flex items-center hover:bg-muted/50 cursor-pointer text-sm border-b border-border/30 ${I?.hash===e.hash?`bg-primary/10`:``}`,style:{height:`${O}px`},onClick:()=>he(e),children:(0,E.jsxs)(`div`,{className:`flex items-center gap-2 flex-1 min-w-0 px-2`,children:[(0,E.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground w-14 shrink-0`,children:e.abbreviatedHash}),i.map(e=>(0,E.jsx)(se,{label:e,color:n,currentBranch:Y,onCheckout:W,onMerge:de,onPush:pe,onCreatePr:me,onDelete:fe},`branch-${e.name}`)),a.map(e=>(0,E.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium shrink-0 bg-amber-500/20 text-amber-500 border border-amber-500/30`,children:[(0,E.jsx)(w,{className:`size-2.5`}),e.name]},`tag-${e.name}`)),(0,E.jsx)(`span`,{className:`flex-1 truncate`,children:e.subject}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground shrink-0 hidden sm:inline`,children:e.authorName}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground shrink-0 w-14 text-right`,children:Ce(e.authorDate)})]})})}),(0,E.jsxs)(_,{children:[(0,E.jsx)(x,{onClick:()=>W(e.hash),children:`Checkout`}),(0,E.jsxs)(x,{onClick:()=>{N({type:`branch`,hash:e.hash}),F(``)},children:[(0,E.jsx)(y,{className:`size-3`}),`Create Branch...`]}),(0,E.jsx)(S,{}),(0,E.jsxs)(x,{onClick:()=>le(e.hash),children:[(0,E.jsx)(ne,{className:`size-3`}),`Cherry Pick`]}),(0,E.jsxs)(x,{onClick:()=>ue(e.hash),children:[(0,E.jsx)(ae,{className:`size-3`}),`Revert`]}),(0,E.jsxs)(x,{onClick:()=>{N({type:`tag`,hash:e.hash}),F(``)},children:[(0,E.jsx)(w,{className:`size-3`}),`Create Tag...`]}),(0,E.jsx)(S,{}),(0,E.jsx)(x,{onClick:()=>ge(e),children:`View Diff`}),(0,E.jsxs)(x,{onClick:()=>q(e.hash),children:[(0,E.jsx)(re,{className:`size-3`}),`Copy Hash`]})]})]},e.hash)})})]})}),I&&(0,E.jsxs)(`div`,{className:`border-t bg-muted/30 max-h-[40%] overflow-auto`,children:[(0,E.jsxs)(`div`,{className:`px-3 py-2 border-b flex items-center justify-between`,children:[(0,E.jsxs)(`span`,{className:`text-sm font-medium truncate`,children:[I.abbreviatedHash,` — `,I.subject]}),(0,E.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:()=>L(null),children:`✕`})]}),(0,E.jsxs)(`div`,{className:`px-3 py-2 text-xs space-y-1`,children:[(0,E.jsxs)(`div`,{className:`flex gap-4`,children:[(0,E.jsx)(`span`,{className:`text-muted-foreground`,children:`Author`}),(0,E.jsxs)(`span`,{children:[I.authorName,` <`,I.authorEmail,`>`]})]}),(0,E.jsxs)(`div`,{className:`flex gap-4`,children:[(0,E.jsx)(`span`,{className:`text-muted-foreground`,children:`Date`}),(0,E.jsx)(`span`,{children:new Date(I.authorDate).toLocaleString()})]}),(0,E.jsxs)(`div`,{className:`flex gap-4`,children:[(0,E.jsx)(`span`,{className:`text-muted-foreground`,children:`Hash`}),(0,E.jsx)(`span`,{className:`font-mono cursor-pointer hover:text-primary`,onClick:()=>q(I.hash),children:I.hash})]}),I.parents.length>0&&(0,E.jsxs)(`div`,{className:`flex gap-4`,children:[(0,E.jsx)(`span`,{className:`text-muted-foreground`,children:`Parents`}),(0,E.jsx)(`span`,{className:`font-mono`,children:I.parents.map(e=>e.slice(0,7)).join(`, `)})]}),I.body&&(0,E.jsx)(`div`,{className:`mt-2 p-2 bg-background rounded text-xs whitespace-pre-wrap`,children:I.body})]}),(0,E.jsxs)(`div`,{className:`px-3 py-1 border-t`,children:[(0,E.jsx)(`div`,{className:`text-xs text-muted-foreground py-1`,children:ce?`Loading files...`:`${R.length} file${R.length===1?``:`s`} changed`}),R.map(e=>(0,E.jsxs)(`div`,{className:`flex items-center gap-2 py-0.5 text-xs hover:bg-muted/50 rounded px-1 cursor-pointer`,onClick:()=>V({type:`git-diff`,title:`Diff ${e.path.split(`/`).pop()}`,closable:!0,metadata:{projectName:t,ref1:I.parents[0]??void 0,ref2:I.hash,filePath:e.path},projectId:t??null}),children:[(0,E.jsx)(`span`,{className:`flex-1 truncate font-mono`,children:e.path}),e.additions>0&&(0,E.jsxs)(`span`,{className:`text-green-500`,children:[`+`,e.additions]}),e.deletions>0&&(0,E.jsxs)(`span`,{className:`text-red-500`,children:[`-`,e.deletions]})]},e.path))]})]}),(0,E.jsx)(g,{open:M.type!==null,onOpenChange:e=>{e||N({type:null})},children:(0,E.jsxs)(m,{children:[(0,E.jsx)(f,{children:(0,E.jsx)(h,{children:M.type===`branch`?`Create Branch`:`Create Tag`})}),(0,E.jsx)(ee,{placeholder:M.type===`branch`?`Branch name`:`Tag name`,value:P,onChange:e=>F(e.target.value),onKeyDown:e=>{e.key===`Enter`&&P.trim()&&(M.type===`branch`?G(P.trim(),M.hash):K(P.trim(),M.hash),N({type:null}))},autoFocus:!0}),(0,E.jsxs)(p,{children:[(0,E.jsx)(r,{variant:`outline`,onClick:()=>N({type:null}),children:`Cancel`}),(0,E.jsx)(r,{disabled:!P.trim(),onClick:()=>{M.type===`branch`?G(P.trim(),M.hash):K(P.trim(),M.hash),N({type:null})},children:`Create`})]})]})})]})}function se({label:e,color:t,currentBranch:n,onCheckout:r,onMerge:i,onPush:s,onCreatePr:c,onDelete:l}){return(0,E.jsxs)(b,{children:[(0,E.jsx)(v,{asChild:!0,children:(0,E.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium shrink-0 cursor-context-menu`,style:{backgroundColor:`${t}30`,color:t,border:`1px solid ${t}50`},children:[(0,E.jsx)(y,{className:`size-2.5`}),e.name]})}),(0,E.jsxs)(_,{children:[(0,E.jsx)(x,{onClick:()=>r(e.name),children:`Checkout`}),(0,E.jsxs)(x,{onClick:()=>i(e.name),disabled:e.name===n?.name,children:[(0,E.jsx)(C,{className:`size-3`}),`Merge into current`]}),(0,E.jsx)(S,{}),(0,E.jsxs)(x,{onClick:()=>s(e.name),children:[(0,E.jsx)(a,{className:`size-3`}),`Push`]}),(0,E.jsxs)(x,{onClick:()=>c(e.name),children:[(0,E.jsx)(o,{className:`size-3`}),`Create PR`]}),(0,E.jsx)(S,{}),(0,E.jsxs)(x,{variant:`destructive`,onClick:()=>l(e.name),disabled:e.name===n?.name,children:[(0,E.jsx)(d,{className:`size-3`}),`Delete`]})]})]})}export{A as GitGraph};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,t as n}from"./jsx-runtime-BnxRlLMJ.js";import{t as r}from"./button-BxijdhtM.js";import{t as i}from"./createLucideIcon-Dy1wlrF7.js";import{t as a}from"./arrow-up-from-line-BXL5dtbG.js";import{a as o,r as s,t as c}from"./api-client-Bnf9LAt4.js";import{t as l}from"./refresh-cw-DtopuYJf.js";import{a as u,i as d,n as f,o as p,r as m,t as h}from"./dialog-RczsXsmw.js";import{C as g,d as _,p as v,u as y,w as b}from"./index-DGSLw2GE.js";var x=i(`arrow-down-to-line`,[[`path`,{d:`M12 17V3`,key:`1cwfxf`}],[`path`,{d:`m6 11 6 6 6-6`,key:`12ii2o`}],[`path`,{d:`M19 21H5`,key:`150jfl`}]]),S=i(`folder-tree`,[[`path`,{d:`M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z`,key:`hod4my`}],[`path`,{d:`M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z`,key:`w4yl2u`}],[`path`,{d:`M3 5a2 2 0 0 0 2 2h3`,key:`f2jnh7`}],[`path`,{d:`M3 3v13a2 2 0 0 0 2 2h3`,key:`k8epm1`}]]),C=i(`list`,[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]),w=i(`minus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}]]),T=i(`undo-2`,[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]),E=e(t(),1),D=n(),O={M:`text-yellow-500`,A:`text-green-500`,D:`text-red-500`,R:`text-blue-500`,C:`text-purple-500`,"?":`text-gray-400`};function k(e){let t=[];for(let n of e){let e=n.path.split(`/`),r=t;for(let t=0;t<e.length;t++){let i=e[t],a=e.slice(0,t+1).join(`/`),o=t===e.length-1,s=r.find(e=>e.name===i);s||(s={name:i,fullPath:a,file:o?n:void 0,children:[]},r.push(s)),o&&(s.file=n),r=s.children}}return t}function A(e){let t=[];e.file&&t.push(e.file);for(let n of e.children)t.push(...A(n));return t}function j({metadata:e,tabId:t}){let n=e?.projectName,[i,g]=(0,E.useState)(null),[b,T]=(0,E.useState)(!0),[O,k]=(0,E.useState)(null),[A,j]=(0,E.useState)(``),[M,P]=(0,E.useState)(!1),[F,I]=(0,E.useState)(null),{openTab:L,updateTab:R}=y(),z=e?.viewMode===`tree`?`tree`:`flat`,B=n=>{t&&R(t,{metadata:{...e,viewMode:n}})},V=(0,E.useCallback)(async()=>{if(n)try{T(!0),g(await c.get(`${s(n)}/git/status`)),k(null)}catch(e){k(e instanceof Error?e.message:`Failed to fetch status`)}finally{T(!1)}},[n]);(0,E.useEffect)(()=>{V()},[V]);let H=async e=>{if(n){P(!0);try{await c.post(`${s(n)}/git/stage`,{files:e}),await V()}catch(e){k(e instanceof Error?e.message:`Stage failed`)}finally{P(!1)}}},U=async e=>{if(n){P(!0);try{await c.post(`${s(n)}/git/unstage`,{files:e}),await V()}catch(e){k(e instanceof Error?e.message:`Unstage failed`)}finally{P(!1)}}},W=async e=>{if(n){P(!0);try{await c.post(`${s(n)}/git/discard`,{files:e}),await V()}catch(e){k(e instanceof Error?e.message:`Discard failed`)}finally{P(!1)}}},G=async()=>{F&&(await W(F.files),I(null))},K=async()=>{if(!(!n||!A.trim()||!i?.staged.length)){P(!0);try{await c.post(`${s(n)}/git/commit`,{message:A.trim()}),j(``),await V()}catch(e){k(e instanceof Error?e.message:`Commit failed`)}finally{P(!1)}}},q=async()=>{if(n){P(!0);try{await c.post(`${s(n)}/git/push`,{}),await V()}catch(e){k(e instanceof Error?e.message:`Push failed`)}finally{P(!1)}}},J=async()=>{if(n){P(!0);try{await c.post(`${s(n)}/git/pull`,{}),await V()}catch(e){k(e instanceof Error?e.message:`Pull failed`)}finally{P(!1)}}},Y=e=>{L({type:`git-diff`,title:e.path.split(`/`).pop()??e.path,closable:!0,metadata:{projectName:n,filePath:e.path},projectId:n??null})},X=(0,E.useMemo)(()=>[...i?.unstaged??[],...i?.untracked.map(e=>({path:e,status:`?`}))??[]],[i]);return n?b&&!i?(0,D.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,D.jsx)(o,{className:`size-5 animate-spin`}),(0,D.jsx)(`span`,{className:`text-sm`,children:`Loading git status...`})]}):O&&!i?(0,D.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-2 text-destructive text-sm`,children:[(0,D.jsx)(`p`,{children:O}),(0,D.jsx)(r,{variant:`outline`,size:`sm`,onClick:V,children:`Retry`})]}):(0,D.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,D.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-2 border-b shrink-0`,children:[(0,D.jsx)(`span`,{className:`text-sm font-medium`,children:i?.current?`On: ${i.current}`:`Git Status`}),(0,D.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,D.jsx)(r,{variant:z===`flat`?`secondary`:`ghost`,size:`icon-xs`,onClick:()=>B(`flat`),title:`Flat view`,children:(0,D.jsx)(C,{className:`size-3.5`})}),(0,D.jsx)(r,{variant:z===`tree`?`secondary`:`ghost`,size:`icon-xs`,onClick:()=>B(`tree`),title:`Tree view`,children:(0,D.jsx)(S,{className:`size-3.5`})}),(0,D.jsx)(r,{variant:`ghost`,size:`icon-xs`,onClick:V,disabled:M,children:(0,D.jsx)(l,{className:b?`animate-spin`:``})})]})]}),O&&(0,D.jsx)(`div`,{className:`px-3 py-1.5 text-xs text-destructive bg-destructive/10 shrink-0`,children:O}),(0,D.jsx)(_,{className:`flex-1 overflow-hidden`,children:(0,D.jsxs)(`div`,{className:`p-2 space-y-3 overflow-hidden`,children:[(0,D.jsx)(N,{title:`Staged Changes`,count:i?.staged.length??0,files:i?.staged??[],viewMode:z,actionIcon:(0,D.jsx)(w,{className:`size-3.5`}),actionTitle:`Unstage`,onAction:e=>U([e.path]),onActionAll:i?.staged.length?()=>U(i.staged.map(e=>e.path)):void 0,actionAllLabel:`Unstage All`,onFolderAction:e=>U(e.map(e=>e.path)),onClickFile:Y,disabled:M}),(0,D.jsx)(N,{title:`Changes`,count:X.length,files:X,viewMode:z,actionIcon:(0,D.jsx)(v,{className:`size-3.5`}),actionTitle:`Stage`,onAction:e=>H([e.path]),onActionAll:X.length?()=>H(X.map(e=>e.path)):void 0,actionAllLabel:`Stage All`,onFolderAction:e=>H(e.map(e=>e.path)),onClickFile:Y,disabled:M,showRevert:!0,onRevert:e=>I({label:e.path,files:[e.path]}),onFolderRevert:(e,t)=>I({label:`${t}/ (${e.length} files)`,files:e.map(e=>e.path)})})]})}),(0,D.jsxs)(`div`,{className:`border-t p-2 space-y-2 shrink-0`,children:[(0,D.jsx)(`textarea`,{className:`w-full h-16 px-2 py-1.5 text-sm bg-muted/50 border rounded resize-none focus:outline-none focus:ring-1 focus:ring-ring`,placeholder:`Commit message...`,value:A,onChange:e=>j(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&K()}}),(0,D.jsx)(r,{size:`sm`,className:`w-full`,disabled:M||!A.trim()||!i?.staged.length,onClick:K,children:M?(0,D.jsx)(o,{className:`size-3 animate-spin`}):`Commit (${i?.staged.length??0})`}),(0,D.jsxs)(`div`,{className:`flex gap-2`,children:[(0,D.jsxs)(r,{variant:`outline`,size:`sm`,className:`flex-1`,disabled:M,onClick:q,children:[(0,D.jsx)(a,{className:`size-3`}),`Push`]}),(0,D.jsxs)(r,{variant:`outline`,size:`sm`,className:`flex-1`,disabled:M,onClick:J,children:[(0,D.jsx)(x,{className:`size-3`}),`Pull`]})]})]}),(0,D.jsx)(h,{open:!!F,onOpenChange:e=>!e&&I(null),children:(0,D.jsxs)(f,{showCloseButton:!1,children:[(0,D.jsxs)(u,{children:[(0,D.jsx)(p,{children:`Discard Changes`}),(0,D.jsxs)(m,{children:[`Are you sure you want to discard all changes to`,` `,(0,D.jsx)(`code`,{className:`px-1 py-0.5 rounded bg-muted text-sm font-mono`,children:F?.label}),`? This action cannot be undone.`]})]}),(0,D.jsxs)(d,{children:[(0,D.jsx)(r,{variant:`outline`,onClick:()=>I(null),children:`Cancel`}),(0,D.jsx)(r,{variant:`destructive`,onClick:G,disabled:M,children:M?(0,D.jsx)(o,{className:`size-3 animate-spin`}):`Discard`})]})]})})]}):(0,D.jsx)(`div`,{className:`flex items-center justify-center h-full text-muted-foreground text-sm`,children:`No project selected.`})}function M({showRevert:e,onRevert:t,onAction:n,actionIcon:r,actionTitle:i,disabled:a}){return(0,D.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0 ml-1`,children:[e&&t&&(0,D.jsx)(`button`,{type:`button`,className:`flex items-center justify-center size-7 rounded border border-border/60 bg-muted/60 text-muted-foreground hover:bg-destructive/15 hover:text-destructive hover:border-destructive/40 active:scale-95 transition-colors`,onClick:e=>{e.stopPropagation(),t()},disabled:a,title:`Discard changes`,children:(0,D.jsx)(T,{className:`size-3.5`})}),(0,D.jsx)(`button`,{type:`button`,className:`flex items-center justify-center size-7 rounded border border-border/60 bg-muted/60 text-muted-foreground hover:bg-accent hover:text-accent-foreground active:scale-95 transition-colors`,onClick:e=>{e.stopPropagation(),n()},disabled:a,title:i,children:r})]})}function N({title:e,count:t,files:n,viewMode:i,actionIcon:a,actionTitle:o,onAction:s,onActionAll:c,actionAllLabel:l,onFolderAction:u,onClickFile:d,disabled:f,showRevert:p,onRevert:m,onFolderRevert:h}){return(0,D.jsxs)(`div`,{children:[(0,D.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,D.jsxs)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase`,children:[e,` (`,t,`)`]}),c&&t>0&&(0,D.jsx)(r,{variant:`ghost`,size:`xs`,onClick:c,disabled:f,title:l,children:l})]}),n.length===0?(0,D.jsx)(`p`,{className:`text-xs text-muted-foreground px-1`,children:`No changes`}):i===`flat`?(0,D.jsx)(`div`,{className:`divide-y divide-border/40 w-full overflow-hidden`,children:n.map(e=>(0,D.jsx)(P,{file:e,actionIcon:a,actionTitle:o,onAction:s,onClickFile:d,disabled:f,showRevert:p,onRevert:m},e.path))}):(0,D.jsx)(F,{files:n,actionIcon:a,actionTitle:o,onAction:s,onFolderAction:u,onClickFile:d,disabled:f,showRevert:p,onRevert:m,onFolderRevert:h})]})}function P({file:e,actionIcon:t,actionTitle:n,onAction:r,onClickFile:i,disabled:a,showRevert:o,onRevert:s,displayName:c}){return(0,D.jsxs)(`div`,{className:`flex items-center gap-1 hover:bg-muted/50 rounded px-1 py-1 w-full min-w-0`,children:[(0,D.jsx)(`span`,{className:`text-xs font-mono w-4 text-center shrink-0 ${O[e.status]??``}`,children:e.status}),(0,D.jsx)(`button`,{type:`button`,className:`flex-1 text-left text-xs font-mono truncate hover:underline min-w-0`,onClick:()=>i(e),title:e.path,children:c??e.path}),(0,D.jsx)(M,{showRevert:o,onRevert:s?()=>s(e):void 0,onAction:()=>r(e),actionIcon:t,actionTitle:n,disabled:a})]})}function F({files:e,actionIcon:t,actionTitle:n,onAction:r,onFolderAction:i,onClickFile:a,disabled:o,showRevert:s,onRevert:c,onFolderRevert:l}){let u=(0,E.useMemo)(()=>k(e),[e]);return(0,D.jsx)(`div`,{children:u.map((e,d)=>(0,D.jsx)(I,{node:e,depth:0,isLast:d===u.length-1,actionIcon:t,actionTitle:n,onAction:r,onFolderAction:i,onClickFile:a,disabled:o,showRevert:s,onRevert:c,onFolderRevert:l},e.fullPath))})}function I({node:e,depth:t,isLast:n,actionIcon:r,actionTitle:i,onAction:a,onFolderAction:o,onClickFile:s,disabled:c,showRevert:l,onRevert:u,onFolderRevert:d}){let[f,p]=(0,E.useState)(!0),m=e.children.length>0&&!e.file;if(e.file)return(0,D.jsxs)(`div`,{className:`relative overflow-hidden border-b border-border/30`,style:{paddingLeft:t*16},children:[t>0&&(0,D.jsx)(`div`,{className:`absolute top-0 bottom-0 border-l border-border/30`,style:{left:t*16-8}}),(0,D.jsx)(P,{file:e.file,displayName:e.name,actionIcon:r,actionTitle:i,onAction:a,onClickFile:s,disabled:c,showRevert:l,onRevert:u})]});if(m){let m=A(e);return(0,D.jsxs)(`div`,{className:`relative overflow-hidden`,children:[t>0&&(0,D.jsx)(`div`,{className:`absolute top-0 border-l border-border/30`,style:{left:t*16-8,bottom:n?`50%`:0}}),(0,D.jsxs)(`div`,{className:`flex items-center hover:bg-muted/50 rounded py-1 pr-1 border-b border-border/30`,style:{paddingLeft:t*16+4},children:[(0,D.jsxs)(`button`,{type:`button`,className:`flex items-center gap-1 flex-1 min-w-0 text-xs font-mono text-muted-foreground`,onClick:()=>p(!f),children:[f?(0,D.jsx)(b,{className:`size-3.5 shrink-0`}):(0,D.jsx)(g,{className:`size-3.5 shrink-0`}),(0,D.jsx)(`span`,{className:`truncate font-semibold`,children:e.name}),(0,D.jsxs)(`span`,{className:`text-[10px] opacity-60 shrink-0`,children:[`(`,m.length,`)`]})]}),(0,D.jsx)(M,{showRevert:l,onRevert:d?()=>d(m,e.fullPath):void 0,onAction:()=>o?.(m),actionIcon:r,actionTitle:`${i} ${e.name}/`,disabled:c})]}),f&&(0,D.jsxs)(`div`,{className:`relative`,children:[(0,D.jsx)(`div`,{className:`absolute top-0 bottom-0 border-l border-border/30`,style:{left:t*16+8}}),e.children.map((n,f)=>(0,D.jsx)(I,{node:n,depth:t+1,isLast:f===e.children.length-1,actionIcon:r,actionTitle:i,onAction:a,onFolderAction:o,onClickFile:s,disabled:c,showRevert:l,onRevert:u,onFolderRevert:d},n.fullPath))]})]})}return null}export{j as GitStatusPanel};
|