clawmini 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -77
- package/dist/adapter-discord/index.mjs +2 -2
- package/dist/{chats-Zd_HXDHx.mjs → chats-BcbxvPlj.mjs} +2 -2
- package/dist/{chats-Zd_HXDHx.mjs.map → chats-BcbxvPlj.mjs.map} +1 -1
- package/dist/{chats-DKgTeU7i.mjs → chats-CpRQrNHj.mjs} +2 -2
- package/dist/{chats-DKgTeU7i.mjs.map → chats-CpRQrNHj.mjs.map} +1 -1
- package/dist/cli/index.mjs +4 -3
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lite.mjs +48 -0
- package/dist/cli/lite.mjs.map +1 -1
- package/dist/daemon/index.mjs +311 -19
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{lite-Dl7WXyaH.mjs → lite-DBUuHsX0.mjs} +2 -2
- package/dist/{lite-Dl7WXyaH.mjs.map → lite-DBUuHsX0.mjs.map} +1 -1
- package/dist/policy-utils-BvfOK6Ih.mjs +114 -0
- package/dist/policy-utils-BvfOK6Ih.mjs.map +1 -0
- package/dist/web/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
- package/dist/web/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
- package/dist/web/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
- package/dist/web/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
- package/dist/web/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
- package/dist/web/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
- package/dist/web/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
- package/dist/web/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
- package/dist/web/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +6 -6
- package/dist/{workspace-CSgfo_2J.mjs → workspace-BC1ahx4R.mjs} +13 -2
- package/dist/workspace-BC1ahx4R.mjs.map +1 -0
- package/docs/CLI_REFERENCE.md +35 -0
- package/docs/guides/sandbox_policies.md +12 -5
- package/package.json +1 -1
- package/web/.svelte-kit/ambient.d.ts +2 -6
- package/web/.svelte-kit/generated/server/internal.js +1 -1
- package/web/.svelte-kit/output/client/.vite/manifest.json +25 -25
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{CSvS_NwK.js → B3YcEpQV.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{COekwvP2.js → CAZeqksE.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/{app.B-vZe7PN.js → app.ZuicLpkH.js} +2 -2
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.DuQwh4Nz.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.B5WFN0zw.js → 0.BB1CjKco.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{1.D1wtJb2k.js → 1.CdSgEHu9.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.BB5wCoBf.js → 3.CKp7Wkn8.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{4.Dr2jvAXK.js → 4.FyeoMY-Y.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BJl7oM3b.js → 5.D6mVN7l7.js} +1 -1
- package/web/.svelte-kit/output/client/_app/version.json +1 -1
- package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
- package/web/.svelte-kit/output/server/manifest-full.js +1 -1
- package/web/.svelte-kit/output/server/manifest.js +1 -1
- package/web/.svelte-kit/output/server/nodes/0.js +1 -1
- package/web/.svelte-kit/output/server/nodes/1.js +1 -1
- package/web/.svelte-kit/output/server/nodes/3.js +1 -1
- package/web/.svelte-kit/output/server/nodes/4.js +1 -1
- package/web/.svelte-kit/output/server/nodes/5.js +1 -1
- package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +0 -1
- package/dist/workspace-CSgfo_2J.mjs.map +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as U,a as d,f as p}from"../chunks/Dc-UOHw9.js";import{a as Ve}from"../chunks/B8yYFADm.js";import{f as z,p as Me,a as Le,F as He,I as P,l as we,n as F,w as e,D as f,aR as Se,G as ke,s as S,c,r as v,t as M,C as Q}from"../chunks/CpaGRn9L.js";import{d as Ge,e as Ee,s as O,a as ie}from"../chunks/DG5RZBw-.js";import{l as de,s as le,p as se,b as Ne,r as Ae,i as L}from"../chunks/C3k55nDF.js";import{I as ce,s as ve,a as Ke,d as qe,c as Qe,e as Te,B as Ue,h as j}from"../chunks/BmUXQ3wy.js";import{i as ne}from"../chunks/CSvS_NwK.js";import{a as oe}from"../chunks/B5abRDXp.js";import"../chunks/Bi0jeV7Q.js";function We(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["circle",{cx:"12",cy:"12",r:"10"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16"}]];ce(k,le({name:"circle-alert"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}function Xe(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["circle",{cx:"12",cy:"12",r:"10"}],["path",{d:"M12 6v6l4 2"}]];ce(k,le({name:"clock"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}function Ye(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}],["path",{d:"m21.854 2.147-10.94 10.939"}]];ce(k,le({name:"send"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}const Ze=async({params:k,fetch:r,depends:m})=>{const{id:n}=k;m(`app:chat:${n}`);try{const y=await r(`/api/chats/${n}`);if(y.ok){const i=await y.json();return{id:n,messages:i}}}catch(y){console.error(y)}return{id:n,messages:[]}},Ot=Object.freeze(Object.defineProperty({__proto__:null,load:Ze},Symbol.toStringTag,{value:"Module"}));var et=p("<textarea></textarea>");function tt(k,r){Me(r,!0);let m=se(r,"ref",15,null),n=se(r,"value",15),y=se(r,"data-slot",3,"textarea"),i=Ae(r,["$$slots","$$events","$$legacy","ref","value","class","data-slot"]);var u=et();He(u),Ke(u,l=>({"data-slot":y(),class:l,...i}),[()=>Qe("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",r.class)]),Ne(u,l=>m(l),()=>m()),qe(u,n),d(k,u),Le()}var at=p('<div class="absolute top-4 left-1/2 -translate-x-1/2 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 text-xs px-3 py-1 rounded-full border border-yellow-500/20 backdrop-blur-sm shadow-sm z-10 flex items-center gap-2"><span class="inline-block w-3 h-3 rounded-full border-2 border-current border-t-transparent animate-spin"></span> Reconnecting...</div>'),rt=p('<div class="flex-1 flex items-center justify-center text-muted-foreground text-sm">No messages yet. Send a message to start the conversation!</div>'),it=p('<div class="px-4 py-2 rounded-2xl bg-primary text-primary-foreground text-sm" data-testid="user-message"> </div>'),st=p('<span class="text-destructive font-bold"> </span>'),nt=p('<div class="whitespace-pre-wrap"> </div>'),ot=p('<div class="whitespace-pre-wrap font-mono text-xs mt-2"> </div>'),dt=p('<div class="whitespace-pre-wrap italic opacity-50 text-xs mt-2">No output</div>'),lt=p('<div class="whitespace-pre-wrap font-mono text-xs mt-2 text-destructive border border-destructive/20 bg-destructive/5 p-2 rounded"> </div>'),ct=p('<div class="font-mono text-xs text-muted-foreground mb-2 flex items-center gap-2"><span> </span> <!></div> <!> <!>',1),vt=p('<div class="whitespace-pre-wrap"> </div>'),ut=p('<div data-testid="log-message"><!></div>'),ft=p('<div><div><!></div> <div class="text-[10px] text-muted-foreground px-2"> </div></div>'),pt=p('<span class="inline-block w-2 h-2 rounded-full border border-current border-t-transparent animate-spin"></span> Sending...',1),mt=p("<!> Offline / Pending",1),xt=p("<!> Failed",1),gt=p('<div class="flex items-center gap-2 mt-1 mr-2 bg-card border rounded-md p-1 shadow-sm text-xs"><button class="px-2 py-1 hover:bg-muted rounded text-primary transition-colors focus:outline-none">Retry manual send</button> <div class="w-px h-3 bg-border"></div> <button class="px-2 py-1 hover:bg-muted rounded text-destructive transition-colors focus:outline-none">Delete message</button></div>'),_t=p('<div><button class="flex items-baseline gap-2 max-w-[80%] flex-row-reverse text-left focus:outline-none"><div data-testid="pending-message"> </div></button> <div><!></div> <!></div>'),ht=p('<!> <span class="sr-only">Send</span>',1),bt=p('<div class="flex flex-col flex-1 h-full overflow-hidden relative"><!> <div class="flex-1 overflow-y-auto p-4"><div class="w-full max-w-4xl mx-auto space-y-6 flex flex-col min-h-full"><!> <!> <!></div></div> <div class="p-4 bg-background/80 backdrop-blur-sm border-t shrink-0"><form class="flex items-center gap-2 max-w-4xl mx-auto"><!> <!></form></div></div>');function zt(k,r){Me(r,!0);let m=P(""),n=P(we([])),y=ke(()=>e(n).filter(t=>t.role==="user"||oe.verbosityLevel==="verbose"?!0:oe.verbosityLevel==="debug"?!t.level||t.level==="default"||t.level==="debug":!t.level||t.level==="default")),i=P(we([])),u=P(void 0),l=null,J=P(!0),W=P(!1),K,R=P(null);async function ue(t){const a=e(i).findIndex(s=>s.id===t);if(a!==-1){e(i)[a].status="sending",D(r.data.id,e(i));try{if(!(await fetch(`/api/chats/${r.data.id}/messages`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e(i)[a].content})})).ok)throw new Error("Failed to send");await ne(`app:chat:${r.data.id}`)}catch(s){console.error("Failed to retry message:",s);const o=e(i).findIndex(x=>x.id===t);o!==-1&&(e(i)[o].status="failed",D(r.data.id,e(i)))}}}function Oe(t){f(i,e(i).filter(a=>a.id!==t),!0),D(r.data.id,e(i))}F(()=>{const t=()=>{e(i).forEach(a=>{(a.status==="pending"||a.status==="failed")&&ue(a.id)})};return window.addEventListener("online",t),()=>{window.removeEventListener("online",t)}});function ze(t){const a=t.target;f(J,Math.abs(a.scrollHeight-a.scrollTop-a.clientHeight)<10)}function X(){e(u)&&(e(u).scrollTop=e(u).scrollHeight)}F(()=>{f(n,r.data.messages,!0);try{const t=localStorage.getItem(`pending_messages_${r.data.id}`);t?f(i,JSON.parse(t),!0):f(i,[],!0)}catch{f(i,[],!0)}f(J,!0),Y(r.data.id)});function D(t,a){localStorage.setItem(`pending_messages_${t}`,JSON.stringify(a))}F(()=>{(e(n).length>0||e(i).length>0)&&e(u)&&e(J)&&Se().then(X)}),F(()=>{e(m),e(J)&&Se().then(X)}),F(()=>{const t=()=>{e(J)&&X()};return window.addEventListener("resize",t),window.visualViewport?.addEventListener("resize",t),()=>{window.removeEventListener("resize",t),window.visualViewport?.removeEventListener("resize",t)}});async function fe(){const t=e(n).length>0?e(n)[e(n).length-1].id:null;if(t)try{const a=await fetch(`/api/chats/${r.data.id}?since=${t}`);if(a.ok){const s=await a.json();for(const o of s)e(n).find(x=>x.id===o.id)||f(n,[...e(n),o],!0)}}catch(a){console.error("Failed to fetch delta messages:",a)}else await ne(`app:chat:${r.data.id}`)}F(()=>{const t=()=>{document.visibilityState==="visible"&&(fe(),(!l||l.readyState===EventSource.CLOSED)&&Y(r.data.id))};return document.addEventListener("visibilitychange",t),()=>{document.removeEventListener("visibilitychange",t)}});function Y(t){l&&(l.close(),clearTimeout(K)),l=new EventSource(`/api/chats/${t}/stream`),l.onopen=()=>{f(W,!1)},l.onerror=()=>{(l?.readyState===EventSource.CLOSED||l?.readyState===EventSource.CONNECTING)&&(f(W,!0),l.close(),clearTimeout(K),K=setTimeout(async()=>{await fe(),Y(t)},3e3))},l.onmessage=a=>{try{const s=JSON.parse(a.data);if(!e(n).find(o=>o.id===s.id)&&(f(n,[...e(n),s],!0),s.role==="user")){const o=e(i).findIndex(x=>x.content===s.content);o!==-1&&(f(i,e(i).filter((x,V)=>V!==o),!0),D(t,e(i)))}}catch(s){console.error("Failed to parse SSE message",s)}}}Ve(()=>{l&&l.close(),clearTimeout(K)});async function pe(t){if(t.preventDefault(),!e(m).trim())return;const a=e(m);f(m,"");const s={id:`pending-${Date.now()}-${Math.random()}`,content:a,timestamp:new Date().toISOString(),status:navigator.onLine?"sending":"pending"};if(f(i,[...e(i),s],!0),D(r.data.id,e(i)),!!navigator.onLine)try{if(!(await fetch(`/api/chats/${r.data.id}/messages`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:a})})).ok)throw new Error("Failed to send");await ne(`app:chat:${r.data.id}`)}catch(o){console.error("Failed to send message:",o),f(i,e(i).map(x=>x.id===s.id?{...x,status:"failed"}:x),!0),D(r.data.id,e(i))}}function $e(t){return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}var Z=bt(),me=c(Z);{var Ce=t=>{var a=at();d(t,a)};L(me,t=>{e(W)&&t(Ce)})}var B=S(me,2),xe=c(B),ge=c(xe);{var Pe=t=>{var a=rt();d(t,a)};L(ge,t=>{e(n).length===0&&t(Pe)})}var _e=S(ge,2);Te(_e,17,()=>e(y),t=>t.id,(t,a)=>{var s=ft(),o=c(s),x=c(o);{var V=E=>{var T=it(),H=c(T,!0);v(T),M(()=>O(H,e(a).content)),d(E,T)},I=E=>{var T=ut(),H=c(T);{var ae=g=>{var w=ct(),$=z(w),N=c($),G=c(N);v(N);var A=S(N,2);{var re=_=>{var h=st(),C=c(h);v(h),M(()=>O(C,`Exit: ${e(a).exitCode??""}`)),d(_,h)};L(A,_=>{e(a).exitCode!==0&&_(re)})}v($);var ye=S($,2);{var Fe=_=>{var h=nt(),C=c(h,!0);v(h),M(()=>O(C,e(a).content)),d(_,h)},je=_=>{var h=ot(),C=c(h,!0);v(h),M(()=>O(C,e(a).stdout)),d(_,h)},Je=_=>{var h=dt();d(_,h)};L(ye,_=>{e(a).content?_(Fe):e(a).stdout?_(je,1):_(Je,-1)})}var Re=S(ye,2);{var Be=_=>{var h=lt(),C=c(h,!0);v(h),M(()=>O(C,e(a).stderr)),d(_,h)};L(Re,_=>{e(a).stderr&&_(Be)})}M(()=>O(G,`$ ${e(a).command??""}`)),d(g,w)},b=g=>{var w=U(),$=z(w);{var N=G=>{var A=vt(),re=c(A,!0);v(A),M(()=>O(re,e(a).content)),d(G,A)};L($,G=>{e(a).content&&G(N)})}d(g,w)};L(H,g=>{oe.verbosityLevel==="verbose"?g(ae):g(b,-1)})}v(T),M(()=>j(T,1,`px-4 py-3 rounded-2xl bg-card border text-card-foreground text-sm shadow-sm ${e(a).level==="verbose"?"border-primary/50 bg-primary/5 shadow-md":""}`)),d(E,T)};L(x,E=>{e(a).role==="user"?E(V):E(I,-1)})}v(o);var q=S(o,2),te=c(q,!0);v(q),v(s),M(E=>{j(s,1,`flex flex-col gap-1 ${e(a).role==="user"?"items-end":"items-start"}`),j(o,1,`flex items-baseline gap-2 max-w-[80%] ${e(a).role==="user"?"flex-row-reverse":"flex-row"}`),O(te,E)},[()=>$e(e(a).timestamp)]),d(t,s)});var De=S(_e,2);Te(De,17,()=>e(i),t=>t.id,(t,a)=>{var s=_t(),o=c(s),x=c(o),V=c(x,!0);v(x),v(o);var I=S(o,2),q=c(I);{var te=b=>{var g=pt();Q(),d(b,g)},E=b=>{var g=mt(),w=z(g);Xe(w,{class:"w-3 h-3"}),Q(),d(b,g)},T=b=>{var g=xt(),w=z(g);We(w,{class:"w-3 h-3"}),Q(),d(b,g)};L(q,b=>{e(a).status==="sending"?b(te):e(a).status==="pending"?b(E,1):e(a).status==="failed"&&b(T,2)})}v(I);var H=S(I,2);{var ae=b=>{var g=gt(),w=c(g),$=S(w,4);v(g),ie("click",w,N=>{N.stopPropagation(),f(R,null),ue(e(a).id)}),ie("click",$,N=>{N.stopPropagation(),f(R,null),Oe(e(a).id)}),d(b,g)};L(H,b=>{e(R)===e(a).id&&e(a).status!=="sending"&&b(ae)})}v(s),M(()=>{j(s,1,`flex flex-col gap-1 items-end ${e(a).status==="sending"?"opacity-50":""} transition-opacity`),j(x,1,`px-4 py-2 rounded-2xl ${e(a).status==="failed"?"bg-destructive/90 text-destructive-foreground":"bg-primary text-primary-foreground"} text-sm`),O(V,e(a).content),j(I,1,`text-[10px] px-2 flex items-center gap-1 ${e(a).status==="failed"?"text-destructive font-medium":"text-muted-foreground"}`)}),ie("click",o,()=>{e(a).status!=="sending"&&f(R,e(R)===e(a).id?null:e(a).id,!0)}),d(t,s)}),v(xe),v(B),Ne(B,t=>f(u,t),()=>e(u));var he=S(B,2),ee=c(he),be=c(ee);tt(be,{placeholder:"Type your message...",class:"flex-1 min-h-[0px] resize-none overflow-hidden h-auto",onkeydown:t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),pe(t))},"data-testid":"message-input",get value(){return e(m)},set value(t){f(m,t,!0)}});var Ie=S(be,2);{let t=ke(()=>!e(m).trim());Ue(Ie,{type:"submit",get disabled(){return e(t)},size:"icon","data-testid":"send-button",children:(a,s)=>{var o=ht(),x=z(o);Ye(x,{class:"w-4 h-4"}),Q(2),d(a,o)},$$slots:{default:!0}})}v(ee),v(he),v(Z),Ee("scroll",B,ze),Ee("submit",ee,pe),d(k,Z),Le()}Ge(["click"]);export{zt as component,Ot as universal};
|
|
1
|
+
import{c as U,a as d,f as p}from"../chunks/Dc-UOHw9.js";import{a as Ve}from"../chunks/B8yYFADm.js";import{f as z,p as Me,a as Le,F as He,I as P,l as we,n as F,w as e,D as f,aR as Se,G as ke,s as S,c,r as v,t as M,C as Q}from"../chunks/CpaGRn9L.js";import{d as Ge,e as Ee,s as O,a as ie}from"../chunks/DG5RZBw-.js";import{l as de,s as le,p as se,b as Ne,r as Ae,i as L}from"../chunks/C3k55nDF.js";import{I as ce,s as ve,a as Ke,d as qe,c as Qe,e as Te,B as Ue,h as j}from"../chunks/BmUXQ3wy.js";import{i as ne}from"../chunks/B3YcEpQV.js";import{a as oe}from"../chunks/B5abRDXp.js";import"../chunks/Bi0jeV7Q.js";function We(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["circle",{cx:"12",cy:"12",r:"10"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16"}]];ce(k,le({name:"circle-alert"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}function Xe(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["circle",{cx:"12",cy:"12",r:"10"}],["path",{d:"M12 6v6l4 2"}]];ce(k,le({name:"clock"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}function Ye(k,r){const m=de(r,["children","$$slots","$$events","$$legacy"]);const n=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}],["path",{d:"m21.854 2.147-10.94 10.939"}]];ce(k,le({name:"send"},()=>m,{get iconNode(){return n},children:(y,i)=>{var u=U(),l=z(u);ve(l,r,"default",{}),d(y,u)},$$slots:{default:!0}}))}const Ze=async({params:k,fetch:r,depends:m})=>{const{id:n}=k;m(`app:chat:${n}`);try{const y=await r(`/api/chats/${n}`);if(y.ok){const i=await y.json();return{id:n,messages:i}}}catch(y){console.error(y)}return{id:n,messages:[]}},Ot=Object.freeze(Object.defineProperty({__proto__:null,load:Ze},Symbol.toStringTag,{value:"Module"}));var et=p("<textarea></textarea>");function tt(k,r){Me(r,!0);let m=se(r,"ref",15,null),n=se(r,"value",15),y=se(r,"data-slot",3,"textarea"),i=Ae(r,["$$slots","$$events","$$legacy","ref","value","class","data-slot"]);var u=et();He(u),Ke(u,l=>({"data-slot":y(),class:l,...i}),[()=>Qe("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",r.class)]),Ne(u,l=>m(l),()=>m()),qe(u,n),d(k,u),Le()}var at=p('<div class="absolute top-4 left-1/2 -translate-x-1/2 bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 text-xs px-3 py-1 rounded-full border border-yellow-500/20 backdrop-blur-sm shadow-sm z-10 flex items-center gap-2"><span class="inline-block w-3 h-3 rounded-full border-2 border-current border-t-transparent animate-spin"></span> Reconnecting...</div>'),rt=p('<div class="flex-1 flex items-center justify-center text-muted-foreground text-sm">No messages yet. Send a message to start the conversation!</div>'),it=p('<div class="px-4 py-2 rounded-2xl bg-primary text-primary-foreground text-sm" data-testid="user-message"> </div>'),st=p('<span class="text-destructive font-bold"> </span>'),nt=p('<div class="whitespace-pre-wrap"> </div>'),ot=p('<div class="whitespace-pre-wrap font-mono text-xs mt-2"> </div>'),dt=p('<div class="whitespace-pre-wrap italic opacity-50 text-xs mt-2">No output</div>'),lt=p('<div class="whitespace-pre-wrap font-mono text-xs mt-2 text-destructive border border-destructive/20 bg-destructive/5 p-2 rounded"> </div>'),ct=p('<div class="font-mono text-xs text-muted-foreground mb-2 flex items-center gap-2"><span> </span> <!></div> <!> <!>',1),vt=p('<div class="whitespace-pre-wrap"> </div>'),ut=p('<div data-testid="log-message"><!></div>'),ft=p('<div><div><!></div> <div class="text-[10px] text-muted-foreground px-2"> </div></div>'),pt=p('<span class="inline-block w-2 h-2 rounded-full border border-current border-t-transparent animate-spin"></span> Sending...',1),mt=p("<!> Offline / Pending",1),xt=p("<!> Failed",1),gt=p('<div class="flex items-center gap-2 mt-1 mr-2 bg-card border rounded-md p-1 shadow-sm text-xs"><button class="px-2 py-1 hover:bg-muted rounded text-primary transition-colors focus:outline-none">Retry manual send</button> <div class="w-px h-3 bg-border"></div> <button class="px-2 py-1 hover:bg-muted rounded text-destructive transition-colors focus:outline-none">Delete message</button></div>'),_t=p('<div><button class="flex items-baseline gap-2 max-w-[80%] flex-row-reverse text-left focus:outline-none"><div data-testid="pending-message"> </div></button> <div><!></div> <!></div>'),ht=p('<!> <span class="sr-only">Send</span>',1),bt=p('<div class="flex flex-col flex-1 h-full overflow-hidden relative"><!> <div class="flex-1 overflow-y-auto p-4"><div class="w-full max-w-4xl mx-auto space-y-6 flex flex-col min-h-full"><!> <!> <!></div></div> <div class="p-4 bg-background/80 backdrop-blur-sm border-t shrink-0"><form class="flex items-center gap-2 max-w-4xl mx-auto"><!> <!></form></div></div>');function zt(k,r){Me(r,!0);let m=P(""),n=P(we([])),y=ke(()=>e(n).filter(t=>t.role==="user"||oe.verbosityLevel==="verbose"?!0:oe.verbosityLevel==="debug"?!t.level||t.level==="default"||t.level==="debug":!t.level||t.level==="default")),i=P(we([])),u=P(void 0),l=null,J=P(!0),W=P(!1),K,R=P(null);async function ue(t){const a=e(i).findIndex(s=>s.id===t);if(a!==-1){e(i)[a].status="sending",D(r.data.id,e(i));try{if(!(await fetch(`/api/chats/${r.data.id}/messages`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e(i)[a].content})})).ok)throw new Error("Failed to send");await ne(`app:chat:${r.data.id}`)}catch(s){console.error("Failed to retry message:",s);const o=e(i).findIndex(x=>x.id===t);o!==-1&&(e(i)[o].status="failed",D(r.data.id,e(i)))}}}function Oe(t){f(i,e(i).filter(a=>a.id!==t),!0),D(r.data.id,e(i))}F(()=>{const t=()=>{e(i).forEach(a=>{(a.status==="pending"||a.status==="failed")&&ue(a.id)})};return window.addEventListener("online",t),()=>{window.removeEventListener("online",t)}});function ze(t){const a=t.target;f(J,Math.abs(a.scrollHeight-a.scrollTop-a.clientHeight)<10)}function X(){e(u)&&(e(u).scrollTop=e(u).scrollHeight)}F(()=>{f(n,r.data.messages,!0);try{const t=localStorage.getItem(`pending_messages_${r.data.id}`);t?f(i,JSON.parse(t),!0):f(i,[],!0)}catch{f(i,[],!0)}f(J,!0),Y(r.data.id)});function D(t,a){localStorage.setItem(`pending_messages_${t}`,JSON.stringify(a))}F(()=>{(e(n).length>0||e(i).length>0)&&e(u)&&e(J)&&Se().then(X)}),F(()=>{e(m),e(J)&&Se().then(X)}),F(()=>{const t=()=>{e(J)&&X()};return window.addEventListener("resize",t),window.visualViewport?.addEventListener("resize",t),()=>{window.removeEventListener("resize",t),window.visualViewport?.removeEventListener("resize",t)}});async function fe(){const t=e(n).length>0?e(n)[e(n).length-1].id:null;if(t)try{const a=await fetch(`/api/chats/${r.data.id}?since=${t}`);if(a.ok){const s=await a.json();for(const o of s)e(n).find(x=>x.id===o.id)||f(n,[...e(n),o],!0)}}catch(a){console.error("Failed to fetch delta messages:",a)}else await ne(`app:chat:${r.data.id}`)}F(()=>{const t=()=>{document.visibilityState==="visible"&&(fe(),(!l||l.readyState===EventSource.CLOSED)&&Y(r.data.id))};return document.addEventListener("visibilitychange",t),()=>{document.removeEventListener("visibilitychange",t)}});function Y(t){l&&(l.close(),clearTimeout(K)),l=new EventSource(`/api/chats/${t}/stream`),l.onopen=()=>{f(W,!1)},l.onerror=()=>{(l?.readyState===EventSource.CLOSED||l?.readyState===EventSource.CONNECTING)&&(f(W,!0),l.close(),clearTimeout(K),K=setTimeout(async()=>{await fe(),Y(t)},3e3))},l.onmessage=a=>{try{const s=JSON.parse(a.data);if(!e(n).find(o=>o.id===s.id)&&(f(n,[...e(n),s],!0),s.role==="user")){const o=e(i).findIndex(x=>x.content===s.content);o!==-1&&(f(i,e(i).filter((x,V)=>V!==o),!0),D(t,e(i)))}}catch(s){console.error("Failed to parse SSE message",s)}}}Ve(()=>{l&&l.close(),clearTimeout(K)});async function pe(t){if(t.preventDefault(),!e(m).trim())return;const a=e(m);f(m,"");const s={id:`pending-${Date.now()}-${Math.random()}`,content:a,timestamp:new Date().toISOString(),status:navigator.onLine?"sending":"pending"};if(f(i,[...e(i),s],!0),D(r.data.id,e(i)),!!navigator.onLine)try{if(!(await fetch(`/api/chats/${r.data.id}/messages`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:a})})).ok)throw new Error("Failed to send");await ne(`app:chat:${r.data.id}`)}catch(o){console.error("Failed to send message:",o),f(i,e(i).map(x=>x.id===s.id?{...x,status:"failed"}:x),!0),D(r.data.id,e(i))}}function $e(t){return new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}var Z=bt(),me=c(Z);{var Ce=t=>{var a=at();d(t,a)};L(me,t=>{e(W)&&t(Ce)})}var B=S(me,2),xe=c(B),ge=c(xe);{var Pe=t=>{var a=rt();d(t,a)};L(ge,t=>{e(n).length===0&&t(Pe)})}var _e=S(ge,2);Te(_e,17,()=>e(y),t=>t.id,(t,a)=>{var s=ft(),o=c(s),x=c(o);{var V=E=>{var T=it(),H=c(T,!0);v(T),M(()=>O(H,e(a).content)),d(E,T)},I=E=>{var T=ut(),H=c(T);{var ae=g=>{var w=ct(),$=z(w),N=c($),G=c(N);v(N);var A=S(N,2);{var re=_=>{var h=st(),C=c(h);v(h),M(()=>O(C,`Exit: ${e(a).exitCode??""}`)),d(_,h)};L(A,_=>{e(a).exitCode!==0&&_(re)})}v($);var ye=S($,2);{var Fe=_=>{var h=nt(),C=c(h,!0);v(h),M(()=>O(C,e(a).content)),d(_,h)},je=_=>{var h=ot(),C=c(h,!0);v(h),M(()=>O(C,e(a).stdout)),d(_,h)},Je=_=>{var h=dt();d(_,h)};L(ye,_=>{e(a).content?_(Fe):e(a).stdout?_(je,1):_(Je,-1)})}var Re=S(ye,2);{var Be=_=>{var h=lt(),C=c(h,!0);v(h),M(()=>O(C,e(a).stderr)),d(_,h)};L(Re,_=>{e(a).stderr&&_(Be)})}M(()=>O(G,`$ ${e(a).command??""}`)),d(g,w)},b=g=>{var w=U(),$=z(w);{var N=G=>{var A=vt(),re=c(A,!0);v(A),M(()=>O(re,e(a).content)),d(G,A)};L($,G=>{e(a).content&&G(N)})}d(g,w)};L(H,g=>{oe.verbosityLevel==="verbose"?g(ae):g(b,-1)})}v(T),M(()=>j(T,1,`px-4 py-3 rounded-2xl bg-card border text-card-foreground text-sm shadow-sm ${e(a).level==="verbose"?"border-primary/50 bg-primary/5 shadow-md":""}`)),d(E,T)};L(x,E=>{e(a).role==="user"?E(V):E(I,-1)})}v(o);var q=S(o,2),te=c(q,!0);v(q),v(s),M(E=>{j(s,1,`flex flex-col gap-1 ${e(a).role==="user"?"items-end":"items-start"}`),j(o,1,`flex items-baseline gap-2 max-w-[80%] ${e(a).role==="user"?"flex-row-reverse":"flex-row"}`),O(te,E)},[()=>$e(e(a).timestamp)]),d(t,s)});var De=S(_e,2);Te(De,17,()=>e(i),t=>t.id,(t,a)=>{var s=_t(),o=c(s),x=c(o),V=c(x,!0);v(x),v(o);var I=S(o,2),q=c(I);{var te=b=>{var g=pt();Q(),d(b,g)},E=b=>{var g=mt(),w=z(g);Xe(w,{class:"w-3 h-3"}),Q(),d(b,g)},T=b=>{var g=xt(),w=z(g);We(w,{class:"w-3 h-3"}),Q(),d(b,g)};L(q,b=>{e(a).status==="sending"?b(te):e(a).status==="pending"?b(E,1):e(a).status==="failed"&&b(T,2)})}v(I);var H=S(I,2);{var ae=b=>{var g=gt(),w=c(g),$=S(w,4);v(g),ie("click",w,N=>{N.stopPropagation(),f(R,null),ue(e(a).id)}),ie("click",$,N=>{N.stopPropagation(),f(R,null),Oe(e(a).id)}),d(b,g)};L(H,b=>{e(R)===e(a).id&&e(a).status!=="sending"&&b(ae)})}v(s),M(()=>{j(s,1,`flex flex-col gap-1 items-end ${e(a).status==="sending"?"opacity-50":""} transition-opacity`),j(x,1,`px-4 py-2 rounded-2xl ${e(a).status==="failed"?"bg-destructive/90 text-destructive-foreground":"bg-primary text-primary-foreground"} text-sm`),O(V,e(a).content),j(I,1,`text-[10px] px-2 flex items-center gap-1 ${e(a).status==="failed"?"text-destructive font-medium":"text-muted-foreground"}`)}),ie("click",o,()=>{e(a).status!=="sending"&&f(R,e(R)===e(a).id?null:e(a).id,!0)}),d(t,s)}),v(xe),v(B),Ne(B,t=>f(u,t),()=>e(u));var he=S(B,2),ee=c(he),be=c(ee);tt(be,{placeholder:"Type your message...",class:"flex-1 min-h-[0px] resize-none overflow-hidden h-auto",onkeydown:t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),pe(t))},"data-testid":"message-input",get value(){return e(m)},set value(t){f(m,t,!0)}});var Ie=S(be,2);{let t=ke(()=>!e(m).trim());Ue(Ie,{type:"submit",get disabled(){return e(t)},size:"icon","data-testid":"send-button",children:(a,s)=>{var o=ht(),x=z(o);Ye(x,{class:"w-4 h-4"}),Q(2),d(a,o)},$$slots:{default:!0}})}v(ee),v(he),v(Z),Ee("scroll",B,ze),Ee("submit",ee,pe),d(k,Z),Le()}Ge(["click"]);export{zt as component,Ot as universal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as W,a as l,f as w,t as D}from"../chunks/Dc-UOHw9.js";import{f as z,p as be,t as j,a as _e,c as r,D as v,w as e,I as J,s as o,r as a,C as N,G as xe}from"../chunks/CpaGRn9L.js";import{s as M,e as ye}from"../chunks/DG5RZBw-.js";import{l as oe,s as se,i as T}from"../chunks/C3k55nDF.js";import{I as de,s as ie,B as H,f as we,g as $e,e as Se}from"../chunks/BmUXQ3wy.js";import{i as re}from"../chunks/
|
|
1
|
+
import{c as W,a as l,f as w,t as D}from"../chunks/Dc-UOHw9.js";import{f as z,p as be,t as j,a as _e,c as r,D as v,w as e,I as J,s as o,r as a,C as N,G as xe}from"../chunks/CpaGRn9L.js";import{s as M,e as ye}from"../chunks/DG5RZBw-.js";import{l as oe,s as se,i as T}from"../chunks/C3k55nDF.js";import{I as de,s as ie,B as H,f as we,g as $e,e as Se}from"../chunks/BmUXQ3wy.js";import{i as re}from"../chunks/B3YcEpQV.js";import{P as ke,I as U}from"../chunks/ZkLyk0mE.js";import"../chunks/Bi0jeV7Q.js";function je($,c){const b=oe(c,["children","$$slots","$$events","$$legacy"]);const u=[["path",{d:"m12 19-7-7 7-7"}],["path",{d:"M19 12H5"}]];de($,se({name:"arrow-left"},()=>b,{get iconNode(){return u},children:(h,m)=>{var p=W(),g=z(p);ie(g,c,"default",{}),l(h,p)},$$slots:{default:!0}}))}function Je($,c){const b=oe(c,["children","$$slots","$$events","$$legacy"]);const u=[["path",{d:"M10 11v6"}],["path",{d:"M14 11v6"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"}],["path",{d:"M3 6h18"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"}]];de($,se({name:"trash-2"},()=>b,{get iconNode(){return u},children:(h,m)=>{var p=W(),g=z(p);ie(g,c,"default",{}),l(h,p)},$$slots:{default:!0}}))}const Me=async({params:$,fetch:c,depends:b})=>{const{id:u}=$;b(`app:chat:${u}:cron`);let h=[];try{const m=await c(`/api/chats/${u}/cron`);m.ok&&(h=await m.json())}catch(m){console.error("Failed to load cron jobs:",m)}return{id:u,cronJobs:h}},Le=Object.freeze(Object.defineProperty({__proto__:null,load:Me},Symbol.toStringTag,{value:"Module"}));var Te=w("<!> Add Job",1),Ee=w('<div class="p-3 bg-destructive/10 text-destructive text-sm rounded-md border border-destructive/20"> </div>'),Ie=w(`<form class="p-4 border rounded-lg space-y-4 bg-card text-card-foreground shadow-sm"><div class="grid grid-cols-2 gap-4"><div class="space-y-2"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="jobId">Job ID</label> <!></div> <div class="space-y-2"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="jobType">Schedule Type</label> <select id="jobType" class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"><option>Cron Expression</option><option>Every (e.g. '1h', '30m')</option><option>At (ISO Date/Time)</option></select></div> <div class="space-y-2 col-span-2"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="jobSchedule">Schedule Expression</label> <!></div> <div class="space-y-2 col-span-2"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="jobMessage">Message / Command</label> <!></div></div> <div class="flex justify-end gap-2 pt-2"><!> <!></div></form>`),Pe=w('<div class="p-8 text-center text-muted-foreground border rounded-lg border-dashed">No cron jobs configured for this chat.</div>'),Ce=w('<!> <span class="sr-only">Delete</span>',1),De=w('<div class="flex items-center justify-between p-4 border rounded-lg bg-card text-card-foreground shadow-sm"><div class="space-y-1.5 overflow-hidden"><div class="font-medium flex items-center gap-2"><span class="truncate"> </span> <span class="shrink-0 px-2 py-0.5 text-[10px] uppercase font-bold tracking-wider rounded-full bg-secondary text-secondary-foreground"><!> <!> <!></span></div> <div class="text-sm text-muted-foreground font-mono bg-muted/50 p-1.5 rounded-md truncate"> </div></div> <!></div>'),Ne=w('<div class="grid gap-4"></div>'),ze=w('<div class="flex-1 overflow-y-auto p-6 h-full bg-background text-foreground"><div class="max-w-4xl mx-auto space-y-8"><div class="flex items-center gap-4"><a class="p-2 -ml-2 rounded-full hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title="Back to Chat"><!></a> <h1 class="text-2xl font-bold tracking-tight">Chat Settings</h1></div> <section class="space-y-4"><div class="flex items-center justify-between"><h2 class="text-xl font-semibold">Cron Jobs</h2> <!></div> <!> <!> <!></section></div></div>');function Ze($,c){be(c,!0);let b=xe(()=>c.data.cronJobs),u=J(!1),h=J(""),m=J(""),p=J(""),g=J("cron"),A=J(!1),O=J("");async function ne(s){if(confirm("Are you sure you want to delete this job?"))try{if(!(await fetch(`/api/chats/${c.data.id}/cron/${s}`,{method:"DELETE"})).ok)throw new Error("Failed to delete job");await re(`app:chat:${c.data.id}:cron`)}catch(t){alert(t instanceof Error?t.message:String(t))}}async function le(s){s.preventDefault(),v(A,!0),v(O,"");try{const t={id:e(h),message:e(m),schedule:{}};e(g)==="cron"?t.schedule.cron=e(p):e(g)==="every"?t.schedule.every=e(p):e(g)==="at"&&(t.schedule.at=e(p));const n=await fetch(`/api/chats/${c.data.id}/cron`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const d=await n.json();throw new Error(d.error||"Failed to add job")}v(u,!1),v(h,""),v(m,""),v(p,""),v(g,"cron"),await re(`app:chat:${c.data.id}:cron`)}catch(t){v(O,t instanceof Error?t.message:String(t),!0)}finally{v(A,!1)}}var V=ze(),X=r(V),G=r(X),L=r(G),ce=r(L);je(ce,{class:"w-5 h-5"}),a(L),N(2),a(G);var Y=o(G,2),Z=r(Y),ve=o(r(Z),2);H(ve,{variant:"outline",size:"sm",onclick:()=>v(u,!e(u)),children:(s,t)=>{var n=Te(),d=z(n);ke(d,{class:"w-4 h-4 mr-2"}),N(),l(s,n)},$$slots:{default:!0}}),a(Z);var ee=o(Z,2);{var ue=s=>{var t=Ee(),n=r(t,!0);a(t),j(()=>M(n,e(O))),l(s,t)};T(ee,s=>{e(O)&&s(ue)})}var te=o(ee,2);{var fe=s=>{var t=Ie(),n=r(t),d=r(n),_=o(r(d),2);U(_,{id:"jobId",placeholder:"e.g. daily-standup",required:!0,get value(){return e(h)},set value(f){v(h,f,!0)}}),a(d);var x=o(d,2),S=o(r(x),2),k=r(S);k.value=k.__value="cron";var I=o(k);I.value=I.__value="every";var P=o(I);P.value=P.__value="at",a(S),a(x);var E=o(x,2),K=o(r(E),2);U(K,{id:"jobSchedule",placeholder:"e.g. * * * * *, 1h, or 2024-01-01T12:00:00Z",required:!0,get value(){return e(p)},set value(f){v(p,f,!0)}}),a(E);var C=o(E,2),Q=o(r(C),2);U(Q,{id:"jobMessage",placeholder:"Command to run...",required:!0,get value(){return e(m)},set value(f){v(m,f,!0)}}),a(C),a(n);var q=o(n,2),B=r(q);H(B,{type:"button",variant:"ghost",onclick:()=>v(u,!1),children:(f,R)=>{N();var i=D("Cancel");l(f,i)},$$slots:{default:!0}});var F=o(B,2);H(F,{type:"submit",get disabled(){return e(A)},children:(f,R)=>{N();var i=D();j(()=>M(i,e(A)?"Saving...":"Save Job")),l(f,i)},$$slots:{default:!0}}),a(q),a(t),ye("submit",t,le),$e(S,()=>e(g),f=>v(g,f)),l(s,t)};T(te,s=>{e(u)&&s(fe)})}var pe=o(te,2);{var he=s=>{var t=W(),n=z(t);{var d=_=>{var x=Pe();l(_,x)};T(n,_=>{e(u)||_(d)})}l(s,t)},me=s=>{var t=Ne();Se(t,21,()=>e(b),n=>n.id,(n,d)=>{var _=De(),x=r(_),S=r(x),k=r(S),I=r(k,!0);a(k);var P=o(k,2),E=r(P);{var K=i=>{var y=D();j(()=>M(y,`cron: ${e(d).schedule.cron??""}`)),l(i,y)};T(E,i=>{e(d).schedule.cron&&i(K)})}var C=o(E,2);{var Q=i=>{var y=D();j(()=>M(y,`every: ${e(d).schedule.every??""}`)),l(i,y)};T(C,i=>{e(d).schedule.every&&i(Q)})}var q=o(C,2);{var B=i=>{var y=D();j(()=>M(y,`at: ${e(d).schedule.at??""}`)),l(i,y)};T(q,i=>{e(d).schedule.at&&i(B)})}a(P),a(S);var F=o(S,2),f=r(F);a(F),a(x);var R=o(x,2);H(R,{variant:"ghost",size:"icon",class:"shrink-0 text-destructive hover:bg-destructive/10 hover:text-destructive",onclick:()=>ne(e(d).id),children:(i,y)=>{var ae=Ce(),ge=z(ae);Je(ge,{class:"w-4 h-4"}),N(2),l(i,ae)},$$slots:{default:!0}}),a(_),j(()=>{M(I,e(d).id),M(f,`$ ${e(d).message??""}`)}),l(n,_)}),a(t),l(s,t)};T(pe,s=>{!e(b)||e(b).length===0?s(he):s(me,-1)})}a(Y),a(X),a(V),j(()=>we(L,"href",`/chats/${c.data.id??""}`)),l($,V),_e()}export{Ze as component,Le as universal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"1773201565623"}
|
package/dist/web/index.html
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />
|
|
6
|
-
<link href="/_app/immutable/entry/start.
|
|
7
|
-
<link href="/_app/immutable/chunks/
|
|
6
|
+
<link href="/_app/immutable/entry/start.DuQwh4Nz.js" rel="modulepreload">
|
|
7
|
+
<link href="/_app/immutable/chunks/B3YcEpQV.js" rel="modulepreload">
|
|
8
8
|
<link href="/_app/immutable/chunks/CpaGRn9L.js" rel="modulepreload">
|
|
9
9
|
<link href="/_app/immutable/chunks/B8yYFADm.js" rel="modulepreload">
|
|
10
|
-
<link href="/_app/immutable/entry/app.
|
|
10
|
+
<link href="/_app/immutable/entry/app.ZuicLpkH.js" rel="modulepreload">
|
|
11
11
|
<link href="/_app/immutable/chunks/DG5RZBw-.js" rel="modulepreload">
|
|
12
12
|
<link href="/_app/immutable/chunks/Dc-UOHw9.js" rel="modulepreload">
|
|
13
13
|
<link href="/_app/immutable/chunks/C3k55nDF.js" rel="modulepreload">
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
<div style="display: contents">
|
|
19
19
|
<script>
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
__sveltekit_746l1x = {
|
|
22
22
|
base: ""
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const element = document.currentScript.parentElement;
|
|
26
26
|
|
|
27
27
|
Promise.all([
|
|
28
|
-
import("/_app/immutable/entry/start.
|
|
29
|
-
import("/_app/immutable/entry/app.
|
|
28
|
+
import("/_app/immutable/entry/start.DuQwh4Nz.js"),
|
|
29
|
+
import("/_app/immutable/entry/app.ZuicLpkH.js")
|
|
30
30
|
]).then(([kit, app]) => {
|
|
31
31
|
kit.start(app, element);
|
|
32
32
|
});
|
|
@@ -92,6 +92,7 @@ var workspace_exports = /* @__PURE__ */ __exportAll({
|
|
|
92
92
|
getChatSettingsPath: () => getChatSettingsPath,
|
|
93
93
|
getClawminiDir: () => getClawminiDir,
|
|
94
94
|
getEnvironmentPath: () => getEnvironmentPath,
|
|
95
|
+
getPoliciesPath: () => getPoliciesPath,
|
|
95
96
|
getSettingsPath: () => getSettingsPath,
|
|
96
97
|
getSocketPath: () => getSocketPath,
|
|
97
98
|
getWorkspaceRoot: () => getWorkspaceRoot,
|
|
@@ -100,6 +101,7 @@ var workspace_exports = /* @__PURE__ */ __exportAll({
|
|
|
100
101
|
readAgentSessionSettings: () => readAgentSessionSettings,
|
|
101
102
|
readChatSettings: () => readChatSettings,
|
|
102
103
|
readEnvironment: () => readEnvironment,
|
|
104
|
+
readPolicies: () => readPolicies,
|
|
103
105
|
readSettings: () => readSettings,
|
|
104
106
|
resolveAgentWorkDir: () => resolveAgentWorkDir,
|
|
105
107
|
resolveEnvironmentTemplatePath: () => resolveEnvironmentTemplatePath,
|
|
@@ -142,6 +144,9 @@ function getSocketPath(startDir = process.cwd()) {
|
|
|
142
144
|
function getSettingsPath(startDir = process.cwd()) {
|
|
143
145
|
return path.join(getClawminiDir(startDir), "settings.json");
|
|
144
146
|
}
|
|
147
|
+
function getPoliciesPath(startDir = process.cwd()) {
|
|
148
|
+
return path.join(getClawminiDir(startDir), "policies.json");
|
|
149
|
+
}
|
|
145
150
|
function getChatSettingsPath(chatId, startDir = process.cwd()) {
|
|
146
151
|
return path.join(getClawminiDir(startDir), "chats", chatId, "settings.json");
|
|
147
152
|
}
|
|
@@ -323,6 +328,12 @@ async function readSettings(startDir = process.cwd()) {
|
|
|
323
328
|
async function writeSettings(data, startDir = process.cwd()) {
|
|
324
329
|
await writeJsonFile(getSettingsPath(startDir), data);
|
|
325
330
|
}
|
|
331
|
+
async function readPolicies(startDir = process.cwd()) {
|
|
332
|
+
const data = await readJsonFile(getPoliciesPath(startDir));
|
|
333
|
+
if (!data) return null;
|
|
334
|
+
if (data.policies && typeof data.policies === "object") return data;
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
326
337
|
function getEnvironmentPath(name, startDir = process.cwd()) {
|
|
327
338
|
return path.join(getClawminiDir(startDir), "environments", name);
|
|
328
339
|
}
|
|
@@ -379,5 +390,5 @@ async function enableEnvironment(name, targetPath = "./", startDir = process.cwd
|
|
|
379
390
|
}
|
|
380
391
|
|
|
381
392
|
//#endregion
|
|
382
|
-
export {
|
|
383
|
-
//# sourceMappingURL=workspace-
|
|
393
|
+
export { CronJobSchema as C, writeSettings as S, readSettings as _, getAgent as a, writeAgentSettings as b, getSettingsPath as c, isValidAgentId as d, listAgents as f, readPolicies as g, readEnvironment as h, getActiveEnvironmentInfo as i, getSocketPath as l, readChatSettings as m, deleteAgent as n, getClawminiDir as o, readAgentSessionSettings as p, enableEnvironment as r, getEnvironmentPath as s, applyTemplateToAgent as t, getWorkspaceRoot as u, workspace_exports as v, SettingsSchema as w, writeChatSettings as x, writeAgentSessionSettings as y };
|
|
394
|
+
//# sourceMappingURL=workspace-BC1ahx4R.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-BC1ahx4R.mjs","names":["fsPromises"],"sources":["../src/shared/config.ts","../src/shared/workspace.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const FallbackSchema = z.looseObject({\n commands: z\n .looseObject({\n new: z.string().optional(),\n append: z.string().optional(),\n getSessionId: z.string().optional(),\n getMessageContent: z.string().optional(),\n })\n .optional(),\n env: z.record(z.string(), z.union([z.string(), z.boolean()])).optional(),\n retries: z.number().int().min(0).default(1),\n delayMs: z.number().int().min(0).default(1000),\n});\n\nexport const AgentSchema = z.looseObject({\n commands: z\n .looseObject({\n new: z.string().optional(),\n append: z.string().optional(),\n getSessionId: z.string().optional(),\n getMessageContent: z.string().optional(),\n })\n .optional(),\n env: z.record(z.string(), z.union([z.string(), z.boolean()])).optional(),\n directory: z.string().optional(),\n fallbacks: z.array(FallbackSchema).optional(),\n files: z.string().default('./attachments').optional(),\n});\n\nexport type Agent = z.infer<typeof AgentSchema>;\n\nexport const CronJobSchema = z.looseObject({\n id: z.string().min(1),\n createdAt: z.string().optional(),\n message: z.string().default(''),\n reply: z.string().optional(),\n agentId: z.string().optional(),\n env: z.record(z.string(), z.union([z.string(), z.boolean()])).optional(),\n session: z.looseObject({ type: z.string() }).optional(),\n schedule: z.union([\n z.looseObject({ cron: z.string() }),\n z.looseObject({ every: z.string() }),\n z.looseObject({ at: z.string() }),\n ]),\n});\n\nexport type CronJob = z.infer<typeof CronJobSchema>;\n\nexport const ChatSettingsSchema = z.looseObject({\n defaultAgent: z.string().optional(),\n sessions: z.record(z.string(), z.string()).optional(),\n routers: z.array(z.string()).optional(),\n jobs: z.array(CronJobSchema).optional(),\n});\n\nexport type ChatSettings = z.infer<typeof ChatSettingsSchema>;\n\nexport const AgentSessionSettingsSchema = z.looseObject({\n env: z.record(z.string(), z.union([z.string(), z.boolean()])).optional(),\n});\n\nexport type AgentSessionSettings = z.infer<typeof AgentSessionSettingsSchema>;\n\nexport const EnvironmentSchema = z.looseObject({\n init: z.string().optional(),\n up: z.string().optional(),\n down: z.string().optional(),\n prefix: z.string().optional(),\n envFormat: z.string().optional(),\n exportLiteTo: z.string().optional(),\n env: z.record(z.string(), z.union([z.string(), z.boolean()])).optional(),\n});\n\nexport type Environment = z.infer<typeof EnvironmentSchema>;\n\nexport const SettingsSchema = z.looseObject({\n chats: z\n .looseObject({\n defaultId: z.string().optional(),\n })\n .optional(),\n defaultAgent: AgentSchema.optional(),\n environments: z.record(z.string(), z.string()).optional(),\n routers: z.array(z.string()).optional(),\n files: z.string().default('./attachments').optional(),\n api: z\n .union([\n z.boolean(),\n z.looseObject({\n host: z.string().optional(),\n port: z.number().optional(),\n proxy_host: z.string().optional(),\n }),\n ])\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","/* eslint-disable max-lines */\nimport { execSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport fsPromises from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n type Agent,\n AgentSchema,\n type ChatSettings,\n ChatSettingsSchema,\n type AgentSessionSettings,\n AgentSessionSettingsSchema,\n type Environment,\n EnvironmentSchema,\n type Settings,\n SettingsSchema,\n} from './config.js';\nimport { pathIsInsideDir } from './utils/fs.js';\n\nexport function getWorkspaceRoot(startDir = process.cwd()): string {\n let curr = startDir;\n while (curr !== path.parse(curr).root) {\n if (fs.existsSync(path.join(curr, '.clawmini'))) {\n return curr;\n }\n if (fs.existsSync(path.join(curr, 'package.json')) || fs.existsSync(path.join(curr, '.git'))) {\n return curr;\n }\n curr = path.dirname(curr);\n }\n return startDir;\n}\n\nexport function resolveAgentWorkDir(\n agentId: string,\n customDir?: string,\n startDir = process.cwd()\n): string {\n const workspaceRoot = getWorkspaceRoot(startDir);\n const dirPath = customDir\n ? path.resolve(workspaceRoot, customDir)\n : path.resolve(workspaceRoot, agentId);\n\n if (!pathIsInsideDir(dirPath, workspaceRoot, { allowSameDir: true })) {\n throw new Error('Invalid agent directory: resolves outside the workspace.');\n }\n\n return dirPath;\n}\n\nexport async function ensureAgentWorkDir(\n agentId: string,\n customDir?: string,\n startDir = process.cwd()\n): Promise<string> {\n const dirPath = resolveAgentWorkDir(agentId, customDir, startDir);\n\n if (!fs.existsSync(dirPath)) {\n await fsPromises.mkdir(dirPath, { recursive: true });\n console.log(`Created agent working directory at ${dirPath}`);\n }\n return dirPath;\n}\n\nexport function getClawminiDir(startDir = process.cwd()): string {\n return path.join(getWorkspaceRoot(startDir), '.clawmini');\n}\n\nexport function getSocketPath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'server.sock');\n}\n\nexport function getSettingsPath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'settings.json');\n}\n\nexport function getPoliciesPath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'policies.json');\n}\n\nexport function getChatSettingsPath(chatId: string, startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'chats', chatId, 'settings.json');\n}\n\nexport function isValidAgentId(agentId: string): boolean {\n if (!agentId || agentId.length === 0) return false;\n return /^[a-zA-Z0-9_]+(?:-[a-zA-Z0-9_]+)*$/.test(agentId);\n}\n\nexport function getAgentDir(agentId: string, startDir = process.cwd()): string {\n if (!isValidAgentId(agentId)) {\n throw new Error(`Invalid agent ID: ${agentId}`);\n }\n return path.join(getClawminiDir(startDir), 'agents', agentId);\n}\n\nexport function getAgentSettingsPath(agentId: string, startDir = process.cwd()): string {\n return path.join(getAgentDir(agentId, startDir), 'settings.json');\n}\n\nexport function getAgentSessionSettingsPath(\n agentId: string,\n sessionId: string,\n startDir = process.cwd()\n): string {\n if (!isValidAgentId(agentId)) {\n throw new Error(`Invalid agent ID: ${agentId}`);\n }\n return path.join(\n getClawminiDir(startDir),\n 'agents',\n agentId,\n 'sessions',\n sessionId,\n 'settings.json'\n );\n}\n\nasync function readJsonFile(filePath: string): Promise<Record<string, unknown> | null> {\n try {\n const data = await fsPromises.readFile(filePath, 'utf-8');\n return JSON.parse(data) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nasync function writeJsonFile(filePath: string, data: Record<string, unknown>): Promise<void> {\n const dir = path.dirname(filePath);\n await fsPromises.mkdir(dir, { recursive: true });\n await fsPromises.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\nexport async function readChatSettings(\n chatId: string,\n startDir = process.cwd()\n): Promise<ChatSettings | null> {\n const data = await readJsonFile(getChatSettingsPath(chatId, startDir));\n if (!data) return null;\n const parsed = ChatSettingsSchema.safeParse(data);\n return parsed.success ? parsed.data : null;\n}\n\nexport async function writeChatSettings(\n chatId: string,\n data: ChatSettings,\n startDir = process.cwd()\n): Promise<void> {\n await writeJsonFile(getChatSettingsPath(chatId, startDir), data as Record<string, unknown>);\n}\n\nexport async function readAgentSessionSettings(\n agentId: string,\n sessionId: string,\n startDir = process.cwd()\n): Promise<AgentSessionSettings | null> {\n const data = await readJsonFile(getAgentSessionSettingsPath(agentId, sessionId, startDir));\n if (!data) return null;\n const parsed = AgentSessionSettingsSchema.safeParse(data);\n return parsed.success ? parsed.data : null;\n}\n\nexport async function writeAgentSessionSettings(\n agentId: string,\n sessionId: string,\n data: AgentSessionSettings,\n startDir = process.cwd()\n): Promise<void> {\n await writeJsonFile(\n getAgentSessionSettingsPath(agentId, sessionId, startDir),\n data as Record<string, unknown>\n );\n}\n\nexport async function getAgent(agentId: string, startDir = process.cwd()): Promise<Agent | null> {\n const filePath = getAgentSettingsPath(agentId, startDir);\n let dataStr: string;\n try {\n dataStr = await fsPromises.readFile(filePath, 'utf-8');\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') return null;\n throw err;\n }\n\n let data: unknown;\n try {\n data = JSON.parse(dataStr);\n } catch (parseErr: unknown) {\n const message = parseErr instanceof Error ? parseErr.message : String(parseErr);\n throw new Error(`Invalid JSON in ${filePath}: ${message}`, { cause: parseErr });\n }\n\n const parsed = AgentSchema.safeParse(data);\n if (!parsed.success) {\n throw new Error(`Invalid schema in ${filePath}: ${parsed.error.message}`);\n }\n return parsed.data;\n}\n\nexport async function writeAgentSettings(\n agentId: string,\n data: Agent,\n startDir = process.cwd()\n): Promise<void> {\n await ensureAgentWorkDir(agentId, data.directory, startDir);\n await writeJsonFile(getAgentSettingsPath(agentId, startDir), data as Record<string, unknown>);\n}\n\nexport async function listAgents(startDir = process.cwd()): Promise<string[]> {\n const agentsDir = path.join(getClawminiDir(startDir), 'agents');\n try {\n const entries = await fsPromises.readdir(agentsDir, { withFileTypes: true });\n const agentIds = [];\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const settingsPath = path.join(agentsDir, entry.name, 'settings.json');\n try {\n await fsPromises.access(settingsPath);\n agentIds.push(entry.name);\n } catch {\n // No settings.json, probably just a sessions dir for a non-existent agent or default agent\n }\n }\n }\n return agentIds;\n } catch {\n return [];\n }\n}\n\nexport async function deleteAgent(agentId: string, startDir = process.cwd()): Promise<void> {\n const dir = getAgentDir(agentId, startDir);\n const agentsDir = path.join(getClawminiDir(startDir), 'agents');\n\n if (!pathIsInsideDir(dir, agentsDir)) {\n throw new Error(`Security Error: Cannot delete agent directory outside of ${agentsDir}`);\n }\n\n try {\n await fsPromises.rm(dir, { recursive: true, force: true });\n } catch {\n // Ignore if not found\n }\n}\n\nasync function isDirectory(dirPath: string): Promise<boolean> {\n try {\n const stat = await fsPromises.stat(dirPath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function resolveTemplatePathBase(\n templateName: string,\n startDir = process.cwd()\n): Promise<string> {\n const workspaceRoot = getWorkspaceRoot(startDir);\n const localTemplatePath = path.join(workspaceRoot, '.clawmini', 'templates', templateName);\n\n if (await isDirectory(localTemplatePath)) {\n return localTemplatePath;\n }\n\n // Fallback to built-in templates\n // Find the clawmini package root by looking for package.json\n let currentDir = path.dirname(fileURLToPath(import.meta.url));\n while (\n currentDir !== path.parse(currentDir).root &&\n !fs.existsSync(path.join(currentDir, 'package.json'))\n ) {\n currentDir = path.dirname(currentDir);\n }\n\n const searchPath = path.join(currentDir, 'templates', templateName);\n\n if (await isDirectory(searchPath)) {\n return searchPath;\n }\n\n throw new Error(\n `Template not found: ${templateName} (searched local: ${localTemplatePath}, built-in: ${searchPath})`\n );\n}\n\nexport async function resolveTemplatePath(\n templateName: string,\n startDir = process.cwd()\n): Promise<string> {\n if (templateName === 'environments' || templateName.startsWith('environments/')) {\n throw new Error(`Template not found: ${templateName}`);\n }\n return resolveTemplatePathBase(templateName, startDir);\n}\n\nexport async function resolveEnvironmentTemplatePath(\n templateName: string,\n startDir = process.cwd()\n): Promise<string> {\n return resolveTemplatePathBase(path.join('environments', templateName), startDir);\n}\n\nexport async function copyTemplateBase(\n templatePath: string,\n targetDir: string,\n allowMissingDir: boolean = false\n): Promise<void> {\n // Check if target directory exists and is not empty\n try {\n const entries = await fsPromises.readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDir}`);\n }\n } catch (err: unknown) {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') {\n if (allowMissingDir) {\n await fsPromises.mkdir(targetDir, { recursive: true });\n } else {\n throw new Error(`Target directory does not exist: ${targetDir}`, { cause: err });\n }\n } else {\n throw err;\n }\n }\n\n // Recursively copy\n await fsPromises.cp(templatePath, targetDir, { recursive: true });\n}\n\nexport async function copyTemplate(\n templateName: string,\n targetDir: string,\n startDir = process.cwd()\n): Promise<void> {\n const templatePath = await resolveTemplatePath(templateName, startDir);\n await copyTemplateBase(templatePath, targetDir, false);\n}\n\nexport async function copyEnvironmentTemplate(\n templateName: string,\n targetDir: string,\n startDir = process.cwd()\n): Promise<void> {\n const templatePath = await resolveEnvironmentTemplatePath(templateName, startDir);\n await copyTemplateBase(templatePath, targetDir, true);\n}\n\nexport async function applyTemplateToAgent(\n agentId: string,\n templateName: string,\n overrides: Agent,\n startDir = process.cwd()\n): Promise<void> {\n const agentWorkDir = resolveAgentWorkDir(agentId, overrides.directory, startDir);\n await copyTemplate(templateName, agentWorkDir, startDir);\n\n const settingsPath = path.join(agentWorkDir, 'settings.json');\n try {\n const rawSettings = await fsPromises.readFile(settingsPath, 'utf-8');\n const parsedSettings = JSON.parse(rawSettings);\n const validation = AgentSchema.safeParse(parsedSettings);\n\n if (validation.success) {\n const templateData = validation.data;\n if (templateData.directory) {\n console.warn(\n `Warning: Ignoring 'directory' field from template settings.json. Using default or provided directory.`\n );\n delete templateData.directory;\n }\n\n // Merge: overrides take precedence over templateData\n const mergedEnv = { ...(templateData.env || {}), ...(overrides.env || {}) };\n const mergedData: Agent = { ...templateData, ...overrides };\n if (Object.keys(mergedEnv).length > 0) {\n mergedData.env = mergedEnv;\n }\n\n await writeAgentSettings(agentId, mergedData, startDir);\n }\n } catch {\n // Ignore parsing or file not found errors\n } finally {\n try {\n await fsPromises.rm(settingsPath);\n } catch {\n // Ignore if it doesn't exist\n }\n }\n}\n\nexport async function readSettings(startDir = process.cwd()): Promise<Settings | null> {\n const data = await readJsonFile(getSettingsPath(startDir));\n if (!data) return null;\n const parsed = SettingsSchema.safeParse(data);\n return parsed.success ? parsed.data : null;\n}\n\nexport async function writeSettings(data: Settings, startDir = process.cwd()): Promise<void> {\n await writeJsonFile(getSettingsPath(startDir), data as Record<string, unknown>);\n}\n\nexport async function readPolicies(\n startDir = process.cwd()\n): Promise<import('./policies.js').PolicyConfig | null> {\n const data = await readJsonFile(getPoliciesPath(startDir));\n if (!data) return null;\n // Basic validation, assuming PolicyConfig structure\n if (data.policies && typeof data.policies === 'object') {\n return data as unknown as import('./policies.js').PolicyConfig;\n }\n return null;\n}\n\nexport function getEnvironmentPath(name: string, startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'environments', name);\n}\n\nexport async function readEnvironment(\n name: string,\n startDir = process.cwd()\n): Promise<Environment | null> {\n const data = await readJsonFile(path.join(getEnvironmentPath(name, startDir), 'env.json'));\n if (!data) return null;\n const parsed = EnvironmentSchema.safeParse(data);\n return parsed.success ? parsed.data : null;\n}\n\nexport async function getActiveEnvironmentInfo(\n targetPath: string,\n startDir = process.cwd()\n): Promise<{ name: string; targetPath: string } | null> {\n const settings = await readSettings(startDir);\n if (!settings?.environments) return null;\n\n const workspaceRoot = getWorkspaceRoot(startDir);\n const resolvedTarget = path.resolve(workspaceRoot, targetPath);\n\n let bestMatch: { name: string; targetPath: string } | null = null;\n let maxDepth = -1;\n\n for (const [envPath, envName] of Object.entries(settings.environments)) {\n const resolvedEnvPath = path.resolve(workspaceRoot, envPath);\n\n if (pathIsInsideDir(resolvedTarget, resolvedEnvPath, { allowSameDir: true })) {\n const depth = resolvedEnvPath.split(path.sep).length;\n if (depth > maxDepth) {\n maxDepth = depth;\n bestMatch = { name: envName, targetPath: resolvedEnvPath };\n }\n }\n }\n\n return bestMatch;\n}\n\nexport async function getActiveEnvironmentName(\n targetPath: string,\n startDir = process.cwd()\n): Promise<string | null> {\n const info = await getActiveEnvironmentInfo(targetPath, startDir);\n return info ? info.name : null;\n}\n\nexport async function enableEnvironment(\n name: string,\n targetPath: string = './',\n startDir = process.cwd()\n): Promise<void> {\n const targetDir = getEnvironmentPath(name, startDir);\n\n // Copy template to targetDir if it does not already exist\n if (!fs.existsSync(targetDir)) {\n await copyEnvironmentTemplate(name, targetDir, startDir);\n console.log(`Copied environment template '${name}'.`);\n } else {\n console.log(`Environment template '${name}' already exists in workspace.`);\n }\n\n const settings = (await readSettings(startDir)) || { chats: { defaultId: '' } };\n const environments = settings.environments || {};\n\n environments[targetPath] = name;\n settings.environments = environments;\n\n await writeSettings(settings, startDir);\n console.log(`Enabled environment '${name}' for path '${targetPath}'.`);\n\n // Execute init command if present\n const envConfig = await readEnvironment(name, startDir);\n if (envConfig?.init) {\n // Get the target directory for the environment\n const workspaceRoot = getWorkspaceRoot(startDir);\n const affectedDir = path.resolve(workspaceRoot, targetPath);\n console.log(`Executing init command for environment '${name}': ${envConfig.init}`);\n execSync(envConfig.init, { cwd: affectedDir, stdio: 'inherit' });\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Command Reference
|
|
2
|
+
|
|
3
|
+
### Initialization & Daemon
|
|
4
|
+
- `clawmini init`: Initialize a new `.clawmini` configuration folder.
|
|
5
|
+
- `clawmini up`: Start the local daemon server in the background.
|
|
6
|
+
- `clawmini down`: Stop the local daemon server.
|
|
7
|
+
- `clawmini export-lite [--out <path>] [--stdout]`: Export the standalone `clawmini-lite` client script.
|
|
8
|
+
|
|
9
|
+
### Chat Management
|
|
10
|
+
- `clawmini chats list`: Display existing chats.
|
|
11
|
+
- `clawmini chats add <id>`: Initialize a new chat.
|
|
12
|
+
- `clawmini chats delete <id>`: Remove a chat.
|
|
13
|
+
- `clawmini chats set-default <id>`: Update the workspace default chat.
|
|
14
|
+
|
|
15
|
+
### Messaging
|
|
16
|
+
- `clawmini messages send <message> [--chat <id>] [--agent <name>]`: Send a new message.
|
|
17
|
+
- `clawmini messages tail [-n NUM] [--json] [--chat <id>]`: View message history.
|
|
18
|
+
|
|
19
|
+
### Agents
|
|
20
|
+
- `clawmini agents list`: Display existing agents.
|
|
21
|
+
- `clawmini agents add <id> [-d, --directory <dir>] [-t, --template <name>] [-e, --env <KEY=VALUE>...]`: Create a new agent.
|
|
22
|
+
- `clawmini agents update <id> [-d, --directory <dir>] [-e, --env <KEY=VALUE>...]`: Update an existing agent.
|
|
23
|
+
- `clawmini agents delete <id>`: Remove an agent.
|
|
24
|
+
|
|
25
|
+
### Background Jobs
|
|
26
|
+
- `clawmini jobs list [--chat <id>]`: Display all background jobs configured.
|
|
27
|
+
- `clawmini jobs add <name> [--cron <expr> | --every <duration> | --at <iso-time>] [-m, --message <text>]`: Create a new scheduled job. Supports standard cron expressions, recurring intervals (e.g., `10m`), or one-off executions at a specific time.
|
|
28
|
+
- `clawmini jobs delete <name> [--chat <id>]`: Remove an existing scheduled job.
|
|
29
|
+
|
|
30
|
+
### Environments
|
|
31
|
+
- `clawmini environments enable <name>`: Enable an environment for a path in the workspace.
|
|
32
|
+
- `clawmini environments disable`: Disable an environment mapping.
|
|
33
|
+
|
|
34
|
+
### Web Interface
|
|
35
|
+
- `clawmini web [-p, --port <number>]`: Start the local web interface (default port: 8080).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Configuring Permission Requests
|
|
2
2
|
|
|
3
3
|
The Sandbox Policies feature provides a secure framework for AI agents operating within restricted sandbox environments to request and execute sensitive or network-dependent operations. Using a formal "request-and-approve" workflow, users retain full control via their chat interface while agents gain the ability to perform complex, privileged tasks like sending emails or promoting files to external systems.
|
|
4
4
|
|
|
5
5
|
## Registering a Policy
|
|
6
6
|
|
|
7
|
-
Policies are configured centrally in a JSON file located at `.clawmini/policies.json`. This configuration maps an easy-to-use policy command name to the actual script or binary you want to run when the request is approved.
|
|
7
|
+
Policies are configured centrally in a JSON file located at `.clawmini/policies.json`. This configuration maps an easy-to-use policy command name to the actual script or binary you want to run when the request is approved.
|
|
8
8
|
|
|
9
9
|
The framework treats the command execution as a "dumb pipe". It executes the specified script using a secure execution wrapper (bypassing the shell to prevent injection attacks) and interpolates safe, verified file paths.
|
|
10
10
|
|
|
@@ -33,15 +33,18 @@ Agents running within their environment can interact with the Policies feature u
|
|
|
33
33
|
|
|
34
34
|
1. **Discovery:**
|
|
35
35
|
Agents can view available policies and their descriptions:
|
|
36
|
+
|
|
36
37
|
```bash
|
|
37
38
|
clawmini-lite requests list
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
2. **Help Documentation:**
|
|
41
42
|
If a policy is configured with `"allowHelp": true`, agents can query it for help. This securely passes the `--help` flag to the underlying wrapper command and returns the output to the agent:
|
|
43
|
+
|
|
42
44
|
```bash
|
|
43
45
|
clawmini-lite request send-email --help
|
|
44
46
|
```
|
|
47
|
+
|
|
45
48
|
If `"allowHelp"` is missing or set to `false`, the agent will receive an error stating that `--help` is not supported.
|
|
46
49
|
|
|
47
50
|
3. **Submitting a Request:**
|
|
@@ -58,19 +61,23 @@ When an agent creates a request, the daemon intercepts it and sends a preview me
|
|
|
58
61
|
You can then review and interact with the pending request using the following slash commands in your chat:
|
|
59
62
|
|
|
60
63
|
- **List Pending Requests:**
|
|
64
|
+
|
|
61
65
|
```text
|
|
62
66
|
/pending
|
|
63
67
|
```
|
|
64
|
-
|
|
68
|
+
|
|
69
|
+
_Lists all active pending requests that need review._
|
|
65
70
|
|
|
66
71
|
- **Approve a Request:**
|
|
72
|
+
|
|
67
73
|
```text
|
|
68
74
|
/approve <request_id>
|
|
69
75
|
```
|
|
70
|
-
|
|
76
|
+
|
|
77
|
+
_Approves the request. The configured script executes securely, and the STDOUT/STDERR results are automatically sent back to the agent in the chat._
|
|
71
78
|
|
|
72
79
|
- **Reject a Request:**
|
|
73
80
|
```text
|
|
74
81
|
/reject <request_id> [reason]
|
|
75
82
|
```
|
|
76
|
-
|
|
83
|
+
_Rejects the request. You can provide an optional natural language reason (e.g., `/reject 123 Tone needs to be more formal`) to help the agent correct its output and try again._
|
package/package.json
CHANGED
|
@@ -50,8 +50,8 @@ declare module '$env/static/private' {
|
|
|
50
50
|
export const GEM_HOME: string;
|
|
51
51
|
export const NVM_CD_FLAGS: string;
|
|
52
52
|
export const rvm_gemstone_url: string;
|
|
53
|
-
export const SHELL: string;
|
|
54
53
|
export const TERM: string;
|
|
54
|
+
export const SHELL: string;
|
|
55
55
|
export const rvm_docs_type: string;
|
|
56
56
|
export const IRBRC: string;
|
|
57
57
|
export const HOMEBREW_REPOSITORY: string;
|
|
@@ -84,7 +84,6 @@ declare module '$env/static/private' {
|
|
|
84
84
|
export const rvm_ruby_make: string;
|
|
85
85
|
export const PATH: string;
|
|
86
86
|
export const npm_package_json: string;
|
|
87
|
-
export const LaunchInstanceID: string;
|
|
88
87
|
export const GHOSTTY_SHELL_FEATURES: string;
|
|
89
88
|
export const _: string;
|
|
90
89
|
export const npm_config_userconfig: string;
|
|
@@ -131,7 +130,6 @@ declare module '$env/static/private' {
|
|
|
131
130
|
export const rvm_bin_flag: string;
|
|
132
131
|
export const rvm_only_path_flag: string;
|
|
133
132
|
export const RUBY_VERSION: string;
|
|
134
|
-
export const SECURITYSESSIONID: string;
|
|
135
133
|
export const npm_node_execpath: string;
|
|
136
134
|
export const npm_config_prefix: string;
|
|
137
135
|
export const COLORTERM: string;
|
|
@@ -235,8 +233,8 @@ declare module '$env/dynamic/private' {
|
|
|
235
233
|
GEM_HOME: string;
|
|
236
234
|
NVM_CD_FLAGS: string;
|
|
237
235
|
rvm_gemstone_url: string;
|
|
238
|
-
SHELL: string;
|
|
239
236
|
TERM: string;
|
|
237
|
+
SHELL: string;
|
|
240
238
|
rvm_docs_type: string;
|
|
241
239
|
IRBRC: string;
|
|
242
240
|
HOMEBREW_REPOSITORY: string;
|
|
@@ -269,7 +267,6 @@ declare module '$env/dynamic/private' {
|
|
|
269
267
|
rvm_ruby_make: string;
|
|
270
268
|
PATH: string;
|
|
271
269
|
npm_package_json: string;
|
|
272
|
-
LaunchInstanceID: string;
|
|
273
270
|
GHOSTTY_SHELL_FEATURES: string;
|
|
274
271
|
_: string;
|
|
275
272
|
npm_config_userconfig: string;
|
|
@@ -316,7 +313,6 @@ declare module '$env/dynamic/private' {
|
|
|
316
313
|
rvm_bin_flag: string;
|
|
317
314
|
rvm_only_path_flag: string;
|
|
318
315
|
RUBY_VERSION: string;
|
|
319
|
-
SECURITYSESSIONID: string;
|
|
320
316
|
npm_node_execpath: string;
|
|
321
317
|
npm_config_prefix: string;
|
|
322
318
|
COLORTERM: string;
|
|
@@ -24,7 +24,7 @@ export const options = {
|
|
|
24
24
|
app: ({ head, body, assets, nonce, env }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, interactive-widget=resizes-content\" />\n\t\t" + head + "\n\t</head>\n\t<body data-sveltekit-preload-data=\"hover\">\n\t\t<div style=\"display: contents\">" + body + "</div>\n\t</body>\n</html>\n",
|
|
25
25
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
|
|
26
26
|
},
|
|
27
|
-
version_hash: "
|
|
27
|
+
version_hash: "746l1x"
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export async function get_hooks() {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"../node_modules/@sveltejs/kit/src/runtime/client/entry.js": {
|
|
3
|
-
"file": "_app/immutable/entry/start.
|
|
3
|
+
"file": "_app/immutable/entry/start.DuQwh4Nz.js",
|
|
4
4
|
"name": "entry/start",
|
|
5
5
|
"src": "../node_modules/@sveltejs/kit/src/runtime/client/entry.js",
|
|
6
6
|
"isEntry": true,
|
|
7
7
|
"imports": [
|
|
8
|
-
"
|
|
8
|
+
"_B3YcEpQV.js"
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
".svelte-kit/generated/client-optimized/app.js": {
|
|
12
|
-
"file": "_app/immutable/entry/app.
|
|
12
|
+
"file": "_app/immutable/entry/app.ZuicLpkH.js",
|
|
13
13
|
"name": "entry/app",
|
|
14
14
|
"src": ".svelte-kit/generated/client-optimized/app.js",
|
|
15
15
|
"isEntry": true,
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
]
|
|
32
32
|
},
|
|
33
33
|
".svelte-kit/generated/client-optimized/nodes/0.js": {
|
|
34
|
-
"file": "_app/immutable/nodes/0.
|
|
34
|
+
"file": "_app/immutable/nodes/0.BB1CjKco.js",
|
|
35
35
|
"name": "nodes/0",
|
|
36
36
|
"src": ".svelte-kit/generated/client-optimized/nodes/0.js",
|
|
37
37
|
"isEntry": true,
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"_CyNaE55B.js",
|
|
46
46
|
"_BPy8HLo7.js",
|
|
47
47
|
"_B8yYFADm.js",
|
|
48
|
-
"
|
|
48
|
+
"_CAZeqksE.js",
|
|
49
49
|
"_ZkLyk0mE.js",
|
|
50
|
-
"
|
|
50
|
+
"_B3YcEpQV.js",
|
|
51
51
|
"_Bi0jeV7Q.js",
|
|
52
52
|
"_B5abRDXp.js"
|
|
53
53
|
],
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
]
|
|
57
57
|
},
|
|
58
58
|
".svelte-kit/generated/client-optimized/nodes/1.js": {
|
|
59
|
-
"file": "_app/immutable/nodes/1.
|
|
59
|
+
"file": "_app/immutable/nodes/1.CdSgEHu9.js",
|
|
60
60
|
"name": "nodes/1",
|
|
61
61
|
"src": ".svelte-kit/generated/client-optimized/nodes/1.js",
|
|
62
62
|
"isEntry": true,
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"_CpaGRn9L.js",
|
|
68
68
|
"_DG5RZBw-.js",
|
|
69
69
|
"_DcrmIfTj.js",
|
|
70
|
-
"
|
|
70
|
+
"_CAZeqksE.js"
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
".svelte-kit/generated/client-optimized/nodes/2.js": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
]
|
|
83
83
|
},
|
|
84
84
|
".svelte-kit/generated/client-optimized/nodes/3.js": {
|
|
85
|
-
"file": "_app/immutable/nodes/3.
|
|
85
|
+
"file": "_app/immutable/nodes/3.CKp7Wkn8.js",
|
|
86
86
|
"name": "nodes/3",
|
|
87
87
|
"src": ".svelte-kit/generated/client-optimized/nodes/3.js",
|
|
88
88
|
"isEntry": true,
|
|
@@ -94,14 +94,14 @@
|
|
|
94
94
|
"_C3k55nDF.js",
|
|
95
95
|
"_BmUXQ3wy.js",
|
|
96
96
|
"_CyNaE55B.js",
|
|
97
|
-
"
|
|
97
|
+
"_B3YcEpQV.js",
|
|
98
98
|
"_ZkLyk0mE.js",
|
|
99
99
|
"_BPy8HLo7.js",
|
|
100
100
|
"_Bi0jeV7Q.js"
|
|
101
101
|
]
|
|
102
102
|
},
|
|
103
103
|
".svelte-kit/generated/client-optimized/nodes/4.js": {
|
|
104
|
-
"file": "_app/immutable/nodes/4.
|
|
104
|
+
"file": "_app/immutable/nodes/4.FyeoMY-Y.js",
|
|
105
105
|
"name": "nodes/4",
|
|
106
106
|
"src": ".svelte-kit/generated/client-optimized/nodes/4.js",
|
|
107
107
|
"isEntry": true,
|
|
@@ -113,13 +113,13 @@
|
|
|
113
113
|
"_DG5RZBw-.js",
|
|
114
114
|
"_C3k55nDF.js",
|
|
115
115
|
"_BmUXQ3wy.js",
|
|
116
|
-
"
|
|
116
|
+
"_B3YcEpQV.js",
|
|
117
117
|
"_B5abRDXp.js",
|
|
118
118
|
"_Bi0jeV7Q.js"
|
|
119
119
|
]
|
|
120
120
|
},
|
|
121
121
|
".svelte-kit/generated/client-optimized/nodes/5.js": {
|
|
122
|
-
"file": "_app/immutable/nodes/5.
|
|
122
|
+
"file": "_app/immutable/nodes/5.D6mVN7l7.js",
|
|
123
123
|
"name": "nodes/5",
|
|
124
124
|
"src": ".svelte-kit/generated/client-optimized/nodes/5.js",
|
|
125
125
|
"isEntry": true,
|
|
@@ -130,11 +130,19 @@
|
|
|
130
130
|
"_DG5RZBw-.js",
|
|
131
131
|
"_C3k55nDF.js",
|
|
132
132
|
"_BmUXQ3wy.js",
|
|
133
|
-
"
|
|
133
|
+
"_B3YcEpQV.js",
|
|
134
134
|
"_ZkLyk0mE.js",
|
|
135
135
|
"_Bi0jeV7Q.js"
|
|
136
136
|
]
|
|
137
137
|
},
|
|
138
|
+
"_B3YcEpQV.js": {
|
|
139
|
+
"file": "_app/immutable/chunks/B3YcEpQV.js",
|
|
140
|
+
"name": "entry",
|
|
141
|
+
"imports": [
|
|
142
|
+
"_CpaGRn9L.js",
|
|
143
|
+
"_B8yYFADm.js"
|
|
144
|
+
]
|
|
145
|
+
},
|
|
138
146
|
"_B5abRDXp.js": {
|
|
139
147
|
"file": "_app/immutable/chunks/B5abRDXp.js",
|
|
140
148
|
"name": "app-state.svelte",
|
|
@@ -188,19 +196,11 @@
|
|
|
188
196
|
"_CpaGRn9L.js"
|
|
189
197
|
]
|
|
190
198
|
},
|
|
191
|
-
"
|
|
192
|
-
"file": "_app/immutable/chunks/
|
|
199
|
+
"_CAZeqksE.js": {
|
|
200
|
+
"file": "_app/immutable/chunks/CAZeqksE.js",
|
|
193
201
|
"name": "index",
|
|
194
202
|
"imports": [
|
|
195
|
-
"
|
|
196
|
-
]
|
|
197
|
-
},
|
|
198
|
-
"_CSvS_NwK.js": {
|
|
199
|
-
"file": "_app/immutable/chunks/CSvS_NwK.js",
|
|
200
|
-
"name": "entry",
|
|
201
|
-
"imports": [
|
|
202
|
-
"_CpaGRn9L.js",
|
|
203
|
-
"_B8yYFADm.js"
|
|
203
|
+
"_B3YcEpQV.js"
|
|
204
204
|
]
|
|
205
205
|
},
|
|
206
206
|
"_CpaGRn9L.js": {
|