@kafca/agentdock 0.1.24 → 0.1.25
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/README.md +2 -0
- package/dist/renderer/assets/{Badge-CXcUMqb-.js → Badge-Bn2h-Qkf.js} +1 -1
- package/dist/renderer/assets/{Chat-BRxdPzi-.js → Chat-Cgo9aneg.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-sWGBIfIb.js → ChatMarkdown-CYzHfSiR.js} +1 -1
- package/dist/renderer/assets/{Config-DqxuxIGg.js → Config-DljB2-eP.js} +1 -1
- package/dist/renderer/assets/{CronList-OgHxbti5.js → CronList-DeVbiY9a.js} +1 -1
- package/dist/renderer/assets/{Dashboard-DmklXiH1.js → Dashboard-fSqx5sm8.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BvDmi8dq.js → EmptyState-DgqKDwlq.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Bj59Hdpo.js → KnowledgeDetail-u8s2SmPV.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-CigQ-nSo.js → KnowledgeHome-BdQw8nbY.js} +1 -1
- package/dist/renderer/assets/{Logs-Bfc7gBpY.js → Logs-DSbndMpy.js} +1 -1
- package/dist/renderer/assets/{Modal-CfmiFknz.js → Modal-0d0EmAuK.js} +1 -1
- package/dist/renderer/assets/{Page-BxtLEw_b.js → Page-CVbOH_Kh.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-CcUphxGm.js → ProjectDetail-C91tF7uA.js} +1 -1
- package/dist/renderer/assets/{ProjectList-CVkvDIfy.js → ProjectList-D78Pc-BQ.js} +1 -1
- package/dist/renderer/assets/{Select-DgQMZ0MD.js → Select-BbKzAIuO.js} +1 -1
- package/dist/renderer/assets/{SessionChat-CRmGKfBx.js → SessionChat-BERvL5e4.js} +1 -1
- package/dist/renderer/assets/{SessionList-D0E8XbYw.js → SessionList-Bomz335M.js} +1 -1
- package/dist/renderer/assets/ThreadChat-CLr3amU2.js +23 -0
- package/dist/renderer/assets/{Workspace-Q4g4rlRT.js → Workspace-In91z4W2.js} +1 -1
- package/dist/renderer/assets/{arrow-left-BySN_zhF.js → arrow-left-FBnVKKBl.js} +1 -1
- package/dist/renderer/assets/{book-open-BGlrnrTc.js → book-open-4_CuP6Sa.js} +1 -1
- package/dist/renderer/assets/{check-BiJogEa5.js → check-vsoVjvac.js} +1 -1
- package/dist/renderer/assets/{chevron-down-D2fHRJv6.js → chevron-down-DFpmFTJW.js} +1 -1
- package/dist/renderer/assets/{circle-CIcjixmI.js → circle-vRULegER.js} +1 -1
- package/dist/renderer/assets/{desktop-DAXY9Bxv.js → desktop-BkMW-h5p.js} +2 -2
- package/dist/renderer/assets/{desktop-DyA_NYew.js → desktop-ul0Tpzyc.js} +1 -1
- package/dist/renderer/assets/{funnel-BUzwb-id.js → funnel-Gu0E_hJ_.js} +1 -1
- package/dist/renderer/assets/{heart-DZEQ1z_V.js → heart-DsdofOHf.js} +1 -1
- package/dist/renderer/assets/{index-CB_KyLOr.js → index-BD3aCyBa.js} +3 -3
- package/dist/renderer/assets/{index-DgsIo4vJ.js → index-pJUFobU7.js} +1 -1
- package/dist/renderer/assets/{pencil-DGL4agcl.js → pencil-DbKmV8nD.js} +1 -1
- package/dist/renderer/assets/{play-DzasCLM4.js → play-BDMsRxSm.js} +1 -1
- package/dist/renderer/assets/{plug-dubNMe_m.js → plug-t2dMl78-.js} +1 -1
- package/dist/renderer/assets/{plus-DN4kML4k.js → plus-BUb6zOAe.js} +1 -1
- package/dist/renderer/assets/projects-4F6D_Q8t.js +1 -0
- package/dist/renderer/assets/{save-CNIc9tjl.js → save-C-_5rQdv.js} +1 -1
- package/dist/renderer/assets/{search-C0EGbF3I.js → search-R3ekHFPM.js} +1 -1
- package/dist/renderer/assets/{server-BMxQ4zmc.js → server-BTuvHf5n.js} +1 -1
- package/dist/renderer/assets/{session-utils-Bf5O-iMi.js → session-utils-ClX6VPFG.js} +1 -1
- package/dist/renderer/assets/{sessions-BMSs6rEI.js → sessions-AFKIC-ub.js} +1 -1
- package/dist/renderer/assets/{shield-check-i3Tf1TUz.js → shield-check-CqMW8CHe.js} +1 -1
- package/dist/renderer/assets/{trash-2-SKrcp18f.js → trash-2-BNLcHyUw.js} +1 -1
- package/dist/renderer/assets/{user-cNUZddjZ.js → user-BCCN8FYK.js} +1 -1
- package/dist/renderer/assets/{wifi-off-Dyb84ANR.js → wifi-off-BsNsx3oX.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/agent-runtime-detector.test.js +64 -0
- package/dist-electron/electron/architecture-docs.test.js +56 -0
- package/dist-electron/electron/channel-content.test.js +8 -0
- package/dist-electron/electron/lac-cli.test.js +248 -0
- package/dist-electron/electron/local-core-refactor.test.js +666 -3
- package/dist-electron/electron/plugin-kernel.test.js +108 -0
- package/dist-electron/electron/renderer-packaging.test.js +77 -0
- package/dist-electron/electron/workspace-task-store.test.js +57 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +67 -6
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js +76 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +201 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +29 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +30 -18
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +112 -210
- package/dist-electron/services/local-ai-core/src/acp/local-core-slash-commands.js +60 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +15 -3
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +11 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/file-utils.js +13 -1
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +8 -1
- package/dist-electron/services/local-ai-core/src/cli/lac.js +3 -1
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +1 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +221 -10
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +39 -9
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +439 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +208 -303
- package/dist-electron/shared/desktop.js +7 -3
- package/dist-electron/src/pages/Threads/thread-chat-message-blocks.js +187 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +1 -0
- package/dist-electron/src/pages/Threads/thread-chat-page-state.js +96 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.js +18 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +277 -0
- package/package.json +4 -2
- package/dist/renderer/assets/ThreadChat-DUgqZSBB.js +0 -23
- package/dist/renderer/assets/projects-migPtfRe.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{G as Te,aK as Ae,r as c,j as x,aL as pe,aM as Ne,aA as te}from"./index-CB_KyLOr.js";var ye=Ae();const De=Te(ye);function X(e,t,{checkForDefaultPrevented:n=!0}={}){return function(o){if(e==null||e(o),n===!1||!o.defaultPrevented)return t==null?void 0:t(o)}}function Jt(e,t){const n=c.createContext(t),r=i=>{const{children:s,...a}=i,h=c.useMemo(()=>a,Object.values(a));return x.jsx(n.Provider,{value:h,children:s})};r.displayName=e+"Provider";function o(i){const s=c.useContext(n);if(s)return s;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[r,o]}function en(e,t=[]){let n=[];function r(i,s){const a=c.createContext(s),h=n.length;n=[...n,s];const l=d=>{var p;const{scope:v,children:y,...w}=d,u=((p=v==null?void 0:v[e])==null?void 0:p[h])||a,m=c.useMemo(()=>w,Object.values(w));return x.jsx(u.Provider,{value:m,children:y})};l.displayName=i+"Provider";function f(d,v){var u;const y=((u=v==null?void 0:v[e])==null?void 0:u[h])||a,w=c.useContext(y);if(w)return w;if(s!==void 0)return s;throw new Error(`\`${d}\` must be used within \`${i}\``)}return[l,f]}const o=()=>{const i=n.map(s=>c.createContext(s));return function(a){const h=(a==null?void 0:a[e])||i;return c.useMemo(()=>({[`__scope${e}`]:{...a,[e]:h}}),[a,h])}};return o.scopeName=e,[r,ke(o,...t)]}function ke(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(i){const s=r.reduce((a,{useScope:h,scopeName:l})=>{const d=h(i)[`__scope${l}`];return{...a,...d}},{});return c.useMemo(()=>({[`__scope${t.scopeName}`]:s}),[s])}};return n.scopeName=t.scopeName,n}var ne=globalThis!=null&&globalThis.document?c.useLayoutEffect:()=>{},Me=pe[" useId ".trim().toString()]||(()=>{}),Fe=0;function tn(e){const[t,n]=c.useState(Me());return ne(()=>{n(r=>r??String(Fe++))},[e]),e||(t?`radix-${t}`:"")}var Ie=pe[" useInsertionEffect ".trim().toString()]||ne;function nn({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){const[o,i,s]=We({defaultProp:t,onChange:n}),a=e!==void 0,h=a?e:o;{const f=c.useRef(e!==void 0);c.useEffect(()=>{const d=f.current;d!==a&&console.warn(`${r} is changing from ${d?"controlled":"uncontrolled"} to ${a?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=a},[a,r])}const l=c.useCallback(f=>{var d;if(a){const v=Be(f)?f(e):f;v!==e&&((d=s.current)==null||d.call(s,v))}else i(f)},[a,e,i,s]);return[h,l]}function We({defaultProp:e,onChange:t}){const[n,r]=c.useState(e),o=c.useRef(n),i=c.useRef(t);return Ie(()=>{i.current=t},[t]),c.useEffect(()=>{var s;o.current!==n&&((s=i.current)==null||s.call(i,n),o.current=n)},[n,o]),[n,r,i]}function Be(e){return typeof e=="function"}function _e(e){const t=je(e),n=c.forwardRef((r,o)=>{const{children:i,...s}=r,a=c.Children.toArray(i),h=a.find($e);if(h){const l=h.props.children,f=a.map(d=>d===h?c.Children.count(l)>1?c.Children.only(null):c.isValidElement(l)?l.props.children:null:d);return x.jsx(t,{...s,ref:o,children:c.isValidElement(l)?c.cloneElement(l,void 0,f):null})}return x.jsx(t,{...s,ref:o,children:i})});return n.displayName=`${e}.Slot`,n}function je(e){const t=c.forwardRef((n,r)=>{const{children:o,...i}=n;if(c.isValidElement(o)){const s=Ke(o),a=Ve(i,o.props);return o.type!==c.Fragment&&(a.ref=r?Ne(r,s):s),c.cloneElement(o,a)}return c.Children.count(o)>1?c.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Ue=Symbol("radix.slottable");function $e(e){return c.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Ue}function Ve(e,t){const n={...t};for(const r in t){const o=e[r],i=t[r];/^on[A-Z]/.test(r)?o&&i?n[r]=(...a)=>{const h=i(...a);return o(...a),h}:o&&(n[r]=o):r==="style"?n[r]={...o,...i}:r==="className"&&(n[r]=[o,i].filter(Boolean).join(" "))}return{...e,...n}}function Ke(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Xe=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],V=Xe.reduce((e,t)=>{const n=_e(`Primitive.${t}`),r=c.forwardRef((o,i)=>{const{asChild:s,...a}=o,h=s?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),x.jsx(h,{...a,ref:i})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function Ye(e,t){e&&ye.flushSync(()=>e.dispatchEvent(t))}function F(e){const t=c.useRef(e);return c.useEffect(()=>{t.current=e}),c.useMemo(()=>(...n)=>{var r;return(r=t.current)==null?void 0:r.call(t,...n)},[])}function He(e,t=globalThis==null?void 0:globalThis.document){const n=F(e);c.useEffect(()=>{const r=o=>{o.key==="Escape"&&n(o)};return t.addEventListener("keydown",r,{capture:!0}),()=>t.removeEventListener("keydown",r,{capture:!0})},[n,t])}var ze="DismissableLayer",J="dismissableLayer.update",Ge="dismissableLayer.pointerDownOutside",Ze="dismissableLayer.focusOutside",oe,Ee=c.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),qe=c.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:o,onFocusOutside:i,onInteractOutside:s,onDismiss:a,...h}=e,l=c.useContext(Ee),[f,d]=c.useState(null),v=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,y]=c.useState({}),w=te(t,E=>d(E)),u=Array.from(l.layers),[m]=[...l.layersWithOutsidePointerEventsDisabled].slice(-1),p=u.indexOf(m),g=f?u.indexOf(f):-1,b=l.layersWithOutsidePointerEventsDisabled.size>0,S=g>=p,C=et(E=>{const L=E.target,T=[...l.branches].some(M=>M.contains(L));!S||T||(o==null||o(E),s==null||s(E),E.defaultPrevented||a==null||a())},v),P=tt(E=>{const L=E.target;[...l.branches].some(M=>M.contains(L))||(i==null||i(E),s==null||s(E),E.defaultPrevented||a==null||a())},v);return He(E=>{g===l.layers.size-1&&(r==null||r(E),!E.defaultPrevented&&a&&(E.preventDefault(),a()))},v),c.useEffect(()=>{if(f)return n&&(l.layersWithOutsidePointerEventsDisabled.size===0&&(oe=v.body.style.pointerEvents,v.body.style.pointerEvents="none"),l.layersWithOutsidePointerEventsDisabled.add(f)),l.layers.add(f),ae(),()=>{n&&l.layersWithOutsidePointerEventsDisabled.size===1&&(v.body.style.pointerEvents=oe)}},[f,v,n,l]),c.useEffect(()=>()=>{f&&(l.layers.delete(f),l.layersWithOutsidePointerEventsDisabled.delete(f),ae())},[f,l]),c.useEffect(()=>{const E=()=>y({});return document.addEventListener(J,E),()=>document.removeEventListener(J,E)},[]),x.jsx(V.div,{...h,ref:w,style:{pointerEvents:b?S?"auto":"none":void 0,...e.style},onFocusCapture:X(e.onFocusCapture,P.onFocusCapture),onBlurCapture:X(e.onBlurCapture,P.onBlurCapture),onPointerDownCapture:X(e.onPointerDownCapture,C.onPointerDownCapture)})});qe.displayName=ze;var Qe="DismissableLayerBranch",Je=c.forwardRef((e,t)=>{const n=c.useContext(Ee),r=c.useRef(null),o=te(t,r);return c.useEffect(()=>{const i=r.current;if(i)return n.branches.add(i),()=>{n.branches.delete(i)}},[n.branches]),x.jsx(V.div,{...e,ref:o})});Je.displayName=Qe;function et(e,t=globalThis==null?void 0:globalThis.document){const n=F(e),r=c.useRef(!1),o=c.useRef(()=>{});return c.useEffect(()=>{const i=a=>{if(a.target&&!r.current){let h=function(){ge(Ge,n,l,{discrete:!0})};const l={originalEvent:a};a.pointerType==="touch"?(t.removeEventListener("click",o.current),o.current=h,t.addEventListener("click",o.current,{once:!0})):h()}else t.removeEventListener("click",o.current);r.current=!1},s=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(s),t.removeEventListener("pointerdown",i),t.removeEventListener("click",o.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function tt(e,t=globalThis==null?void 0:globalThis.document){const n=F(e),r=c.useRef(!1);return c.useEffect(()=>{const o=i=>{i.target&&!r.current&&ge(Ze,n,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",o),()=>t.removeEventListener("focusin",o)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function ae(){const e=new CustomEvent(J);document.dispatchEvent(e)}function ge(e,t,n,{discrete:r}){const o=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&o.addEventListener(e,t,{once:!0}),r?Ye(o,i):o.dispatchEvent(i)}var Y="focusScope.autoFocusOnMount",H="focusScope.autoFocusOnUnmount",ce={bubbles:!1,cancelable:!0},nt="FocusScope",rt=c.forwardRef((e,t)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:o,onUnmountAutoFocus:i,...s}=e,[a,h]=c.useState(null),l=F(o),f=F(i),d=c.useRef(null),v=te(t,u=>h(u)),y=c.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;c.useEffect(()=>{if(r){let u=function(b){if(y.paused||!a)return;const S=b.target;a.contains(S)?d.current=S:O(d.current,{select:!0})},m=function(b){if(y.paused||!a)return;const S=b.relatedTarget;S!==null&&(a.contains(S)||O(d.current,{select:!0}))},p=function(b){if(document.activeElement===document.body)for(const C of b)C.removedNodes.length>0&&O(a)};document.addEventListener("focusin",u),document.addEventListener("focusout",m);const g=new MutationObserver(p);return a&&g.observe(a,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",u),document.removeEventListener("focusout",m),g.disconnect()}}},[r,a,y.paused]),c.useEffect(()=>{if(a){se.add(y);const u=document.activeElement;if(!a.contains(u)){const p=new CustomEvent(Y,ce);a.addEventListener(Y,l),a.dispatchEvent(p),p.defaultPrevented||(ot(ut(be(a)),{select:!0}),document.activeElement===u&&O(a))}return()=>{a.removeEventListener(Y,l),setTimeout(()=>{const p=new CustomEvent(H,ce);a.addEventListener(H,f),a.dispatchEvent(p),p.defaultPrevented||O(u??document.body,{select:!0}),a.removeEventListener(H,f),se.remove(y)},0)}}},[a,l,f,y]);const w=c.useCallback(u=>{if(!n&&!r||y.paused)return;const m=u.key==="Tab"&&!u.altKey&&!u.ctrlKey&&!u.metaKey,p=document.activeElement;if(m&&p){const g=u.currentTarget,[b,S]=at(g);b&&S?!u.shiftKey&&p===S?(u.preventDefault(),n&&O(b,{select:!0})):u.shiftKey&&p===b&&(u.preventDefault(),n&&O(S,{select:!0})):p===g&&u.preventDefault()}},[n,r,y.paused]);return x.jsx(V.div,{tabIndex:-1,...s,ref:v,onKeyDown:w})});rt.displayName=nt;function ot(e,{select:t=!1}={}){const n=document.activeElement;for(const r of e)if(O(r,{select:t}),document.activeElement!==n)return}function at(e){const t=be(e),n=ie(t,e),r=ie(t.reverse(),e);return[n,r]}function be(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const o=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||o?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function ie(e,t){for(const n of e)if(!ct(n,{upTo:t}))return n}function ct(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function it(e){return e instanceof HTMLInputElement&&"select"in e}function O(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&it(e)&&t&&e.select()}}var se=st();function st(){let e=[];return{add(t){const n=e[0];t!==n&&(n==null||n.pause()),e=ue(e,t),e.unshift(t)},remove(t){var n;e=ue(e,t),(n=e[0])==null||n.resume()}}}function ue(e,t){const n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function ut(e){return e.filter(t=>t.tagName!=="A")}var lt="Portal",ft=c.forwardRef((e,t)=>{var a;const{container:n,...r}=e,[o,i]=c.useState(!1);ne(()=>i(!0),[]);const s=n||o&&((a=globalThis==null?void 0:globalThis.document)==null?void 0:a.body);return s?De.createPortal(x.jsx(V.div,{...r,ref:t}),s):null});ft.displayName=lt;var z=0;function rn(){c.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??le()),document.body.insertAdjacentElement("beforeend",e[1]??le()),z++,()=>{z===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),z--}},[])}function le(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var R=function(){return R=Object.assign||function(t){for(var n,r=1,o=arguments.length;r<o;r++){n=arguments[r];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},R.apply(this,arguments)};function Se(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n}function dt(e,t,n){if(n||arguments.length===2)for(var r=0,o=t.length,i;r<o;r++)(i||!(r in t))&&(i||(i=Array.prototype.slice.call(t,0,r)),i[r]=t[r]);return e.concat(i||Array.prototype.slice.call(t))}var U="right-scroll-bar-position",$="width-before-scroll-bar",vt="with-scroll-bars-hidden",ht="--removed-body-scroll-bar-size";function G(e,t){return typeof e=="function"?e(t):e&&(e.current=t),e}function mt(e,t){var n=c.useState(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(r){var o=n.value;o!==r&&(n.value=r,n.callback(r,o))}}}})[0];return n.callback=t,n.facade}var pt=typeof window<"u"?c.useLayoutEffect:c.useEffect,fe=new WeakMap;function yt(e,t){var n=mt(null,function(r){return e.forEach(function(o){return G(o,r)})});return pt(function(){var r=fe.get(n);if(r){var o=new Set(r),i=new Set(e),s=n.current;o.forEach(function(a){i.has(a)||G(a,null)}),i.forEach(function(a){o.has(a)||G(a,s)})}fe.set(n,e)},[e]),n}function Et(e){return e}function gt(e,t){t===void 0&&(t=Et);var n=[],r=!1,o={read:function(){if(r)throw new Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return n.length?n[n.length-1]:e},useMedium:function(i){var s=t(i,r);return n.push(s),function(){n=n.filter(function(a){return a!==s})}},assignSyncMedium:function(i){for(r=!0;n.length;){var s=n;n=[],s.forEach(i)}n={push:function(a){return i(a)},filter:function(){return n}}},assignMedium:function(i){r=!0;var s=[];if(n.length){var a=n;n=[],a.forEach(i),s=n}var h=function(){var f=s;s=[],f.forEach(i)},l=function(){return Promise.resolve().then(h)};l(),n={push:function(f){s.push(f),l()},filter:function(f){return s=s.filter(f),n}}}};return o}function bt(e){e===void 0&&(e={});var t=gt(null);return t.options=R({async:!0,ssr:!1},e),t}var we=function(e){var t=e.sideCar,n=Se(e,["sideCar"]);if(!t)throw new Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw new Error("Sidecar medium not found");return c.createElement(r,R({},n))};we.isSideCarExport=!0;function St(e,t){return e.useMedium(t),we}var Ce=bt(),Z=function(){},K=c.forwardRef(function(e,t){var n=c.useRef(null),r=c.useState({onScrollCapture:Z,onWheelCapture:Z,onTouchMoveCapture:Z}),o=r[0],i=r[1],s=e.forwardProps,a=e.children,h=e.className,l=e.removeScrollBar,f=e.enabled,d=e.shards,v=e.sideCar,y=e.noRelative,w=e.noIsolation,u=e.inert,m=e.allowPinchZoom,p=e.as,g=p===void 0?"div":p,b=e.gapMode,S=Se(e,["forwardProps","children","className","removeScrollBar","enabled","shards","sideCar","noRelative","noIsolation","inert","allowPinchZoom","as","gapMode"]),C=v,P=yt([n,t]),E=R(R({},S),o);return c.createElement(c.Fragment,null,f&&c.createElement(C,{sideCar:Ce,removeScrollBar:l,shards:d,noRelative:y,noIsolation:w,inert:u,setCallbacks:i,allowPinchZoom:!!m,lockRef:n,gapMode:b}),s?c.cloneElement(c.Children.only(a),R(R({},E),{ref:P})):c.createElement(g,R({},E,{className:h,ref:P}),a))});K.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1};K.classNames={fullWidth:$,zeroRight:U};var wt=function(){if(typeof __webpack_nonce__<"u")return __webpack_nonce__};function Ct(){if(!document)return null;var e=document.createElement("style");e.type="text/css";var t=wt();return t&&e.setAttribute("nonce",t),e}function Pt(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function Rt(e){var t=document.head||document.getElementsByTagName("head")[0];t.appendChild(e)}var xt=function(){var e=0,t=null;return{add:function(n){e==0&&(t=Ct())&&(Pt(t,n),Rt(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},Ot=function(){var e=xt();return function(t,n){c.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},Pe=function(){var e=Ot(),t=function(n){var r=n.styles,o=n.dynamic;return e(r,o),null};return t},Lt={left:0,top:0,right:0,gap:0},q=function(e){return parseInt(e||"",10)||0},Tt=function(e){var t=window.getComputedStyle(document.body),n=t[e==="padding"?"paddingLeft":"marginLeft"],r=t[e==="padding"?"paddingTop":"marginTop"],o=t[e==="padding"?"paddingRight":"marginRight"];return[q(n),q(r),q(o)]},At=function(e){if(e===void 0&&(e="margin"),typeof window>"u")return Lt;var t=Tt(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Nt=Pe(),k="data-scroll-locked",Dt=function(e,t,n,r){var o=e.left,i=e.top,s=e.right,a=e.gap;return n===void 0&&(n="margin"),`
|
|
1
|
+
import{G as Te,aK as Ae,r as c,j as x,aL as pe,aM as Ne,aA as te}from"./index-BD3aCyBa.js";var ye=Ae();const De=Te(ye);function X(e,t,{checkForDefaultPrevented:n=!0}={}){return function(o){if(e==null||e(o),n===!1||!o.defaultPrevented)return t==null?void 0:t(o)}}function Jt(e,t){const n=c.createContext(t),r=i=>{const{children:s,...a}=i,h=c.useMemo(()=>a,Object.values(a));return x.jsx(n.Provider,{value:h,children:s})};r.displayName=e+"Provider";function o(i){const s=c.useContext(n);if(s)return s;if(t!==void 0)return t;throw new Error(`\`${i}\` must be used within \`${e}\``)}return[r,o]}function en(e,t=[]){let n=[];function r(i,s){const a=c.createContext(s),h=n.length;n=[...n,s];const l=d=>{var p;const{scope:v,children:y,...w}=d,u=((p=v==null?void 0:v[e])==null?void 0:p[h])||a,m=c.useMemo(()=>w,Object.values(w));return x.jsx(u.Provider,{value:m,children:y})};l.displayName=i+"Provider";function f(d,v){var u;const y=((u=v==null?void 0:v[e])==null?void 0:u[h])||a,w=c.useContext(y);if(w)return w;if(s!==void 0)return s;throw new Error(`\`${d}\` must be used within \`${i}\``)}return[l,f]}const o=()=>{const i=n.map(s=>c.createContext(s));return function(a){const h=(a==null?void 0:a[e])||i;return c.useMemo(()=>({[`__scope${e}`]:{...a,[e]:h}}),[a,h])}};return o.scopeName=e,[r,ke(o,...t)]}function ke(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(o=>({useScope:o(),scopeName:o.scopeName}));return function(i){const s=r.reduce((a,{useScope:h,scopeName:l})=>{const d=h(i)[`__scope${l}`];return{...a,...d}},{});return c.useMemo(()=>({[`__scope${t.scopeName}`]:s}),[s])}};return n.scopeName=t.scopeName,n}var ne=globalThis!=null&&globalThis.document?c.useLayoutEffect:()=>{},Me=pe[" useId ".trim().toString()]||(()=>{}),Fe=0;function tn(e){const[t,n]=c.useState(Me());return ne(()=>{n(r=>r??String(Fe++))},[e]),e||(t?`radix-${t}`:"")}var Ie=pe[" useInsertionEffect ".trim().toString()]||ne;function nn({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){const[o,i,s]=We({defaultProp:t,onChange:n}),a=e!==void 0,h=a?e:o;{const f=c.useRef(e!==void 0);c.useEffect(()=>{const d=f.current;d!==a&&console.warn(`${r} is changing from ${d?"controlled":"uncontrolled"} to ${a?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),f.current=a},[a,r])}const l=c.useCallback(f=>{var d;if(a){const v=Be(f)?f(e):f;v!==e&&((d=s.current)==null||d.call(s,v))}else i(f)},[a,e,i,s]);return[h,l]}function We({defaultProp:e,onChange:t}){const[n,r]=c.useState(e),o=c.useRef(n),i=c.useRef(t);return Ie(()=>{i.current=t},[t]),c.useEffect(()=>{var s;o.current!==n&&((s=i.current)==null||s.call(i,n),o.current=n)},[n,o]),[n,r,i]}function Be(e){return typeof e=="function"}function _e(e){const t=je(e),n=c.forwardRef((r,o)=>{const{children:i,...s}=r,a=c.Children.toArray(i),h=a.find($e);if(h){const l=h.props.children,f=a.map(d=>d===h?c.Children.count(l)>1?c.Children.only(null):c.isValidElement(l)?l.props.children:null:d);return x.jsx(t,{...s,ref:o,children:c.isValidElement(l)?c.cloneElement(l,void 0,f):null})}return x.jsx(t,{...s,ref:o,children:i})});return n.displayName=`${e}.Slot`,n}function je(e){const t=c.forwardRef((n,r)=>{const{children:o,...i}=n;if(c.isValidElement(o)){const s=Ke(o),a=Ve(i,o.props);return o.type!==c.Fragment&&(a.ref=r?Ne(r,s):s),c.cloneElement(o,a)}return c.Children.count(o)>1?c.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var Ue=Symbol("radix.slottable");function $e(e){return c.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===Ue}function Ve(e,t){const n={...t};for(const r in t){const o=e[r],i=t[r];/^on[A-Z]/.test(r)?o&&i?n[r]=(...a)=>{const h=i(...a);return o(...a),h}:o&&(n[r]=o):r==="style"?n[r]={...o,...i}:r==="className"&&(n[r]=[o,i].filter(Boolean).join(" "))}return{...e,...n}}function Ke(e){var r,o;let t=(r=Object.getOwnPropertyDescriptor(e.props,"ref"))==null?void 0:r.get,n=t&&"isReactWarning"in t&&t.isReactWarning;return n?e.ref:(t=(o=Object.getOwnPropertyDescriptor(e,"ref"))==null?void 0:o.get,n=t&&"isReactWarning"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Xe=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],V=Xe.reduce((e,t)=>{const n=_e(`Primitive.${t}`),r=c.forwardRef((o,i)=>{const{asChild:s,...a}=o,h=s?n:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),x.jsx(h,{...a,ref:i})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function Ye(e,t){e&&ye.flushSync(()=>e.dispatchEvent(t))}function F(e){const t=c.useRef(e);return c.useEffect(()=>{t.current=e}),c.useMemo(()=>(...n)=>{var r;return(r=t.current)==null?void 0:r.call(t,...n)},[])}function He(e,t=globalThis==null?void 0:globalThis.document){const n=F(e);c.useEffect(()=>{const r=o=>{o.key==="Escape"&&n(o)};return t.addEventListener("keydown",r,{capture:!0}),()=>t.removeEventListener("keydown",r,{capture:!0})},[n,t])}var ze="DismissableLayer",J="dismissableLayer.update",Ge="dismissableLayer.pointerDownOutside",Ze="dismissableLayer.focusOutside",oe,Ee=c.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),qe=c.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:o,onFocusOutside:i,onInteractOutside:s,onDismiss:a,...h}=e,l=c.useContext(Ee),[f,d]=c.useState(null),v=(f==null?void 0:f.ownerDocument)??(globalThis==null?void 0:globalThis.document),[,y]=c.useState({}),w=te(t,E=>d(E)),u=Array.from(l.layers),[m]=[...l.layersWithOutsidePointerEventsDisabled].slice(-1),p=u.indexOf(m),g=f?u.indexOf(f):-1,b=l.layersWithOutsidePointerEventsDisabled.size>0,S=g>=p,C=et(E=>{const L=E.target,T=[...l.branches].some(M=>M.contains(L));!S||T||(o==null||o(E),s==null||s(E),E.defaultPrevented||a==null||a())},v),P=tt(E=>{const L=E.target;[...l.branches].some(M=>M.contains(L))||(i==null||i(E),s==null||s(E),E.defaultPrevented||a==null||a())},v);return He(E=>{g===l.layers.size-1&&(r==null||r(E),!E.defaultPrevented&&a&&(E.preventDefault(),a()))},v),c.useEffect(()=>{if(f)return n&&(l.layersWithOutsidePointerEventsDisabled.size===0&&(oe=v.body.style.pointerEvents,v.body.style.pointerEvents="none"),l.layersWithOutsidePointerEventsDisabled.add(f)),l.layers.add(f),ae(),()=>{n&&l.layersWithOutsidePointerEventsDisabled.size===1&&(v.body.style.pointerEvents=oe)}},[f,v,n,l]),c.useEffect(()=>()=>{f&&(l.layers.delete(f),l.layersWithOutsidePointerEventsDisabled.delete(f),ae())},[f,l]),c.useEffect(()=>{const E=()=>y({});return document.addEventListener(J,E),()=>document.removeEventListener(J,E)},[]),x.jsx(V.div,{...h,ref:w,style:{pointerEvents:b?S?"auto":"none":void 0,...e.style},onFocusCapture:X(e.onFocusCapture,P.onFocusCapture),onBlurCapture:X(e.onBlurCapture,P.onBlurCapture),onPointerDownCapture:X(e.onPointerDownCapture,C.onPointerDownCapture)})});qe.displayName=ze;var Qe="DismissableLayerBranch",Je=c.forwardRef((e,t)=>{const n=c.useContext(Ee),r=c.useRef(null),o=te(t,r);return c.useEffect(()=>{const i=r.current;if(i)return n.branches.add(i),()=>{n.branches.delete(i)}},[n.branches]),x.jsx(V.div,{...e,ref:o})});Je.displayName=Qe;function et(e,t=globalThis==null?void 0:globalThis.document){const n=F(e),r=c.useRef(!1),o=c.useRef(()=>{});return c.useEffect(()=>{const i=a=>{if(a.target&&!r.current){let h=function(){ge(Ge,n,l,{discrete:!0})};const l={originalEvent:a};a.pointerType==="touch"?(t.removeEventListener("click",o.current),o.current=h,t.addEventListener("click",o.current,{once:!0})):h()}else t.removeEventListener("click",o.current);r.current=!1},s=window.setTimeout(()=>{t.addEventListener("pointerdown",i)},0);return()=>{window.clearTimeout(s),t.removeEventListener("pointerdown",i),t.removeEventListener("click",o.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function tt(e,t=globalThis==null?void 0:globalThis.document){const n=F(e),r=c.useRef(!1);return c.useEffect(()=>{const o=i=>{i.target&&!r.current&&ge(Ze,n,{originalEvent:i},{discrete:!1})};return t.addEventListener("focusin",o),()=>t.removeEventListener("focusin",o)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function ae(){const e=new CustomEvent(J);document.dispatchEvent(e)}function ge(e,t,n,{discrete:r}){const o=n.originalEvent.target,i=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&o.addEventListener(e,t,{once:!0}),r?Ye(o,i):o.dispatchEvent(i)}var Y="focusScope.autoFocusOnMount",H="focusScope.autoFocusOnUnmount",ce={bubbles:!1,cancelable:!0},nt="FocusScope",rt=c.forwardRef((e,t)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:o,onUnmountAutoFocus:i,...s}=e,[a,h]=c.useState(null),l=F(o),f=F(i),d=c.useRef(null),v=te(t,u=>h(u)),y=c.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;c.useEffect(()=>{if(r){let u=function(b){if(y.paused||!a)return;const S=b.target;a.contains(S)?d.current=S:O(d.current,{select:!0})},m=function(b){if(y.paused||!a)return;const S=b.relatedTarget;S!==null&&(a.contains(S)||O(d.current,{select:!0}))},p=function(b){if(document.activeElement===document.body)for(const C of b)C.removedNodes.length>0&&O(a)};document.addEventListener("focusin",u),document.addEventListener("focusout",m);const g=new MutationObserver(p);return a&&g.observe(a,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",u),document.removeEventListener("focusout",m),g.disconnect()}}},[r,a,y.paused]),c.useEffect(()=>{if(a){se.add(y);const u=document.activeElement;if(!a.contains(u)){const p=new CustomEvent(Y,ce);a.addEventListener(Y,l),a.dispatchEvent(p),p.defaultPrevented||(ot(ut(be(a)),{select:!0}),document.activeElement===u&&O(a))}return()=>{a.removeEventListener(Y,l),setTimeout(()=>{const p=new CustomEvent(H,ce);a.addEventListener(H,f),a.dispatchEvent(p),p.defaultPrevented||O(u??document.body,{select:!0}),a.removeEventListener(H,f),se.remove(y)},0)}}},[a,l,f,y]);const w=c.useCallback(u=>{if(!n&&!r||y.paused)return;const m=u.key==="Tab"&&!u.altKey&&!u.ctrlKey&&!u.metaKey,p=document.activeElement;if(m&&p){const g=u.currentTarget,[b,S]=at(g);b&&S?!u.shiftKey&&p===S?(u.preventDefault(),n&&O(b,{select:!0})):u.shiftKey&&p===b&&(u.preventDefault(),n&&O(S,{select:!0})):p===g&&u.preventDefault()}},[n,r,y.paused]);return x.jsx(V.div,{tabIndex:-1,...s,ref:v,onKeyDown:w})});rt.displayName=nt;function ot(e,{select:t=!1}={}){const n=document.activeElement;for(const r of e)if(O(r,{select:t}),document.activeElement!==n)return}function at(e){const t=be(e),n=ie(t,e),r=ie(t.reverse(),e);return[n,r]}function be(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const o=r.tagName==="INPUT"&&r.type==="hidden";return r.disabled||r.hidden||o?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function ie(e,t){for(const n of e)if(!ct(n,{upTo:t}))return n}function ct(e,{upTo:t}){if(getComputedStyle(e).visibility==="hidden")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display==="none")return!0;e=e.parentElement}return!1}function it(e){return e instanceof HTMLInputElement&&"select"in e}function O(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&it(e)&&t&&e.select()}}var se=st();function st(){let e=[];return{add(t){const n=e[0];t!==n&&(n==null||n.pause()),e=ue(e,t),e.unshift(t)},remove(t){var n;e=ue(e,t),(n=e[0])==null||n.resume()}}}function ue(e,t){const n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function ut(e){return e.filter(t=>t.tagName!=="A")}var lt="Portal",ft=c.forwardRef((e,t)=>{var a;const{container:n,...r}=e,[o,i]=c.useState(!1);ne(()=>i(!0),[]);const s=n||o&&((a=globalThis==null?void 0:globalThis.document)==null?void 0:a.body);return s?De.createPortal(x.jsx(V.div,{...r,ref:t}),s):null});ft.displayName=lt;var z=0;function rn(){c.useEffect(()=>{const e=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",e[0]??le()),document.body.insertAdjacentElement("beforeend",e[1]??le()),z++,()=>{z===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(t=>t.remove()),z--}},[])}function le(){const e=document.createElement("span");return e.setAttribute("data-radix-focus-guard",""),e.tabIndex=0,e.style.outline="none",e.style.opacity="0",e.style.position="fixed",e.style.pointerEvents="none",e}var R=function(){return R=Object.assign||function(t){for(var n,r=1,o=arguments.length;r<o;r++){n=arguments[r];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},R.apply(this,arguments)};function Se(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n}function dt(e,t,n){if(n||arguments.length===2)for(var r=0,o=t.length,i;r<o;r++)(i||!(r in t))&&(i||(i=Array.prototype.slice.call(t,0,r)),i[r]=t[r]);return e.concat(i||Array.prototype.slice.call(t))}var U="right-scroll-bar-position",$="width-before-scroll-bar",vt="with-scroll-bars-hidden",ht="--removed-body-scroll-bar-size";function G(e,t){return typeof e=="function"?e(t):e&&(e.current=t),e}function mt(e,t){var n=c.useState(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(r){var o=n.value;o!==r&&(n.value=r,n.callback(r,o))}}}})[0];return n.callback=t,n.facade}var pt=typeof window<"u"?c.useLayoutEffect:c.useEffect,fe=new WeakMap;function yt(e,t){var n=mt(null,function(r){return e.forEach(function(o){return G(o,r)})});return pt(function(){var r=fe.get(n);if(r){var o=new Set(r),i=new Set(e),s=n.current;o.forEach(function(a){i.has(a)||G(a,null)}),i.forEach(function(a){o.has(a)||G(a,s)})}fe.set(n,e)},[e]),n}function Et(e){return e}function gt(e,t){t===void 0&&(t=Et);var n=[],r=!1,o={read:function(){if(r)throw new Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return n.length?n[n.length-1]:e},useMedium:function(i){var s=t(i,r);return n.push(s),function(){n=n.filter(function(a){return a!==s})}},assignSyncMedium:function(i){for(r=!0;n.length;){var s=n;n=[],s.forEach(i)}n={push:function(a){return i(a)},filter:function(){return n}}},assignMedium:function(i){r=!0;var s=[];if(n.length){var a=n;n=[],a.forEach(i),s=n}var h=function(){var f=s;s=[],f.forEach(i)},l=function(){return Promise.resolve().then(h)};l(),n={push:function(f){s.push(f),l()},filter:function(f){return s=s.filter(f),n}}}};return o}function bt(e){e===void 0&&(e={});var t=gt(null);return t.options=R({async:!0,ssr:!1},e),t}var we=function(e){var t=e.sideCar,n=Se(e,["sideCar"]);if(!t)throw new Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw new Error("Sidecar medium not found");return c.createElement(r,R({},n))};we.isSideCarExport=!0;function St(e,t){return e.useMedium(t),we}var Ce=bt(),Z=function(){},K=c.forwardRef(function(e,t){var n=c.useRef(null),r=c.useState({onScrollCapture:Z,onWheelCapture:Z,onTouchMoveCapture:Z}),o=r[0],i=r[1],s=e.forwardProps,a=e.children,h=e.className,l=e.removeScrollBar,f=e.enabled,d=e.shards,v=e.sideCar,y=e.noRelative,w=e.noIsolation,u=e.inert,m=e.allowPinchZoom,p=e.as,g=p===void 0?"div":p,b=e.gapMode,S=Se(e,["forwardProps","children","className","removeScrollBar","enabled","shards","sideCar","noRelative","noIsolation","inert","allowPinchZoom","as","gapMode"]),C=v,P=yt([n,t]),E=R(R({},S),o);return c.createElement(c.Fragment,null,f&&c.createElement(C,{sideCar:Ce,removeScrollBar:l,shards:d,noRelative:y,noIsolation:w,inert:u,setCallbacks:i,allowPinchZoom:!!m,lockRef:n,gapMode:b}),s?c.cloneElement(c.Children.only(a),R(R({},E),{ref:P})):c.createElement(g,R({},E,{className:h,ref:P}),a))});K.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1};K.classNames={fullWidth:$,zeroRight:U};var wt=function(){if(typeof __webpack_nonce__<"u")return __webpack_nonce__};function Ct(){if(!document)return null;var e=document.createElement("style");e.type="text/css";var t=wt();return t&&e.setAttribute("nonce",t),e}function Pt(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function Rt(e){var t=document.head||document.getElementsByTagName("head")[0];t.appendChild(e)}var xt=function(){var e=0,t=null;return{add:function(n){e==0&&(t=Ct())&&(Pt(t,n),Rt(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},Ot=function(){var e=xt();return function(t,n){c.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},Pe=function(){var e=Ot(),t=function(n){var r=n.styles,o=n.dynamic;return e(r,o),null};return t},Lt={left:0,top:0,right:0,gap:0},q=function(e){return parseInt(e||"",10)||0},Tt=function(e){var t=window.getComputedStyle(document.body),n=t[e==="padding"?"paddingLeft":"marginLeft"],r=t[e==="padding"?"paddingTop":"marginTop"],o=t[e==="padding"?"paddingRight":"marginRight"];return[q(n),q(r),q(o)]},At=function(e){if(e===void 0&&(e="margin"),typeof window>"u")return Lt;var t=Tt(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Nt=Pe(),k="data-scroll-locked",Dt=function(e,t,n,r){var o=e.left,i=e.top,s=e.right,a=e.gap;return n===void 0&&(n="margin"),`
|
|
2
2
|
.`.concat(vt,` {
|
|
3
3
|
overflow: hidden `).concat(r,`;
|
|
4
4
|
padding-right: `).concat(a,"px ").concat(r,`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as t}from"./index-BD3aCyBa.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as o}from"./index-
|
|
1
|
+
import{z as o}from"./index-BD3aCyBa.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
|
package/dist/renderer/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>AgentDock</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-BD3aCyBa.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="./assets/index-DFiJR0vv.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body class="bg-[#f5f5f7] dark:bg-[#151516]">
|
|
@@ -26,6 +26,8 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
26
26
|
strict_1.default.equal(byType.get('opencode')?.source, 'path');
|
|
27
27
|
strict_1.default.equal(byType.get('opencode')?.command, opencode);
|
|
28
28
|
strict_1.default.equal(byType.get('opencode')?.binaryPath, opencode);
|
|
29
|
+
strict_1.default.equal(byType.get('pi')?.installed, false);
|
|
30
|
+
strict_1.default.equal(byType.get('pi')?.status, 'not_installed');
|
|
29
31
|
strict_1.default.equal(byType.get('codex')?.installed, false);
|
|
30
32
|
strict_1.default.equal(byType.get('codex')?.status, 'not_installed');
|
|
31
33
|
strict_1.default.equal(byType.get('localcore-acp')?.installed, true);
|
|
@@ -36,6 +38,15 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
36
38
|
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
37
39
|
}
|
|
38
40
|
});
|
|
41
|
+
(0, node_test_1.default)('agent runtime detector reports bundled pi coding agent when available', () => {
|
|
42
|
+
const pi = (0, agent_runtime_detector_js_1.detectInstalledAgentRuntimes)({
|
|
43
|
+
env: { PATH: '' },
|
|
44
|
+
}).find((runtime) => runtime.agentType === 'pi');
|
|
45
|
+
strict_1.default.equal(pi?.installed, true);
|
|
46
|
+
strict_1.default.equal(pi?.status, 'installed');
|
|
47
|
+
strict_1.default.equal(pi?.source, 'bundled');
|
|
48
|
+
strict_1.default.match(pi?.command || '', /@mariozechner[/\\]pi-coding-agent[/\\]dist[/\\]cli\.js$/);
|
|
49
|
+
});
|
|
39
50
|
(0, node_test_1.default)('agent runtime detector reports bundled codex ACP when available', () => {
|
|
40
51
|
const codex = (0, agent_runtime_detector_js_1.detectInstalledAgentRuntimes)({
|
|
41
52
|
env: { PATH: '' },
|
|
@@ -45,6 +56,39 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
45
56
|
strict_1.default.equal(codex?.source, 'bundled');
|
|
46
57
|
strict_1.default.match(codex?.command || '', /@zed-industries[/\\]codex-acp[/\\]bin[/\\]codex-acp\.js$/);
|
|
47
58
|
});
|
|
59
|
+
(0, node_test_1.default)('agent runtime detector honors configured pi command before bundled runtime', () => {
|
|
60
|
+
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-pi-config-'));
|
|
61
|
+
try {
|
|
62
|
+
const customPi = (0, node_path_1.join)(dir, 'custom-pi');
|
|
63
|
+
(0, node_fs_1.writeFileSync)(customPi, '#!/bin/sh\nexit 0\n', 'utf8');
|
|
64
|
+
(0, node_fs_1.chmodSync)(customPi, 0o755);
|
|
65
|
+
const runtimes = (0, agent_runtime_detector_js_1.detectInstalledAgentRuntimes)({
|
|
66
|
+
env: { PATH: '' },
|
|
67
|
+
config: {
|
|
68
|
+
projects: [
|
|
69
|
+
{
|
|
70
|
+
name: 'configured-pi',
|
|
71
|
+
agent: {
|
|
72
|
+
type: 'pi',
|
|
73
|
+
options: {
|
|
74
|
+
command: customPi,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
platforms: [],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const pi = runtimes.find((runtime) => runtime.agentType === 'pi');
|
|
83
|
+
strict_1.default.equal(pi?.installed, true);
|
|
84
|
+
strict_1.default.equal(pi?.status, 'installed');
|
|
85
|
+
strict_1.default.equal(pi?.source, 'config');
|
|
86
|
+
strict_1.default.equal(pi?.command, customPi);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
48
92
|
(0, node_test_1.default)('agent runtime detector honors configured project commands', () => {
|
|
49
93
|
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-config-'));
|
|
50
94
|
try {
|
|
@@ -78,6 +122,26 @@ const agent_runtime_detector_js_1 = require("../services/local-ai-core/src/runti
|
|
|
78
122
|
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
79
123
|
}
|
|
80
124
|
});
|
|
125
|
+
(0, node_test_1.default)('agent runtime detector reports pi version when PATH command succeeds', () => {
|
|
126
|
+
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-pi-version-'));
|
|
127
|
+
try {
|
|
128
|
+
const pi = (0, node_path_1.join)(dir, 'pi');
|
|
129
|
+
(0, node_fs_1.writeFileSync)(pi, '#!/bin/sh\necho "pi 0.72.1"\n', 'utf8');
|
|
130
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, 'package.json'), '{}\n', 'utf8');
|
|
131
|
+
(0, node_fs_1.chmodSync)(pi, 0o755);
|
|
132
|
+
const piRuntime = (0, agent_runtime_detector_js_1.detectInstalledAgentRuntimes)({
|
|
133
|
+
env: { PATH: dir },
|
|
134
|
+
requireFrom: (0, node_path_1.join)(dir, 'package.json'),
|
|
135
|
+
}).find((runtime) => runtime.agentType === 'pi');
|
|
136
|
+
strict_1.default.equal(piRuntime?.status, 'installed');
|
|
137
|
+
strict_1.default.equal(piRuntime?.source, 'path');
|
|
138
|
+
strict_1.default.equal(piRuntime?.version, '0.72.1');
|
|
139
|
+
strict_1.default.equal(piRuntime?.issues.length, 0);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
143
|
+
}
|
|
144
|
+
});
|
|
81
145
|
(0, node_test_1.default)('agent runtime detector reports version when version command succeeds', () => {
|
|
82
146
|
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agent-runtime-version-'));
|
|
83
147
|
try {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
11
|
+
const rootDir = node_process_1.default.cwd();
|
|
12
|
+
(0, node_test_1.default)('state ownership docs identify Local AI Core owners for durable chat and channel state', () => {
|
|
13
|
+
const content = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'docs', 'architecture', 'state-ownership.md'), 'utf8');
|
|
14
|
+
for (const state of [
|
|
15
|
+
'Task lifecycle',
|
|
16
|
+
'Run lifecycle',
|
|
17
|
+
'Thread messages',
|
|
18
|
+
'Permission requests',
|
|
19
|
+
'Attachments',
|
|
20
|
+
'Channel inbound content',
|
|
21
|
+
'Channel outbound content',
|
|
22
|
+
]) {
|
|
23
|
+
strict_1.default.match(content, new RegExp(`\\| ${state} \\|[^\\n]*Local AI Core`), `${state} must have a Local AI Core owner`);
|
|
24
|
+
}
|
|
25
|
+
strict_1.default.match(content, /Renderer owns transient UI state only/, 'renderer ownership must remain transient');
|
|
26
|
+
strict_1.default.match(content, /Shared packages define cross-process data shapes/, 'shared contracts boundary must remain explicit');
|
|
27
|
+
});
|
|
28
|
+
(0, node_test_1.default)('message and channel contract docs cover canonical concepts and field lifecycles', () => {
|
|
29
|
+
const content = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'docs', 'architecture', 'message-and-channel-contracts.md'), 'utf8');
|
|
30
|
+
for (const concept of [
|
|
31
|
+
'Thread',
|
|
32
|
+
'Run',
|
|
33
|
+
'Task',
|
|
34
|
+
'PermissionRequest',
|
|
35
|
+
'MessageBlock',
|
|
36
|
+
'Attachment',
|
|
37
|
+
'ChannelInboundContent',
|
|
38
|
+
'ChannelOutboundContent',
|
|
39
|
+
]) {
|
|
40
|
+
strict_1.default.match(content, new RegExp(`\\| ${concept} \\|`), `${concept} must be listed in the contract index`);
|
|
41
|
+
}
|
|
42
|
+
for (const heading of ['Persisted fields', 'Streamed fields', 'Rendered fields', 'Platform-specific fields']) {
|
|
43
|
+
strict_1.default.match(content, new RegExp(`\\| ${heading} `), `${heading} must stay documented`);
|
|
44
|
+
}
|
|
45
|
+
strict_1.default.match(content, /Permission requests are durable thread\/run state/, 'permission state must not be renderer-inferred');
|
|
46
|
+
strict_1.default.match(content, /Thinking blocks are not overwritten by final answer blocks/, 'thinking/final separation invariant must remain documented');
|
|
47
|
+
strict_1.default.match(content, /Sending files through a channel uses one outbound path/, 'outbound file path invariant must remain documented');
|
|
48
|
+
});
|
|
49
|
+
(0, node_test_1.default)('thread chat renderer state types reuse canonical contracts instead of ad hoc duplicates', () => {
|
|
50
|
+
const taskStateSource = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'src', 'pages', 'Threads', 'thread-chat-task-state.ts'), 'utf8');
|
|
51
|
+
const permissionSource = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'src', 'pages', 'Threads', 'thread-chat-permission.ts'), 'utf8');
|
|
52
|
+
strict_1.default.match(taskStateSource, /import type \{ ChatTaskState \} from '\.\/thread-chat-model';/, 'task-state helpers must reuse the canonical Thread Chat task-state type');
|
|
53
|
+
strict_1.default.doesNotMatch(taskStateSource, /type ChatTaskState\s*=/, 'task-state helpers must not redeclare ChatTaskState');
|
|
54
|
+
strict_1.default.match(permissionSource, /export type PendingPermissionRequest = ThreadPendingPermissionRequest;/, 'renderer pending permission state must alias the shared thread permission contract');
|
|
55
|
+
strict_1.default.doesNotMatch(permissionSource, /type PermissionTaskState\s*=/, 'permission helpers must not carry a second task-state union');
|
|
56
|
+
});
|
|
@@ -5,7 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const node_test_1 = __importDefault(require("node:test"));
|
|
7
7
|
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
8
9
|
const content_js_1 = require("../services/local-ai-core/src/channel/shared/content.js");
|
|
10
|
+
const file_utils_js_1 = require("../services/local-ai-core/src/channel/shared/file-utils.js");
|
|
9
11
|
(0, node_test_1.default)('channel thread message input stays plain text when there are no attachments', () => {
|
|
10
12
|
const input = (0, content_js_1.createChannelThreadMessageInput)('Alice: hello', [
|
|
11
13
|
{ type: 'text', text: 'hello' },
|
|
@@ -27,3 +29,9 @@ const content_js_1 = require("../services/local-ai-core/src/channel/shared/conte
|
|
|
27
29
|
],
|
|
28
30
|
});
|
|
29
31
|
});
|
|
32
|
+
(0, node_test_1.default)('channel outbound file paths resolve relative to the current workspace root', () => {
|
|
33
|
+
strict_1.default.equal((0, file_utils_js_1.resolveChannelFilePath)('reports/out.pdf', '/workspace/project'), (0, node_path_1.join)('/workspace/project', 'reports', 'out.pdf'));
|
|
34
|
+
});
|
|
35
|
+
(0, node_test_1.default)('channel outbound file paths keep allowed absolute paths unchanged', () => {
|
|
36
|
+
strict_1.default.equal((0, file_utils_js_1.resolveChannelFilePath)('/tmp/out.pdf', '/workspace/project'), '/tmp/out.pdf');
|
|
37
|
+
});
|
|
@@ -162,6 +162,131 @@ function createIo() {
|
|
|
162
162
|
});
|
|
163
163
|
strict_1.default.match(read().stdout, /Created scheduler job job-local-1/);
|
|
164
164
|
});
|
|
165
|
+
(0, node_test_1.default)('lac channel send-file posts a workspace-relative file through outbound message parts', async () => {
|
|
166
|
+
let capturedBody = null;
|
|
167
|
+
const server = (0, node_http_1.createServer)(async (req, res) => {
|
|
168
|
+
if (req.method === 'POST' && req.url === '/api/local/v1/platforms/lark/%E7%9F%A5%E8%AF%86%E5%BA%93/messages') {
|
|
169
|
+
const chunks = [];
|
|
170
|
+
for await (const chunk of req) {
|
|
171
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
172
|
+
}
|
|
173
|
+
capturedBody = Buffer.concat(chunks).toString('utf8');
|
|
174
|
+
res.setHeader('content-type', 'application/json');
|
|
175
|
+
res.end(JSON.stringify({
|
|
176
|
+
ok: true,
|
|
177
|
+
data: {
|
|
178
|
+
platform: 'lark',
|
|
179
|
+
workspaceId: '知识库',
|
|
180
|
+
channelId: 'chat-1',
|
|
181
|
+
messageIds: ['msg-file-1'],
|
|
182
|
+
attachments: [{
|
|
183
|
+
kind: 'file',
|
|
184
|
+
attachmentId: 'file-key-1',
|
|
185
|
+
fileName: 'out.pdf',
|
|
186
|
+
fileSize: 123,
|
|
187
|
+
metadata: { fileKey: 'file-key-1' },
|
|
188
|
+
}],
|
|
189
|
+
},
|
|
190
|
+
}));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
res.statusCode = 404;
|
|
194
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
195
|
+
});
|
|
196
|
+
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
197
|
+
const address = server.address();
|
|
198
|
+
(0, strict_1.default)(address && typeof address === 'object');
|
|
199
|
+
const { io, read } = createIo();
|
|
200
|
+
const exitCode = await (0, lac_js_1.runCli)(['channel', 'send-file', '--path', 'reports/out.pdf', '--name', 'out.pdf'], {
|
|
201
|
+
LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
|
|
202
|
+
LOCAL_AI_WORKSPACE_ID: '知识库',
|
|
203
|
+
LOCAL_AI_WORKSPACE_PATH: '/workspace/project',
|
|
204
|
+
LOCAL_AI_PLATFORM: 'lark',
|
|
205
|
+
LOCAL_AI_CHAT_ID: 'chat-1',
|
|
206
|
+
LOCAL_AI_PLATFORM_USER_ID: 'user-1',
|
|
207
|
+
}, io);
|
|
208
|
+
server.close();
|
|
209
|
+
strict_1.default.equal(exitCode, 0);
|
|
210
|
+
(0, strict_1.default)(capturedBody);
|
|
211
|
+
strict_1.default.deepEqual(JSON.parse(capturedBody), {
|
|
212
|
+
route: {
|
|
213
|
+
type: 'channel.chat',
|
|
214
|
+
channelId: 'chat-1',
|
|
215
|
+
participantId: 'user-1',
|
|
216
|
+
},
|
|
217
|
+
parts: [{
|
|
218
|
+
type: 'file',
|
|
219
|
+
path: 'reports/out.pdf',
|
|
220
|
+
fileName: 'out.pdf',
|
|
221
|
+
metadata: {
|
|
222
|
+
workspacePath: '/workspace/project',
|
|
223
|
+
},
|
|
224
|
+
}],
|
|
225
|
+
});
|
|
226
|
+
strict_1.default.match(read().stdout, /Sent file out\.pdf to chat-1: msg-file-1/);
|
|
227
|
+
});
|
|
228
|
+
(0, node_test_1.default)('lac channel send-file posts allowed absolute paths through the same outbound message path', async () => {
|
|
229
|
+
let capturedBody = null;
|
|
230
|
+
const server = (0, node_http_1.createServer)(async (req, res) => {
|
|
231
|
+
if (req.method === 'POST' && req.url === '/api/local/v1/platforms/lark/%E7%9F%A5%E8%AF%86%E5%BA%93/messages') {
|
|
232
|
+
const chunks = [];
|
|
233
|
+
for await (const chunk of req) {
|
|
234
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
235
|
+
}
|
|
236
|
+
capturedBody = Buffer.concat(chunks).toString('utf8');
|
|
237
|
+
res.setHeader('content-type', 'application/json');
|
|
238
|
+
res.end(JSON.stringify({
|
|
239
|
+
ok: true,
|
|
240
|
+
data: {
|
|
241
|
+
platform: 'lark',
|
|
242
|
+
workspaceId: '知识库',
|
|
243
|
+
channelId: 'chat-1',
|
|
244
|
+
messageIds: ['msg-file-2'],
|
|
245
|
+
attachments: [{
|
|
246
|
+
kind: 'file',
|
|
247
|
+
attachmentId: 'file-key-2',
|
|
248
|
+
fileName: 'absolute.pdf',
|
|
249
|
+
fileSize: 456,
|
|
250
|
+
metadata: { fileKey: 'file-key-2' },
|
|
251
|
+
}],
|
|
252
|
+
},
|
|
253
|
+
}));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
res.statusCode = 404;
|
|
257
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
258
|
+
});
|
|
259
|
+
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
260
|
+
const address = server.address();
|
|
261
|
+
(0, strict_1.default)(address && typeof address === 'object');
|
|
262
|
+
const { io, read } = createIo();
|
|
263
|
+
const exitCode = await (0, lac_js_1.runCli)(['channel', 'send-file', '--path', '/tmp/absolute.pdf'], {
|
|
264
|
+
LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
|
|
265
|
+
LOCAL_AI_WORKSPACE_ID: '知识库',
|
|
266
|
+
LOCAL_AI_WORKSPACE_PATH: '/workspace/project',
|
|
267
|
+
LOCAL_AI_PLATFORM: 'lark',
|
|
268
|
+
LOCAL_AI_CHAT_ID: 'chat-1',
|
|
269
|
+
LOCAL_AI_PLATFORM_USER_ID: 'user-1',
|
|
270
|
+
}, io);
|
|
271
|
+
server.close();
|
|
272
|
+
strict_1.default.equal(exitCode, 0);
|
|
273
|
+
(0, strict_1.default)(capturedBody);
|
|
274
|
+
strict_1.default.deepEqual(JSON.parse(capturedBody), {
|
|
275
|
+
route: {
|
|
276
|
+
type: 'channel.chat',
|
|
277
|
+
channelId: 'chat-1',
|
|
278
|
+
participantId: 'user-1',
|
|
279
|
+
},
|
|
280
|
+
parts: [{
|
|
281
|
+
type: 'file',
|
|
282
|
+
path: '/tmp/absolute.pdf',
|
|
283
|
+
metadata: {
|
|
284
|
+
workspacePath: '/workspace/project',
|
|
285
|
+
},
|
|
286
|
+
}],
|
|
287
|
+
});
|
|
288
|
+
strict_1.default.match(read().stdout, /Sent file absolute\.pdf to chat-1: msg-file-2/);
|
|
289
|
+
});
|
|
165
290
|
(0, node_test_1.default)('lac scheduler list shows workspace jobs by default', async () => {
|
|
166
291
|
const server = (0, node_http_1.createServer)((req, res) => {
|
|
167
292
|
if (req.method === 'GET' && req.url === '/api/local/v1/scheduler/jobs?workspace_id=%E7%9F%A5%E8%AF%86%E5%BA%93') {
|
|
@@ -267,6 +392,129 @@ function createIo() {
|
|
|
267
392
|
strict_1.default.match(read().stdout, /Job: 826aff79/);
|
|
268
393
|
strict_1.default.doesNotMatch(read().stdout, /job:826aff79/);
|
|
269
394
|
});
|
|
395
|
+
(0, node_test_1.default)('lac scheduler edit patches a short job id and normalizes execution mode', async () => {
|
|
396
|
+
let capturedBody = null;
|
|
397
|
+
const server = (0, node_http_1.createServer)(async (req, res) => {
|
|
398
|
+
if (req.method === 'PATCH' && req.url === '/api/local/v1/scheduler/jobs/826aff79') {
|
|
399
|
+
const chunks = [];
|
|
400
|
+
for await (const chunk of req) {
|
|
401
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
402
|
+
}
|
|
403
|
+
capturedBody = Buffer.concat(chunks).toString('utf8');
|
|
404
|
+
res.setHeader('content-type', 'application/json');
|
|
405
|
+
res.end(JSON.stringify({
|
|
406
|
+
ok: true,
|
|
407
|
+
data: {
|
|
408
|
+
id: 'job:826aff79-570b-4308-822e-18318e2c96ba',
|
|
409
|
+
workspaceId: '知识库',
|
|
410
|
+
platform: 'lark',
|
|
411
|
+
route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1', threadId: 'thread-1' },
|
|
412
|
+
executionMode: 'side-thread',
|
|
413
|
+
triggerType: 'cron',
|
|
414
|
+
cronExpr: '0 10 * * *',
|
|
415
|
+
promptTemplate: 'updated ping',
|
|
416
|
+
description: 'daily updated ping',
|
|
417
|
+
enabled: false,
|
|
418
|
+
concurrencyPolicy: 'skip_if_running',
|
|
419
|
+
createdAt: '2026-04-22T06:00:00.000Z',
|
|
420
|
+
updatedAt: '2026-04-22T07:00:00.000Z',
|
|
421
|
+
},
|
|
422
|
+
}));
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
res.statusCode = 404;
|
|
426
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
427
|
+
});
|
|
428
|
+
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
429
|
+
const address = server.address();
|
|
430
|
+
(0, strict_1.default)(address && typeof address === 'object');
|
|
431
|
+
const { io, read } = createIo();
|
|
432
|
+
const exitCode = await (0, lac_js_1.runCli)([
|
|
433
|
+
'scheduler',
|
|
434
|
+
'edit',
|
|
435
|
+
'826aff79',
|
|
436
|
+
'--cron',
|
|
437
|
+
'0 10 * * *',
|
|
438
|
+
'--message',
|
|
439
|
+
'updated ping',
|
|
440
|
+
'--desc',
|
|
441
|
+
'daily updated ping',
|
|
442
|
+
'--enabled',
|
|
443
|
+
'false',
|
|
444
|
+
'--execution-mode',
|
|
445
|
+
'side_thread',
|
|
446
|
+
], {
|
|
447
|
+
LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
|
|
448
|
+
}, io);
|
|
449
|
+
server.close();
|
|
450
|
+
strict_1.default.equal(exitCode, 0);
|
|
451
|
+
(0, strict_1.default)(capturedBody);
|
|
452
|
+
strict_1.default.deepEqual(JSON.parse(capturedBody), {
|
|
453
|
+
cronExpr: '0 10 * * *',
|
|
454
|
+
promptTemplate: 'updated ping',
|
|
455
|
+
description: 'daily updated ping',
|
|
456
|
+
enabled: false,
|
|
457
|
+
executionMode: 'side-thread',
|
|
458
|
+
});
|
|
459
|
+
strict_1.default.match(read().stdout, /Updated scheduler job 826aff79/);
|
|
460
|
+
strict_1.default.doesNotMatch(read().stdout, /job:826aff79/);
|
|
461
|
+
});
|
|
462
|
+
(0, node_test_1.default)('lac scheduler del deletes a short job id', async () => {
|
|
463
|
+
const server = (0, node_http_1.createServer)((req, res) => {
|
|
464
|
+
if (req.method === 'DELETE' && req.url === '/api/local/v1/scheduler/jobs/826aff79') {
|
|
465
|
+
res.setHeader('content-type', 'application/json');
|
|
466
|
+
res.end(JSON.stringify({ ok: true, data: { deleted: true } }));
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
res.statusCode = 404;
|
|
470
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
471
|
+
});
|
|
472
|
+
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
473
|
+
const address = server.address();
|
|
474
|
+
(0, strict_1.default)(address && typeof address === 'object');
|
|
475
|
+
const { io, read } = createIo();
|
|
476
|
+
const exitCode = await (0, lac_js_1.runCli)(['scheduler', 'del', '826aff79'], {
|
|
477
|
+
LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
|
|
478
|
+
}, io);
|
|
479
|
+
server.close();
|
|
480
|
+
strict_1.default.equal(exitCode, 0);
|
|
481
|
+
strict_1.default.match(read().stdout, /Deleted scheduler job 826aff79/);
|
|
482
|
+
strict_1.default.doesNotMatch(read().stdout, /job:826aff79/);
|
|
483
|
+
});
|
|
484
|
+
(0, node_test_1.default)('lac scheduler run triggers a short job id', async () => {
|
|
485
|
+
const server = (0, node_http_1.createServer)((req, res) => {
|
|
486
|
+
if (req.method === 'POST' && req.url === '/api/local/v1/scheduler/jobs/826aff79/run') {
|
|
487
|
+
res.setHeader('content-type', 'application/json');
|
|
488
|
+
res.end(JSON.stringify({
|
|
489
|
+
ok: true,
|
|
490
|
+
data: {
|
|
491
|
+
id: 'run-1',
|
|
492
|
+
jobId: 'job:826aff79-570b-4308-822e-18318e2c96ba',
|
|
493
|
+
status: 'queued',
|
|
494
|
+
triggeredAt: '2026-04-22T07:00:00.000Z',
|
|
495
|
+
startedAt: '2026-04-22T07:00:00.000Z',
|
|
496
|
+
completedAt: '',
|
|
497
|
+
output: '',
|
|
498
|
+
error: '',
|
|
499
|
+
},
|
|
500
|
+
}));
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
res.statusCode = 404;
|
|
504
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
505
|
+
});
|
|
506
|
+
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
507
|
+
const address = server.address();
|
|
508
|
+
(0, strict_1.default)(address && typeof address === 'object');
|
|
509
|
+
const { io, read } = createIo();
|
|
510
|
+
const exitCode = await (0, lac_js_1.runCli)(['scheduler', 'run', '826aff79'], {
|
|
511
|
+
LOCAL_AI_CORE_BASE: `http://127.0.0.1:${address.port}/api/local/v1`,
|
|
512
|
+
}, io);
|
|
513
|
+
server.close();
|
|
514
|
+
strict_1.default.equal(exitCode, 0);
|
|
515
|
+
strict_1.default.match(read().stdout, /Triggered scheduler job 826aff79: queued/);
|
|
516
|
+
strict_1.default.doesNotMatch(read().stdout, /job:826aff79/);
|
|
517
|
+
});
|
|
270
518
|
(0, node_test_1.default)('lac scheduler list --thread filters by current thread context', async () => {
|
|
271
519
|
const server = (0, node_http_1.createServer)((req, res) => {
|
|
272
520
|
if (req.method === 'GET' && req.url === '/api/local/v1/scheduler/jobs?workspace_id=%E7%9F%A5%E8%AF%86%E5%BA%93') {
|