@hienlh/ppm 0.2.0 → 0.2.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/CHANGELOG.md +53 -0
- package/dist/web/assets/{button-KIZetva8.js → button-CvHWF07y.js} +1 -1
- package/dist/web/assets/{chat-tab-D7dR7kbZ.js → chat-tab-C4ovA2w4.js} +3 -3
- package/dist/web/assets/{code-editor-r8P6Gk4M.js → code-editor-BgiyQO-M.js} +1 -1
- package/dist/web/assets/{dialog-D8ulRTfX.js → dialog-f3IZM-6v.js} +1 -1
- package/dist/web/assets/{diff-viewer-vSvrem_i.js → diff-viewer-8_asmBRZ.js} +1 -1
- package/dist/web/assets/{dist-C4W3AGh3.js → dist-CCBctnax.js} +1 -1
- package/dist/web/assets/{git-graph-Cn-s1k0-.js → git-graph-BiyTIbCz.js} +1 -1
- package/dist/web/assets/{git-status-panel-QjAQzNAi.js → git-status-panel-BifyO31N.js} +1 -1
- package/dist/web/assets/index-DILaVO6p.css +2 -0
- package/dist/web/assets/index-DasstYgw.js +11 -0
- package/dist/web/assets/project-list-C7L3hZct.js +1 -0
- package/dist/web/assets/settings-tab-Cn5Ja0_J.js +1 -0
- package/dist/web/assets/{terminal-tab-DDf6S-Tu.js → terminal-tab-CyjhG4Ao.js} +1 -1
- package/dist/web/index.html +8 -8
- package/dist/web/sw.js +1 -1
- package/package.json +3 -2
- package/src/cli/commands/init.ts +11 -1
- package/src/cli/commands/logs.ts +58 -0
- package/src/cli/commands/report.ts +60 -0
- package/src/cli/commands/status.ts +31 -22
- package/src/cli/commands/stop.ts +37 -29
- package/src/index.ts +21 -1
- package/src/server/index.ts +147 -65
- package/src/types/config.ts +2 -0
- package/src/version.ts +7 -0
- package/src/web/app.tsx +8 -0
- package/src/web/components/auth/login-screen.tsx +8 -1
- package/src/web/components/layout/sidebar.tsx +15 -0
- package/src/web/components/ui/sonner.tsx +9 -6
- package/src/web/hooks/use-health-check.ts +95 -0
- package/src/web/stores/settings-store.ts +19 -0
- package/src/web/stores/tab-store.ts +28 -8
- package/dist/web/assets/index-DUBI96T5.css +0 -2
- package/dist/web/assets/index-nk1dAWff.js +0 -10
- package/dist/web/assets/project-list-DqiatpaH.js +0 -1
- package/dist/web/assets/settings-tab-iCGeFFdt.js +0 -1
- /package/dist/web/assets/{dist-PA84y4Ga.js → dist-B6sG2GPc.js} +0 -0
- /package/dist/web/assets/{react-BSLFEYu8.js → react-gOPBns57.js} +0 -0
- /package/dist/web/assets/{utils-DpJF9mAi.js → utils-61GRB9Cb.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-BFALxl05.js";import{t as i}from"./button-CvHWF07y.js";import{a,i as o,n as s,o as c,t as l}from"./dialog-f3IZM-6v.js";import{t as u}from"./utils-61GRB9Cb.js";import{t as d}from"./api-client-BgVufYKf.js";import{_ as f,b as p,c as m,h,l as g,n as _,v}from"./index-DasstYgw.js";var y=t(`circle`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),b=t(`folder-git-2`,[[`path`,{d:`M18 19a5 5 0 0 1-5-5v8`,key:`sz5oeg`}],[`path`,{d:`M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5`,key:`1w6njk`}],[`circle`,{cx:`13`,cy:`12`,r:`2`,key:`1j92g6`}],[`circle`,{cx:`20`,cy:`19`,r:`2`,key:`1obnsp`}]]),x=e(n(),1),S=r();function C({value:e,onChange:t,onSelect:n,placeholder:r,autoFocus:i}){let[a,o]=(0,x.useState)([]),[s,c]=(0,x.useState)([]),[l,u]=(0,x.useState)(!1),[p,m]=(0,x.useState)(0),[h,g]=(0,x.useState)(!1),v=(0,x.useRef)(null),y=(0,x.useRef)(!1);(0,x.useEffect)(()=>{y.current||(y.current=!0,g(!0),d.get(`/api/projects/suggest-dirs`).then(e=>{o(e),c(e.slice(0,50)),u(e.length>0)}).catch(()=>o([])).finally(()=>g(!1)))},[]),(0,x.useEffect)(()=>{if(a.length===0)return;let t=e.trim().toLowerCase();c(t?a.filter(e=>e.path.toLowerCase().includes(t)||e.name.toLowerCase().includes(t)).slice(0,50):a.slice(0,50)),m(0)},[e,a]),(0,x.useEffect)(()=>{let e=v.current;e&&e.children[p]?.scrollIntoView({block:`nearest`})},[p]);let C=(0,x.useCallback)(e=>{t(e.path),n?.(e),u(!1)},[t,n]),w=(0,x.useCallback)(e=>{if(!(!l||s.length===0))switch(e.key){case`ArrowDown`:e.preventDefault(),m(e=>e<s.length-1?e+1:0);break;case`ArrowUp`:e.preventDefault(),m(e=>e>0?e-1:s.length-1);break;case`Tab`:case`Enter`:s[p]&&(e.preventDefault(),C(s[p]));break;case`Escape`:e.preventDefault(),u(!1);break}},[l,s,p,C]);return(0,S.jsxs)(`div`,{className:`relative`,children:[(0,S.jsxs)(`div`,{className:`relative`,children:[(0,S.jsx)(_,{placeholder:r??`/home/user/my-project`,value:e,onChange:e=>t(e.target.value),onKeyDown:w,onFocus:()=>s.length>0&&u(!0),onBlur:()=>setTimeout(()=>u(!1),200),autoFocus:i}),h&&(0,S.jsx)(f,{className:`absolute right-2 top-1/2 -translate-y-1/2 size-4 text-text-subtle animate-spin`})]}),l&&s.length>0&&(0,S.jsx)(`div`,{className:`absolute z-50 left-0 right-0 top-full mt-1 max-h-48 overflow-y-auto rounded-md border border-border bg-surface shadow-lg`,children:(0,S.jsx)(`div`,{ref:v,className:`py-1`,children:s.map((e,t)=>(0,S.jsxs)(`button`,{type:`button`,className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-sm transition-colors ${t===p?`bg-primary/10 text-primary`:`hover:bg-surface-hover text-text-primary`}`,onMouseEnter:()=>m(t),onMouseDown:t=>{t.preventDefault(),C(e)},children:[(0,S.jsx)(b,{className:`size-4 text-green-500 shrink-0`}),(0,S.jsxs)(`div`,{className:`min-w-0 flex-1 flex items-baseline gap-2`,children:[(0,S.jsx)(`span`,{className:`font-medium`,children:e.name}),(0,S.jsx)(`span`,{className:`text-xs text-text-subtle truncate`,children:e.path})]})]},e.path))})})]})}function w(){let{projects:e,activeProject:t,setActiveProject:n,fetchProjects:r,loading:f,error:b}=m(),w=g(e=>e.openTab),[T,E]=(0,x.useState)(!1),[D,O]=(0,x.useState)(``),[k,A]=(0,x.useState)(``),[j,M]=(0,x.useState)(``);(0,x.useEffect)(()=>{r()},[r]);function N(e){n(e)}function P(e){n(e),w({type:`terminal`,title:`Terminal - ${e.name}`,metadata:{projectName:e.name},projectId:e.name,closable:!0})}let F=(0,x.useCallback)(async()=>{if(D.trim()){M(``);try{await d.post(`/api/projects`,{path:D.trim(),name:k.trim()||void 0}),await r(),E(!1),O(``),A(``)}catch(e){M(e instanceof Error?e.message:`Failed to add project`)}}},[D,k,r]);return b?(0,S.jsx)(`div`,{className:`flex items-center justify-center h-full p-4`,children:(0,S.jsx)(`p`,{className:`text-error text-sm`,children:b})}):(0,S.jsxs)(`div`,{className:`h-full p-4 space-y-4 overflow-auto`,children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,S.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Projects`}),(0,S.jsxs)(i,{variant:`outline`,size:`sm`,onClick:()=>E(!0),className:`gap-1.5`,children:[(0,S.jsx)(h,{className:`size-4`}),`Add Project`]})]}),f&&(0,S.jsx)(`p`,{className:`text-text-secondary text-sm`,children:`Loading projects...`}),!f&&e.length===0&&(0,S.jsxs)(`div`,{className:`text-center py-8 space-y-2`,children:[(0,S.jsx)(p,{className:`size-10 mx-auto text-text-subtle`}),(0,S.jsx)(`p`,{className:`text-text-secondary text-sm`,children:`No projects registered`}),(0,S.jsxs)(`p`,{className:`text-text-subtle text-xs`,children:[`Click "Add Project" or use `,(0,S.jsx)(`code`,{className:`font-mono bg-surface-elevated px-1 py-0.5 rounded`,children:`ppm projects add <path>`})]})]}),(0,S.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2 lg:grid-cols-3`,children:e.map(e=>(0,S.jsx)(`button`,{onClick:()=>N(e),onDoubleClick:()=>P(e),className:u(`text-left p-4 rounded-lg border transition-colors`,`min-h-[44px]`,t?.name===e.name?`bg-surface border-primary`:`bg-surface border-border hover:border-text-subtle`),children:(0,S.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,S.jsx)(p,{className:`size-5 text-primary shrink-0 mt-0.5`}),(0,S.jsxs)(`div`,{className:`flex-1 min-w-0 space-y-1`,children:[(0,S.jsx)(`p`,{className:`font-medium truncate`,children:e.name}),(0,S.jsx)(`p`,{className:`text-xs text-text-secondary truncate`,children:e.path}),e.branch&&(0,S.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-text-secondary`,children:[(0,S.jsx)(v,{className:`size-3`}),(0,S.jsx)(`span`,{children:e.branch}),e.status&&(0,S.jsx)(y,{className:u(`size-2 fill-current`,e.status===`clean`?`text-success`:`text-warning`)})]})]})]})},e.name))}),(0,S.jsx)(l,{open:T,onOpenChange:E,children:(0,S.jsxs)(s,{children:[(0,S.jsx)(a,{children:(0,S.jsx)(c,{children:`Add Project`})}),(0,S.jsxs)(`div`,{className:`space-y-3`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`label`,{className:`text-sm text-text-secondary`,children:`Path (required)`}),(0,S.jsx)(C,{value:D,onChange:O,onSelect:e=>{k.trim()||A(e.name)},placeholder:`/home/user/my-project`,autoFocus:!0})]}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`label`,{className:`text-sm text-text-secondary`,children:`Name (optional)`}),(0,S.jsx)(_,{placeholder:`Auto-detected from folder name`,value:k,onChange:e=>A(e.target.value),onKeyDown:e=>e.key===`Enter`&&F()})]}),j&&(0,S.jsx)(`p`,{className:`text-sm text-error`,children:j})]}),(0,S.jsxs)(o,{children:[(0,S.jsx)(i,{variant:`outline`,onClick:()=>E(!1),children:`Cancel`}),(0,S.jsx)(i,{onClick:F,disabled:!D.trim(),children:`Add`})]})]})})]})}export{w as ProjectList};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-BFALxl05.js";import{_ as i,a,b as o,c as s,d as c,f as l,h as u,i as d,l as f,m as p,n as m,o as h,r as g,s as _,t as v,u as y,x as b}from"./button-CvHWF07y.js";import{a as x,i as S,n as C,o as w,r as T,t as E}from"./dist-CCBctnax.js";import{n as ee,t as D}from"./dist-B6sG2GPc.js";import{t as O}from"./utils-61GRB9Cb.js";import{t as k}from"./api-client-BgVufYKf.js";import{D as A,O as j,d as M,f as N,n as P,t as F}from"./index-DasstYgw.js";var te=t(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),I=t(`monitor`,[[`rect`,{width:`20`,height:`14`,x:`2`,y:`3`,rx:`2`,key:`48i651`}],[`line`,{x1:`8`,x2:`16`,y1:`21`,y2:`21`,key:`1svkeh`}],[`line`,{x1:`12`,x2:`12`,y1:`17`,y2:`21`,key:`vw1qmm`}]]),L=t(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),R=t(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),z=e(n(),1);function B(e){let t=z.useRef({value:e,previous:e});return z.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}var V=r(),H=`Label`,ne=z.forwardRef((e,t)=>(0,V.jsx)(u.label,{...e,ref:t,onMouseDown:t=>{t.target.closest(`button, input, select, textarea`)||(e.onMouseDown?.(t),!t.defaultPrevented&&t.detail>1&&t.preventDefault())}}));ne.displayName=H;var re=ne,ie=e(b(),1),ae=[` `,`Enter`,`ArrowUp`,`ArrowDown`],oe=[` `,`Enter`],U=`Select`,[W,se,ce]=w(U),[G,le]=p(U,[ce,x]),K=x(),[ue,q]=G(U),[de,fe]=G(U),pe=e=>{let{__scopeSelect:t,children:n,open:r,defaultOpen:i,onOpenChange:a,value:o,defaultValue:s,onValueChange:c,dir:l,name:u,autoComplete:d,disabled:p,required:m,form:h}=e,g=K(t),[_,v]=z.useState(null),[b,x]=z.useState(null),[C,w]=z.useState(!1),T=ee(l),[E,D]=y({prop:r,defaultProp:i??!1,onChange:a,caller:U}),[O,k]=y({prop:o,defaultProp:s,onChange:c,caller:U}),A=z.useRef(null),j=_?h||!!_.closest(`form`):!0,[M,N]=z.useState(new Set),P=Array.from(M).map(e=>e.props.value).join(`;`);return(0,V.jsx)(S,{...g,children:(0,V.jsxs)(ue,{required:m,scope:t,trigger:_,onTriggerChange:v,valueNode:b,onValueNodeChange:x,valueNodeHasChildren:C,onValueNodeHasChildrenChange:w,contentId:f(),value:O,onValueChange:k,open:E,onOpenChange:D,dir:T,triggerPointerDownPosRef:A,disabled:p,children:[(0,V.jsx)(W.Provider,{scope:t,children:(0,V.jsx)(de,{scope:e.__scopeSelect,onNativeOptionAdd:z.useCallback(e=>{N(t=>new Set(t).add(e))},[]),onNativeOptionRemove:z.useCallback(e=>{N(t=>{let n=new Set(t);return n.delete(e),n})},[]),children:n})}),j?(0,V.jsxs)(rt,{"aria-hidden":!0,required:m,tabIndex:-1,name:u,autoComplete:d,value:O,onChange:e=>k(e.target.value),disabled:p,form:h,children:[O===void 0?(0,V.jsx)(`option`,{value:``}):null,Array.from(M)]},P):null]})})};pe.displayName=U;var me=`SelectTrigger`,he=z.forwardRef((e,t)=>{let{__scopeSelect:n,disabled:r=!1,...i}=e,a=K(n),s=q(me,n),c=s.disabled||r,d=o(t,s.onTriggerChange),f=se(n),p=z.useRef(`touch`),[m,h,g]=at(e=>{let t=f().filter(e=>!e.disabled),n=ot(t,e,t.find(e=>e.value===s.value));n!==void 0&&s.onValueChange(n.value)}),_=e=>{c||(s.onOpenChange(!0),g()),e&&(s.triggerPointerDownPosRef.current={x:Math.round(e.pageX),y:Math.round(e.pageY)})};return(0,V.jsx)(E,{asChild:!0,...a,children:(0,V.jsx)(u.button,{type:`button`,role:`combobox`,"aria-controls":s.contentId,"aria-expanded":s.open,"aria-required":s.required,"aria-autocomplete":`none`,dir:s.dir,"data-state":s.open?`open`:`closed`,disabled:c,"data-disabled":c?``:void 0,"data-placeholder":it(s.value)?``:void 0,...i,ref:d,onClick:l(i.onClick,e=>{e.currentTarget.focus(),p.current!==`mouse`&&_(e)}),onPointerDown:l(i.onPointerDown,e=>{p.current=e.pointerType;let t=e.target;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),e.button===0&&e.ctrlKey===!1&&e.pointerType===`mouse`&&(_(e),e.preventDefault())}),onKeyDown:l(i.onKeyDown,e=>{let t=m.current!==``;!(e.ctrlKey||e.altKey||e.metaKey)&&e.key.length===1&&h(e.key),!(t&&e.key===` `)&&ae.includes(e.key)&&(_(),e.preventDefault())})})})});he.displayName=me;var ge=`SelectValue`,_e=z.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,children:a,placeholder:s=``,...l}=e,d=q(ge,n),{onValueNodeHasChildrenChange:f}=d,p=a!==void 0,m=o(t,d.onValueNodeChange);return c(()=>{f(p)},[f,p]),(0,V.jsx)(u.span,{...l,ref:m,style:{pointerEvents:`none`},children:it(d.value)?(0,V.jsx)(V.Fragment,{children:s}):a})});_e.displayName=ge;var ve=`SelectIcon`,ye=z.forwardRef((e,t)=>{let{__scopeSelect:n,children:r,...i}=e;return(0,V.jsx)(u.span,{"aria-hidden":!0,...i,ref:t,children:r||`▼`})});ye.displayName=ve;var be=`SelectPortal`,xe=e=>(0,V.jsx)(a,{asChild:!0,...e});xe.displayName=be;var J=`SelectContent`,Se=z.forwardRef((e,t)=>{let n=q(J,e.__scopeSelect),[r,i]=z.useState();if(c(()=>{i(new DocumentFragment)},[]),!n.open){let t=r;return t?ie.createPortal((0,V.jsx)(Ce,{scope:e.__scopeSelect,children:(0,V.jsx)(W.Slot,{scope:e.__scopeSelect,children:(0,V.jsx)(`div`,{children:e.children})})}),t):null}return(0,V.jsx)(Ee,{...e,ref:t})});Se.displayName=J;var Y=10,[Ce,X]=G(J),we=`SelectContentImpl`,Te=i(`SelectContent.RemoveScroll`),Ee=z.forwardRef((e,t)=>{let{__scopeSelect:n,position:r=`item-aligned`,onCloseAutoFocus:i,onEscapeKeyDown:a,onPointerDownOutside:s,side:c,sideOffset:u,align:f,alignOffset:p,arrowPadding:v,collisionBoundary:y,collisionPadding:b,sticky:x,hideWhenDetached:S,avoidCollisions:C,...w}=e,T=q(J,n),[E,ee]=z.useState(null),[D,O]=z.useState(null),k=o(t,e=>ee(e)),[A,j]=z.useState(null),[M,N]=z.useState(null),P=se(n),[F,te]=z.useState(!1),I=z.useRef(!1);z.useEffect(()=>{if(E)return m(E)},[E]),d();let L=z.useCallback(e=>{let[t,...n]=P().map(e=>e.ref.current),[r]=n.slice(-1),i=document.activeElement;for(let n of e)if(n===i||(n?.scrollIntoView({block:`nearest`}),n===t&&D&&(D.scrollTop=0),n===r&&D&&(D.scrollTop=D.scrollHeight),n?.focus(),document.activeElement!==i))return},[P,D]),R=z.useCallback(()=>L([A,E]),[L,A,E]);z.useEffect(()=>{F&&R()},[F,R]);let{onOpenChange:B,triggerPointerDownPosRef:H}=T;z.useEffect(()=>{if(E){let e={x:0,y:0},t=t=>{e={x:Math.abs(Math.round(t.pageX)-(H.current?.x??0)),y:Math.abs(Math.round(t.pageY)-(H.current?.y??0))}},n=n=>{e.x<=10&&e.y<=10?n.preventDefault():E.contains(n.target)||B(!1),document.removeEventListener(`pointermove`,t),H.current=null};return H.current!==null&&(document.addEventListener(`pointermove`,t),document.addEventListener(`pointerup`,n,{capture:!0,once:!0})),()=>{document.removeEventListener(`pointermove`,t),document.removeEventListener(`pointerup`,n,{capture:!0})}}},[E,B,H]),z.useEffect(()=>{let e=()=>B(!1);return window.addEventListener(`blur`,e),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`blur`,e),window.removeEventListener(`resize`,e)}},[B]);let[ne,re]=at(e=>{let t=P().filter(e=>!e.disabled),n=ot(t,e,t.find(e=>e.ref.current===document.activeElement));n&&setTimeout(()=>n.ref.current.focus())}),ie=z.useCallback((e,t,n)=>{let r=!I.current&&!n;(T.value!==void 0&&T.value===t||r)&&(j(e),r&&(I.current=!0))},[T.value]),ae=z.useCallback(()=>E?.focus(),[E]),oe=z.useCallback((e,t,n)=>{let r=!I.current&&!n;(T.value!==void 0&&T.value===t||r)&&N(e)},[T.value]),U=r===`popper`?Ae:Oe,W=U===Ae?{side:c,sideOffset:u,align:f,alignOffset:p,arrowPadding:v,collisionBoundary:y,collisionPadding:b,sticky:x,hideWhenDetached:S,avoidCollisions:C}:{};return(0,V.jsx)(Ce,{scope:n,content:E,viewport:D,onViewportChange:O,itemRefCallback:ie,selectedItem:A,onItemLeave:ae,itemTextRefCallback:oe,focusSelectedItem:R,selectedItemText:M,position:r,isPositioned:F,searchRef:ne,children:(0,V.jsx)(g,{as:Te,allowPinchZoom:!0,children:(0,V.jsx)(h,{asChild:!0,trapped:T.open,onMountAutoFocus:e=>{e.preventDefault()},onUnmountAutoFocus:l(i,e=>{T.trigger?.focus({preventScroll:!0}),e.preventDefault()}),children:(0,V.jsx)(_,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:a,onPointerDownOutside:s,onFocusOutside:e=>e.preventDefault(),onDismiss:()=>T.onOpenChange(!1),children:(0,V.jsx)(U,{role:`listbox`,id:T.contentId,"data-state":T.open?`open`:`closed`,dir:T.dir,onContextMenu:e=>e.preventDefault(),...w,...W,onPlaced:()=>te(!0),ref:k,style:{display:`flex`,flexDirection:`column`,outline:`none`,...w.style},onKeyDown:l(w.onKeyDown,e=>{let t=e.ctrlKey||e.altKey||e.metaKey;if(e.key===`Tab`&&e.preventDefault(),!t&&e.key.length===1&&re(e.key),[`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key)){let t=P().filter(e=>!e.disabled).map(e=>e.ref.current);if([`ArrowUp`,`End`].includes(e.key)&&(t=t.slice().reverse()),[`ArrowUp`,`ArrowDown`].includes(e.key)){let n=e.target,r=t.indexOf(n);t=t.slice(r+1)}setTimeout(()=>L(t)),e.preventDefault()}})})})})})})});Ee.displayName=we;var De=`SelectItemAlignedPosition`,Oe=z.forwardRef((e,t)=>{let{__scopeSelect:n,onPlaced:r,...i}=e,a=q(J,n),s=X(J,n),[l,d]=z.useState(null),[f,p]=z.useState(null),m=o(t,e=>p(e)),h=se(n),g=z.useRef(!1),_=z.useRef(!0),{viewport:v,selectedItem:y,selectedItemText:b,focusSelectedItem:x}=s,S=z.useCallback(()=>{if(a.trigger&&a.valueNode&&l&&f&&v&&y&&b){let e=a.trigger.getBoundingClientRect(),t=f.getBoundingClientRect(),n=a.valueNode.getBoundingClientRect(),i=b.getBoundingClientRect();if(a.dir!==`rtl`){let r=i.left-t.left,a=n.left-r,o=e.left-a,s=e.width+o,c=Math.max(s,t.width),u=window.innerWidth-Y,d=D(a,[Y,Math.max(Y,u-c)]);l.style.minWidth=s+`px`,l.style.left=d+`px`}else{let r=t.right-i.right,a=window.innerWidth-n.right-r,o=window.innerWidth-e.right-a,s=e.width+o,c=Math.max(s,t.width),u=window.innerWidth-Y,d=D(a,[Y,Math.max(Y,u-c)]);l.style.minWidth=s+`px`,l.style.right=d+`px`}let o=h(),s=window.innerHeight-Y*2,c=v.scrollHeight,u=window.getComputedStyle(f),d=parseInt(u.borderTopWidth,10),p=parseInt(u.paddingTop,10),m=parseInt(u.borderBottomWidth,10),_=parseInt(u.paddingBottom,10),x=d+p+c+_+m,S=Math.min(y.offsetHeight*5,x),C=window.getComputedStyle(v),w=parseInt(C.paddingTop,10),T=parseInt(C.paddingBottom,10),E=e.top+e.height/2-Y,ee=s-E,O=y.offsetHeight/2,k=y.offsetTop+O,A=d+p+k,j=x-A;if(A<=E){let e=o.length>0&&y===o[o.length-1].ref.current;l.style.bottom=`0px`;let t=f.clientHeight-v.offsetTop-v.offsetHeight,n=A+Math.max(ee,O+(e?T:0)+t+m);l.style.height=n+`px`}else{let e=o.length>0&&y===o[0].ref.current;l.style.top=`0px`;let t=Math.max(E,d+v.offsetTop+(e?w:0)+O)+j;l.style.height=t+`px`,v.scrollTop=A-E+v.offsetTop}l.style.margin=`${Y}px 0`,l.style.minHeight=S+`px`,l.style.maxHeight=s+`px`,r?.(),requestAnimationFrame(()=>g.current=!0)}},[h,a.trigger,a.valueNode,l,f,v,y,b,a.dir,r]);c(()=>S(),[S]);let[C,w]=z.useState();return c(()=>{f&&w(window.getComputedStyle(f).zIndex)},[f]),(0,V.jsx)(je,{scope:n,contentWrapper:l,shouldExpandOnScrollRef:g,onScrollButtonChange:z.useCallback(e=>{e&&_.current===!0&&(S(),x?.(),_.current=!1)},[S,x]),children:(0,V.jsx)(`div`,{ref:d,style:{display:`flex`,flexDirection:`column`,position:`fixed`,zIndex:C},children:(0,V.jsx)(u.div,{...i,ref:m,style:{boxSizing:`border-box`,maxHeight:`100%`,...i.style}})})})});Oe.displayName=De;var ke=`SelectPopperPosition`,Ae=z.forwardRef((e,t)=>{let{__scopeSelect:n,align:r=`start`,collisionPadding:i=Y,...a}=e,o=K(n);return(0,V.jsx)(T,{...o,...a,ref:t,align:r,collisionPadding:i,style:{boxSizing:`border-box`,...a.style,"--radix-select-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-select-content-available-width":`var(--radix-popper-available-width)`,"--radix-select-content-available-height":`var(--radix-popper-available-height)`,"--radix-select-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-select-trigger-height":`var(--radix-popper-anchor-height)`}})});Ae.displayName=ke;var[je,Me]=G(J,{}),Ne=`SelectViewport`,Pe=z.forwardRef((e,t)=>{let{__scopeSelect:n,nonce:r,...i}=e,a=X(Ne,n),s=Me(Ne,n),c=o(t,a.onViewportChange),d=z.useRef(0);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`style`,{dangerouslySetInnerHTML:{__html:`[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`},nonce:r}),(0,V.jsx)(W.Slot,{scope:n,children:(0,V.jsx)(u.div,{"data-radix-select-viewport":``,role:`presentation`,...i,ref:c,style:{position:`relative`,flex:1,overflow:`hidden auto`,...i.style},onScroll:l(i.onScroll,e=>{let t=e.currentTarget,{contentWrapper:n,shouldExpandOnScrollRef:r}=s;if(r?.current&&n){let e=Math.abs(d.current-t.scrollTop);if(e>0){let r=window.innerHeight-Y*2,i=parseFloat(n.style.minHeight),a=parseFloat(n.style.height),o=Math.max(i,a);if(o<r){let i=o+e,a=Math.min(r,i),s=i-a;n.style.height=a+`px`,n.style.bottom===`0px`&&(t.scrollTop=s>0?s:0,n.style.justifyContent=`flex-end`)}}}d.current=t.scrollTop})})})]})});Pe.displayName=Ne;var Fe=`SelectGroup`,[Ie,Le]=G(Fe),Re=z.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=f();return(0,V.jsx)(Ie,{scope:n,id:i,children:(0,V.jsx)(u.div,{role:`group`,"aria-labelledby":i,...r,ref:t})})});Re.displayName=Fe;var ze=`SelectLabel`,Be=z.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=Le(ze,n);return(0,V.jsx)(u.div,{id:i.id,...r,ref:t})});Be.displayName=ze;var Z=`SelectItem`,[Ve,He]=G(Z),Ue=z.forwardRef((e,t)=>{let{__scopeSelect:n,value:r,disabled:i=!1,textValue:a,...s}=e,c=q(Z,n),d=X(Z,n),p=c.value===r,[m,h]=z.useState(a??``),[g,_]=z.useState(!1),v=o(t,e=>d.itemRefCallback?.(e,r,i)),y=f(),b=z.useRef(`touch`),x=()=>{i||(c.onValueChange(r),c.onOpenChange(!1))};if(r===``)throw Error(`A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.`);return(0,V.jsx)(Ve,{scope:n,value:r,disabled:i,textId:y,isSelected:p,onItemTextChange:z.useCallback(e=>{h(t=>t||(e?.textContent??``).trim())},[]),children:(0,V.jsx)(W.ItemSlot,{scope:n,value:r,disabled:i,textValue:m,children:(0,V.jsx)(u.div,{role:`option`,"aria-labelledby":y,"data-highlighted":g?``:void 0,"aria-selected":p&&g,"data-state":p?`checked`:`unchecked`,"aria-disabled":i||void 0,"data-disabled":i?``:void 0,tabIndex:i?void 0:-1,...s,ref:v,onFocus:l(s.onFocus,()=>_(!0)),onBlur:l(s.onBlur,()=>_(!1)),onClick:l(s.onClick,()=>{b.current!==`mouse`&&x()}),onPointerUp:l(s.onPointerUp,()=>{b.current===`mouse`&&x()}),onPointerDown:l(s.onPointerDown,e=>{b.current=e.pointerType}),onPointerMove:l(s.onPointerMove,e=>{b.current=e.pointerType,i?d.onItemLeave?.():b.current===`mouse`&&e.currentTarget.focus({preventScroll:!0})}),onPointerLeave:l(s.onPointerLeave,e=>{e.currentTarget===document.activeElement&&d.onItemLeave?.()}),onKeyDown:l(s.onKeyDown,e=>{d.searchRef?.current!==``&&e.key===` `||(oe.includes(e.key)&&x(),e.key===` `&&e.preventDefault())})})})})});Ue.displayName=Z;var Q=`SelectItemText`,We=z.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,...a}=e,s=q(Q,n),l=X(Q,n),d=He(Q,n),f=fe(Q,n),[p,m]=z.useState(null),h=o(t,e=>m(e),d.onItemTextChange,e=>l.itemTextRefCallback?.(e,d.value,d.disabled)),g=p?.textContent,_=z.useMemo(()=>(0,V.jsx)(`option`,{value:d.value,disabled:d.disabled,children:g},d.value),[d.disabled,d.value,g]),{onNativeOptionAdd:v,onNativeOptionRemove:y}=f;return c(()=>(v(_),()=>y(_)),[v,y,_]),(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(u.span,{id:d.textId,...a,ref:h}),d.isSelected&&s.valueNode&&!s.valueNodeHasChildren?ie.createPortal(a.children,s.valueNode):null]})});We.displayName=Q;var Ge=`SelectItemIndicator`,Ke=z.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return He(Ge,n).isSelected?(0,V.jsx)(u.span,{"aria-hidden":!0,...r,ref:t}):null});Ke.displayName=Ge;var qe=`SelectScrollUpButton`,Je=z.forwardRef((e,t)=>{let n=X(qe,e.__scopeSelect),r=Me(qe,e.__scopeSelect),[i,a]=z.useState(!1),s=o(t,r.onScrollButtonChange);return c(()=>{if(n.viewport&&n.isPositioned){let e=function(){a(t.scrollTop>0)},t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,V.jsx)(Ze,{...e,ref:s,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop-=t.offsetHeight)}}):null});Je.displayName=qe;var Ye=`SelectScrollDownButton`,Xe=z.forwardRef((e,t)=>{let n=X(Ye,e.__scopeSelect),r=Me(Ye,e.__scopeSelect),[i,a]=z.useState(!1),s=o(t,r.onScrollButtonChange);return c(()=>{if(n.viewport&&n.isPositioned){let e=function(){let e=t.scrollHeight-t.clientHeight;a(Math.ceil(t.scrollTop)<e)},t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,V.jsx)(Ze,{...e,ref:s,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop+=t.offsetHeight)}}):null});Xe.displayName=Ye;var Ze=z.forwardRef((e,t)=>{let{__scopeSelect:n,onAutoScroll:r,...i}=e,a=X(`SelectScrollButton`,n),o=z.useRef(null),s=se(n),d=z.useCallback(()=>{o.current!==null&&(window.clearInterval(o.current),o.current=null)},[]);return z.useEffect(()=>()=>d(),[d]),c(()=>{s().find(e=>e.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:`nearest`})},[s]),(0,V.jsx)(u.div,{"aria-hidden":!0,...i,ref:t,style:{flexShrink:0,...i.style},onPointerDown:l(i.onPointerDown,()=>{o.current===null&&(o.current=window.setInterval(r,50))}),onPointerMove:l(i.onPointerMove,()=>{a.onItemLeave?.(),o.current===null&&(o.current=window.setInterval(r,50))}),onPointerLeave:l(i.onPointerLeave,()=>{d()})})}),Qe=`SelectSeparator`,$e=z.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return(0,V.jsx)(u.div,{"aria-hidden":!0,...r,ref:t})});$e.displayName=Qe;var et=`SelectArrow`,tt=z.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=K(n),a=q(et,n),o=X(et,n);return a.open&&o.position===`popper`?(0,V.jsx)(C,{...i,...r,ref:t}):null});tt.displayName=et;var nt=`SelectBubbleInput`,rt=z.forwardRef(({__scopeSelect:e,value:t,...n},r)=>{let i=z.useRef(null),a=o(r,i),s=B(t);return z.useEffect(()=>{let e=i.current;if(!e)return;let n=window.HTMLSelectElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`).set;if(s!==t&&r){let n=new Event(`change`,{bubbles:!0});r.call(e,t),e.dispatchEvent(n)}},[s,t]),(0,V.jsx)(u.select,{...n,style:{...M,...n.style},ref:a,defaultValue:t})});rt.displayName=nt;function it(e){return e===``||e===void 0}function at(e){let t=s(e),n=z.useRef(``),r=z.useRef(0),i=z.useCallback(e=>{let i=n.current+e;t(i),(function e(t){n.current=t,window.clearTimeout(r.current),t!==``&&(r.current=window.setTimeout(()=>e(``),1e3))})(i)},[t]),a=z.useCallback(()=>{n.current=``,window.clearTimeout(r.current)},[]);return z.useEffect(()=>()=>window.clearTimeout(r.current),[]),[n,i,a]}function ot(e,t,n){let r=t.length>1&&Array.from(t).every(e=>e===t[0])?t[0]:t,i=n?e.indexOf(n):-1,a=st(e,Math.max(i,0));r.length===1&&(a=a.filter(e=>e!==n));let o=a.find(e=>e.textValue.toLowerCase().startsWith(r.toLowerCase()));return o===n?void 0:o}function st(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var ct=pe,lt=he,ut=_e,dt=ye,ft=xe,pt=Se,mt=Pe,ht=Ue,gt=We,_t=Ke,vt=Je,yt=Xe;function $({className:e,...t}){return(0,V.jsx)(re,{"data-slot":`label`,className:O(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,e),...t})}function bt({...e}){return(0,V.jsx)(ct,{"data-slot":`select`,...e})}function xt({...e}){return(0,V.jsx)(ut,{"data-slot":`select-value`,...e})}function St({className:e,size:t=`default`,children:n,...r}){return(0,V.jsxs)(lt,{"data-slot":`select-trigger`,"data-size":t,className:O(`flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground`,e),...r,children:[n,(0,V.jsx)(dt,{asChild:!0,children:(0,V.jsx)(A,{className:`size-4 opacity-50`})})]})}function Ct({className:e,children:t,position:n=`item-aligned`,align:r=`center`,...i}){return(0,V.jsx)(ft,{children:(0,V.jsxs)(pt,{"data-slot":`select-content`,className:O(`relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95`,n===`popper`&&`data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,e),position:n,align:r,...i,children:[(0,V.jsx)(Tt,{}),(0,V.jsx)(mt,{className:O(`p-1`,n===`popper`&&`h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1`),children:t}),(0,V.jsx)(Et,{})]})})}function wt({className:e,children:t,...n}){return(0,V.jsxs)(ht,{"data-slot":`select-item`,className:O(`relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,e),...n,children:[(0,V.jsx)(`span`,{"data-slot":`select-item-indicator`,className:`absolute right-2 flex size-3.5 items-center justify-center`,children:(0,V.jsx)(_t,{children:(0,V.jsx)(j,{className:`size-4`})})}),(0,V.jsx)(gt,{children:t})]})}function Tt({className:e,...t}){return(0,V.jsx)(vt,{"data-slot":`select-scroll-up-button`,className:O(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,V.jsx)(te,{className:`size-4`})})}function Et({className:e,...t}){return(0,V.jsx)(yt,{"data-slot":`select-scroll-down-button`,className:O(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,V.jsx)(A,{className:`size-4`})})}function Dt(){return k.get(`/api/settings/ai`)}function Ot(e){return k.put(`/api/settings/ai`,e)}var kt=[{value:`claude-sonnet-4-6`,label:`Claude Sonnet 4.6`},{value:`claude-opus-4-6`,label:`Claude Opus 4.6`},{value:`claude-haiku-4-5`,label:`Claude Haiku 4.5`}],At=[{value:`low`,label:`Low`},{value:`medium`,label:`Medium`},{value:`high`,label:`High`},{value:`max`,label:`Max`}];function jt(){let[e,t]=(0,z.useState)(null),[n,r]=(0,z.useState)(!1),[i,a]=(0,z.useState)(null),[o,s]=(0,z.useState)(0);(0,z.useEffect)(()=>{Dt().then(t).catch(e=>a(e.message))},[]);let c=e?.default_provider??`claude`,l=e?.providers[c],u=async(n,i)=>{if(e){r(!0),a(null);try{t(await Ot({providers:{[c]:{[n]:i}}})),s(e=>e+1)}catch(e){a(e.message)}finally{r(!1)}}};return e?(0,V.jsxs)(`div`,{className:`space-y-4`,children:[(0,V.jsx)(`h3`,{className:`text-sm font-medium text-text-secondary`,children:`AI Provider`}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsx)($,{htmlFor:`ai-model`,children:`Model`}),(0,V.jsxs)(bt,{value:l?.model??`claude-sonnet-4-6`,onValueChange:e=>u(`model`,e),children:[(0,V.jsx)(St,{id:`ai-model`,className:`w-full`,children:(0,V.jsx)(xt,{})}),(0,V.jsx)(Ct,{children:kt.map(e=>(0,V.jsx)(wt,{value:e.value,children:e.label},e.value))})]})]}),(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsx)($,{htmlFor:`ai-effort`,children:`Effort`}),(0,V.jsxs)(bt,{value:l?.effort??`high`,onValueChange:e=>u(`effort`,e),children:[(0,V.jsx)(St,{id:`ai-effort`,className:`w-full`,children:(0,V.jsx)(xt,{})}),(0,V.jsx)(Ct,{children:At.map(e=>(0,V.jsx)(wt,{value:e.value,children:e.label},e.value))})]})]}),(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsx)($,{htmlFor:`ai-max-turns`,children:`Max Turns (1-500)`}),(0,V.jsx)(P,{id:`ai-max-turns`,type:`number`,min:1,max:500,defaultValue:l?.max_turns??100,onBlur:e=>{let t=parseInt(e.target.value);isNaN(t)||u(`max_turns`,t)}},`turns-${o}`)]}),(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsx)($,{htmlFor:`ai-budget`,children:`Max Budget (USD)`}),(0,V.jsx)(P,{id:`ai-budget`,type:`number`,step:.1,min:.01,max:50,defaultValue:l?.max_budget_usd??``,placeholder:`No limit`,onBlur:e=>{let t=parseFloat(e.target.value);u(`max_budget_usd`,isNaN(t)?void 0:t)}},`budget-${o}`)]}),(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsx)($,{htmlFor:`ai-thinking`,children:`Thinking Budget (tokens)`}),(0,V.jsx)(P,{id:`ai-thinking`,type:`number`,min:0,defaultValue:l?.thinking_budget_tokens??``,placeholder:`Disabled`,onBlur:e=>{let t=parseInt(e.target.value);u(`thinking_budget_tokens`,isNaN(t)?void 0:t)}},`thinking-${o}`)]})]}),n&&(0,V.jsx)(`p`,{className:`text-xs text-text-subtle`,children:`Saving...`}),i&&(0,V.jsx)(`p`,{className:`text-xs text-red-500`,children:i})]}):(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsx)(`h3`,{className:`text-sm font-medium text-text-secondary`,children:`AI Provider`}),(0,V.jsx)(`p`,{className:`text-sm text-text-subtle`,children:i?`Error: ${i}`:`Loading...`})]})}var Mt=[{value:`light`,label:`Light`,icon:R},{value:`dark`,label:`Dark`,icon:L},{value:`system`,label:`System`,icon:I}];function Nt(){let{theme:e,setTheme:t}=N();return(0,V.jsxs)(`div`,{className:`h-full p-4 space-y-6 overflow-auto max-w-lg`,children:[(0,V.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Settings`}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsx)(`h3`,{className:`text-sm font-medium text-text-secondary`,children:`Theme`}),(0,V.jsx)(`div`,{className:`flex gap-2`,children:Mt.map(n=>{let r=n.icon;return(0,V.jsxs)(v,{variant:e===n.value?`default`:`outline`,size:`lg`,onClick:()=>t(n.value),className:O(`flex-1 gap-2`,e===n.value&&`ring-2 ring-primary`),children:[(0,V.jsx)(r,{className:`size-4`}),n.label]},n.value)})})]}),(0,V.jsx)(F,{}),(0,V.jsx)(jt,{}),(0,V.jsx)(F,{}),(0,V.jsxs)(`div`,{className:`space-y-3`,children:[(0,V.jsx)(`h3`,{className:`text-sm font-medium text-text-secondary`,children:`About`}),(0,V.jsx)(`p`,{className:`text-sm text-text-secondary`,children:`PPM — Personal Project Manager`}),(0,V.jsx)(`p`,{className:`text-xs text-text-subtle`,children:`A mobile-first web IDE for managing your projects.`})]})]})}export{Nt as SettingsTab};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-BFALxl05.js";import{t as i}from"./copy-B-kLwqzg.js";import{t as a}from"./utils-DpJF9mAi.js";var o=t(`clipboard-paste`,[[`path`,{d:`M11 14h10`,key:`1w8e9d`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v1.344`,key:`1e62lh`}],[`path`,{d:`m17 18 4-4-4-4`,key:`z2g111`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113`,key:`bjbb7m`}],[`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,key:`ublpy`}]]),s=e(n(),1),c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},d=(e,t,n,r)=>{for(var i=r>1?void 0:r?l(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&c(t,n,i),i},f=(e,t)=>(n,r)=>t(n,r,e),p=`Terminal input`,m={get:()=>p,set:e=>p=e},h=`Too much output to announce, navigate to rows manually to read`,g={get:()=>h,set:e=>h=e};function _(e){return e.replace(/\r?\n/g,`\r`)}function v(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ee(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function te(e,t,n,r){e.stopPropagation(),e.clipboardData&&ne(e.clipboardData.getData(`text/plain`),t,n,r)}function ne(e,t,n,r){e=_(e),e=v(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function re(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ie(e,t,n,r,i){re(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function y(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function ae(e,t=0,n=e.length){let r=``;for(let i=t;i<n;++i){let t=e[i];t>65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var oe=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a<n;++a){let i=e.charCodeAt(a);if(55296<=i&&i<=56319){if(++a>=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},b=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l<u;){if(l>=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}else this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d<n;){for(;d<u&&!((i=e[d])&128)&&!((a=e[d+1])&128)&&!((o=e[d+2])&128)&&!((s=e[d+3])&128);)t[r++]=i,t[r++]=a,t[r++]=o,t[r++]=s,d+=4;if(i=e[d++],i<128)t[r++]=i;else if((i&224)==192){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},se=``,ce=` `,le=class e{constructor(){this.fg=0,this.bg=0,this.extended=new x}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return(this.fg&50331648)==0}isBgDefault(){return(this.bg&50331648)==0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},x=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},S=class e extends le{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new x,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?y(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},ue=`di$target`,de=`di$dependencies`,C=new Map;function fe(e){return e[de]||[]}function w(e){if(C.has(e))return C.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);pe(t,e,r)};return t._id=e,C.set(e,t),t}function pe(e,t,n){t[ue]===t?t[de].push({id:e,index:n}):(t[de]=[{id:e,index:n}],t[ue]=t)}var T=w(`BufferService`),me=w(`CoreMouseService`),E=w(`CoreService`),he=w(`CharsetService`),ge=w(`InstantiationService`),_e=w(`LogService`),D=w(`OptionsService`),ve=w(`OscLinkService`),ye=w(`UnicodeService`),be=w(`DecorationService`),xe=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new S,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;t<o;t++)if(!(c===-1&&!n.hasContent(t))){if(n.loadCell(t,a),a.hasExtendedAttrs()&&a.extended.urlId)if(c===-1){c=t,s=a.extended.urlId;continue}else l=a.extended.urlId!==s;else c!==-1&&(l=!0);if(l||c!==-1&&t===o-1){let n=this._oscLinkService.getLinkData(s)?.uri;if(n){let a={start:{x:c+1,y:e},end:{x:t+(!l&&t===o-1?1:0),y:e}},s=!1;if(!i?.allowNonHttpProtocols)try{let e=new URL(n);[`http:`,`https:`].includes(e.protocol)||(s=!0)}catch{s=!0}s||r.push({text:n,range:a,activate:(e,t)=>i?i.activate(e,t,a):Se(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};xe=d([f(0,T),f(1,D),f(2,ve)],xe);function Se(e,t){if(confirm(`Do you want to navigate to ${t}?
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-BFALxl05.js";import{t as i}from"./copy-B-kLwqzg.js";import{t as a}from"./utils-61GRB9Cb.js";var o=t(`clipboard-paste`,[[`path`,{d:`M11 14h10`,key:`1w8e9d`}],[`path`,{d:`M16 4h2a2 2 0 0 1 2 2v1.344`,key:`1e62lh`}],[`path`,{d:`m17 18 4-4-4-4`,key:`z2g111`}],[`path`,{d:`M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113`,key:`bjbb7m`}],[`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,key:`ublpy`}]]),s=e(n(),1),c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,u=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},d=(e,t,n,r)=>{for(var i=r>1?void 0:r?l(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&c(t,n,i),i},f=(e,t)=>(n,r)=>t(n,r,e),p=`Terminal input`,m={get:()=>p,set:e=>p=e},h=`Too much output to announce, navigate to rows manually to read`,g={get:()=>h,set:e=>h=e};function _(e){return e.replace(/\r?\n/g,`\r`)}function v(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ee(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function te(e,t,n,r){e.stopPropagation(),e.clipboardData&&ne(e.clipboardData.getData(`text/plain`),t,n,r)}function ne(e,t,n,r){e=_(e),e=v(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function re(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ie(e,t,n,r,i){re(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function y(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function ae(e,t=0,n=e.length){let r=``;for(let i=t;i<n;++i){let t=e[i];t>65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var oe=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a<n;++a){let i=e.charCodeAt(a);if(55296<=i&&i<=56319){if(++a>=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},b=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l<u;){if(l>=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}else this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d<n;){for(;d<u&&!((i=e[d])&128)&&!((a=e[d+1])&128)&&!((o=e[d+2])&128)&&!((s=e[d+3])&128);)t[r++]=i,t[r++]=a,t[r++]=o,t[r++]=s,d+=4;if(i=e[d++],i<128)t[r++]=i;else if((i&224)==192){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},se=``,ce=` `,le=class e{constructor(){this.fg=0,this.bg=0,this.extended=new x}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return(this.fg&50331648)==0}isBgDefault(){return(this.bg&50331648)==0}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==0:this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},x=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},S=class e extends le{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new x,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?y(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},ue=`di$target`,de=`di$dependencies`,C=new Map;function fe(e){return e[de]||[]}function w(e){if(C.has(e))return C.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);pe(t,e,r)};return t._id=e,C.set(e,t),t}function pe(e,t,n){t[ue]===t?t[de].push({id:e,index:n}):(t[de]=[{id:e,index:n}],t[ue]=t)}var T=w(`BufferService`),me=w(`CoreMouseService`),E=w(`CoreService`),he=w(`CharsetService`),ge=w(`InstantiationService`),_e=w(`LogService`),D=w(`OptionsService`),ve=w(`OscLinkService`),ye=w(`UnicodeService`),be=w(`DecorationService`),xe=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new S,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;t<o;t++)if(!(c===-1&&!n.hasContent(t))){if(n.loadCell(t,a),a.hasExtendedAttrs()&&a.extended.urlId)if(c===-1){c=t,s=a.extended.urlId;continue}else l=a.extended.urlId!==s;else c!==-1&&(l=!0);if(l||c!==-1&&t===o-1){let n=this._oscLinkService.getLinkData(s)?.uri;if(n){let a={start:{x:c+1,y:e},end:{x:t+(!l&&t===o-1?1:0),y:e}},s=!1;if(!i?.allowNonHttpProtocols)try{let e=new URL(n);[`http:`,`https:`].includes(e.protocol)||(s=!0)}catch{s=!0}s||r.push({text:n,range:a,activate:(e,t)=>i?i.activate(e,t,a):Se(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};xe=d([f(0,T),f(1,D),f(2,ve)],xe);function Se(e,t){if(confirm(`Do you want to navigate to ${t}?
|
|
2
2
|
|
|
3
3
|
WARNING: This link could potentially be dangerous`)){let e=window.open();if(e){try{e.opener=null}catch{}e.location.href=t}else console.warn(`Opening link blocked as opener could not be cleared`)}}var Ce=w(`CharSizeService`),we=w(`CoreBrowserService`),Te=w(`MouseService`),Ee=w(`RenderService`),De=w(`SelectionService`),Oe=w(`CharacterJoinerService`),ke=w(`ThemeService`),Ae=w(`LinkProviderService`),je=new class{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout(()=>{throw e.stack?Le.isErrorNoTelemetry(e)?new Le(e.message+`
|
|
4
4
|
|
package/dist/web/index.html
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/assets/index-DasstYgw.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-BFALxl05.js">
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/utils-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/button-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/utils-61GRB9Cb.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/button-CvHWF07y.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/dist-CCBctnax.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/dist-B6sG2GPc.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/x-BxhOxZ5p.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
19
|
-
<link rel="modulepreload" crossorigin href="/assets/react-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/dialog-f3IZM-6v.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/react-gOPBns57.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/api-client-BgVufYKf.js">
|
|
21
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
21
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DILaVO6p.css">
|
|
22
22
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
23
23
|
<body class="bg-[#0f1419] text-[#e5e7eb] font-sans antialiased">
|
|
24
24
|
<div id="root"></div>
|
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let s,e={};const i=(i,l)=>(i=new URL(i+".js",l).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(l,
|
|
1
|
+
if(!self.define){let s,e={};const i=(i,l)=>(i=new URL(i+".js",l).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(l,n)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let t={};const u=s=>i(s,r),o={module:{uri:r},exports:t,require:u};e[r]=Promise.all(l.map(s=>o[s]||u(s))).then(s=>(n(...s),t))}}define(["./workbox-3e722498"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"a901473b3162fa81ec87e095b1092e71"},{url:"icon-512.svg",revision:"a0fb34fc84eb148d51812cd62669f20d"},{url:"icon-192.svg",revision:"a0fb34fc84eb148d51812cd62669f20d"},{url:"assets/x-BxhOxZ5p.js",revision:null},{url:"assets/utils-61GRB9Cb.js",revision:null},{url:"assets/trash-2-CjahwKg8.js",revision:null},{url:"assets/terminal-tab-CyjhG4Ao.js",revision:null},{url:"assets/terminal-tab-BrP-ENHg.css",revision:null},{url:"assets/settings-tab-Cn5Ja0_J.js",revision:null},{url:"assets/refresh-cw-DJSjl6Ev.js",revision:null},{url:"assets/react-gOPBns57.js",revision:null},{url:"assets/project-list-C7L3hZct.js",revision:null},{url:"assets/marked.esm-Cv8mjgnt.js",revision:null},{url:"assets/jsx-runtime-BFALxl05.js",revision:null},{url:"assets/index-DasstYgw.js",revision:null},{url:"assets/index-DILaVO6p.css",revision:null},{url:"assets/git-status-panel-BifyO31N.js",revision:null},{url:"assets/git-graph-BiyTIbCz.js",revision:null},{url:"assets/external-link-Dim3NH6h.js",revision:null},{url:"assets/dist-CCBctnax.js",revision:null},{url:"assets/dist-CBiGQxfr.js",revision:null},{url:"assets/dist-B6sG2GPc.js",revision:null},{url:"assets/diff-viewer-8_asmBRZ.js",revision:null},{url:"assets/dialog-f3IZM-6v.js",revision:null},{url:"assets/copy-B-kLwqzg.js",revision:null},{url:"assets/code-editor-BgiyQO-M.js",revision:null},{url:"assets/chat-tab-C4ovA2w4.js",revision:null},{url:"assets/button-CvHWF07y.js",revision:null},{url:"assets/arrow-up-from-line-DjfWTP75.js",revision:null},{url:"assets/api-client-BgVufYKf.js",revision:null},{url:"manifest.webmanifest",revision:"79c8870653c8f419f2e3323085e1f4be"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"))),s.registerRoute(/^https?:\/\/.*\/api\//,new s.NetworkOnly,"GET"),s.registerRoute(/^https?:\/\/.*\/ws\//,new s.NetworkOnly,"GET")});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hienlh/ppm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Personal Project Manager — mobile-first web IDE with AI assistance",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"ppm": "src/index.ts"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"dev": "bun run --hot src/index.ts start",
|
|
11
|
+
"dev": "bun run --hot src/index.ts start -f & bun run vite --config vite.config.ts",
|
|
12
|
+
"dev:server": "bun run --hot src/index.ts start -f",
|
|
12
13
|
"dev:web": "bun run vite --config vite.config.ts",
|
|
13
14
|
"build:web": "bun run vite build --config vite.config.ts",
|
|
14
15
|
"build": "bun run build:web && bun build src/index.ts --compile --outfile dist/ppm",
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -41,7 +41,16 @@ export async function initProject(options: InitOptions = {}) {
|
|
|
41
41
|
|
|
42
42
|
console.log("\n 🔧 PPM Setup\n");
|
|
43
43
|
|
|
44
|
-
// 1.
|
|
44
|
+
// 1. Device name
|
|
45
|
+
const defaultHostname = (await import("node:os")).hostname();
|
|
46
|
+
const deviceName = nonInteractive
|
|
47
|
+
? (options as any).deviceName ?? defaultHostname
|
|
48
|
+
: await input({
|
|
49
|
+
message: "Device name (shown in UI to identify this machine):",
|
|
50
|
+
default: defaultHostname,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// 2. Port
|
|
45
54
|
const portValue = options.port
|
|
46
55
|
? parseInt(options.port, 10)
|
|
47
56
|
: nonInteractive
|
|
@@ -140,6 +149,7 @@ export async function initProject(options: InitOptions = {}) {
|
|
|
140
149
|
|
|
141
150
|
// Apply config
|
|
142
151
|
configService.load();
|
|
152
|
+
configService.set("device_name", deviceName);
|
|
143
153
|
configService.set("port", portValue);
|
|
144
154
|
configService.set("auth", { enabled: authEnabled, token: authToken });
|
|
145
155
|
configService.set("ai", {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
const LOG_FILE = resolve(homedir(), ".ppm", "ppm.log");
|
|
6
|
+
|
|
7
|
+
export async function showLogs(options: { tail?: string; follow?: boolean; clear?: boolean }) {
|
|
8
|
+
if (options.clear) {
|
|
9
|
+
const { writeFileSync } = await import("node:fs");
|
|
10
|
+
writeFileSync(LOG_FILE, "");
|
|
11
|
+
console.log("Logs cleared.");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!existsSync(LOG_FILE)) {
|
|
16
|
+
console.log("No log file found. Start PPM daemon first.");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const lines = parseInt(options.tail ?? "50", 10);
|
|
21
|
+
const content = readFileSync(LOG_FILE, "utf-8");
|
|
22
|
+
const allLines = content.split("\n");
|
|
23
|
+
const lastN = allLines.slice(-lines).join("\n");
|
|
24
|
+
|
|
25
|
+
if (!lastN.trim()) {
|
|
26
|
+
console.log("Log file is empty.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(lastN);
|
|
31
|
+
|
|
32
|
+
if (options.follow) {
|
|
33
|
+
// Tail -f behavior
|
|
34
|
+
const { watch } = await import("node:fs");
|
|
35
|
+
let lastSize = statSync(LOG_FILE).size;
|
|
36
|
+
console.log("\n--- Following logs (Ctrl+C to stop) ---\n");
|
|
37
|
+
|
|
38
|
+
watch(LOG_FILE, () => {
|
|
39
|
+
try {
|
|
40
|
+
const newSize = statSync(LOG_FILE).size;
|
|
41
|
+
if (newSize > lastSize) {
|
|
42
|
+
const fd = Bun.file(LOG_FILE);
|
|
43
|
+
fd.slice(lastSize, newSize).text().then((text) => {
|
|
44
|
+
process.stdout.write(text);
|
|
45
|
+
});
|
|
46
|
+
lastSize = newSize;
|
|
47
|
+
}
|
|
48
|
+
} catch {}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Get last N lines of log for bug reports */
|
|
54
|
+
export function getRecentLogs(lines = 30): string {
|
|
55
|
+
if (!existsSync(LOG_FILE)) return "(no logs)";
|
|
56
|
+
const content = readFileSync(LOG_FILE, "utf-8");
|
|
57
|
+
return content.split("\n").slice(-lines).join("\n").trim() || "(empty)";
|
|
58
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { homedir, platform, arch, release } from "node:os";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { getRecentLogs } from "./logs.ts";
|
|
5
|
+
|
|
6
|
+
const REPO = "hienlh/ppm";
|
|
7
|
+
|
|
8
|
+
export async function reportBug() {
|
|
9
|
+
const { VERSION: version } = await import("../../version.ts");
|
|
10
|
+
const logs = getRecentLogs(30);
|
|
11
|
+
const statusFile = resolve(homedir(), ".ppm", "status.json");
|
|
12
|
+
let statusInfo = "(not running)";
|
|
13
|
+
if (existsSync(statusFile)) {
|
|
14
|
+
try { statusInfo = readFileSync(statusFile, "utf-8"); } catch {}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const body = [
|
|
18
|
+
"## Environment",
|
|
19
|
+
`- PPM: v${version}`,
|
|
20
|
+
`- OS: ${platform()} ${arch()} ${release()}`,
|
|
21
|
+
`- Bun: ${Bun.version}`,
|
|
22
|
+
"",
|
|
23
|
+
"## Description",
|
|
24
|
+
"<!-- Describe the bug -->",
|
|
25
|
+
"",
|
|
26
|
+
"## Steps to Reproduce",
|
|
27
|
+
"1. ",
|
|
28
|
+
"",
|
|
29
|
+
"## Expected Behavior",
|
|
30
|
+
"",
|
|
31
|
+
"## Daemon Status",
|
|
32
|
+
"```json",
|
|
33
|
+
statusInfo,
|
|
34
|
+
"```",
|
|
35
|
+
"",
|
|
36
|
+
"## Recent Logs (last 30 lines)",
|
|
37
|
+
"```",
|
|
38
|
+
logs,
|
|
39
|
+
"```",
|
|
40
|
+
].join("\n");
|
|
41
|
+
|
|
42
|
+
const title = encodeURIComponent("bug: ");
|
|
43
|
+
const encodedBody = encodeURIComponent(body);
|
|
44
|
+
const url = `https://github.com/${REPO}/issues/new?title=${title}&body=${encodedBody}`;
|
|
45
|
+
|
|
46
|
+
console.log(" Opening GitHub issue form in browser...\n");
|
|
47
|
+
console.log(" Environment info and recent logs will be pre-filled.\n");
|
|
48
|
+
|
|
49
|
+
const { $ } = await import("bun");
|
|
50
|
+
try {
|
|
51
|
+
if (platform() === "darwin") {
|
|
52
|
+
await $`open ${url}`.quiet();
|
|
53
|
+
} else {
|
|
54
|
+
await $`xdg-open ${url}`.quiet();
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
console.log(" Could not open browser. Copy this URL:\n");
|
|
58
|
+
console.log(` ${url}\n`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -11,40 +11,46 @@ interface DaemonStatus {
|
|
|
11
11
|
port: number | null;
|
|
12
12
|
host: string | null;
|
|
13
13
|
shareUrl: string | null;
|
|
14
|
+
tunnelPid: number | null;
|
|
15
|
+
tunnelAlive: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isAlive(pid: number): boolean {
|
|
19
|
+
try { process.kill(pid, 0); return true; } catch { return false; }
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
function getDaemonStatus(): DaemonStatus {
|
|
17
|
-
const
|
|
23
|
+
const dead: DaemonStatus = {
|
|
24
|
+
running: false, pid: null, port: null, host: null,
|
|
25
|
+
shareUrl: null, tunnelPid: null, tunnelAlive: false,
|
|
26
|
+
};
|
|
18
27
|
|
|
19
|
-
// Try status.json first
|
|
20
28
|
if (existsSync(STATUS_FILE)) {
|
|
21
29
|
try {
|
|
22
30
|
const data = JSON.parse(readFileSync(STATUS_FILE, "utf-8"));
|
|
23
31
|
const pid = data.pid as number;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const tunnelPid = (data.tunnelPid as number) ?? null;
|
|
33
|
+
const tunnelAlive = tunnelPid ? isAlive(tunnelPid) : false;
|
|
34
|
+
return {
|
|
35
|
+
running: isAlive(pid),
|
|
36
|
+
pid,
|
|
37
|
+
port: data.port,
|
|
38
|
+
host: data.host,
|
|
39
|
+
shareUrl: data.shareUrl ?? null,
|
|
40
|
+
tunnelPid,
|
|
41
|
+
tunnelAlive,
|
|
42
|
+
};
|
|
43
|
+
} catch { return dead; }
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
// Fallback to ppm.pid
|
|
37
46
|
if (existsSync(PID_FILE)) {
|
|
38
47
|
try {
|
|
39
48
|
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
} catch {
|
|
43
|
-
return notRunning;
|
|
44
|
-
}
|
|
49
|
+
return { ...dead, running: isAlive(pid), pid };
|
|
50
|
+
} catch { return dead; }
|
|
45
51
|
}
|
|
46
52
|
|
|
47
|
-
return
|
|
53
|
+
return dead;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
export async function showStatus(options: { json?: boolean }) {
|
|
@@ -55,14 +61,17 @@ export async function showStatus(options: { json?: boolean }) {
|
|
|
55
61
|
return;
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
if (!status.running) {
|
|
64
|
+
if (!status.running && !status.tunnelAlive) {
|
|
59
65
|
console.log(" PPM is not running.");
|
|
60
66
|
return;
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
console.log(`\n PPM daemon
|
|
64
|
-
console.log(` PID:
|
|
69
|
+
console.log(`\n PPM daemon status\n`);
|
|
70
|
+
console.log(` Server: ${status.running ? "running" : "stopped"} (PID: ${status.pid})`);
|
|
65
71
|
if (status.port) console.log(` Local: http://localhost:${status.port}/`);
|
|
72
|
+
if (status.tunnelPid) {
|
|
73
|
+
console.log(` Tunnel: ${status.tunnelAlive ? "running" : "stopped"} (PID: ${status.tunnelPid})`);
|
|
74
|
+
}
|
|
66
75
|
if (status.shareUrl) {
|
|
67
76
|
console.log(` Share: ${status.shareUrl}`);
|
|
68
77
|
const qr = await import("qrcode-terminal");
|
package/src/cli/commands/stop.ts
CHANGED
|
@@ -5,43 +5,51 @@ import { readFileSync, unlinkSync, existsSync } from "node:fs";
|
|
|
5
5
|
const PID_FILE = resolve(homedir(), ".ppm", "ppm.pid");
|
|
6
6
|
const STATUS_FILE = resolve(homedir(), ".ppm", "status.json");
|
|
7
7
|
|
|
8
|
+
function killPid(pid: number, label: string): boolean {
|
|
9
|
+
try {
|
|
10
|
+
process.kill(pid);
|
|
11
|
+
console.log(` Stopped ${label} (PID: ${pid})`);
|
|
12
|
+
return true;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
const err = e as NodeJS.ErrnoException;
|
|
15
|
+
if (err.code !== "ESRCH") console.error(` Failed to stop ${label}: ${err.message}`);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export async function stopServer() {
|
|
9
|
-
let
|
|
21
|
+
let status: { pid?: number; tunnelPid?: number } | null = null;
|
|
10
22
|
|
|
11
|
-
//
|
|
23
|
+
// Read status.json
|
|
12
24
|
if (existsSync(STATUS_FILE)) {
|
|
13
|
-
try {
|
|
14
|
-
const status = JSON.parse(readFileSync(STATUS_FILE, "utf-8"));
|
|
15
|
-
pid = status.pid;
|
|
16
|
-
} catch {}
|
|
25
|
+
try { status = JSON.parse(readFileSync(STATUS_FILE, "utf-8")); } catch {}
|
|
17
26
|
}
|
|
18
27
|
|
|
19
|
-
// Fallback to ppm.pid
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
// Fallback to ppm.pid
|
|
29
|
+
const pidFromFile = existsSync(PID_FILE)
|
|
30
|
+
? parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10)
|
|
31
|
+
: NaN;
|
|
32
|
+
|
|
33
|
+
const serverPid = status?.pid ?? (isNaN(pidFromFile) ? null : pidFromFile);
|
|
34
|
+
const tunnelPid = status?.tunnelPid ?? null;
|
|
23
35
|
|
|
24
|
-
if (!
|
|
36
|
+
if (!serverPid && !tunnelPid) {
|
|
25
37
|
console.log("No PPM daemon running.");
|
|
26
|
-
|
|
27
|
-
if (existsSync(STATUS_FILE)) unlinkSync(STATUS_FILE);
|
|
28
|
-
if (existsSync(PID_FILE)) unlinkSync(PID_FILE);
|
|
38
|
+
cleanup();
|
|
29
39
|
return;
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
}
|
|
42
|
+
// Kill server process
|
|
43
|
+
if (serverPid) killPid(serverPid, "server");
|
|
44
|
+
|
|
45
|
+
// Kill tunnel process (independent from server)
|
|
46
|
+
if (tunnelPid) killPid(tunnelPid, "tunnel");
|
|
47
|
+
|
|
48
|
+
cleanup();
|
|
49
|
+
console.log("PPM stopped.");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function cleanup() {
|
|
53
|
+
if (existsSync(STATUS_FILE)) unlinkSync(STATUS_FILE);
|
|
54
|
+
if (existsSync(PID_FILE)) unlinkSync(PID_FILE);
|
|
47
55
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
+
import { VERSION } from "./version.ts";
|
|
3
4
|
|
|
4
5
|
const program = new Command();
|
|
5
6
|
|
|
6
7
|
program
|
|
7
8
|
.name("ppm")
|
|
8
9
|
.description("Personal Project Manager — mobile-first web IDE")
|
|
9
|
-
.version(
|
|
10
|
+
.version(VERSION);
|
|
10
11
|
|
|
11
12
|
program
|
|
12
13
|
.command("start")
|
|
@@ -52,6 +53,25 @@ program
|
|
|
52
53
|
await openBrowser();
|
|
53
54
|
});
|
|
54
55
|
|
|
56
|
+
program
|
|
57
|
+
.command("logs")
|
|
58
|
+
.description("View PPM daemon logs")
|
|
59
|
+
.option("-n, --tail <lines>", "Number of lines to show", "50")
|
|
60
|
+
.option("-f, --follow", "Follow log output")
|
|
61
|
+
.option("--clear", "Clear log file")
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
const { showLogs } = await import("./cli/commands/logs.ts");
|
|
64
|
+
await showLogs(options);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
program
|
|
68
|
+
.command("report")
|
|
69
|
+
.description("Report a bug on GitHub (pre-fills env info + logs)")
|
|
70
|
+
.action(async () => {
|
|
71
|
+
const { reportBug } = await import("./cli/commands/report.ts");
|
|
72
|
+
await reportBug();
|
|
73
|
+
});
|
|
74
|
+
|
|
55
75
|
program
|
|
56
76
|
.command("init")
|
|
57
77
|
.description("Initialize PPM configuration (interactive or via flags)")
|