codemini-cli 0.6.4 → 0.6.6
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/codemini-web/dist/assets/{AboutDialog-MRopwNIL.js → AboutDialog-dFkTshay.js} +2 -2
- package/codemini-web/dist/assets/CodeWikiPanel-Dqup5Sen.js +1 -0
- package/codemini-web/dist/assets/ConfigDialog-DTehAh2r.js +1 -0
- package/codemini-web/dist/assets/{GitDiffDialog-gSysUg2J.js → GitDiffDialog-D4uMixee.js} +2 -2
- package/codemini-web/dist/assets/{MemoryDialog-DFUmo3Kl.js → MemoryDialog-DJqtWamU.js} +3 -3
- package/codemini-web/dist/assets/MessageBubble-BGnFIxcq.js +12 -0
- package/codemini-web/dist/assets/{PatchDiff-B8rwvEg5.js → PatchDiff-CpHAbmv3.js} +1 -1
- package/codemini-web/dist/assets/ProjectSelector-CgJDcTNL.js +1 -0
- package/codemini-web/dist/assets/SkillDialog-D1J46nMC.js +8 -0
- package/codemini-web/dist/assets/{SoulDialog-BLjUGqqB.js → SoulDialog-DIqK4utD.js} +1 -1
- package/codemini-web/dist/assets/chevron-right-BBG4s6Zh.js +1 -0
- package/codemini-web/dist/assets/{chunk-BO2N2NFS-6uELoidu.js → chunk-BO2N2NFS-fRXUeu1b.js} +4 -4
- package/codemini-web/dist/assets/{highlighted-body-OFNGDK62-gb1UMBZ5.js → highlighted-body-OFNGDK62-CKKvx7S1.js} +1 -1
- package/codemini-web/dist/assets/index-DF9s7Tuc.css +2 -0
- package/codemini-web/dist/assets/{index-CDXQGwPs.js → index-DyIUhlc8.js} +6 -6
- package/codemini-web/dist/assets/input-BKNu4DOt.js +1 -0
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-BM8yuNk5.js +1 -0
- package/codemini-web/dist/assets/{pencil-BhT11Ztp.js → pencil-C0uznNC_.js} +1 -1
- package/codemini-web/dist/assets/{refresh-cw-D7R5Lth6.js → refresh-cw-DUgU5bEu.js} +1 -1
- package/codemini-web/dist/assets/select-J6668k2a.js +1 -0
- package/codemini-web/dist/assets/{trash-2-BfNZcWfX.js → trash-2-H0DiWqiE.js} +1 -1
- package/codemini-web/dist/index.html +2 -2
- package/codemini-web/lib/runtime-bridge.js +7 -0
- package/codemini-web/server.js +100 -74
- package/package.json +1 -1
- package/src/commands/skill.js +188 -48
- package/src/core/agent-loop.js +73 -34
- package/src/core/chat-runtime.js +22 -17
- package/src/core/config-store.js +2 -4
- package/src/core/git-oplog-change-tracker.js +96 -15
- package/src/core/shell-profile.js +3 -2
- package/src/core/tools.js +144 -51
- package/codemini-web/dist/assets/CodeWikiPanel-UpK5xGE3.js +0 -1
- package/codemini-web/dist/assets/ConfigDialog-CNl28wsj.js +0 -1
- package/codemini-web/dist/assets/MessageBubble-CGnnViv0.js +0 -12
- package/codemini-web/dist/assets/ProjectSelector-BF59M1zb.js +0 -1
- package/codemini-web/dist/assets/SkillDialog-CQTjbSiw.js +0 -8
- package/codemini-web/dist/assets/chevron-right--85xg7qk.js +0 -1
- package/codemini-web/dist/assets/index-1xqD0R5t.css +0 -2
- package/codemini-web/dist/assets/input-Ca8O_061.js +0 -1
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-ROliF8Yd.js +0 -1
- package/codemini-web/dist/assets/select-DBvcHBzs.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./rolldown-runtime-S-ySWqyJ.js";import{a as e,r as t}from"./bundle-mjs-C44PrJ2C.js";import{pt as n}from"./index-DyIUhlc8.js";e();var r=t();function i({className:e,type:t,...i}){return(0,r.jsx)(`input`,{type:t,"data-slot":`input`,className:n(`h-8 w-full min-w-0 rounded-md border border-(--border-default) bg-[color-mix(in_srgb,var(--bg-input)_88%,var(--text-muted)_12%)] px-3 py-1 text-[13px] text-(--text-primary) transition-colors outline-none placeholder:text-(--text-muted) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50`,`hover:bg-[color-mix(in_srgb,var(--bg-input)_76%,var(--text-muted)_24%)] focus-visible:border-(--text-secondary) focus-visible:bg-(--bg-input) focus-visible:ring-0`,e),...i})}export{i as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e}from"./chunk-BO2N2NFS-fRXUeu1b.js";export{e as Mermaid};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./index-
|
|
1
|
+
import{P as e}from"./index-DyIUhlc8.js";var t=e(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),n=e(`pencil`,[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}]]);export{t as n,n as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./index-
|
|
1
|
+
import{P as e}from"./index-DyIUhlc8.js";var t=e(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]);export{t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-S-ySWqyJ.js";import{a as t,i as n,r}from"./bundle-mjs-C44PrJ2C.js";import{A as i,At as a,Ct as o,Et as s,Ft as c,Mt as l,Nt as u,Ot as d,Pt as f,St as p,Tt as m,_t as h,bt as g,gt as _,ht as v,jt as y,k as b,kt as x,mt as S,pt as C,vt as w,wt as ee,xt as T,yt as E}from"./index-DyIUhlc8.js";var D=e(n(),1),O=e(t(),1),k=r();function A(e){let t=e+`CollectionProvider`,[n,r]=y(t),[i,a]=n(t,{collectionRef:{current:null},itemMap:new Map}),o=e=>{let{scope:t,children:n}=e,r=O.useRef(null),a=O.useRef(new Map).current;return(0,k.jsx)(i,{scope:t,itemMap:a,collectionRef:r,children:n})};o.displayName=t;let s=e+`CollectionSlot`,l=f(s),u=O.forwardRef((e,t)=>{let{scope:n,children:r}=e;return(0,k.jsx)(l,{ref:c(t,a(s,n).collectionRef),children:r})});u.displayName=s;let d=e+`CollectionItemSlot`,p=`data-radix-collection-item`,m=f(d),h=O.forwardRef((e,t)=>{let{scope:n,children:r,...i}=e,o=O.useRef(null),s=c(t,o),l=a(d,n);return O.useEffect(()=>(l.itemMap.set(o,{ref:o,...i}),()=>void l.itemMap.delete(o))),(0,k.jsx)(m,{[p]:``,ref:s,children:r})});h.displayName=d;function g(t){let n=a(e+`CollectionConsumer`,t);return O.useCallback(()=>{let e=n.collectionRef.current;if(!e)return[];let t=Array.from(e.querySelectorAll(`[${p}]`));return Array.from(n.itemMap.values()).sort((e,n)=>t.indexOf(e.ref.current)-t.indexOf(n.ref.current))},[n.collectionRef,n.itemMap])}return[{Provider:o,Slot:u,ItemSlot:h},g,r]}var j=O.createContext(void 0);function M(e){let t=O.useContext(j);return e||t||`ltr`}function N(e){let t=O.useRef({value:e,previous:e});return O.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}function P(e,[t,n]){return Math.min(n,Math.max(t,e))}var F=[` `,`Enter`,`ArrowUp`,`ArrowDown`],I=[` `,`Enter`],L=`Select`,[R,z,B]=A(L),[V,H]=y(L,[B,w]),U=w(),[W,G]=V(L),[te,ne]=V(L),K=e=>{let{__scopeSelect:t,children:n,open:r,defaultOpen:i,onOpenChange:a,value:o,defaultValue:c,onValueChange:l,dir:u,name:f,autoComplete:p,disabled:m,required:g,form:_}=e,v=U(t),[y,b]=O.useState(null),[x,S]=O.useState(null),[C,w]=O.useState(!1),ee=M(u),[T,E]=d({prop:r,defaultProp:i??!1,onChange:a,caller:L}),[D,A]=d({prop:o,defaultProp:c,onChange:l,caller:L}),j=O.useRef(null),N=y?_||!!y.closest(`form`):!0,[P,F]=O.useState(new Set),I=Array.from(P).map(e=>e.props.value).join(`;`);return(0,k.jsx)(h,{...v,children:(0,k.jsxs)(W,{required:g,scope:t,trigger:y,onTriggerChange:b,valueNode:x,onValueNodeChange:S,valueNodeHasChildren:C,onValueNodeHasChildrenChange:w,contentId:s(),value:D,onValueChange:A,open:T,onOpenChange:E,dir:ee,triggerPointerDownPosRef:j,disabled:m,children:[(0,k.jsx)(R.Provider,{scope:t,children:(0,k.jsx)(te,{scope:e.__scopeSelect,onNativeOptionAdd:O.useCallback(e=>{F(t=>new Set(t).add(e))},[]),onNativeOptionRemove:O.useCallback(e=>{F(t=>{let n=new Set(t);return n.delete(e),n})},[]),children:n})}),N?(0,k.jsxs)(We,{"aria-hidden":!0,required:g,tabIndex:-1,name:f,autoComplete:p,value:D,onChange:e=>A(e.target.value),disabled:m,form:_,children:[D===void 0?(0,k.jsx)(`option`,{value:``}):null,Array.from(P)]},I):null]})})};K.displayName=L;var q=`SelectTrigger`,re=O.forwardRef((e,t)=>{let{__scopeSelect:n,disabled:r=!1,...i}=e,o=U(n),s=G(q,n),l=s.disabled||r,d=c(t,s.onTriggerChange),f=z(n),p=O.useRef(`touch`),[m,h,g]=Ke(e=>{let t=f().filter(e=>!e.disabled),n=qe(t,e,t.find(e=>e.value===s.value));n!==void 0&&s.onValueChange(n.value)}),_=e=>{l||(s.onOpenChange(!0),g()),e&&(s.triggerPointerDownPosRef.current={x:Math.round(e.pageX),y:Math.round(e.pageY)})};return(0,k.jsx)(S,{asChild:!0,...o,children:(0,k.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:l,"data-disabled":l?``:void 0,"data-placeholder":Ge(s.value)?``:void 0,...i,ref:d,onClick:a(i.onClick,e=>{e.currentTarget.focus(),p.current!==`mouse`&&_(e)}),onPointerDown:a(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:a(i.onKeyDown,e=>{let t=m.current!==``;!(e.ctrlKey||e.altKey||e.metaKey)&&e.key.length===1&&h(e.key),!(t&&e.key===` `)&&F.includes(e.key)&&(_(),e.preventDefault())})})})});re.displayName=q;var J=`SelectValue`,ie=O.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,children:a,placeholder:o=``,...s}=e,l=G(J,n),{onValueNodeHasChildrenChange:d}=l,f=a!==void 0,p=c(t,l.onValueNodeChange);return x(()=>{d(f)},[d,f]),(0,k.jsx)(u.span,{...s,ref:p,style:{pointerEvents:`none`},children:Ge(l.value)?(0,k.jsx)(k.Fragment,{children:o}):a})});ie.displayName=J;var ae=`SelectIcon`,oe=O.forwardRef((e,t)=>{let{__scopeSelect:n,children:r,...i}=e;return(0,k.jsx)(u.span,{"aria-hidden":!0,...i,ref:t,children:r||`▼`})});oe.displayName=ae;var se=`SelectPortal`,ce=e=>(0,k.jsx)(p,{asChild:!0,...e});ce.displayName=se;var Y=`SelectContent`,le=O.forwardRef((e,t)=>{let n=G(Y,e.__scopeSelect),[r,i]=O.useState();if(x(()=>{i(new DocumentFragment)},[]),!n.open){let t=r;return t?D.createPortal((0,k.jsx)(ue,{scope:e.__scopeSelect,children:(0,k.jsx)(R.Slot,{scope:e.__scopeSelect,children:(0,k.jsx)(`div`,{children:e.children})})}),t):null}return(0,k.jsx)(pe,{...e,ref:t})});le.displayName=Y;var X=10,[ue,Z]=V(Y),de=`SelectContentImpl`,fe=f(`SelectContent.RemoveScroll`),pe=O.forwardRef((e,t)=>{let{__scopeSelect:n,position:r=`item-aligned`,onCloseAutoFocus:i,onEscapeKeyDown:s,onPointerDownOutside:l,side:u,sideOffset:d,align:f,alignOffset:p,arrowPadding:m,collisionBoundary:h,collisionPadding:_,sticky:v,hideWhenDetached:y,avoidCollisions:b,...x}=e,S=G(Y,n),[C,w]=O.useState(null),[D,A]=O.useState(null),j=c(t,e=>w(e)),[M,N]=O.useState(null),[P,F]=O.useState(null),I=z(n),[L,R]=O.useState(!1),B=O.useRef(!1);O.useEffect(()=>{if(C)return E(C)},[C]),T();let V=O.useCallback(e=>{let[t,...n]=I().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},[I,D]),H=O.useCallback(()=>V([M,C]),[V,M,C]);O.useEffect(()=>{L&&H()},[L,H]);let{onOpenChange:U,triggerPointerDownPosRef:W}=S;O.useEffect(()=>{if(C){let e={x:0,y:0},t=t=>{e={x:Math.abs(Math.round(t.pageX)-(W.current?.x??0)),y:Math.abs(Math.round(t.pageY)-(W.current?.y??0))}},n=n=>{e.x<=10&&e.y<=10?n.preventDefault():C.contains(n.target)||U(!1),document.removeEventListener(`pointermove`,t),W.current=null};return W.current!==null&&(document.addEventListener(`pointermove`,t),document.addEventListener(`pointerup`,n,{capture:!0,once:!0})),()=>{document.removeEventListener(`pointermove`,t),document.removeEventListener(`pointerup`,n,{capture:!0})}}},[C,U,W]),O.useEffect(()=>{let e=()=>U(!1);return window.addEventListener(`blur`,e),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`blur`,e),window.removeEventListener(`resize`,e)}},[U]);let[te,ne]=Ke(e=>{let t=I().filter(e=>!e.disabled),n=qe(t,e,t.find(e=>e.ref.current===document.activeElement));n&&setTimeout(()=>n.ref.current.focus())}),K=O.useCallback((e,t,n)=>{let r=!B.current&&!n;(S.value!==void 0&&S.value===t||r)&&(N(e),r&&(B.current=!0))},[S.value]),q=O.useCallback(()=>C?.focus(),[C]),re=O.useCallback((e,t,n)=>{let r=!B.current&&!n;(S.value!==void 0&&S.value===t||r)&&F(e)},[S.value]),J=r===`popper`?_e:he,ie=J===_e?{side:u,sideOffset:d,align:f,alignOffset:p,arrowPadding:m,collisionBoundary:h,collisionPadding:_,sticky:v,hideWhenDetached:y,avoidCollisions:b}:{};return(0,k.jsx)(ue,{scope:n,content:C,viewport:D,onViewportChange:A,itemRefCallback:K,selectedItem:M,onItemLeave:q,itemTextRefCallback:re,focusSelectedItem:H,selectedItemText:P,position:r,isPositioned:L,searchRef:te,children:(0,k.jsx)(g,{as:fe,allowPinchZoom:!0,children:(0,k.jsx)(o,{asChild:!0,trapped:S.open,onMountAutoFocus:e=>{e.preventDefault()},onUnmountAutoFocus:a(i,e=>{S.trigger?.focus({preventScroll:!0}),e.preventDefault()}),children:(0,k.jsx)(ee,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:s,onPointerDownOutside:l,onFocusOutside:e=>e.preventDefault(),onDismiss:()=>S.onOpenChange(!1),children:(0,k.jsx)(J,{role:`listbox`,id:S.contentId,"data-state":S.open?`open`:`closed`,dir:S.dir,onContextMenu:e=>e.preventDefault(),...x,...ie,onPlaced:()=>R(!0),ref:j,style:{display:`flex`,flexDirection:`column`,outline:`none`,...x.style},onKeyDown:a(x.onKeyDown,e=>{let t=e.ctrlKey||e.altKey||e.metaKey;if(e.key===`Tab`&&e.preventDefault(),!t&&e.key.length===1&&ne(e.key),[`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key)){let t=I().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(()=>V(t)),e.preventDefault()}})})})})})})});pe.displayName=de;var me=`SelectItemAlignedPosition`,he=O.forwardRef((e,t)=>{let{__scopeSelect:n,onPlaced:r,...i}=e,a=G(Y,n),o=Z(Y,n),[s,l]=O.useState(null),[d,f]=O.useState(null),p=c(t,e=>f(e)),m=z(n),h=O.useRef(!1),g=O.useRef(!0),{viewport:_,selectedItem:v,selectedItemText:y,focusSelectedItem:b}=o,S=O.useCallback(()=>{if(a.trigger&&a.valueNode&&s&&d&&_&&v&&y){let e=a.trigger.getBoundingClientRect(),t=d.getBoundingClientRect(),n=a.valueNode.getBoundingClientRect(),i=y.getBoundingClientRect();if(a.dir!==`rtl`){let r=i.left-t.left,a=n.left-r,o=e.left-a,c=e.width+o,l=Math.max(c,t.width),u=window.innerWidth-X,d=P(a,[X,Math.max(X,u-l)]);s.style.minWidth=c+`px`,s.style.left=d+`px`}else{let r=t.right-i.right,a=window.innerWidth-n.right-r,o=window.innerWidth-e.right-a,c=e.width+o,l=Math.max(c,t.width),u=window.innerWidth-X,d=P(a,[X,Math.max(X,u-l)]);s.style.minWidth=c+`px`,s.style.right=d+`px`}let o=m(),c=window.innerHeight-X*2,l=_.scrollHeight,u=window.getComputedStyle(d),f=parseInt(u.borderTopWidth,10),p=parseInt(u.paddingTop,10),g=parseInt(u.borderBottomWidth,10),b=parseInt(u.paddingBottom,10),x=f+p+l+b+g,S=Math.min(v.offsetHeight*5,x),C=window.getComputedStyle(_),w=parseInt(C.paddingTop,10),ee=parseInt(C.paddingBottom,10),T=e.top+e.height/2-X,E=c-T,D=v.offsetHeight/2,O=v.offsetTop+D,k=f+p+O,A=x-k;if(k<=T){let e=o.length>0&&v===o[o.length-1].ref.current;s.style.bottom=`0px`;let t=d.clientHeight-_.offsetTop-_.offsetHeight,n=k+Math.max(E,D+(e?ee:0)+t+g);s.style.height=n+`px`}else{let e=o.length>0&&v===o[0].ref.current;s.style.top=`0px`;let t=Math.max(T,f+_.offsetTop+(e?w:0)+D)+A;s.style.height=t+`px`,_.scrollTop=k-T+_.offsetTop}s.style.margin=`${X}px 0`,s.style.minHeight=S+`px`,s.style.maxHeight=c+`px`,r?.(),requestAnimationFrame(()=>h.current=!0)}},[m,a.trigger,a.valueNode,s,d,_,v,y,a.dir,r]);x(()=>S(),[S]);let[C,w]=O.useState();return x(()=>{d&&w(window.getComputedStyle(d).zIndex)},[d]),(0,k.jsx)(ve,{scope:n,contentWrapper:s,shouldExpandOnScrollRef:h,onScrollButtonChange:O.useCallback(e=>{e&&g.current===!0&&(S(),b?.(),g.current=!1)},[S,b]),children:(0,k.jsx)(`div`,{ref:l,style:{display:`flex`,flexDirection:`column`,position:`fixed`,zIndex:C},children:(0,k.jsx)(u.div,{...i,ref:p,style:{boxSizing:`border-box`,maxHeight:`100%`,...i.style}})})})});he.displayName=me;var ge=`SelectPopperPosition`,_e=O.forwardRef((e,t)=>{let{__scopeSelect:n,align:r=`start`,collisionPadding:i=X,...a}=e,o=U(n);return(0,k.jsx)(_,{...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)`}})});_e.displayName=ge;var[ve,ye]=V(Y,{}),be=`SelectViewport`,xe=O.forwardRef((e,t)=>{let{__scopeSelect:n,nonce:r,...i}=e,o=Z(be,n),s=ye(be,n),l=c(t,o.onViewportChange),d=O.useRef(0);return(0,k.jsxs)(k.Fragment,{children:[(0,k.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,k.jsx)(R.Slot,{scope:n,children:(0,k.jsx)(u.div,{"data-radix-select-viewport":``,role:`presentation`,...i,ref:l,style:{position:`relative`,flex:1,overflow:`hidden auto`,...i.style},onScroll:a(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-X*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})})})]})});xe.displayName=be;var Se=`SelectGroup`,[Ce,we]=V(Se),Te=O.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=s();return(0,k.jsx)(Ce,{scope:n,id:i,children:(0,k.jsx)(u.div,{role:`group`,"aria-labelledby":i,...r,ref:t})})});Te.displayName=Se;var Ee=`SelectLabel`,De=O.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=we(Ee,n);return(0,k.jsx)(u.div,{id:i.id,...r,ref:t})});De.displayName=Ee;var Q=`SelectItem`,[Oe,ke]=V(Q),Ae=O.forwardRef((e,t)=>{let{__scopeSelect:n,value:r,disabled:i=!1,textValue:o,...l}=e,d=G(Q,n),f=Z(Q,n),p=d.value===r,[m,h]=O.useState(o??``),[g,_]=O.useState(!1),v=c(t,e=>f.itemRefCallback?.(e,r,i)),y=s(),b=O.useRef(`touch`),x=()=>{i||(d.onValueChange(r),d.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,k.jsx)(Oe,{scope:n,value:r,disabled:i,textId:y,isSelected:p,onItemTextChange:O.useCallback(e=>{h(t=>t||(e?.textContent??``).trim())},[]),children:(0,k.jsx)(R.ItemSlot,{scope:n,value:r,disabled:i,textValue:m,children:(0,k.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,...l,ref:v,onFocus:a(l.onFocus,()=>_(!0)),onBlur:a(l.onBlur,()=>_(!1)),onClick:a(l.onClick,()=>{b.current!==`mouse`&&x()}),onPointerUp:a(l.onPointerUp,()=>{b.current===`mouse`&&x()}),onPointerDown:a(l.onPointerDown,e=>{b.current=e.pointerType}),onPointerMove:a(l.onPointerMove,e=>{b.current=e.pointerType,i?f.onItemLeave?.():b.current===`mouse`&&e.currentTarget.focus({preventScroll:!0})}),onPointerLeave:a(l.onPointerLeave,e=>{e.currentTarget===document.activeElement&&f.onItemLeave?.()}),onKeyDown:a(l.onKeyDown,e=>{f.searchRef?.current!==``&&e.key===` `||(I.includes(e.key)&&x(),e.key===` `&&e.preventDefault())})})})})});Ae.displayName=Q;var $=`SelectItemText`,je=O.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,...a}=e,o=G($,n),s=Z($,n),l=ke($,n),d=ne($,n),[f,p]=O.useState(null),m=c(t,e=>p(e),l.onItemTextChange,e=>s.itemTextRefCallback?.(e,l.value,l.disabled)),h=f?.textContent,g=O.useMemo(()=>(0,k.jsx)(`option`,{value:l.value,disabled:l.disabled,children:h},l.value),[l.disabled,l.value,h]),{onNativeOptionAdd:_,onNativeOptionRemove:v}=d;return x(()=>(_(g),()=>v(g)),[_,v,g]),(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(u.span,{id:l.textId,...a,ref:m}),l.isSelected&&o.valueNode&&!o.valueNodeHasChildren?D.createPortal(a.children,o.valueNode):null]})});je.displayName=$;var Me=`SelectItemIndicator`,Ne=O.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return ke(Me,n).isSelected?(0,k.jsx)(u.span,{"aria-hidden":!0,...r,ref:t}):null});Ne.displayName=Me;var Pe=`SelectScrollUpButton`,Fe=O.forwardRef((e,t)=>{let n=Z(Pe,e.__scopeSelect),r=ye(Pe,e.__scopeSelect),[i,a]=O.useState(!1),o=c(t,r.onScrollButtonChange);return x(()=>{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,k.jsx)(Re,{...e,ref:o,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop-=t.offsetHeight)}}):null});Fe.displayName=Pe;var Ie=`SelectScrollDownButton`,Le=O.forwardRef((e,t)=>{let n=Z(Ie,e.__scopeSelect),r=ye(Ie,e.__scopeSelect),[i,a]=O.useState(!1),o=c(t,r.onScrollButtonChange);return x(()=>{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,k.jsx)(Re,{...e,ref:o,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop+=t.offsetHeight)}}):null});Le.displayName=Ie;var Re=O.forwardRef((e,t)=>{let{__scopeSelect:n,onAutoScroll:r,...i}=e,o=Z(`SelectScrollButton`,n),s=O.useRef(null),c=z(n),l=O.useCallback(()=>{s.current!==null&&(window.clearInterval(s.current),s.current=null)},[]);return O.useEffect(()=>()=>l(),[l]),x(()=>{c().find(e=>e.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:`nearest`})},[c]),(0,k.jsx)(u.div,{"aria-hidden":!0,...i,ref:t,style:{flexShrink:0,...i.style},onPointerDown:a(i.onPointerDown,()=>{s.current===null&&(s.current=window.setInterval(r,50))}),onPointerMove:a(i.onPointerMove,()=>{o.onItemLeave?.(),s.current===null&&(s.current=window.setInterval(r,50))}),onPointerLeave:a(i.onPointerLeave,()=>{l()})})}),ze=`SelectSeparator`,Be=O.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return(0,k.jsx)(u.div,{"aria-hidden":!0,...r,ref:t})});Be.displayName=ze;var Ve=`SelectArrow`,He=O.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=U(n),a=G(Ve,n),o=Z(Ve,n);return a.open&&o.position===`popper`?(0,k.jsx)(v,{...i,...r,ref:t}):null});He.displayName=Ve;var Ue=`SelectBubbleInput`,We=O.forwardRef(({__scopeSelect:e,value:t,...n},r)=>{let i=O.useRef(null),a=c(r,i),o=N(t);return O.useEffect(()=>{let e=i.current;if(!e)return;let n=window.HTMLSelectElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`).set;if(o!==t&&r){let n=new Event(`change`,{bubbles:!0});r.call(e,t),e.dispatchEvent(n)}},[o,t]),(0,k.jsx)(u.select,{...n,style:{...l,...n.style},ref:a,defaultValue:t})});We.displayName=Ue;function Ge(e){return e===``||e===void 0}function Ke(e){let t=m(e),n=O.useRef(``),r=O.useRef(0),i=O.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=O.useCallback(()=>{n.current=``,window.clearTimeout(r.current)},[]);return O.useEffect(()=>()=>window.clearTimeout(r.current),[]),[n,i,a]}function qe(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=Je(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 Je(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var Ye=K,Xe=re,Ze=ie,Qe=oe,$e=ce,et=le,tt=xe,nt=Ae,rt=je,it=Ne,at=Fe,ot=Le;function st({...e}){return(0,k.jsx)(Ye,{"data-slot":`select`,...e})}function ct({...e}){return(0,k.jsx)(Ze,{"data-slot":`select-value`,...e})}function lt({className:e,size:t,children:n,...r}){return(0,k.jsxs)(Xe,{"data-slot":`select-trigger`,"data-size":t,className:C(`flex w-fit items-center justify-between gap-2 rounded-md border border-(--border-default) bg-[color-mix(in_srgb,var(--bg-input)_88%,var(--text-muted)_12%)] px-3 py-1 text-[13px] text-(--text-primary) whitespace-nowrap transition-colors outline-none hover:bg-[color-mix(in_srgb,var(--bg-input)_76%,var(--text-muted)_24%)] focus-visible:border-(--text-secondary) focus-visible:bg-(--bg-input) focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-(--text-muted) 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 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-(--text-muted)`,e),...r,children:[n,(0,k.jsx)(Qe,{asChild:!0,children:(0,k.jsx)(b,{className:`size-3.5 opacity-50`})})]})}function ut({className:e,children:t,position:n=`item-aligned`,align:r=`center`,...i}){return(0,k.jsx)($e,{children:(0,k.jsxs)(et,{"data-slot":`select-content`,className:C(`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-lg border border-(--border-default) bg-(--bg-primary) text-(--text-primary) 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,k.jsx)(ft,{}),(0,k.jsx)(tt,{className:C(`p-1`,n===`popper`&&`h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]`),children:t}),(0,k.jsx)(pt,{})]})})}function dt({className:e,children:t,...n}){return(0,k.jsxs)(nt,{"data-slot":`select-item`,className:C(`relative flex w-full cursor-pointer items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-[13px] outline-hidden select-none hover:bg-(--bg-hover) 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-(--text-muted) *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,e),...n,children:[(0,k.jsx)(`span`,{"data-slot":`select-item-indicator`,className:`absolute right-2 flex size-3.5 items-center justify-center`,children:(0,k.jsx)(it,{children:(0,k.jsx)(i,{className:`size-4`})})}),(0,k.jsx)(rt,{children:t})]})}function ft({className:e,...t}){return(0,k.jsx)(at,{"data-slot":`select-scroll-up-button`,className:C(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,k.jsx)(b,{className:`size-4 rotate-180`})})}function pt({className:e,...t}){return(0,k.jsx)(ot,{"data-slot":`select-scroll-down-button`,className:C(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,k.jsx)(b,{className:`size-4`})})}export{ct as a,lt as i,ut as n,P as o,dt as r,M as s,st as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e}from"./index-
|
|
1
|
+
import{P as e}from"./index-DyIUhlc8.js";var t=e(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),n=e(`trash-2`,[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]);export{t as n,n as t};
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
}
|
|
27
27
|
})();
|
|
28
28
|
</script>
|
|
29
|
-
<script type="module" crossorigin src="/assets/index-
|
|
29
|
+
<script type="module" crossorigin src="/assets/index-DyIUhlc8.js"></script>
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-S-ySWqyJ.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/bundle-mjs-C44PrJ2C.js">
|
|
32
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
32
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DF9s7Tuc.css">
|
|
33
33
|
</head>
|
|
34
34
|
<body class="font-sans antialiased">
|
|
35
35
|
<div id="root"></div>
|
|
@@ -746,6 +746,13 @@ export class RuntimeBridge {
|
|
|
746
746
|
return result || { error: true, message: 'Git change oplog is not available' };
|
|
747
747
|
}
|
|
748
748
|
|
|
749
|
+
async undoChangeSets(ids) {
|
|
750
|
+
if (this.#busy) return { error: true, message: 'A request is already in progress' };
|
|
751
|
+
const result = await this.#runtime.undoChangeSets?.(ids);
|
|
752
|
+
this.#broadcast({ type: 'change:undone', result });
|
|
753
|
+
return result || { error: true, message: 'Git change oplog is not available' };
|
|
754
|
+
}
|
|
755
|
+
|
|
749
756
|
async getUiMessages() {
|
|
750
757
|
this.#resetUiTranscriptIfSessionChanged();
|
|
751
758
|
if (this.#uiMessages.length > 0) return this.#uiMessages;
|
package/codemini-web/server.js
CHANGED
|
@@ -1165,7 +1165,7 @@ async function main() {
|
|
|
1165
1165
|
}
|
|
1166
1166
|
return;
|
|
1167
1167
|
}
|
|
1168
|
-
if (req.method === 'POST' && url.pathname.startsWith('/api/session-changes/') && url.pathname.endsWith('/undo')) {
|
|
1168
|
+
if (req.method === 'POST' && url.pathname !== '/api/session-changes/undo' && url.pathname.startsWith('/api/session-changes/') && url.pathname.endsWith('/undo')) {
|
|
1169
1169
|
const id = decodeURIComponent(url.pathname.slice('/api/session-changes/'.length, -'/undo'.length));
|
|
1170
1170
|
try {
|
|
1171
1171
|
jsonResponse(res, await bridge.undoChangeSet(id));
|
|
@@ -1174,6 +1174,15 @@ async function main() {
|
|
|
1174
1174
|
}
|
|
1175
1175
|
return;
|
|
1176
1176
|
}
|
|
1177
|
+
if (req.method === 'POST' && url.pathname === '/api/session-changes/undo') {
|
|
1178
|
+
const { ids } = await readBody(req);
|
|
1179
|
+
try {
|
|
1180
|
+
jsonResponse(res, await bridge.undoChangeSets(ids));
|
|
1181
|
+
} catch (err) {
|
|
1182
|
+
jsonResponse(res, { error: true, message: err?.message || 'Failed to undo changes' }, 409);
|
|
1183
|
+
}
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1177
1186
|
if (req.method === 'POST' && url.pathname === '/api/git-batch') {
|
|
1178
1187
|
const { dirs } = await readBody(req);
|
|
1179
1188
|
const result = {};
|
|
@@ -1341,18 +1350,21 @@ async function main() {
|
|
|
1341
1350
|
jsonResponse(res, { name: skill.name, content, scope: skill.scope });
|
|
1342
1351
|
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
1343
1352
|
return;
|
|
1344
|
-
}
|
|
1345
|
-
if (req.method === 'POST' && url.pathname === '/api/skills/create') {
|
|
1346
|
-
const { name, description, content, scope: rawScope } = await readBody(req);
|
|
1347
|
-
if (!name || !content) { jsonResponse(res, { error: true, message: 'Missing name or content' }, 400); return; }
|
|
1348
|
-
if (!isSafeSkillName(name)) { jsonResponse(res, { error: true, message: 'Invalid skill name' }, 400); return; }
|
|
1349
|
-
try {
|
|
1350
|
-
const scope = normalizeSkillScope(rawScope);
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1353
|
+
}
|
|
1354
|
+
if (req.method === 'POST' && url.pathname === '/api/skills/create') {
|
|
1355
|
+
const { name, description, content, scope: rawScope, projectDir } = await readBody(req);
|
|
1356
|
+
if (!name || !content) { jsonResponse(res, { error: true, message: 'Missing name or content' }, 400); return; }
|
|
1357
|
+
if (!isSafeSkillName(name)) { jsonResponse(res, { error: true, message: 'Invalid skill name' }, 400); return; }
|
|
1358
|
+
try {
|
|
1359
|
+
const scope = normalizeSkillScope(rawScope);
|
|
1360
|
+
const targetProjectDir = scope === 'project'
|
|
1361
|
+
? await resolveRequestProjectDir(projectDir, currentProjectDir)
|
|
1362
|
+
: currentProjectDir;
|
|
1363
|
+
const skillBaseDir = skillBaseDirForScope(scope, targetProjectDir);
|
|
1364
|
+
const skillDir = path.join(skillBaseDir, name);
|
|
1365
|
+
await fs.mkdir(skillDir, { recursive: true });
|
|
1366
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
1367
|
+
await fs.writeFile(skillFile, content, 'utf8');
|
|
1356
1368
|
if (scope === 'global') {
|
|
1357
1369
|
await upsertSkillRegistryEntry(undefined, {
|
|
1358
1370
|
name,
|
|
@@ -1362,38 +1374,41 @@ async function main() {
|
|
|
1362
1374
|
source: 'web-create',
|
|
1363
1375
|
entryFile: 'SKILL.md',
|
|
1364
1376
|
sha256: await computeFileSha256(skillFile),
|
|
1365
|
-
installedAt: new Date().toISOString()
|
|
1366
|
-
});
|
|
1367
|
-
} else {
|
|
1368
|
-
await upsertProjectSkillMetadata(
|
|
1369
|
-
description: description || '',
|
|
1370
|
-
mode: 'agent_requested',
|
|
1371
|
-
triggers: [],
|
|
1372
|
-
enabled: true,
|
|
1377
|
+
installedAt: new Date().toISOString()
|
|
1378
|
+
});
|
|
1379
|
+
} else {
|
|
1380
|
+
await upsertProjectSkillMetadata(targetProjectDir, name, {
|
|
1381
|
+
description: description || '',
|
|
1382
|
+
mode: 'agent_requested',
|
|
1383
|
+
triggers: [],
|
|
1384
|
+
enabled: true,
|
|
1373
1385
|
priority: 50
|
|
1374
1386
|
});
|
|
1375
1387
|
}
|
|
1376
1388
|
const config = await loadConfig();
|
|
1377
1389
|
config.skills = config.skills || {};
|
|
1378
1390
|
config.skills.enabled = config.skills.enabled || {};
|
|
1379
|
-
config.skills.enabled[name] = true;
|
|
1380
|
-
await saveConfig(config);
|
|
1381
|
-
await bridge.reloadCommandsAndSkills();
|
|
1382
|
-
jsonResponse(res, { ok: true, name, scope });
|
|
1383
|
-
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1386
|
-
if (req.method === 'POST' && url.pathname === '/api/skills/install') {
|
|
1387
|
-
const { source, scope: rawScope } = await readBody(req);
|
|
1388
|
-
if (!source) { jsonResponse(res, { error: true, message: 'Missing source' }, 400); return; }
|
|
1389
|
-
try {
|
|
1390
|
-
const scope = normalizeSkillScope(rawScope);
|
|
1391
|
-
const
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1391
|
+
config.skills.enabled[name] = true;
|
|
1392
|
+
await saveConfig(config);
|
|
1393
|
+
await bridge.reloadCommandsAndSkills();
|
|
1394
|
+
jsonResponse(res, { ok: true, name, scope, projectDir: scope === 'project' ? targetProjectDir : '' });
|
|
1395
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
if (req.method === 'POST' && url.pathname === '/api/skills/install') {
|
|
1399
|
+
const { source, scope: rawScope, projectDir } = await readBody(req);
|
|
1400
|
+
if (!source) { jsonResponse(res, { error: true, message: 'Missing source' }, 400); return; }
|
|
1401
|
+
try {
|
|
1402
|
+
const scope = normalizeSkillScope(rawScope);
|
|
1403
|
+
const targetProjectDir = scope === 'project'
|
|
1404
|
+
? await resolveRequestProjectDir(projectDir, currentProjectDir)
|
|
1405
|
+
: currentProjectDir;
|
|
1406
|
+
const installed = await installSkillSource(source, { scope, cwd: targetProjectDir });
|
|
1407
|
+
await bridge.reloadCommandsAndSkills();
|
|
1408
|
+
jsonResponse(res, { ok: true, installed, scope, projectDir: scope === 'project' ? targetProjectDir : '' });
|
|
1409
|
+
} catch (err) { jsonResponse(res, { error: true, message: err.message }, 500); }
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1397
1412
|
if (req.method === 'PUT' && url.pathname.startsWith('/api/skills/') && url.pathname.endsWith('/content')) {
|
|
1398
1413
|
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length, -'/content'.length));
|
|
1399
1414
|
const { content, projectDir } = await readBody(req);
|
|
@@ -1439,27 +1454,34 @@ async function main() {
|
|
|
1439
1454
|
}
|
|
1440
1455
|
if (req.method === 'PUT' && url.pathname.startsWith('/api/skills/') && url.pathname.endsWith('/metadata')) {
|
|
1441
1456
|
const name = decodeURIComponent(url.pathname.slice('/api/skills/'.length, -'/metadata'.length));
|
|
1442
|
-
const body = await readBody(req);
|
|
1443
|
-
try {
|
|
1444
|
-
const targetProjectDir = await resolveRequestProjectDir(body?.projectDir, currentProjectDir);
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1457
|
+
const body = await readBody(req);
|
|
1458
|
+
try {
|
|
1459
|
+
const targetProjectDir = await resolveRequestProjectDir(body?.projectDir, currentProjectDir);
|
|
1460
|
+
const requestedProjectDir = body?.targetProjectDir
|
|
1461
|
+
? await resolveRequestProjectDir(body.targetProjectDir, currentProjectDir)
|
|
1462
|
+
: targetProjectDir;
|
|
1463
|
+
const entries = await listSkillEntries({ scope: 'all', cwd: targetProjectDir });
|
|
1464
|
+
const skill = entries.find(s => s.name === name);
|
|
1465
|
+
if (!skill) { jsonResponse(res, { error: true, message: 'Skill not found' }, 404); return; }
|
|
1448
1466
|
if (skill.scope === 'builtin' && body?.scope && body.scope !== 'builtin') {
|
|
1449
1467
|
jsonResponse(res, { error: true, message: 'Cannot move builtin skill' }, 403);
|
|
1450
1468
|
return;
|
|
1451
1469
|
}
|
|
1452
1470
|
const metadataPatch = normalizeSkillMetadataPatch(body || {});
|
|
1453
|
-
let metadata = metadataPatch;
|
|
1454
|
-
const requestedScope = body?.scope ? normalizeSkillScope(body.scope) : skill.scope;
|
|
1455
|
-
let nextScope = skill.scope;
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1471
|
+
let metadata = metadataPatch;
|
|
1472
|
+
const requestedScope = body?.scope ? normalizeSkillScope(body.scope) : skill.scope;
|
|
1473
|
+
let nextScope = skill.scope;
|
|
1474
|
+
let nextProjectDir = targetProjectDir;
|
|
1475
|
+
|
|
1476
|
+
if (
|
|
1477
|
+
skill.scope !== 'builtin' &&
|
|
1478
|
+
(requestedScope !== skill.scope || (requestedScope === 'project' && requestedProjectDir !== targetProjectDir))
|
|
1479
|
+
) {
|
|
1480
|
+
const sourceDir = path.dirname(skill.path);
|
|
1481
|
+
const targetBaseDir = skillBaseDirForScope(requestedScope, requestedProjectDir);
|
|
1482
|
+
const targetDir = path.join(targetBaseDir, name);
|
|
1483
|
+
await fs.rm(targetDir, { recursive: true, force: true });
|
|
1484
|
+
await fs.mkdir(path.dirname(targetDir), { recursive: true });
|
|
1463
1485
|
await fs.cp(sourceDir, targetDir, { recursive: true, force: true });
|
|
1464
1486
|
await fs.rm(sourceDir, { recursive: true, force: true });
|
|
1465
1487
|
if (requestedScope === 'global') {
|
|
@@ -1472,29 +1494,33 @@ async function main() {
|
|
|
1472
1494
|
source: 'web-move',
|
|
1473
1495
|
entryFile: 'SKILL.md',
|
|
1474
1496
|
sha256: await computeFileSha256(path.join(targetDir, 'SKILL.md')),
|
|
1475
|
-
installedAt: new Date().toISOString()
|
|
1476
|
-
});
|
|
1477
|
-
} else {
|
|
1478
|
-
const registry = await readSkillRegistry();
|
|
1479
|
-
registry.skills = (registry.skills || []).filter(s => s.name !== name);
|
|
1480
|
-
await writeSkillRegistry(undefined, registry);
|
|
1481
|
-
await deleteSkillCatalogMetadata(getSkillsDir(), name);
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1497
|
+
installedAt: new Date().toISOString()
|
|
1498
|
+
});
|
|
1499
|
+
} else {
|
|
1500
|
+
const registry = await readSkillRegistry();
|
|
1501
|
+
registry.skills = (registry.skills || []).filter(s => s.name !== name);
|
|
1502
|
+
await writeSkillRegistry(undefined, registry);
|
|
1503
|
+
await deleteSkillCatalogMetadata(getSkillsDir(), name);
|
|
1504
|
+
if (requestedProjectDir !== targetProjectDir) {
|
|
1505
|
+
await deleteSkillCatalogMetadata(getProjectSkillsDir(targetProjectDir), name);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
nextScope = requestedScope;
|
|
1509
|
+
nextProjectDir = requestedScope === 'project' ? requestedProjectDir : targetProjectDir;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
if (nextScope === 'global') {
|
|
1487
1513
|
await upsertSkillRegistryEntry(undefined, {
|
|
1488
1514
|
name,
|
|
1489
1515
|
...(metadataPatch.description !== undefined ? { description: metadataPatch.description } : {}),
|
|
1490
1516
|
...(metadataPatch.enabled !== undefined ? { enabled: metadataPatch.enabled } : {})
|
|
1491
|
-
});
|
|
1492
|
-
metadata = await upsertSkillCatalogMetadata(getSkillsDir(), name, body || {});
|
|
1493
|
-
} else if (nextScope === 'project') {
|
|
1494
|
-
metadata = await upsertProjectSkillMetadata(
|
|
1495
|
-
} else if (skill.scope !== 'builtin') {
|
|
1496
|
-
metadata = await upsertProjectSkillMetadata(targetProjectDir, name, body || {});
|
|
1497
|
-
} else {
|
|
1517
|
+
});
|
|
1518
|
+
metadata = await upsertSkillCatalogMetadata(getSkillsDir(), name, body || {});
|
|
1519
|
+
} else if (nextScope === 'project') {
|
|
1520
|
+
metadata = await upsertProjectSkillMetadata(nextProjectDir, name, body || {});
|
|
1521
|
+
} else if (skill.scope !== 'builtin') {
|
|
1522
|
+
metadata = await upsertProjectSkillMetadata(targetProjectDir, name, body || {});
|
|
1523
|
+
} else {
|
|
1498
1524
|
metadata = await upsertProjectSkillMetadata(targetProjectDir, name, body || {});
|
|
1499
1525
|
}
|
|
1500
1526
|
if (skill.scope !== 'builtin' && body?.enabled !== undefined) {
|
package/package.json
CHANGED
package/src/commands/skill.js
CHANGED
|
@@ -6,13 +6,15 @@ import { copyRecursive } from '../core/fs-utils.js';
|
|
|
6
6
|
import { loadConfig, saveConfig } from '../core/config-store.js';
|
|
7
7
|
import { loadCommandsAndSkills } from '../core/command-loader.js';
|
|
8
8
|
import { getProjectSkillsDir, getSkillsDir } from '../core/paths.js';
|
|
9
|
-
import {
|
|
10
|
-
computeFileSha256,
|
|
11
|
-
readSkillRegistry,
|
|
12
|
-
upsertSkillRegistryEntry,
|
|
13
|
-
writeSkillRegistry
|
|
14
|
-
} from '../core/skill-registry.js';
|
|
15
|
-
|
|
9
|
+
import {
|
|
10
|
+
computeFileSha256,
|
|
11
|
+
readSkillRegistry,
|
|
12
|
+
upsertSkillRegistryEntry,
|
|
13
|
+
writeSkillRegistry
|
|
14
|
+
} from '../core/skill-registry.js';
|
|
15
|
+
|
|
16
|
+
const SKILL_CATALOG_FILE = 'codemini.skills.json';
|
|
17
|
+
|
|
16
18
|
function parseScopeArgs(args = [], { defaultScope = 'project', allowAll = false } = {}) {
|
|
17
19
|
let scope = defaultScope;
|
|
18
20
|
const rest = [];
|
|
@@ -195,16 +197,132 @@ async function runTarExtract(tgzPath, destDir) {
|
|
|
195
197
|
});
|
|
196
198
|
}
|
|
197
199
|
|
|
198
|
-
async function readManifestSafe(skillRoot) {
|
|
199
|
-
const p = path.join(skillRoot, 'manifest.json');
|
|
200
|
-
try {
|
|
201
|
-
const raw = await fs.readFile(p, 'utf8');
|
|
202
|
-
return JSON.parse(raw);
|
|
200
|
+
async function readManifestSafe(skillRoot) {
|
|
201
|
+
const p = path.join(skillRoot, 'manifest.json');
|
|
202
|
+
try {
|
|
203
|
+
const raw = await fs.readFile(p, 'utf8');
|
|
204
|
+
return JSON.parse(raw);
|
|
203
205
|
} catch {
|
|
204
206
|
return null;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function parseArrayText(value) {
|
|
211
|
+
const inner = value.slice(1, -1).trim();
|
|
212
|
+
if (!inner) return [];
|
|
213
|
+
return inner.split(',').map((item) => item.trim().replace(/^["']|["']$/g, ''));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function parseSkillFrontmatter(raw) {
|
|
217
|
+
const normalized = String(raw || '').replace(/\r\n/g, '\n');
|
|
218
|
+
if (!normalized.startsWith('---\n')) {
|
|
219
|
+
return { metadata: {}, content: normalized };
|
|
220
|
+
}
|
|
221
|
+
const end = normalized.indexOf('\n---\n', 4);
|
|
222
|
+
if (end === -1) {
|
|
223
|
+
return { metadata: {}, content: normalized };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const metadata = {};
|
|
227
|
+
const metaRaw = normalized.slice(4, end).trim();
|
|
228
|
+
for (const line of metaRaw.split('\n')) {
|
|
229
|
+
const idx = line.indexOf(':');
|
|
230
|
+
if (idx <= 0) continue;
|
|
231
|
+
const key = line.slice(0, idx).trim();
|
|
232
|
+
const value = line.slice(idx + 1).trim();
|
|
233
|
+
metadata[key] = value.startsWith('[') && value.endsWith(']')
|
|
234
|
+
? parseArrayText(value)
|
|
235
|
+
: value.replace(/^["']|["']$/g, '');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
metadata,
|
|
240
|
+
content: normalized.slice(end + 5).trim()
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function cleanDescriptionText(value) {
|
|
245
|
+
return String(value || '')
|
|
246
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
247
|
+
.replace(/[`*_~]/g, '')
|
|
248
|
+
.replace(/\s+/g, ' ')
|
|
249
|
+
.trim()
|
|
250
|
+
.slice(0, 240);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function inferDescriptionFromSkillMarkdown(content) {
|
|
254
|
+
const lines = String(content || '').replace(/\r\n/g, '\n').split('\n');
|
|
255
|
+
let inFence = false;
|
|
256
|
+
const paragraph = [];
|
|
257
|
+
|
|
258
|
+
for (const rawLine of lines) {
|
|
259
|
+
const trimmed = rawLine.trim();
|
|
260
|
+
if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {
|
|
261
|
+
inFence = !inFence;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (inFence) continue;
|
|
265
|
+
|
|
266
|
+
if (!trimmed) {
|
|
267
|
+
if (paragraph.length > 0) break;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (/^#{1,6}\s+/.test(trimmed)) continue;
|
|
271
|
+
if (/^<!--/.test(trimmed)) continue;
|
|
272
|
+
if (/^[-*_]{3,}$/.test(trimmed)) continue;
|
|
273
|
+
|
|
274
|
+
const withoutListMarker = trimmed.replace(/^([-*+]|\d+[.)])\s+/, '');
|
|
275
|
+
if (/^(name|version|author|license|entry)\s*:/i.test(withoutListMarker)) continue;
|
|
276
|
+
paragraph.push(withoutListMarker);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return cleanDescriptionText(paragraph.join(' '));
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async function readSkillDocumentMeta(skillRoot, entryFile = 'SKILL.md') {
|
|
283
|
+
const entryPath = path.join(skillRoot, entryFile || 'SKILL.md');
|
|
284
|
+
try {
|
|
285
|
+
const raw = await fs.readFile(entryPath, 'utf8');
|
|
286
|
+
const parsed = parseSkillFrontmatter(raw);
|
|
287
|
+
return {
|
|
288
|
+
version: parsed.metadata.version ? String(parsed.metadata.version) : '',
|
|
289
|
+
description: parsed.metadata.description
|
|
290
|
+
? cleanDescriptionText(parsed.metadata.description)
|
|
291
|
+
: inferDescriptionFromSkillMarkdown(parsed.content)
|
|
292
|
+
};
|
|
293
|
+
} catch {
|
|
294
|
+
return { version: '', description: '' };
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function readSkillCatalogSafe(baseDir) {
|
|
299
|
+
const catalogPath = path.join(baseDir, SKILL_CATALOG_FILE);
|
|
300
|
+
try {
|
|
301
|
+
const parsed = JSON.parse(await fs.readFile(catalogPath, 'utf8'));
|
|
302
|
+
return parsed && typeof parsed === 'object' && parsed.skills && typeof parsed.skills === 'object'
|
|
303
|
+
? parsed
|
|
304
|
+
: { version: 1, skills: {} };
|
|
305
|
+
} catch {
|
|
306
|
+
return { version: 1, skills: {} };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async function writeSkillCatalog(baseDir, catalog) {
|
|
311
|
+
await fs.mkdir(baseDir, { recursive: true });
|
|
312
|
+
await fs.writeFile(path.join(baseDir, SKILL_CATALOG_FILE), `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function upsertSkillCatalogEntry(baseDir, name, entry) {
|
|
316
|
+
const catalog = await readSkillCatalogSafe(baseDir);
|
|
317
|
+
catalog.version = catalog.version || 1;
|
|
318
|
+
catalog.skills = catalog.skills || {};
|
|
319
|
+
catalog.skills[name] = {
|
|
320
|
+
...(catalog.skills[name] || {}),
|
|
321
|
+
...entry
|
|
322
|
+
};
|
|
323
|
+
await writeSkillCatalog(baseDir, catalog);
|
|
324
|
+
}
|
|
325
|
+
|
|
208
326
|
async function resolveSkillSourceDir(sourcePath) {
|
|
209
327
|
const absSrc = path.resolve(sourcePath);
|
|
210
328
|
const srcStat = await fs.stat(absSrc);
|
|
@@ -277,22 +395,30 @@ export async function installSkill(sourcePath, { scope = 'project', cwd = proces
|
|
|
277
395
|
|
|
278
396
|
const entryFile = manifest?.entry || 'SKILL.md';
|
|
279
397
|
const entryPath = path.join(targetDir, entryFile);
|
|
280
|
-
await fs.access(entryPath);
|
|
281
|
-
|
|
282
|
-
const hash = await computeFileSha256(entryPath);
|
|
283
|
-
|
|
284
|
-
|
|
398
|
+
await fs.access(entryPath);
|
|
399
|
+
|
|
400
|
+
const hash = await computeFileSha256(entryPath);
|
|
401
|
+
const documentMeta = await readSkillDocumentMeta(targetDir, entryFile);
|
|
402
|
+
const description = manifest?.description || documentMeta.description || '';
|
|
403
|
+
const version = manifest?.version || documentMeta.version || '0.0.0';
|
|
404
|
+
if (scope === 'global') {
|
|
405
|
+
await upsertSkillRegistryEntry(undefined, {
|
|
285
406
|
name: folderName,
|
|
286
|
-
version
|
|
287
|
-
description
|
|
407
|
+
version,
|
|
408
|
+
description,
|
|
288
409
|
enabled: true,
|
|
289
410
|
source: sourceLabel,
|
|
290
411
|
entryFile,
|
|
291
412
|
sha256: hash,
|
|
292
413
|
installedAt: new Date().toISOString()
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
414
|
+
});
|
|
415
|
+
} else {
|
|
416
|
+
await upsertSkillCatalogEntry(baseDirForScope(scope, cwd), folderName, {
|
|
417
|
+
description,
|
|
418
|
+
enabled: true
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
await setSkillEnabledConfig(folderName, true);
|
|
296
422
|
|
|
297
423
|
if (resolved.cleanupDir) {
|
|
298
424
|
await fs.rm(resolved.cleanupDir, { recursive: true, force: true });
|
|
@@ -387,37 +513,51 @@ async function reindexSkills({ scope = 'global', cwd = process.cwd() } = {}) {
|
|
|
387
513
|
if (!entry.isDirectory()) continue;
|
|
388
514
|
const name = entry.name;
|
|
389
515
|
const dir = path.join(baseDir, name);
|
|
390
|
-
const manifest = await readManifestSafe(dir);
|
|
391
|
-
const entryFile = manifest?.entry || 'SKILL.md';
|
|
392
|
-
const entryPath = path.join(dir, entryFile);
|
|
393
|
-
try {
|
|
394
|
-
await fs.access(entryPath);
|
|
516
|
+
const manifest = await readManifestSafe(dir);
|
|
517
|
+
const entryFile = manifest?.entry || 'SKILL.md';
|
|
518
|
+
const entryPath = path.join(dir, entryFile);
|
|
519
|
+
try {
|
|
520
|
+
await fs.access(entryPath);
|
|
395
521
|
} catch {
|
|
396
522
|
continue;
|
|
397
|
-
}
|
|
398
|
-
const hash = await computeFileSha256(entryPath);
|
|
399
|
-
const prior = byName.get(name);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
523
|
+
}
|
|
524
|
+
const hash = await computeFileSha256(entryPath);
|
|
525
|
+
const prior = byName.get(name);
|
|
526
|
+
const documentMeta = await readSkillDocumentMeta(dir, entryFile);
|
|
527
|
+
rebuilt.push({
|
|
528
|
+
name: manifest?.name || name,
|
|
529
|
+
version: manifest?.version || documentMeta.version || prior?.version || '0.0.0',
|
|
530
|
+
description: manifest?.description || documentMeta.description || prior?.description || '',
|
|
531
|
+
enabled: prior?.enabled !== false,
|
|
532
|
+
source: prior?.source || 'reindex',
|
|
533
|
+
entryFile,
|
|
534
|
+
sha256: hash,
|
|
535
|
+
installedAt: prior?.installedAt || new Date().toISOString()
|
|
409
536
|
});
|
|
410
537
|
}
|
|
411
538
|
|
|
412
539
|
if (scope === 'global') {
|
|
413
540
|
await writeSkillRegistry(undefined, {
|
|
414
541
|
version: 1,
|
|
415
|
-
skills: rebuilt
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
542
|
+
skills: rebuilt
|
|
543
|
+
});
|
|
544
|
+
} else if (scope === 'project') {
|
|
545
|
+
const catalog = await readSkillCatalogSafe(baseDir);
|
|
546
|
+
catalog.version = catalog.version || 1;
|
|
547
|
+
catalog.skills = catalog.skills || {};
|
|
548
|
+
for (const item of rebuilt) {
|
|
549
|
+
catalog.skills[item.name] = {
|
|
550
|
+
...(catalog.skills[item.name] || {}),
|
|
551
|
+
description: item.description,
|
|
552
|
+
enabled: item.enabled !== false,
|
|
553
|
+
triggers: Array.isArray(catalog.skills[item.name]?.triggers) ? catalog.skills[item.name].triggers : []
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
await writeSkillCatalog(baseDir, catalog);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return rebuilt.length;
|
|
560
|
+
}
|
|
421
561
|
|
|
422
562
|
function usage() {
|
|
423
563
|
console.log(`Usage:
|