diff --git a/ventures/agentlore/agentlore-source.tgz b/ventures/agentlore/agentlore-source.tgz new file mode 100644 index 0000000..1a23821 Binary files /dev/null and b/ventures/agentlore/agentlore-source.tgz differ diff --git a/ventures/agentlore/assets/index-BwJ7n8WL.js b/ventures/agentlore/assets/index-BwJ7n8WL.js new file mode 100644 index 0000000..5264c3a --- /dev/null +++ b/ventures/agentlore/assets/index-BwJ7n8WL.js @@ -0,0 +1,176 @@ +var Eh=i=>{throw TypeError(i)};var Th=(i,r,s)=>r.has(i)||Eh("Cannot "+s);var mt=(i,r,s)=>(Th(i,r,"read from private field"),s?s.call(i):r.get(i)),_h=(i,r,s)=>r.has(i)?Eh("Cannot add the same private member more than once"):r instanceof WeakSet?r.add(i):r.set(i,s),hs=(i,r,s,o)=>(Th(i,r,"write to private field"),o?o.call(i,s):r.set(i,s),s);function cp(i,r){for(var s=0;so[d]})}}}return Object.freeze(Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}))}(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))o(d);new MutationObserver(d=>{for(const m of d)if(m.type==="childList")for(const g of m.addedNodes)g.tagName==="LINK"&&g.rel==="modulepreload"&&o(g)}).observe(document,{childList:!0,subtree:!0});function s(d){const m={};return d.integrity&&(m.integrity=d.integrity),d.referrerPolicy&&(m.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?m.credentials="include":d.crossOrigin==="anonymous"?m.credentials="omit":m.credentials="same-origin",m}function o(d){if(d.ep)return;d.ep=!0;const m=s(d);fetch(d.href,m)}})();function op(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var gs={exports:{}},se={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ch;function rp(){if(Ch)return se;Ch=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),s=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),m=Symbol.for("react.consumer"),g=Symbol.for("react.context"),S=Symbol.for("react.forward_ref"),O=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),z=Symbol.for("react.lazy"),h=Symbol.for("react.activity"),R=Symbol.for("react.view_transition"),D=Symbol.iterator;function V(b){return b===null||typeof b!="object"?null:(b=D&&b[D]||b["@@iterator"],typeof b=="function"?b:null)}var Z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Y=Object.assign,K={};function H(b,j,k){this.props=b,this.context=j,this.refs=K,this.updater=k||Z}H.prototype.isReactComponent={},H.prototype.setState=function(b,j){if(typeof b!="object"&&typeof b!="function"&&b!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,b,j,"setState")},H.prototype.forceUpdate=function(b){this.updater.enqueueForceUpdate(this,b,"forceUpdate")};function F(){}F.prototype=H.prototype;function ue(b,j,k){this.props=b,this.context=j,this.refs=K,this.updater=k||Z}var fe=ue.prototype=new F;fe.constructor=ue,Y(fe,H.prototype),fe.isPureReactComponent=!0;var ae=Array.isArray;function X(){}var B={H:null,A:null,T:null,S:null},L=Object.prototype.hasOwnProperty;function J(b,j,k){var ne=k.ref;return{$$typeof:i,type:b,key:j,ref:ne!==void 0?ne:null,props:k}}function de(b,j){return J(b.type,j,b.props)}function Re(b){return typeof b=="object"&&b!==null&&b.$$typeof===i}function He(b){var j={"=":"=0",":":"=2"};return"$"+b.replace(/[=:]/g,function(k){return j[k]})}var Xe=/\/+/g;function Ce(b,j){return typeof b=="object"&&b!==null&&b.key!=null?He(""+b.key):j.toString(36)}function q(b){switch(b.status){case"fulfilled":return b.value;case"rejected":throw b.reason;default:switch(typeof b.status=="string"?b.then(X,X):(b.status="pending",b.then(function(j){b.status==="pending"&&(b.status="fulfilled",b.value=j)},function(j){b.status==="pending"&&(b.status="rejected",b.reason=j)})),b.status){case"fulfilled":return b.value;case"rejected":throw b.reason}}throw b}function $(b,j,k,ne,Ee){var ce=typeof b;(ce==="undefined"||ce==="boolean")&&(b=null);var Ae=!1;if(b===null)Ae=!0;else switch(ce){case"bigint":case"string":case"number":Ae=!0;break;case"object":switch(b.$$typeof){case i:case r:Ae=!0;break;case z:return Ae=b._init,$(Ae(b._payload),j,k,ne,Ee)}}if(Ae)return Ee=Ee(b),Ae=ne===""?"."+Ce(b,0):ne,ae(Ee)?(k="",Ae!=null&&(k=Ae.replace(Xe,"$&/")+"/"),$(Ee,j,k,"",function(Nt){return Nt})):Ee!=null&&(Re(Ee)&&(Ee=de(Ee,k+(Ee.key==null||b&&b.key===Ee.key?"":(""+Ee.key).replace(Xe,"$&/")+"/")+Ae)),j.push(Ee)),1;Ae=0;var ee=ne===""?".":ne+":";if(ae(b))for(var oe=0;oe>>1,G=q[he];if(0>>1;hed(ht,le))bd(j,ht)?(q[he]=j,q[b]=le,he=b):(q[he]=ht,q[We]=le,he=We);else if(bd(j,le))q[he]=j,q[b]=le,he=b;else break e}}return $}function d(q,$){var le=q.sortIndex-$.sortIndex;return le!==0?le:q.id-$.id}if(i.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var m=performance;i.unstable_now=function(){return m.now()}}else{var g=Date,S=g.now();i.unstable_now=function(){return g.now()-S}}var O=[],x=[],z=1,h=null,R=3,D=!1,V=!1,Z=!1,Y=!1,K=typeof setTimeout=="function"?setTimeout:null,H=typeof clearTimeout=="function"?clearTimeout:null,F=typeof setImmediate<"u"?setImmediate:null;function ue(q){for(var $=s(x);$!==null;){if($.callback===null)o(x);else if($.startTime<=q)o(x),$.sortIndex=$.expirationTime,r(O,$);else break;$=s(x)}}function fe(q){if(Z=!1,ue(q),!V)if(s(O)!==null)V=!0,ae||(ae=!0,Re());else{var $=s(x);$!==null&&Ce(fe,$.startTime-q)}}var ae=!1,X=-1,B=5,L=-1;function J(){return Y?!0:!(i.unstable_now()-Lq&&J());){var he=h.callback;if(typeof he=="function"){h.callback=null,R=h.priorityLevel;var G=he(h.expirationTime<=q);if(q=i.unstable_now(),typeof G=="function"){h.callback=G,ue(q),$=!0;break t}h===s(O)&&o(O),ue(q)}else o(O);h=s(O)}if(h!==null)$=!0;else{var ze=s(x);ze!==null&&Ce(fe,ze.startTime-q),$=!1}}break e}finally{h=null,R=le,D=!1}$=void 0}}finally{$?Re():ae=!1}}}var Re;if(typeof F=="function")Re=function(){F(de)};else if(typeof MessageChannel<"u"){var He=new MessageChannel,Xe=He.port2;He.port1.onmessage=de,Re=function(){Xe.postMessage(null)}}else Re=function(){K(de,0)};function Ce(q,$){X=K(function(){q(i.unstable_now())},$)}i.unstable_IdlePriority=5,i.unstable_ImmediatePriority=1,i.unstable_LowPriority=4,i.unstable_NormalPriority=3,i.unstable_Profiling=null,i.unstable_UserBlockingPriority=2,i.unstable_cancelCallback=function(q){q.callback=null},i.unstable_forceFrameRate=function(q){0>q||125he?(q.sortIndex=le,r(x,q),s(O)===null&&q===s(x)&&(Z?(H(X),X=-1):Z=!0,Ce(fe,le-he))):(q.sortIndex=G,r(O,q),V||D||(V=!0,ae||(ae=!0,Re()))),q},i.unstable_shouldYield=J,i.unstable_wrapCallback=function(q){var $=R;return function(){var le=R;R=$;try{return q.apply(this,arguments)}finally{R=le}}}})(ps)),ps}var Nh;function fp(){return Nh||(Nh=1,bs.exports=sp()),bs.exports}var Ss={exports:{}},vt={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Oh;function dp(){if(Oh)return vt;Oh=1;var i=ws();function r(z){var h="https://react.dev/errors/"+z;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(r){console.error(r)}}return i(),Ss.exports=dp(),Ss.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Rh;function mp(){if(Rh)return qu;Rh=1;var i=fp(),r=ws(),s=Ph();function o(e){var t="https://react.dev/errors/"+e;if(1In||(e.current=Ll[In],Ll[In]=null,In--)}function Be(e,t){In++,Ll[In]=e.current,e.current=t}var il=ul(null),Za=ul(null),Vl=ul(null),Qu=ul(null);function Zu(e,t){switch(Be(Vl,t),Be(Za,e),Be(il,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Rv(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Rv(t),e=Mv(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}it(il),Be(il,e)}function Fn(){it(il),it(Za),it(Vl)}function Uc(e){var t=e.memoizedState;t!==null&&(Ba._currentValue=t.memoizedState,Be(Qu,e)),t=il.current;var l=Mv(t,e.type);t!==l&&(Be(Za,e),Be(il,l))}function ku(e){Za.current===e&&(it(il),it(Za)),Qu.current===e&&(it(Qu),Ba._currentValue=Nt)}var Hc,Is;function Xl(e){if(Hc===void 0)try{throw Error()}catch(l){var t=l.stack.trim().match(/\n( *(at )?)/);Hc=t&&t[1]||"",Is=-1)":-1a||v[n]!==T[a]){var A=` +`+v[n].replace(" at new "," at ");return e.displayName&&A.includes("")&&(A=A.replace("",e.displayName)),A}while(1<=n&&0<=a);break}}}finally{jc=!1,Error.prepareStackTrace=l}return(l=e?e.displayName||e.name:"")?Xl(l):""}function fg(e,t){switch(e.tag){case 26:case 27:case 5:return Xl(e.type);case 16:return Xl("Lazy");case 13:return e.child!==t&&t!==null?Xl("Suspense Fallback"):Xl("Suspense");case 19:return Xl("SuspenseList");case 0:case 15:return Gc(e.type,!1);case 11:return Gc(e.type.render,!1);case 1:return Gc(e.type,!0);case 31:return Xl("Activity");case 30:return Xl("ViewTransition");default:return""}}function Fs(e){try{var t="",l=null;do t+=fg(e,l),l=e,e=e.return;while(e);return t}catch(n){return` +Error generating stack: `+n.message+` +`+n.stack}}var Bc=Object.prototype.hasOwnProperty,qc=i.unstable_scheduleCallback,Yc=i.unstable_cancelCallback,dg=i.unstable_shouldYield,mg=i.unstable_requestPaint,Ot=i.unstable_now,vg=i.unstable_getCurrentPriorityLevel,Ws=i.unstable_ImmediatePriority,Ps=i.unstable_UserBlockingPriority,Ku=i.unstable_NormalPriority,hg=i.unstable_LowPriority,ef=i.unstable_IdlePriority,gg=i.log,yg=i.unstable_setDisableYieldValue,ka=null,xt=null;function Ql(e){if(typeof gg=="function"&&yg(e),xt&&typeof xt.setStrictMode=="function")try{xt.setStrictMode(ka,e)}catch{}}var Rt=Math.clz32?Math.clz32:Sg,bg=Math.log,pg=Math.LN2;function Sg(e){return e>>>=0,e===0?32:31-(bg(e)/pg|0)|0}var Ju=256,$u=262144,Iu=4194304;function En(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Fu(e,t,l){var n=e.pendingLanes;if(n===0)return 0;var a=0,u=e.suspendedLanes,c=e.pingedLanes;e=e.warmLanes;var f=n&134217727;return f!==0?(n=f&~u,n!==0?a=En(n):(c&=f,c!==0?a=En(c):l||(l=f&~e,l!==0&&(a=En(l))))):(f=n&~u,f!==0?a=En(f):c!==0?a=En(c):l||(l=n&~e,l!==0&&(a=En(l)))),a===0?0:t!==0&&t!==a&&(t&u)===0&&(u=a&-a,l=t&-t,u>=l||u===32&&(l&4194048)!==0)?t:a}function Ka(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function tf(e,t){(t&8)!==0&&(t|=t&32);var l=e.entangledLanes;if(l!==0)for(e=e.entanglements,l&=t;0l;l++)t.push(e);return t}function Ja(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Tg(e,t,l,n,a,u){var c=e.pendingLanes;e.pendingLanes=l,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=l,e.entangledLanes&=l,e.errorRecoveryDisabledLanes&=l,e.shellSuspendCounter=0;var f=e.entanglements,v=e.expirationTimes,T=e.hiddenUpdates;for(l=c&~l;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Fc=!1;if(Tl)try{var Wa={};Object.defineProperty(Wa,"passive",{get:function(){Fc=!0}}),window.addEventListener("test",Wa,Wa),window.removeEventListener("test",Wa,Wa)}catch{Fc=!1}var Zl=null,Wc=null,ni=null;function Af(){if(ni)return ni;var e,t=Wc,l=t.length,n,a="value"in Zl?Zl.value:Zl.textContent,u=a.length;for(e=0;e=tu),Df=" ",wf=!1;function Uf(e,t){switch(e){case"keyup":return ay.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Hf(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ia=!1;function iy(e,t){switch(e){case"compositionend":return Hf(t);case"keypress":return t.which!==32?null:(wf=!0,Df);case"textInput":return e=t.data,e===Df&&wf?null:e;default:return null}}function cy(e,t){if(ia)return e==="compositionend"||!no&&Uf(e,t)?(e=Af(),ni=Wc=Zl=null,ia=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Xf(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Qf(e,t){var l=Xf(e);e=0;for(var n;l;){if(l.nodeType===3){if(n=e+l.textContent.length,e<=t&&n>=t)return{node:l,offset:t-e};e=n}e:{for(;l;){if(l.nextSibling){l=l.nextSibling;break e}l=l.parentNode}l=void 0}l=Xf(l)}}function Zf(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Zf(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function kf(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=io(e.document);t instanceof e.HTMLIFrameElement;){try{var l=typeof t.contentWindow.location.href=="string"}catch{l=!1}if(l)e=t.contentWindow;else break;t=io(e.document)}return t}function co(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var hy=Tl&&"documentMode"in document&&11>=document.documentMode,ca=null,oo=null,uu=null,ro=!1;function Kf(e,t,l){var n=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;ro||ca==null||ca!==io(n)||(n=ca,"selectionStart"in n&&co(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}),uu&&au(uu,n)||(uu=n,n=oc(oo,"onSelect"),0>=c,a-=c,ol=1<<32-Rt(t)+a|l<re?(Fe=ie,ie=null):Fe=ie.sibling;var Ne=p(E,ie,_[re],w);if(Ne===null){ie===null&&(ie=Fe);break}e&&ie&&Ne.alternate===null&&t(E,ie),y=u(Ne,y,re),_e===null?I=Ne:_e.sibling=Ne,_e=Ne,ie=Fe}if(re===_.length)return l(E,ie),ge&&Al(E,re),I;if(ie===null){for(;re<_.length;re++)ie=U(E,_[re],w),ie!==null&&(y=u(ie,y,re),_e===null?I=ie:_e.sibling=ie,_e=ie);return ge&&Al(E,re),I}for(ie=n(ie);re<_.length;re++)Fe=C(ie,E,re,_[re],w),Fe!==null&&(e&&(Ne=Fe.alternate,Ne!==null&&ie.delete(Ne.key===null?re:Ne.key)),y=u(Fe,y,re),_e===null?I=Fe:_e.sibling=Fe,_e=Fe);return e&&ie.forEach(function(yn){return t(E,yn)}),ge&&Al(E,re),I}function te(E,y,_,w){if(_==null)throw Error(o(151));for(var I=null,_e=null,ie=y,re=y=0,Fe=null,Ne=_.next();ie!==null&&!Ne.done;re++,Ne=_.next()){ie.index>re?(Fe=ie,ie=null):Fe=ie.sibling;var yn=p(E,ie,Ne.value,w);if(yn===null){ie===null&&(ie=Fe);break}e&&ie&&yn.alternate===null&&t(E,ie),y=u(yn,y,re),_e===null?I=yn:_e.sibling=yn,_e=yn,ie=Fe}if(Ne.done)return l(E,ie),ge&&Al(E,re),I;if(ie===null){for(;!Ne.done;re++,Ne=_.next())Ne=U(E,Ne.value,w),Ne!==null&&(y=u(Ne,y,re),_e===null?I=Ne:_e.sibling=Ne,_e=Ne);return ge&&Al(E,re),I}for(ie=n(ie);!Ne.done;re++,Ne=_.next())Ne=C(ie,E,re,Ne.value,w),Ne!==null&&(e&&(Fe=Ne.alternate,Fe!==null&&ie.delete(Fe.key===null?re:Fe.key)),y=u(Ne,y,re),_e===null?I=Ne:_e.sibling=Ne,_e=Ne);return e&&ie.forEach(function(ip){return t(E,ip)}),ge&&Al(E,re),I}function ve(E,y,_,w){if(typeof _=="object"&&_!==null&&_.type===de&&_.key===null&&_.props.ref===void 0&&(_=_.props.children),typeof _=="object"&&_!==null){switch(_.$$typeof){case L:e:{for(var I=_.key;y!==null;){if(y.key===I){if(I=_.type,I===de){if(y.tag===7){l(E,y.sibling),w=a(y,_.props.children),Fl(w,_),w.return=E,E=w;break e}}else if(y.elementType===I||typeof I=="object"&&I!==null&&I.$$typeof===G&&Un(I)===y.type){l(E,y.sibling),w=a(y,_.props),Fl(w,_),w.return=E,E=w;break e}l(E,y);break}else t(E,y);y=y.sibling}_.type===de?(w=Nn(_.props.children,E.mode,w,_.key),Fl(w,_),w.return=E,E=w):(w=mi(_.type,_.key,_.props,null,E.mode,w),Fl(w,_),w.return=E,E=w)}return c(E);case J:e:{for(I=_.key;y!==null;){if(y.key===I)if(y.tag===4&&y.stateNode.containerInfo===_.containerInfo&&y.stateNode.implementation===_.implementation){l(E,y.sibling),w=a(y,_.children||[]),w.return=E,E=w;break e}else{l(E,y);break}else t(E,y);y=y.sibling}w=yo(_,E.mode,w),w.return=E,E=w}return c(E);case G:return _=Un(_),ve(E,y,_,w)}if(Ae(_))return Q(E,y,_,w);if(ne(_)){if(I=ne(_),typeof I!="function")throw Error(o(150));return _=I.call(_),te(E,y,_,w)}if(typeof _.then=="function")return ve(E,y,_i(_),w);if(_.$$typeof===Ce)return ve(E,y,pi(E,_),w);Ci(E,_)}return typeof _=="string"&&_!==""||typeof _=="number"||typeof _=="bigint"?(_=""+_,y!==null&&y.tag===6?(l(E,y.sibling),w=a(y,_),w.return=E,E=w):(l(E,y),w=go(_,E.mode,w),w.return=E,E=w),c(E)):l(E,y)}return function(E,y,_,w){try{fu=0;var I=ve(E,y,_,w);return ga=null,I}catch(ie){if(ie===ha||ie===Ei)throw ie;var _e=Tt(29,ie,null,E.mode);return _e.lanes=w,_e.return=E,_e}finally{}}}var jn=yd(!0),bd=yd(!1),Wl=!1;function No(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Oo(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Pl(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function en(e,t,l){var n=e.updateQueue;if(n===null)return null;if(n=n.shared,(xe&2)!==0){var a=n.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),n.pending=t,t=di(e),td(e,null,l),t}return fi(e,n,t,l),di(e)}function du(e,t,l){if(t=t.updateQueue,t!==null&&(t=t.shared,(l&4194048)!==0)){var n=t.lanes;n&=e.pendingLanes,l|=n,t.lanes=l,af(e,l)}}function xo(e,t){var l=e.updateQueue,n=e.alternate;if(n!==null&&(n=n.updateQueue,l===n)){var a=null,u=null;if(l=l.firstBaseUpdate,l!==null){do{var c={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};u===null?a=u=c:u=u.next=c,l=l.next}while(l!==null);u===null?a=u=t:u=u.next=t}else a=u=t;l={baseState:n.baseState,firstBaseUpdate:a,lastBaseUpdate:u,shared:n.shared,callbacks:n.callbacks},e.updateQueue=l;return}e=l.lastBaseUpdate,e===null?l.firstBaseUpdate=t:e.next=t,l.lastBaseUpdate=t}var Ro=!1;function mu(){if(Ro){var e=va;if(e!==null)throw e}}function vu(e,t,l,n){Ro=!1;var a=e.updateQueue;Wl=!1;var u=a.firstBaseUpdate,c=a.lastBaseUpdate,f=a.shared.pending;if(f!==null){a.shared.pending=null;var v=f,T=v.next;v.next=null,c===null?u=T:c.next=T,c=v;var A=e.alternate;A!==null&&(A=A.updateQueue,f=A.lastBaseUpdate,f!==c&&(f===null?A.firstBaseUpdate=T:f.next=T,A.lastBaseUpdate=v))}if(u!==null){var U=a.baseState;c=0,A=T=v=null,f=u;do{var p=f.lane&-536870913,C=p!==f.lane;if(C?(Te&p)===p:(n&p)===p){p!==0&&p===Dn&&(Ro=!0),A!==null&&(A=A.next={lane:0,tag:f.tag,payload:f.payload,callback:null,next:null});e:{var Q=e,te=f;p=t;var ve=l;switch(te.tag){case 1:if(Q=te.payload,typeof Q=="function"){U=Q.call(ve,U,p);break e}U=Q;break e;case 3:Q.flags=Q.flags&-65537|128;case 0:if(Q=te.payload,p=typeof Q=="function"?Q.call(ve,U,p):Q,p==null)break e;U=X({},U,p);break e;case 2:Wl=!0}}p=f.callback,p!==null&&(e.flags|=64,C&&(e.flags|=8192),C=a.callbacks,C===null?a.callbacks=[p]:C.push(p))}else C={lane:p,tag:f.tag,payload:f.payload,callback:f.callback,next:null},A===null?(T=A=C,v=U):A=A.next=C,c|=p;if(f=f.next,f===null){if(f=a.shared.pending,f===null)break;C=f,f=C.next,C.next=null,a.lastBaseUpdate=C,a.shared.pending=null}}while(!0);A===null&&(v=U),a.baseState=v,a.firstBaseUpdate=T,a.lastBaseUpdate=A,u===null&&(a.shared.lanes=0),on|=c,e.lanes=c,e.memoizedState=U}}function pd(e,t){if(typeof e!="function")throw Error(o(191,e));e.call(t)}function Sd(e,t){var l=e.callbacks;if(l!==null)for(e.callbacks=null,e=0;eu?u:8;var c=ee.T,f={};f.types=c!==null?c.types:null,ee.T=f,Io(e,!1,t,l);try{var v=a(),T=ee.S;if(T!==null&&T(f,v),v!==null&&typeof v=="object"&&typeof v.then=="function"){var A=Ay(v,n);bu(e,t,A,Gt(e))}else bu(e,t,n,Gt(e))}catch(U){bu(e,t,{then:function(){},status:"rejected",reason:U},Gt())}finally{oe.p=u,c!==null&&f.types!==null&&(c.types=f.types),ee.T=c}}function Dy(){}function Jo(e,t,l,n){if(e.tag!==5)throw Error(o(476));var a=Wd(e).queue;Fd(e,a,t,Nt,l===null?Dy:function(){return Pd(e),l(n)})}function Wd(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:Nt,baseState:Nt,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Rl,lastRenderedState:Nt},next:null};var l={};return t.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Rl,lastRenderedState:l},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Pd(e){var t=Wd(e);t.next===null&&(t=e.alternate.memoizedState),bu(e,t.next.queue,{},Gt())}function $o(){return ot(Ba)}function em(){return ke().memoizedState}function tm(){return ke().memoizedState}function wy(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var l=Gt();e=Pl(l);var n=en(t,e,l);n!==null&&(At(n,t,l),du(n,t,l)),t={cache:_o()},e.payload=t;return}t=t.return}}function Uy(e,t,l){var n=Gt();l={lane:n,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Ui(e)?nm(t,l):(l=vo(e,t,l,n),l!==null&&(At(l,e,n),am(l,t,n)))}function lm(e,t,l){var n=Gt();bu(e,t,l,n)}function bu(e,t,l,n){var a={lane:n,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Ui(e))nm(t,a);else{var u=e.alternate;if(e.lanes===0&&(u===null||u.lanes===0)&&(u=t.lastRenderedReducer,u!==null))try{var c=t.lastRenderedState,f=u(c,l);if(a.hasEagerState=!0,a.eagerState=f,Dt(f,c))return fi(e,t,a,0),Ge===null&&si(),!1}catch{}finally{}if(l=vo(e,t,a,n),l!==null)return At(l,e,n),am(l,t,n),!0}return!1}function Io(e,t,l,n){if(n={lane:2,revertLane:Yr(),gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ui(e)){if(t)throw Error(o(479))}else t=vo(e,l,n,2),t!==null&&At(t,e,2)}function Ui(e){var t=e.alternate;return e===me||t!==null&&t===me}function nm(e,t){ya=Ni=!0;var l=e.pending;l===null?t.next=t:(t.next=l.next,l.next=t),e.pending=t}function am(e,t,l){if((l&4194048)!==0){var n=t.lanes;n&=e.pendingLanes,l|=n,t.lanes=l,af(e,l)}}var Hi={readContext:ot,use:Ri,useCallback:Qe,useContext:Qe,useEffect:Qe,useImperativeHandle:Qe,useLayoutEffect:Qe,useInsertionEffect:Qe,useMemo:Qe,useReducer:Qe,useRef:Qe,useState:Qe,useDebugValue:Qe,useDeferredValue:Qe,useTransition:Qe,useSyncExternalStore:Qe,useId:Qe,useHostTransitionStatus:Qe,useFormState:Qe,useActionState:Qe,useOptimistic:Qe,useMemoCache:Qe,useCacheRefresh:Qe,useEffectEvent:Qe},um={readContext:ot,use:Ri,useCallback:function(e,t){return bt().memoizedState=[e,t===void 0?null:t],e},useContext:ot,useEffect:Vd,useImperativeHandle:function(e,t,l){l=l!=null?l.concat([e]):null,Di(4194308,4,kd.bind(null,t,e),l)},useLayoutEffect:function(e,t){return Di(4194308,4,e,t)},useInsertionEffect:function(e,t){Di(4,2,e,t)},useMemo:function(e,t){var l=bt();t=t===void 0?null:t;var n=e();if(Gn){Ql(!0);try{e()}finally{Ql(!1)}}return l.memoizedState=[n,t],n},useReducer:function(e,t,l){var n=bt();if(l!==void 0){var a=l(t);if(Gn){Ql(!0);try{l(t)}finally{Ql(!1)}}}else a=t;return n.memoizedState=n.baseState=a,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:a},n.queue=e,e=e.dispatch=Uy.bind(null,me,e),[n.memoizedState,e]},useRef:function(e){var t=bt();return e={current:e},t.memoizedState=e},useState:function(e){e=Xo(e);var t=e.queue,l=lm.bind(null,me,t);return t.dispatch=l,[e.memoizedState,l]},useDebugValue:ko,useDeferredValue:function(e,t){var l=bt();return Ko(l,e,t)},useTransition:function(){var e=Xo(!1);return e=Fd.bind(null,me,e.queue,!0,!1),bt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,l){var n=me,a=bt();if(ge){if(l===void 0)throw Error(o(407));l=l()}else{if(l=t(),Ge===null)throw Error(o(349));(Te&127)!==0||Ad(n,t,l)}a.memoizedState=l;var u={value:l,getSnapshot:t};return a.queue=u,Vd(Od.bind(null,n,u,e),[e]),n.flags|=2048,pa(9,{destroy:void 0},Nd.bind(null,n,u,l,t),null),l},useId:function(){var e=bt(),t=Ge.identifierPrefix;if(ge){var l=rl,n=ol;l=(n&~(1<<32-Rt(n)-1)).toString(32)+l,t="_"+t+"R_"+l,l=Oi++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof n.is=="string"?c.createElement("select",{is:n.is}):c.createElement("select"),n.multiple?u.multiple=!0:n.size&&(u.size=n.size);break;default:u=typeof n.is=="string"?c.createElement(a,{is:n.is}):c.createElement(a)}}u[ct]=t,u[Et]=n;e:for(c=t.child;c!==null;){if(c.tag===5||c.tag===6)u.appendChild(c.stateNode);else if(c.tag!==4&&c.tag!==27&&c.child!==null){c.child.return=c,c=c.child;continue}if(c===t)break e;for(;c.sibling===null;){if(c.return===null||c.return===t)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}t.stateNode=u;e:switch(dt(u,a,n),a){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}n&&Dl(t)}}return Ye(t),t.subtreeFlags&=-33554433,rr(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,l),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==n&&Dl(t);else{if(typeof n!="string"&&t.stateNode===null)throw Error(o(166));if(e=Vl.current,ma(t)){if(e=t.stateNode,l=t.memoizedProps,n=null,a=nt,a!==null)switch(a.tag){case 27:case 5:n=a.memoizedProps}e[ct]=t,e=!!(e.nodeValue===l||n!==null&&n.suppressHydrationWarning===!0||Ov(e.nodeValue,l)),e||$l(t,!0)}else e=Mu(e).createTextNode(n),e[ct]=t,t.stateNode=e}return Ye(t),null;case 31:if(l=t.memoizedState,e===null||e.memoizedState!==null){if(n=ma(t),l!==null){if(e===null){if(!n)throw Error(o(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(o(557));e[ct]=t}else On(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Ye(t),e=!1}else l=So(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=l),e=!0;if(!e)return t.flags&256?(wt(t),t):(wt(t),null);if((t.flags&128)!==0)throw Error(o(558))}return Ye(t),null;case 13:if(n=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=ma(t),n!==null&&n.dehydrated!==null){if(e===null){if(!a)throw Error(o(318));if(a=t.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(o(317));a[ct]=t}else On(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Ye(t),a=!1}else a=So(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(wt(t),t):(wt(t),null)}return wt(t),(t.flags&128)!==0?(t.lanes=l,t):(l=n!==null,e=e!==null&&e.memoizedState!==null,l&&(n=t.child,a=null,n.alternate!==null&&n.alternate.memoizedState!==null&&n.alternate.memoizedState.cachePool!==null&&(a=n.alternate.memoizedState.cachePool.pool),u=null,n.memoizedState!==null&&n.memoizedState.cachePool!==null&&(u=n.memoizedState.cachePool.pool),u!==a&&(n.flags|=2048)),l!==e&&l&&(t.child.flags|=8192),Li(t,t.updateQueue),Ye(t),null);case 4:return Fn(),e===null&&Qr(t.stateNode.containerInfo),t.flags|=67108864,Ye(t),null;case 10:return Ol(t.type),Ye(t),null;case 19:if(Uo(t),n=t.memoizedState,n===null)return Ye(t),null;if(a=(t.flags&128)!==0,u=n.rendering,u===null)if(a)Su(n,!1);else{if(Ze!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(u=Ai(e),u!==null){for(t.flags|=128,Su(n,!1),e=u.updateQueue,t.updateQueue=e,Li(t,e),t.subtreeFlags=0,e=l,l=t.child;l!==null;)ld(l,e),l=l.sibling;return hu(t,st.current&1|2),ge&&Al(t,n.treeForkCount),t.child}e=e.sibling}n.tail!==null&&Ot()>Pi&&(t.flags|=128,a=!0,Su(n,!1),t.lanes=4194304)}else{if(!a)if(e=Ai(u),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Li(t,e),Su(n,!0),n.tail===null&&n.tailMode!=="collapsed"&&n.tailMode!=="visible"&&!u.alternate&&!ge)return Ye(t),null}else 2*Ot()-n.renderingStartTime>Pi&&l!==536870912&&(t.flags|=128,a=!0,Su(n,!1),t.lanes=4194304);n.isBackwards?(u.sibling=t.child,t.child=u):(e=n.last,e!==null?e.sibling=u:t.child=u,n.last=u)}if(n.tail!==null){e=n.tail;e:{for(l=e;l!==null;){if(l.alternate!==null){l=!1;break e}l=l.sibling}l=!0}return n.rendering=e,n.tail=e.sibling,n.renderingStartTime=Ot(),e.sibling=null,u=st.current,u=a?u&1|2:u&1,n.tailMode==="visible"||n.tailMode==="collapsed"||!l||ge?hu(t,u):(l=u,Be(rt,t),Be(st,l),gt===null&&(gt=t)),ge&&Al(t,n.treeForkCount),e}return Ye(t),null;case 22:case 23:return wt(t),Do(),n=t.memoizedState!==null,e!==null?e.memoizedState!==null!==n&&(t.flags|=8192):n&&(t.flags|=8192),n?(l&536870912)!==0&&(t.flags&128)===0&&(Ye(t),t.subtreeFlags&6&&(t.flags|=8192)):Ye(t),l=t.updateQueue,l!==null&&Li(t,l.retryQueue),l=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(l=e.memoizedState.cachePool.pool),n=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(n=t.memoizedState.cachePool.pool),n!==l&&(t.flags|=2048),e!==null&&it(wn),null;case 24:return l=null,e!==null&&(l=e.memoizedState.cache),t.memoizedState.cache!==l&&(t.flags|=2048),Ol(Je),Ye(t),null;case 25:return null;case 30:return t.flags|=33554432,Ye(t),null}throw Error(o(156,t.tag))}function Ly(e,t){switch(bo(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ol(Je),Fn(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ku(t),null;case 31:if(t.memoizedState!==null){if(wt(t),t.alternate===null)throw Error(o(340));On()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(wt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(o(340));On()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Uo(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Fn(),null;case 10:return Ol(t.type),null;case 22:case 23:return wt(t),Do(),e!==null&&it(wn),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ol(Je),null;case 25:return null;default:return null}}function Rm(e,t){switch(bo(t),t.tag){case 3:Ol(Je),Fn();break;case 26:case 27:case 5:ku(t);break;case 4:Fn();break;case 31:t.memoizedState!==null&&wt(t);break;case 13:wt(t);break;case 19:Uo(t);break;case 10:Ol(t.type);break;case 22:case 23:wt(t),Do(),e!==null&&it(wn);break;case 24:Ol(Je)}}function Eu(e,t){try{var l=t.updateQueue,n=l!==null?l.lastEffect:null;if(n!==null){var a=n.next;l=a;do{if((l.tag&e)===e){n=void 0;var u=l.create,c=l.inst;n=u(),c.destroy=n}l=l.next}while(l!==a)}}catch(f){we(t,t.return,f)}}function an(e,t,l){try{var n=t.updateQueue,a=n!==null?n.lastEffect:null;if(a!==null){var u=a.next;n=u;do{if((n.tag&e)===e){var c=n.inst,f=c.destroy;if(f!==void 0){c.destroy=void 0,a=t;var v=l,T=f;try{T()}catch(A){we(a,v,A)}}}n=n.next}while(n!==u)}}catch(A){we(t,t.return,A)}}function Mm(e){var t=e.updateQueue;if(t!==null){var l=e.stateNode;try{Sd(t,l)}catch(n){we(e,e.return,n)}}}function Dm(e,t,l){l.props=Bn(e.type,e.memoizedProps),l.state=e.memoizedState;try{l.componentWillUnmount()}catch(n){we(e,t,n)}}function sl(e,t){try{var l=e.ref;if(l!==null){switch(e.tag){case 26:case 27:case 5:var n=e.stateNode;break;case 30:var a=e.stateNode,u=_l(e.memoizedProps,a);(a.ref===null||a.ref.name!==u)&&(a.ref=qv(u)),n=a.ref;break;case 7:if(e.stateNode===null){var c=new Bt(e);h(e.child,!1,Mb,c,void 0,void 0),e.stateNode=c}n=e.stateNode;break;default:n=e.stateNode}typeof l=="function"?e.refCleanup=l(n):l.current=n}}catch(f){we(e,t,f)}}function ft(e,t){var l=e.ref,n=e.refCleanup;if(l!==null)if(typeof n=="function")try{n()}catch(a){we(e,t,a)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(a){we(e,t,a)}else l.current=null}function Vi(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var l=0;l title"))),dt(n,t,l),n[ct]=e,lt(n),t=n;break e;case"link":if(u=lh("link","href",a).get(t+(l.href||""))){for(c=0;cve&&(c=ve,ve=te,te=c);var E=Qf(f,te),y=Qf(f,ve);if(E&&y&&(C.rangeCount!==1||C.anchorNode!==E.node||C.anchorOffset!==E.offset||C.focusNode!==y.node||C.focusOffset!==y.offset)){var _=U.createRange();_.setStart(E.node,E.offset),C.removeAllRanges(),te>ve?(C.addRange(_),C.extend(y.node,y.offset)):(_.setEnd(y.node,y.offset),C.addRange(_))}}}}for(U=[],C=f;C=C.parentNode;)C.nodeType===1&&U.push({element:C,left:C.scrollLeft,top:C.scrollTop});for(typeof f.focus=="function"&&f.focus(),f=0;fl?32:l,ee.T=null,l=Rr,Rr=null;var u=nl,c=gl;if(Ve=0,Vn=nl=null,gl=0,(xe&6)!==0)throw Error(o(331));var f=xe;if(xe|=4,tv(u.current),Wm(u,u.current,c,l),xe=f,Ou(0,!1),xt&&typeof xt.onPostCommitFiberRoot=="function")try{xt.onPostCommitFiberRoot(ka,u)}catch{}return!0}finally{oe.p=a,ee.T=n,gv(e,t)}}function yv(e,t,l){t=Qt(l,t),t=Po(e.stateNode,t,2),e=en(e,t,2),e!==null&&(Ja(e,2),yl(e))}function we(e,t,l){if(e.tag===3)yv(e,e,l);else for(;t!==null;){if(t.tag===3){yv(t,e,l);break}else if(t.tag===1){var n=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(rn===null||!rn.has(n))){e=Qt(l,e),l=mm(2),n=en(t,l,2),n!==null&&(vm(l,n,t,e),Ja(n,2),yl(n));break}}t=t.return}}function Gr(e,t,l){var n=e.pingCache;if(n===null){n=e.pingCache=new Zy;var a=new Set;n.set(t,a)}else a=n.get(t),a===void 0&&(a=new Set,n.set(t,a));a.has(l)||(Nr=!0,a.add(l),e=Py.bind(null,e,t,l),t.then(e,e))}function Py(e,t,l){var n=e.pingCache;n!==null&&n.delete(t),e.pingedLanes|=e.suspendedLanes&l,e.warmLanes&=~l,Ge===e&&(Te&l)===l&&((Ze===4||Ze===3&&(Te&62914560)===Te&&300>Ot()-Wi)&&(xe&2)===0?Ra(e,0):Fi|=l,za===Te&&(za=0)),yl(e)}function bv(e,t){t===0&&(t=lf()),e=An(e,t),e!==null&&(Ja(e,t),yl(e))}function eb(e){var t=e.memoizedState,l=0;t!==null&&(l=t.retryLane),bv(e,l)}function tb(e,t){var l=0;switch(e.tag){case 31:case 13:var n=e.stateNode,a=e.memoizedState;a!==null&&(l=a.retryLane);break;case 19:n=e.stateNode;break;case 22:n=e.stateNode._retryCache;break;default:throw Error(o(314))}n!==null&&n.delete(t),bv(e,l)}function lb(e,t){return qc(e,t)}var Da=null,wa=null,Br=!1,ic=!1,qr=!1,fn=0;function yl(e){e!==wa&&e.next===null&&(wa===null?Da=wa=e:wa=wa.next=e),ic=!0,Br||(Br=!0,ab())}function Ou(e,t){if(!qr&&ic){qr=!0;do for(var l=!1,n=Da;n!==null;){if(e!==0){var a=n.pendingLanes;if(a===0)var u=0;else{var c=n.suspendedLanes,f=n.pingedLanes;u=(1<<31-Rt(42|e)+1)-1,u&=a&~(c&~f),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(l=!0,Tv(n,u))}else u=Te,u=Fu(n,n===Ge?u:0,n.cancelPendingCommit!==null||n.timeoutHandle!==-1),(u&3)===0||Ka(n,u)||(l=!0,Tv(n,u));n=n.next}while(l);qr=!1}}function nb(){pv()}function pv(){ic=Br=!1;var e=0;fn!==0&&hb()&&(e=fn);for(var t=Ot(),l=null,n=Da;n!==null;){var a=n.next,u=Sv(n,t);u===0?(n.next=null,l===null?Da=a:l.next=a,a===null&&(wa=l)):(l=n,(e!==0||(u&3)!==0)&&(ic=!0)),n=a}Ve!==0&&Ve!==5||Ou(e),fn!==0&&(fn=0)}function Sv(e,t){for(var l=e.suspendedLanes,n=e.pingedLanes,a=e.expirationTimes,u=e.pendingLanes&-62914561;0f)break;var A=v.transferSize,U=v.initiatorType;A&&xv(U)&&(v=v.responseEnd,c+=A*(vfc){te.length=Q;break}_=new Promise(Eb.bind(_)),te.push(_)}}}if(0"u"?null:document;function Wv(e,t,l){var n=Ha;if(n&&typeof t=="string"&&t){var a=Vt(t);a='link[rel="'+e+'"][href="'+a+'"]',typeof l=="string"&&(a+='[crossorigin="'+l+'"]'),Fv.has(a)||(Fv.add(a),e={rel:e,crossOrigin:l,href:t},n.querySelector(a)===null&&(t=n.createElement("link"),dt(t,"link",e),lt(t),n.head.appendChild(t)))}}function Yb(e){Ul.D(e),Wv("dns-prefetch",e,null)}function Lb(e,t){Ul.C(e,t),Wv("preconnect",e,t)}function Vb(e,t,l){Ul.L(e,t,l);var n=Ha;if(n&&e&&t){var a='link[rel="preload"][as="'+Vt(t)+'"]';t==="image"&&l&&l.imageSrcSet?(a+='[imagesrcset="'+Vt(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(a+='[imagesizes="'+Vt(l.imageSizes)+'"]')):a+='[href="'+Vt(e)+'"]';var u=a;switch(t){case"style":u=ja(e);break;case"script":u=Ga(e)}if(!(It.has(u)||(e=X({rel:"preload",href:t==="image"&&l&&l.imageSrcSet?void 0:e,as:t},l),It.set(u,e),n.querySelector(a)!==null||t==="style"&&n.querySelector(wu(u))||t==="script"&&n.querySelector(Uu(u))))){var c=n.createElement("link");dt(c,"link",e),t==="style"&&(c[Wu]=!0,c.onload=c.onerror=function(){ff(c)}),lt(c),n.head.appendChild(c)}}}function Xb(e,t){Ul.m(e,t);var l=Ha;if(l&&e){var n=t&&typeof t.as=="string"?t.as:"script",a='link[rel="modulepreload"][as="'+Vt(n)+'"][href="'+Vt(e)+'"]',u=a;switch(n){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Ga(e)}if(!It.has(u)&&(e=X({rel:"modulepreload",href:e},t),It.set(u,e),l.querySelector(a)===null)){switch(n){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(Uu(u)))return}n=l.createElement("link"),dt(n,"link",e),lt(n),l.head.appendChild(n)}}}function Qb(e,t,l){Ul.S(e,t,l);var n=Ha;if(n&&e){var a=ea(n).hoistableStyles,u=ja(e);t=t||"default";var c=a.get(u);if(!c){var f={loading:0,preload:null};if(c=n.querySelector(wu(u)))f.loading=5;else{e=X({rel:"stylesheet",href:e,"data-precedence":t},l),(l=It.get(u))&&is(e,l);var v=c=n.createElement("link");lt(v),dt(v,"link",e),v._p=new Promise(function(T,A){v.onload=T,v.onerror=A}),v.addEventListener("load",function(){f.loading|=1}),v.addEventListener("error",function(){f.loading|=2}),f.loading|=4,rc(c,t,n)}c={type:"stylesheet",instance:c,count:1,state:f},a.set(u,c)}}}function Zb(e,t){Ul.X(e,t);var l=Ha;if(l&&e){var n=ea(l).hoistableScripts,a=Ga(e),u=n.get(a);u||(u=l.querySelector(Uu(a)),u||(e=X({src:e,async:!0},t),(t=It.get(a))&&cs(e,t),u=l.createElement("script"),lt(u),dt(u,"link",e),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},n.set(a,u))}}function kb(e,t){Ul.M(e,t);var l=Ha;if(l&&e){var n=ea(l).hoistableScripts,a=Ga(e),u=n.get(a);u||(u=l.querySelector(Uu(a)),u||(e=X({src:e,async:!0,type:"module"},t),(t=It.get(a))&&cs(e,t),u=l.createElement("script"),lt(u),dt(u,"link",e),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},n.set(a,u))}}function Pv(e,t,l,n){var a=(a=Vl.current)?Du(a):null;if(!a)throw Error(o(446));switch(e){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(l=ja(l.href),t=ea(a).hoistableStyles,n=t.get(l),n||(n={type:"style",instance:null,count:0,state:null},t.set(l,n)),n):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){e=ja(l.href);var u=ea(a).hoistableStyles,c=u.get(e);if(c||(a=a.ownerDocument||a,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(e,c),(u=a.querySelector(wu(e)))?u._p||(c.instance=u,c.state.loading=5):(u=It.get(e),u||(u={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},It.set(e,u)),Kb(a,e,u,c.state))),t&&n===null)throw Error(o(528,""));return c}if(t&&n!==null)throw Error(o(529,""));return null;case"script":return t=l.async,l=l.src,typeof l=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(l=Ga(l),t=ea(a).hoistableScripts,n=t.get(l),n||(n={type:"script",instance:null,count:0,state:null},t.set(l,n)),n):{type:"void",instance:null,count:0,state:null};default:throw Error(o(444,e))}}function ja(e){return'href="'+Vt(e)+'"'}function wu(e){return'link[rel="stylesheet"]['+e+"]"}function eh(e){return X({},e,{"data-precedence":e.precedence,precedence:null})}function Kb(e,t,l,n){if(t=e.querySelector('link[rel="preload"][as="style"]['+t+"]")){if(t[Wu]!==!0){n.loading=1;return}}else t=e.createElement("link"),t[Wu]=!0,t.onload=t.onerror=ff.bind(null,t),dt(t,"link",l),lt(t),e.head.appendChild(t);n.preload=t,t.addEventListener("load",function(){return n.loading|=1}),t.addEventListener("error",function(){return n.loading|=2})}function Ga(e){return'[src="'+Vt(e)+'"]'}function Uu(e){return"script[async]"+e}function th(e,t,l){if(t.count++,t.instance===null)switch(t.type){case"style":var n=e.querySelector('style[data-href~="'+Vt(l.href)+'"]');if(n)return t.instance=n,lt(n),n;var a=X({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return n=(e.ownerDocument||e).createElement("style"),lt(n),dt(n,"style",a),rc(n,l.precedence,e),t.instance=n;case"stylesheet":a=ja(l.href);var u=e.querySelector(wu(a));if(u)return t.state.loading|=4,t.instance=u,lt(u),u;n=eh(l),(a=It.get(a))&&is(n,a),u=(e.ownerDocument||e).createElement("link"),lt(u);var c=u;return c._p=new Promise(function(f,v){c.onload=f,c.onerror=v}),dt(u,"link",n),t.state.loading|=4,rc(u,l.precedence,e),t.instance=u;case"script":return u=Ga(l.src),(a=e.querySelector(Uu(u)))?(t.instance=a,lt(a),a):(n=l,(a=It.get(u))&&(n=X({},l),cs(n,a)),e=e.ownerDocument||e,a=e.createElement("script"),lt(a),dt(a,"link",n),e.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(o(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(n=t.instance,t.state.loading|=4,rc(n,l.precedence,e));return t.instance}function rc(e,t,l){for(var n=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=n.length?n[n.length-1]:null,u=a,c=0;c title"):null)}function Jb(e,t,l){if(l===1||t.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return e=t.disabled,typeof t.precedence=="string"&&e==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function nh(e,t){return e==="img"&&t.src!=null&&t.src!==""&&t.onLoad==null&&t.loading!=="lazy"}function ah(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function uh(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio=="number"?devicePixelRatio:1)*.25}function ih(e,t){typeof t.decode=="function"&&(e.imgCount++,t.complete||(e.imgBytes+=uh(t),e.suspenseyImages.push(t)),e=Fb.bind(e),t.decode().then(e,e))}function $b(e,t,l,n){if(l.type==="stylesheet"&&(typeof n.media!="string"||matchMedia(n.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var a=ja(n.href),u=t.querySelector(wu(a));if(u){t=u._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=Hu.bind(e),t.then(e,e)),l.state.loading|=4,l.instance=u,lt(u);return}u=t.ownerDocument||t,n=eh(n),(a=It.get(a))&&is(n,a),u=u.createElement("link"),lt(u);var c=u;c._p=new Promise(function(f,v){c.onload=f,c.onerror=v}),dt(u,"link",n),l.instance=u}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(l,t),(t=l.state.preload)&&(l.state.loading&3)===0&&(e.count++,l=Hu.bind(e),t.addEventListener("load",l),t.addEventListener("error",l))}}var fc=0;function Ib(e,t){return e.stylesheets&&e.count===0&&mc(e,e.stylesheets),0fc?50:800)+t);return e.unsuspend=l,function(){e.unsuspend=null,clearTimeout(n),clearTimeout(a)}}:null}function ch(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)mc(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function Hu(){this.count--,ch(this)}function Fb(){this.imgCount--,ch(this)}var dc=null;function mc(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,dc=new Map,t.forEach(Wb,e),dc=null,Hu.call(e))}function Wb(e,t){if(!(t.state.loading&4)){var l=dc.get(e);if(l)var n=l.get(null);else{l=new Map,dc.set(e,l);for(var a=e.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(r){console.error(r)}}return i(),ys.exports=mp(),ys.exports}var hp=vp(),gp=Object.defineProperty,Us=(i,r)=>gp(i,"name",{value:r,configurable:!0});function Ns(i,r){if(typeof i=="function")return i(r);i!=null&&(i.current=r)}Us(Ns,"setRef");function e0(...i){return r=>{let s=!1;const o=i.map(d=>{const m=Ns(d,r);return!s&&typeof m=="function"&&(s=!0),m});if(s)return()=>{for(let d=0;dyp(i,"name",{value:r,configurable:!0});function Zn(i){const r=M.forwardRef((s,o)=>{let{children:d,...m}=s,g=null,S=!1;const O=[];d=i0(d),M.Children.forEach(d,R=>{var D;if(a0(R)){S=!0;const V=R;let Z="child"in V.props?V.props.child:V.props.children;for(;Hs(Z)&&typeof Rc=="function";)Z=Rc(Z._payload);g=Sp(V,Z),O.push((D=g==null?void 0:g.props)==null?void 0:D.children)}else O.push(R)}),g?g=M.cloneElement(g,void 0,O):!S&&M.Children.count(d)===1&&M.isValidElement(d)&&(g=d);const x=g?n0(g):void 0,z=pl(o,x);if(!g){if(d||d===0)throw new Error(S?_p(i):Tp(i));return d}const h=l0(m,g.props??{});return g.type!==M.Fragment&&(h.ref=o?z:x),M.cloneElement(g,h)});return r.displayName=`${i}.Slot`,r}Lt(Zn,"createSlot");var bp=Zn("Slot"),t0=Symbol.for("radix.slottable");function pp(i){const r=Lt(s=>"child"in s?s.children(s.child):s.children,"Slottable");return r.displayName=`${i}.Slottable`,r.__radixId=t0,r}Lt(pp,"createSlottable");var Sp=Lt((i,r)=>"child"in i.props?M.isValidElement(r)?M.cloneElement(r,void 0,i.props.children(r.props.children)):null:M.isValidElement(r)?r:null,"getSlottableElementFromSlottable");function l0(i,r){const s={...r};for(const o in r){const d=i[o],m=r[o];/^on[A-Z]/.test(o)?d&&m?s[o]=(...S)=>{const O=m(...S);return d(...S),O}:d&&(s[o]=d):o==="style"?s[o]={...d,...m}:o==="className"?s[o]=[d,m].filter(Boolean).join(" "):o==="aria-describedby"&&(s[o]=c0(m,d))}return{...i,...s}}Lt(l0,"mergeProps");function n0(i){var o,d;let r=(o=Object.getOwnPropertyDescriptor(i.props,"ref"))==null?void 0:o.get,s=r&&"isReactWarning"in r&&r.isReactWarning;return s?i.ref:(r=(d=Object.getOwnPropertyDescriptor(i,"ref"))==null?void 0:d.get,s=r&&"isReactWarning"in r&&r.isReactWarning,s?i.props.ref:i.props.ref||i.ref)}Lt(n0,"getElementRef");function a0(i){return M.isValidElement(i)&&typeof i.type=="function"&&"__radixId"in i.type&&i.type.__radixId===t0}Lt(a0,"isSlottable");var Ep=Symbol.for("react.lazy");function Hs(i){return i!=null&&typeof i=="object"&&"$$typeof"in i&&i.$$typeof===Ep&&"_payload"in i&&u0(i._payload)}Lt(Hs,"isLazyComponent");function u0(i){return typeof i=="object"&&i!==null&&"then"in i}Lt(u0,"isPromiseLike");function i0(i){let r=i;for(;Hs(r)&&typeof Rc=="function";)r=Rc(r._payload);return r}Lt(i0,"useUnwrappedLazy");function c0(...i){const r=new Set;for(const s of i)if(typeof s=="string")for(const o of String(s).trim().split(/\s+/))o&&r.add(o);return r.size>0?Array.from(r).join(" "):void 0}Lt(c0,"concatAriaDescribedby");var Tp=Lt(i=>`${i} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,"createSlotError"),_p=Lt(i=>`${i} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,"createSlottableError"),Rc=kn[" use ".trim().toString()];function o0(i){var r,s,o="";if(typeof i=="string"||typeof i=="number")o+=i;else if(typeof i=="object")if(Array.isArray(i)){var d=i.length;for(r=0;rtypeof i=="boolean"?`${i}`:i===0?"0":i,wh=r0,s0=(i,r)=>s=>{var o;if((r==null?void 0:r.variants)==null)return wh(i,s==null?void 0:s.class,s==null?void 0:s.className);const{variants:d,defaultVariants:m}=r,g=Object.keys(d).map(x=>{const z=s==null?void 0:s[x],h=m==null?void 0:m[x];if(z===null)return null;const R=Dh(z)||Dh(h);return d[x][R]}),S=s&&Object.entries(s).reduce((x,z)=>{let[h,R]=z;return R===void 0||(x[h]=R),x},{}),O=r==null||(o=r.compoundVariants)===null||o===void 0?void 0:o.reduce((x,z)=>{let{class:h,className:R,...D}=z;return Object.entries(D).every(V=>{let[Z,Y]=V;return Array.isArray(Y)?Y.includes({...m,...S}[Z]):{...m,...S}[Z]===Y})?[...x,h,R]:x},[]);return wh(i,g,O,s==null?void 0:s.class,s==null?void 0:s.className)},Cp=(i,r)=>{const s=new Array(i.length+r.length);for(let o=0;o({classGroupId:i,validator:r}),f0=(i=new Map,r=null,s)=>({nextPart:i,validators:r,classGroupId:s}),Mc="-",Uh=[],Ap="arbitrary..",Np=i=>{const r=xp(i),{conflictingClassGroups:s,conflictingClassGroupModifiers:o}=i;return{getClassGroupId:g=>{if(g.startsWith("[")&&g.endsWith("]"))return Op(g);const S=g.split(Mc),O=S[0]===""&&S.length>1?1:0;return d0(S,O,r)},getConflictingClassGroupIds:(g,S)=>{if(S){const O=o[g],x=s[g];return O?x?Cp(x,O):O:x||Uh}return s[g]||Uh}}},d0=(i,r,s)=>{if(i.length-r===0)return s.classGroupId;const d=i[r],m=s.nextPart.get(d);if(m){const x=d0(i,r+1,m);if(x)return x}const g=s.validators;if(g===null)return;const S=r===0?i.join(Mc):i.slice(r).join(Mc),O=g.length;for(let x=0;xi.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const r=i.slice(1,-1),s=r.indexOf(":"),o=r.slice(0,s);return o?Ap+o:void 0})(),xp=i=>{const{theme:r,classGroups:s}=i;return Rp(s,r)},Rp=(i,r)=>{const s=f0();for(const o in i){const d=i[o];js(d,s,o,r)}return s},js=(i,r,s,o)=>{const d=i.length;for(let m=0;m{if(typeof i=="string"){Dp(i,r,s);return}if(typeof i=="function"){wp(i,r,s,o);return}Up(i,r,s,o)},Dp=(i,r,s)=>{const o=i===""?r:m0(r,i);o.classGroupId=s},wp=(i,r,s,o)=>{if(Hp(i)){js(i(o),r,s,o);return}r.validators===null&&(r.validators=[]),r.validators.push(zp(s,i))},Up=(i,r,s,o)=>{const d=Object.entries(i),m=d.length;for(let g=0;g{let s=i;const o=r.split(Mc),d=o.length;for(let m=0;m"isThemeGetter"in i&&i.isThemeGetter===!0,jp=i=>{if(i<1)return{get:()=>{},set:()=>{}};let r=0,s=Object.create(null),o=Object.create(null);const d=(m,g)=>{s[m]=g,r++,r>i&&(r=0,o=s,s=Object.create(null))};return{get(m){let g=s[m];if(g!==void 0)return g;if((g=o[m])!==void 0)return d(m,g),g},set(m,g){m in s?s[m]=g:d(m,g)}}},Os="!",Hh=":",Gp=[],jh=(i,r,s,o,d)=>({modifiers:i,hasImportantModifier:r,baseClassName:s,maybePostfixModifierPosition:o,isExternal:d}),Bp=i=>{const{prefix:r,experimentalParseClassName:s}=i;let o=d=>{const m=[];let g=0,S=0,O=0,x;const z=d.length;for(let Z=0;ZO?x-O:void 0;return jh(m,D,R,V)};if(r){const d=r+Hh,m=o;o=g=>g.startsWith(d)?m(g.slice(d.length)):jh(Gp,!1,g,void 0,!0)}if(s){const d=o;o=m=>s({className:m,parseClassName:d})}return o},qp=i=>{const r=new Map;return i.orderSensitiveModifiers.forEach((s,o)=>{r.set(s,1e6+o)}),s=>{const o=[];let d=[];for(let m=0;m0&&(d.sort(),o.push(...d),d=[]),o.push(g)):d.push(g)}return d.length>0&&(d.sort(),o.push(...d)),o}},Yp=i=>({cache:jp(i.cacheSize),parseClassName:Bp(i),sortModifiers:qp(i),postfixLookupClassGroupIds:Lp(i),...Np(i)}),Lp=i=>{const r=Object.create(null),s=i.postfixLookupClassGroups;if(s)for(let o=0;o{const{parseClassName:s,getClassGroupId:o,getConflictingClassGroupIds:d,sortModifiers:m,postfixLookupClassGroupIds:g}=r,S=[],O=i.trim().split(Vp);let x="";for(let z=O.length-1;z>=0;z-=1){const h=O[z],{isExternal:R,modifiers:D,hasImportantModifier:V,baseClassName:Z,maybePostfixModifierPosition:Y}=s(h);if(R){x=h+(x.length>0?" "+x:x);continue}let K=!!Y,H;if(K){const X=Z.substring(0,Y);H=o(X);const B=H&&g[H]?o(Z):void 0;B&&B!==H&&(H=B,K=!1)}else H=o(Z);if(!H){if(!K){x=h+(x.length>0?" "+x:x);continue}if(H=o(Z),!H){x=h+(x.length>0?" "+x:x);continue}K=!1}const F=D.length===0?"":D.length===1?D[0]:m(D).join(":"),ue=V?F+Os:F,fe=ue+H;if(S.indexOf(fe)>-1)continue;S.push(fe);const ae=d(H,K);for(let X=0;X0?" "+x:x)}return x},Qp=(...i)=>{let r=0,s,o,d="";for(;r{if(typeof i=="string")return i;let r,s="";for(let o=0;o{let s,o,d,m;const g=O=>{const x=r.reduce((z,h)=>h(z),i());return s=Yp(x),o=s.cache.get,d=s.cache.set,m=S,S(O)},S=O=>{const x=o(O);if(x)return x;const z=Xp(O,s);return d(O,z),z};return m=g,(...O)=>m(Qp(...O))},kp=[],et=i=>{const r=s=>s[i]||kp;return r.isThemeGetter=!0,r.themeKey=i,r},h0=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,g0=/^\((?:(\w[\w-]*):)?(.+)\)$/i,Kp=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,Jp=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,$p=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Ip=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix|color|light-dark)\(.+\)$/,Fp=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Wp=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,bn=i=>Kp.test(i),ye=i=>!!i&&!Number.isNaN(Number(i)),bl=i=>!!i&&Number.isInteger(Number(i)),Es=i=>i.endsWith("%")&&ye(i.slice(0,-1)),Hl=i=>Jp.test(i),y0=()=>!0,Pp=i=>$p.test(i)&&!Ip.test(i),Gs=()=>!1,e1=i=>Fp.test(i),t1=i=>Wp.test(i),l1=i=>!W(i)&&!P(i),n1=i=>i.startsWith("@container")&&(i[10]==="/"&&i[11]!==void 0||i[11]==="s"&&i[16]!==void 0&&i.startsWith("-size/",10)||i[11]==="n"&&i[18]!==void 0&&i.startsWith("-normal/",10)),a1=i=>Sn(i,S0,Gs),W=i=>h0.test(i),Qn=i=>Sn(i,E0,Pp),Gh=i=>Sn(i,d1,ye),u1=i=>Sn(i,_0,y0),i1=i=>Sn(i,T0,Gs),Bh=i=>Sn(i,b0,Gs),c1=i=>Sn(i,p0,t1),Sc=i=>Sn(i,C0,e1),P=i=>g0.test(i),Yu=i=>Kn(i,E0),o1=i=>Kn(i,T0),qh=i=>Kn(i,b0),r1=i=>Kn(i,S0),s1=i=>Kn(i,p0),Ec=i=>Kn(i,C0,!0),f1=i=>Kn(i,_0,!0),Sn=(i,r,s)=>{const o=h0.exec(i);return o?o[1]?r(o[1]):s(o[2]):!1},Kn=(i,r,s=!1)=>{const o=g0.exec(i);return o?o[1]?r(o[1]):s:!1},b0=i=>i==="position"||i==="percentage",p0=i=>i==="image"||i==="url",S0=i=>i==="length"||i==="size"||i==="bg-size",E0=i=>i==="length",d1=i=>i==="number",T0=i=>i==="family-name",_0=i=>i==="number"||i==="weight",C0=i=>i==="shadow",m1=()=>{const i=et("color"),r=et("font"),s=et("text"),o=et("font-weight"),d=et("tracking"),m=et("leading"),g=et("breakpoint"),S=et("container"),O=et("spacing"),x=et("radius"),z=et("shadow"),h=et("inset-shadow"),R=et("text-shadow"),D=et("drop-shadow"),V=et("blur"),Z=et("perspective"),Y=et("aspect"),K=et("ease"),H=et("animate"),F=()=>["auto","avoid","all","avoid-page","page","left","right","column"],ue=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],fe=()=>[...ue(),P,W],ae=()=>["auto","hidden","clip","visible","scroll"],X=()=>["auto","contain","none"],B=()=>[P,W,O],L=()=>[bn,"full","auto",...B()],J=()=>[bl,"none","subgrid",P,W],de=()=>["auto",{span:["full",bl,P,W]},bl,P,W],Re=()=>[bl,"auto",P,W],He=()=>["auto","min","max","fr",P,W],Xe=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],Ce=()=>["start","end","center","stretch","center-safe","end-safe"],q=()=>["auto",...B()],$=()=>[bn,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...B()],le=()=>[S,bn,"screen","full","dvw","lvw","svw","min","max","fit",...B()],he=()=>[bn,"screen","full","lh","dvh","lvh","svh","min","max","fit",...B()],G=()=>[i,P,W],ze=()=>[...ue(),qh,Bh,{position:[P,W]}],We=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ht=()=>["auto","cover","contain",r1,a1,{size:[P,W]}],b=()=>[Es,Yu,Qn],j=()=>["","none","full",x,P,W],k=()=>["",ye,Yu,Qn],ne=()=>["solid","dashed","dotted","double"],Ee=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],ce=()=>[ye,Es,qh,Bh],Ae=()=>["","none",V,P,W],ee=()=>["none",ye,P,W],oe=()=>["none",ye,P,W],Nt=()=>[ye,P,W],Ll=()=>[bn,"full",...B()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[Hl],breakpoint:[Hl],color:[y0],container:[Hl],"drop-shadow":[Hl],ease:["in","out","in-out"],font:[l1],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[Hl],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[Hl],shadow:[Hl],spacing:["px",ye],text:[Hl],"text-shadow":[Hl],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",bn,W,P,Y]}],container:["container"],"container-type":[{"@container":["","normal","size",P,W]}],"container-named":[n1],columns:[{columns:[ye,"auto",W,P,S]}],"break-after":[{"break-after":F()}],"break-before":[{"break-before":F()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:fe()}],overflow:[{overflow:ae()}],"overflow-x":[{"overflow-x":ae()}],"overflow-y":[{"overflow-y":ae()}],overscroll:[{overscroll:X()}],"overscroll-x":[{"overscroll-x":X()}],"overscroll-y":[{"overscroll-y":X()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:L()}],"inset-x":[{"inset-x":L()}],"inset-y":[{"inset-y":L()}],start:[{"inset-s":L(),start:L()}],end:[{"inset-e":L(),end:L()}],"inset-bs":[{"inset-bs":L()}],"inset-be":[{"inset-be":L()}],top:[{top:L()}],right:[{right:L()}],bottom:[{bottom:L()}],left:[{left:L()}],visibility:["visible","invisible","collapse"],z:[{z:[bl,"auto",P,W]}],basis:[{basis:[bn,"full","auto",S,...B()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[ye,bn,"auto","initial","none",W]}],grow:[{grow:["",ye,P,W]}],shrink:[{shrink:["",ye,P,W]}],order:[{order:[bl,"first","last","none",P,W]}],"grid-cols":[{"grid-cols":J()}],"col-start-end":[{col:de()}],"col-start":[{"col-start":Re()}],"col-end":[{"col-end":Re()}],"grid-rows":[{"grid-rows":J()}],"row-start-end":[{row:de()}],"row-start":[{"row-start":Re()}],"row-end":[{"row-end":Re()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":He()}],"auto-rows":[{"auto-rows":He()}],gap:[{gap:B()}],"gap-x":[{"gap-x":B()}],"gap-y":[{"gap-y":B()}],"justify-content":[{justify:[...Xe(),"normal"]}],"justify-items":[{"justify-items":[...Ce(),"normal"]}],"justify-self":[{"justify-self":["auto",...Ce()]}],"align-content":[{content:["normal",...Xe()]}],"align-items":[{items:[...Ce(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...Ce(),{baseline:["","last"]}]}],"place-content":[{"place-content":Xe()}],"place-items":[{"place-items":[...Ce(),"baseline"]}],"place-self":[{"place-self":["auto",...Ce()]}],p:[{p:B()}],px:[{px:B()}],py:[{py:B()}],ps:[{ps:B()}],pe:[{pe:B()}],pbs:[{pbs:B()}],pbe:[{pbe:B()}],pt:[{pt:B()}],pr:[{pr:B()}],pb:[{pb:B()}],pl:[{pl:B()}],m:[{m:q()}],mx:[{mx:q()}],my:[{my:q()}],ms:[{ms:q()}],me:[{me:q()}],mbs:[{mbs:q()}],mbe:[{mbe:q()}],mt:[{mt:q()}],mr:[{mr:q()}],mb:[{mb:q()}],ml:[{ml:q()}],"space-x":[{"space-x":B()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":B()}],"space-y-reverse":["space-y-reverse"],size:[{size:$()}],"inline-size":[{inline:["auto",...le()]}],"min-inline-size":[{"min-inline":["auto",...le()]}],"max-inline-size":[{"max-inline":["none",...le()]}],"block-size":[{block:["auto",...he()]}],"min-block-size":[{"min-block":["auto",...he()]}],"max-block-size":[{"max-block":["none",...he()]}],w:[{w:[S,"screen",...$()]}],"min-w":[{"min-w":[S,"screen","none",...$()]}],"max-w":[{"max-w":[S,"screen","none","prose",{screen:[g]},...$()]}],h:[{h:["screen","lh",...$()]}],"min-h":[{"min-h":["screen","lh","none",...$()]}],"max-h":[{"max-h":["screen","lh","none",...$()]}],"font-size":[{text:["base",s,Yu,Qn]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[o,f1,u1]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",Es,W]}],"font-family":[{font:[o1,i1,r]}],"font-features":[{"font-features":[W]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[d,P,W]}],"line-clamp":[{"line-clamp":[ye,"none",P,Gh]}],leading:[{leading:["none",m,...B()]}],"list-image":[{"list-image":["none",P,W]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",P,W]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:G()}],"text-color":[{text:G()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...ne(),"wavy"]}],"text-decoration-thickness":[{decoration:[ye,"from-font","auto",P,Qn]}],"text-decoration-color":[{decoration:G()}],"underline-offset":[{"underline-offset":[ye,"auto",P,W]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:B()}],"tab-size":[{tab:[bl,P,W]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",P,W]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",P,W]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ze()}],"bg-repeat":[{bg:We()}],"bg-size":[{bg:ht()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},bl,P,W],radial:["",P,W],conic:["",bl,P,W]},s1,c1]}],"bg-color":[{bg:G()}],"gradient-from-pos":[{from:b()}],"gradient-via-pos":[{via:b()}],"gradient-to-pos":[{to:b()}],"gradient-from":[{from:G()}],"gradient-via":[{via:G()}],"gradient-to":[{to:G()}],rounded:[{rounded:j()}],"rounded-s":[{"rounded-s":j()}],"rounded-e":[{"rounded-e":j()}],"rounded-t":[{"rounded-t":j()}],"rounded-r":[{"rounded-r":j()}],"rounded-b":[{"rounded-b":j()}],"rounded-l":[{"rounded-l":j()}],"rounded-ss":[{"rounded-ss":j()}],"rounded-se":[{"rounded-se":j()}],"rounded-ee":[{"rounded-ee":j()}],"rounded-es":[{"rounded-es":j()}],"rounded-tl":[{"rounded-tl":j()}],"rounded-tr":[{"rounded-tr":j()}],"rounded-br":[{"rounded-br":j()}],"rounded-bl":[{"rounded-bl":j()}],"border-w":[{border:k()}],"border-w-x":[{"border-x":k()}],"border-w-y":[{"border-y":k()}],"border-w-s":[{"border-s":k()}],"border-w-e":[{"border-e":k()}],"border-w-bs":[{"border-bs":k()}],"border-w-be":[{"border-be":k()}],"border-w-t":[{"border-t":k()}],"border-w-r":[{"border-r":k()}],"border-w-b":[{"border-b":k()}],"border-w-l":[{"border-l":k()}],"divide-x":[{"divide-x":k()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":k()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...ne(),"hidden","none"]}],"divide-style":[{divide:[...ne(),"hidden","none"]}],"border-color":[{border:G()}],"border-color-x":[{"border-x":G()}],"border-color-y":[{"border-y":G()}],"border-color-s":[{"border-s":G()}],"border-color-e":[{"border-e":G()}],"border-color-bs":[{"border-bs":G()}],"border-color-be":[{"border-be":G()}],"border-color-t":[{"border-t":G()}],"border-color-r":[{"border-r":G()}],"border-color-b":[{"border-b":G()}],"border-color-l":[{"border-l":G()}],"divide-color":[{divide:G()}],"outline-style":[{outline:[...ne(),"none","hidden"]}],"outline-offset":[{"outline-offset":[ye,P,W]}],"outline-w":[{outline:["",ye,Yu,Qn]}],"outline-color":[{outline:G()}],shadow:[{shadow:["","inner","none",z,Ec,Sc]}],"shadow-color":[{shadow:G()}],"inset-shadow":[{"inset-shadow":["none",h,Ec,Sc]}],"inset-shadow-color":[{"inset-shadow":G()}],"ring-w":[{ring:k()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:G()}],"ring-offset-w":[{"ring-offset":[ye,Qn]}],"ring-offset-color":[{"ring-offset":G()}],"inset-ring-w":[{"inset-ring":k()}],"inset-ring-color":[{"inset-ring":G()}],"text-shadow":[{"text-shadow":["none",R,Ec,Sc]}],"text-shadow-color":[{"text-shadow":G()}],opacity:[{opacity:[ye,P,W]}],"mix-blend":[{"mix-blend":[...Ee(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":Ee()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[ye]}],"mask-image-linear-from-pos":[{"mask-linear-from":ce()}],"mask-image-linear-to-pos":[{"mask-linear-to":ce()}],"mask-image-linear-from-color":[{"mask-linear-from":G()}],"mask-image-linear-to-color":[{"mask-linear-to":G()}],"mask-image-t-from-pos":[{"mask-t-from":ce()}],"mask-image-t-to-pos":[{"mask-t-to":ce()}],"mask-image-t-from-color":[{"mask-t-from":G()}],"mask-image-t-to-color":[{"mask-t-to":G()}],"mask-image-r-from-pos":[{"mask-r-from":ce()}],"mask-image-r-to-pos":[{"mask-r-to":ce()}],"mask-image-r-from-color":[{"mask-r-from":G()}],"mask-image-r-to-color":[{"mask-r-to":G()}],"mask-image-b-from-pos":[{"mask-b-from":ce()}],"mask-image-b-to-pos":[{"mask-b-to":ce()}],"mask-image-b-from-color":[{"mask-b-from":G()}],"mask-image-b-to-color":[{"mask-b-to":G()}],"mask-image-l-from-pos":[{"mask-l-from":ce()}],"mask-image-l-to-pos":[{"mask-l-to":ce()}],"mask-image-l-from-color":[{"mask-l-from":G()}],"mask-image-l-to-color":[{"mask-l-to":G()}],"mask-image-x-from-pos":[{"mask-x-from":ce()}],"mask-image-x-to-pos":[{"mask-x-to":ce()}],"mask-image-x-from-color":[{"mask-x-from":G()}],"mask-image-x-to-color":[{"mask-x-to":G()}],"mask-image-y-from-pos":[{"mask-y-from":ce()}],"mask-image-y-to-pos":[{"mask-y-to":ce()}],"mask-image-y-from-color":[{"mask-y-from":G()}],"mask-image-y-to-color":[{"mask-y-to":G()}],"mask-image-radial":[{"mask-radial":[P,W]}],"mask-image-radial-from-pos":[{"mask-radial-from":ce()}],"mask-image-radial-to-pos":[{"mask-radial-to":ce()}],"mask-image-radial-from-color":[{"mask-radial-from":G()}],"mask-image-radial-to-color":[{"mask-radial-to":G()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":ue()}],"mask-image-conic-pos":[{"mask-conic":[ye]}],"mask-image-conic-from-pos":[{"mask-conic-from":ce()}],"mask-image-conic-to-pos":[{"mask-conic-to":ce()}],"mask-image-conic-from-color":[{"mask-conic-from":G()}],"mask-image-conic-to-color":[{"mask-conic-to":G()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ze()}],"mask-repeat":[{mask:We()}],"mask-size":[{mask:ht()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",P,W]}],filter:[{filter:["","none",P,W]}],blur:[{blur:Ae()}],brightness:[{brightness:[ye,P,W]}],contrast:[{contrast:[ye,P,W]}],"drop-shadow":[{"drop-shadow":["","none",D,Ec,Sc]}],"drop-shadow-color":[{"drop-shadow":G()}],grayscale:[{grayscale:["",ye,P,W]}],"hue-rotate":[{"hue-rotate":[ye,P,W]}],invert:[{invert:["",ye,P,W]}],saturate:[{saturate:[ye,P,W]}],sepia:[{sepia:["",ye,P,W]}],"backdrop-filter":[{"backdrop-filter":["","none",P,W]}],"backdrop-blur":[{"backdrop-blur":Ae()}],"backdrop-brightness":[{"backdrop-brightness":[ye,P,W]}],"backdrop-contrast":[{"backdrop-contrast":[ye,P,W]}],"backdrop-grayscale":[{"backdrop-grayscale":["",ye,P,W]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[ye,P,W]}],"backdrop-invert":[{"backdrop-invert":["",ye,P,W]}],"backdrop-opacity":[{"backdrop-opacity":[ye,P,W]}],"backdrop-saturate":[{"backdrop-saturate":[ye,P,W]}],"backdrop-sepia":[{"backdrop-sepia":["",ye,P,W]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":B()}],"border-spacing-x":[{"border-spacing-x":B()}],"border-spacing-y":[{"border-spacing-y":B()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",P,W]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[ye,"initial",P,W]}],ease:[{ease:["linear","initial",K,P,W]}],delay:[{delay:[ye,P,W]}],animate:[{animate:["none",H,P,W]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[Z,P,W]}],"perspective-origin":[{"perspective-origin":fe()}],rotate:[{rotate:ee()}],"rotate-x":[{"rotate-x":ee()}],"rotate-y":[{"rotate-y":ee()}],"rotate-z":[{"rotate-z":ee()}],scale:[{scale:oe()}],"scale-x":[{"scale-x":oe()}],"scale-y":[{"scale-y":oe()}],"scale-z":[{"scale-z":oe()}],"scale-3d":["scale-3d"],skew:[{skew:Nt()}],"skew-x":[{"skew-x":Nt()}],"skew-y":[{"skew-y":Nt()}],transform:[{transform:[P,W,"","none","gpu","cpu"]}],"transform-origin":[{origin:fe()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:Ll()}],"translate-x":[{"translate-x":Ll()}],"translate-y":[{"translate-y":Ll()}],"translate-z":[{"translate-z":Ll()}],"translate-none":["translate-none"],zoom:[{zoom:[bl,P,W]}],accent:[{accent:G()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:G()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",P,W]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":G()}],"scrollbar-track-color":[{"scrollbar-track":G()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":B()}],"scroll-mx":[{"scroll-mx":B()}],"scroll-my":[{"scroll-my":B()}],"scroll-ms":[{"scroll-ms":B()}],"scroll-me":[{"scroll-me":B()}],"scroll-mbs":[{"scroll-mbs":B()}],"scroll-mbe":[{"scroll-mbe":B()}],"scroll-mt":[{"scroll-mt":B()}],"scroll-mr":[{"scroll-mr":B()}],"scroll-mb":[{"scroll-mb":B()}],"scroll-ml":[{"scroll-ml":B()}],"scroll-p":[{"scroll-p":B()}],"scroll-px":[{"scroll-px":B()}],"scroll-py":[{"scroll-py":B()}],"scroll-ps":[{"scroll-ps":B()}],"scroll-pe":[{"scroll-pe":B()}],"scroll-pbs":[{"scroll-pbs":B()}],"scroll-pbe":[{"scroll-pbe":B()}],"scroll-pt":[{"scroll-pt":B()}],"scroll-pr":[{"scroll-pr":B()}],"scroll-pb":[{"scroll-pb":B()}],"scroll-pl":[{"scroll-pl":B()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",P,W]}],fill:[{fill:["none",...G()]}],"stroke-w":[{stroke:[ye,Yu,Qn,Gh]}],stroke:[{stroke:["none",...G()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["start","end","right","left"],"inset-y":["inset-bs","inset-be","top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["ps","pe","pr","pl"],py:["pbs","pbe","pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["ms","me","mr","ml"],my:["mbs","mbe","mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-s","border-w-e","border-w-r","border-w-l"],"border-w-y":["border-w-bs","border-w-be","border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-s","border-color-e","border-color-r","border-color-l"],"border-color-y":["border-color-bs","border-color-be","border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-ms","scroll-me","scroll-mr","scroll-ml"],"scroll-my":["scroll-mbs","scroll-mbe","scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-ps","scroll-pe","scroll-pr","scroll-pl"],"scroll-py":["scroll-pbs","scroll-pbe","scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},v1=Zp(m1);function pn(...i){return v1(r0(i))}const h1=s0("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",{variants:{variant:{default:"bg-primary text-primary-foreground shadow hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",outline:"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-md px-3 text-xs",lg:"h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),jl=M.forwardRef(({className:i,variant:r,size:s,asChild:o=!1,...d},m)=>{const g=o?bp:"button";return M.createElement(g,{className:pn(h1({variant:r,size:s,className:i})),ref:m,...d})});jl.displayName="Button";const g1=s0("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",outline:"text-foreground"}},defaultVariants:{variant:"default"}});function Lu({className:i,variant:r,...s}){return M.createElement("div",{className:pn(g1({variant:r}),i),...s})}var Ts={exports:{}},Vu={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Yh;function y1(){if(Yh)return Vu;Yh=1;var i=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function s(o,d,m){var g=null;if(m!==void 0&&(g=""+m),d.key!==void 0&&(g=""+d.key),"key"in d){m={};for(var S in d)S!=="key"&&(m[S]=d[S])}else m=d;return d=m.ref,{$$typeof:i,type:o,key:g,ref:d!==void 0?d:null,props:m}}return Vu.Fragment=r,Vu.jsx=s,Vu.jsxs=s,Vu}var Lh;function b1(){return Lh||(Lh=1,Ts.exports=y1()),Ts.exports}var be=b1(),p1=Object.defineProperty,Ft=(i,r)=>p1(i,"name",{value:r,configurable:!0});function S1(i,r){const s=M.createContext(r);s.displayName=i+"Context";const o=Ft(m=>{const{children:g,...S}=m,O=M.useMemo(()=>S,Object.values(S));return be.jsx(s.Provider,{value:O,children:g})},"Provider");o.displayName=i+"Provider";function d(m,g={}){const{optional:S=!1}=g,O=M.useContext(s);if(O)return O;if(r!==void 0)return r;if(!S)throw new Error(`\`${m}\` must be used within \`${i}\``)}return Ft(d,"useContext"),[o,d]}Ft(S1,"createContext");function Va(i,r=[]){let s=[];function o(m,g){const S=M.createContext(g);S.displayName=m+"Context";const O=s.length;s=[...s,g];const x=Ft(h=>{var K;const{scope:R,children:D,...V}=h,Z=((K=R==null?void 0:R[i])==null?void 0:K[O])||S,Y=M.useMemo(()=>V,Object.values(V));return be.jsx(Z.Provider,{value:Y,children:D})},"Provider");x.displayName=m+"Provider";function z(h,R,D={}){var K;const{optional:V=!1}=D,Z=((K=R==null?void 0:R[i])==null?void 0:K[O])||S,Y=M.useContext(Z);if(Y)return Y;if(g!==void 0)return g;if(!V)throw new Error(`\`${h}\` must be used within \`${m}\``)}return Ft(z,"useContext"),[x,z]}Ft(o,"createContext");const d=Ft(()=>{const m=s.map(g=>M.createContext(g));return Ft(function(S){const O=(S==null?void 0:S[i])||m;return M.useMemo(()=>({[`__scope${i}`]:{...S,[i]:O}}),[S,O])},"useScope")},"createScope");return d.scopeName=i,[o,z0(d,...r)]}Ft(Va,"createContextScope");function z0(...i){const r=i[0];if(i.length===1)return r;const s=Ft(()=>{const o=i.map(d=>({useScope:d(),scopeName:d.scopeName}));return Ft(function(m){const g=o.reduce((S,{useScope:O,scopeName:x})=>{const h=O(m)[`__scope${x}`];return{...S,...h}},{});return M.useMemo(()=>({[`__scope${r.scopeName}`]:g}),[g])},"useComposedScopes")},"createScope");return s.scopeName=r.scopeName,s}Ft(z0,"composeContextScopes");var E1=Object.defineProperty,Xa=(i,r)=>E1(i,"name",{value:r,configurable:!0}),A0=!!(typeof window<"u"&&window.document&&window.document.createElement);function Yt(i,r,{checkForDefaultPrevented:s=!0}={}){return Xa(function(d){if(i==null||i(d),s===!1||!d||!d.defaultPrevented)return r==null?void 0:r(d)},"handleEvent")}Xa(Yt,"composeEventHandlers");function T1(i){var r;if(!A0)throw new Error("Cannot access window outside of the DOM");return((r=i==null?void 0:i.ownerDocument)==null?void 0:r.defaultView)??window}Xa(T1,"getOwnerWindow");function xs(i){if(!A0)throw new Error("Cannot access document outside of the DOM");return(i==null?void 0:i.ownerDocument)??document}Xa(xs,"getOwnerDocument");function N0(i,r=!1){const{activeElement:s}=xs(i);if(!(s!=null&&s.nodeName))return null;if(O0(s)&&s.contentDocument)return N0(s.contentDocument.body,r);if(r){const o=s.getAttribute("aria-activedescendant");if(o){const d=xs(s).getElementById(o);if(d)return d}}return s}Xa(N0,"getActiveElement");function O0(i){return i.tagName==="IFRAME"}Xa(O0,"isFrame");var Gl=globalThis!=null&&globalThis.document?M.useLayoutEffect:()=>{},_1=Object.defineProperty,C1=(i,r)=>_1(i,"name",{value:r,configurable:!0}),Vh=kn[" useEffectEvent ".trim().toString()],Xh=kn[" useInsertionEffect ".trim().toString()];function x0(i){if(typeof Vh=="function")return Vh(i);const r=M.useRef(()=>{throw new Error("Cannot call an event handler while rendering.")});return typeof Xh=="function"?Xh(()=>{r.current=i}):Gl(()=>{r.current=i}),M.useMemo(()=>((...s)=>{var o;return(o=r.current)==null?void 0:o.call(r,...s)}),[])}C1(x0,"useEffectEvent");var z1=Object.defineProperty,Xu=(i,r)=>z1(i,"name",{value:r,configurable:!0}),A1=kn[" useInsertionEffect ".trim().toString()]||Gl;function Dc({prop:i,defaultProp:r,onChange:s=Xu(()=>{},"onChange"),caller:o}){const[d,m,g]=R0({defaultProp:r,onChange:s}),S=i!==void 0,O=S?i:d,x=M.useCallback(z=>{var h;if(S){const R=M0(z)?z(i):z;R!==i&&((h=g.current)==null||h.call(g,R))}else m(z)},[S,i,m,g]);return[O,x]}Xu(Dc,"useControllableState");function R0({defaultProp:i,onChange:r}){const[s,o]=M.useState(i),d=M.useRef(s),m=M.useRef(r);return A1(()=>{m.current=r},[r]),M.useEffect(()=>{var g;d.current!==s&&((g=m.current)==null||g.call(m,s),d.current=s)},[s,d]),[s,o,m]}Xu(R0,"useUncontrolledState");function M0(i){return typeof i=="function"}Xu(M0,"isFunction");var Qh=Symbol("RADIX:SYNC_STATE");function N1(i,r,s,o){const{prop:d,defaultProp:m,onChange:g,caller:S}=r,O=d!==void 0,x=x0(g),z=[{...s,state:m}];o&&z.push(o);const[h,R]=M.useReducer((Y,K)=>{if(K.type===Qh)return{...Y,state:K.state};const H=i(Y,K);return O&&!Object.is(H.state,Y.state)&&x(H.state),H},...z),D=h.state,V=M.useRef(D);M.useEffect(()=>{V.current!==D&&(V.current=D,O||x(D))},[D,V,O]);const Z=M.useMemo(()=>d!==void 0?{...h,state:d}:h,[h,d]);return M.useEffect(()=>{O&&!Object.is(d,h.state)&&R({type:Qh,state:d})},[d,h.state,O]),[Z,R]}Xu(N1,"useControllableStateReducer");var O1=Object.defineProperty,x1=(i,r)=>O1(i,"name",{value:r,configurable:!0});function D0(i){const[r,s]=M.useState(void 0);return Gl(()=>{if(i){s({width:i.offsetWidth,height:i.offsetHeight});let o=0;const d=new ResizeObserver(m=>{if(!Array.isArray(m)||!m.length)return;const g=m[0];window.cancelAnimationFrame(o),o=window.requestAnimationFrame(()=>{let S,O;if("borderBoxSize"in g){const x=g.borderBoxSize,z=Array.isArray(x)?x[0]:x;S=z.inlineSize,O=z.blockSize}else S=i.offsetWidth,O=i.offsetHeight;s({width:S,height:O})})});return d.observe(i,{box:"border-box"}),()=>{window.cancelAnimationFrame(o),d.unobserve(i)}}else s(void 0)},[i]),r}x1(D0,"useSize");var R1=Object.defineProperty,Bl=(i,r)=>R1(i,"name",{value:r,configurable:!0});function w0(i,r){return M.useReducer((s,o)=>r[s][o]??s,i)}Bl(w0,"useStateMachine");var U0=Bl(i=>{const{present:r,children:s}=i,o=H0(r),d=typeof s=="function"?s({present:o.isPresent}):M.Children.only(s),m=j0(o.ref,G0(d));return typeof s=="function"||o.isPresent?M.cloneElement(d,{ref:m}):null},"Presence");function H0(i){const[r,s]=M.useState(),o=M.useRef(null),d=M.useRef(i),m=M.useRef("none"),g=M.useRef(void 0),S=i?"mounted":"unmounted",[O,x]=w0(S,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return M.useEffect(()=>{O==="mounted"?(m.current=g.current??La(o.current),g.current=void 0):m.current="none"},[O]),Gl(()=>{const z=o.current,h=d.current;if(h!==i){const D=m.current,V=La(z);i?(g.current=V,x("MOUNT")):V==="none"||(z==null?void 0:z.display)==="none"?x("UNMOUNT"):x(h&&D!==V?"ANIMATION_OUT":"UNMOUNT"),d.current=i}},[i,x]),Gl(()=>{if(r){let z;const h=r.ownerDocument.defaultView??window,R=Bl(V=>{const Y=La(o.current).includes(CSS.escape(V.animationName));if(V.target===r&&Y&&(x("ANIMATION_END"),!d.current)){const K=r.style.animationFillMode;r.style.animationFillMode="forwards",z=h.setTimeout(()=>{r.style.animationFillMode==="forwards"&&(r.style.animationFillMode=K)})}},"handleAnimationEnd"),D=Bl(V=>{V.target===r&&(m.current=La(o.current))},"handleAnimationStart");return r.addEventListener("animationstart",D),r.addEventListener("animationcancel",R),r.addEventListener("animationend",R),()=>{h.clearTimeout(z),r.removeEventListener("animationstart",D),r.removeEventListener("animationcancel",R),r.removeEventListener("animationend",R)}}else x("ANIMATION_END")},[r,x]),{isPresent:["mounted","unmountSuspended"].includes(O),ref:M.useCallback(z=>{if(z){const h=getComputedStyle(z);o.current=h,g.current=La(h)}else o.current=null;s(z)},[])}}Bl(H0,"usePresence");function Rs(i,r){if(typeof i=="function")return i(r);i!=null&&(i.current=r)}Bl(Rs,"setRef");function j0(...i){const r=M.useRef(i);return r.current=i,M.useCallback(s=>{const o=r.current;let d=!1;const m=o.map(g=>{const S=Rs(g,s);return!d&&typeof S=="function"&&(d=!0),S});if(d)return()=>{for(let g=0;gD1(i,"name",{value:r,configurable:!0}),U1=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Yl=U1.reduce((i,r)=>{const s=Zn(`Primitive.${r}`),o=M.forwardRef((d,m)=>{const{asChild:g,...S}=d,O=g?s:r;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),be.jsx(O,{...S,ref:m})});return o.displayName=`Primitive.${r}`,{...i,[r]:o}},{});function H1(i,r){i&&M1.flushSync(()=>i.dispatchEvent(r))}w1(H1,"dispatchDiscreteCustomEvent");var j1=Object.defineProperty,ql=(i,r)=>j1(i,"name",{value:r,configurable:!0}),Bs="Checkbox",[G1,XS]=Va(Bs),[B1,qs]=G1(Bs);function B0(i){const{__scopeCheckbox:r,checked:s,children:o,defaultChecked:d,disabled:m,form:g,name:S,onCheckedChange:O,required:x,value:z="on",internal_do_not_use_render:h}=i,[R,D]=Dc({prop:s,defaultProp:d??!1,onChange:O,caller:Bs}),[V,Z]=M.useState(null),[Y,K]=M.useState(null),[H,F]=M.useState(null),ue=V?!!g||!!V.closest("form"):!0,fe={checked:R,disabled:m,setChecked:D,control:V,setControl:Z,name:S,form:g,value:z,userClick:H,onUserClick:F,required:x,defaultChecked:Wt(d)?!1:d,isFormControl:ue,bubbleInput:Y,setBubbleInput:K};return be.jsx(B1,{scope:r,...fe,children:Y0(h)?h(fe):o})}ql(B0,"CheckboxProvider");var q1="CheckboxTrigger",Y1=M.forwardRef(ql(function({__scopeCheckbox:r,onKeyDown:s,onClick:o,...d},m){const{control:g,value:S,disabled:O,checked:x,required:z,setControl:h,setChecked:R,onUserClick:D,isFormControl:V,bubbleInput:Z}=qs(q1,r),Y=pl(m,h),K=M.useRef(x);return M.useEffect(()=>{const H=g==null?void 0:g.form;if(H){const F=ql(()=>R(K.current),"reset");return H.addEventListener("reset",F),()=>H.removeEventListener("reset",F)}},[g,R]),be.jsx(Yl.button,{type:"button",role:"checkbox","aria-checked":Wt(x)?"mixed":x,"aria-required":z,"data-state":Ys(x),"data-disabled":O?"":void 0,disabled:O,value:S,...d,ref:Y,onKeyDown:Yt(s,H=>{H.key==="Enter"&&H.preventDefault()}),onClick:Yt(o,H=>{const F=H.isPropagationStopped();D({requestedChecked:Wt(x)?!0:!x,hasConsumerStoppedPropagation:F}),R(ue=>Wt(ue)?!0:!ue),Z&&V&&(F||H.stopPropagation())})})},"CheckboxTrigger")),q0=M.forwardRef(ql(function(r,s){const{__scopeCheckbox:o,name:d,checked:m,defaultChecked:g,required:S,disabled:O,value:x,onCheckedChange:z,form:h,...R}=r;return be.jsx(B0,{__scopeCheckbox:o,checked:m,defaultChecked:g,disabled:O,required:S,onCheckedChange:z,name:d,form:h,value:x,internal_do_not_use_render:({isFormControl:D})=>be.jsxs(be.Fragment,{children:[be.jsx(Y1,{...R,ref:s,__scopeCheckbox:o}),D&&be.jsx(Q1,{__scopeCheckbox:o})]})})},"Checkbox")),L1="CheckboxIndicator",V1=M.forwardRef(ql(function(r,s){const{__scopeCheckbox:o,forceMount:d,...m}=r,g=qs(L1,o);return be.jsx(U0,{present:d||Wt(g.checked)||g.checked===!0,children:be.jsx(Yl.span,{"data-state":Ys(g.checked),"data-disabled":g.disabled?"":void 0,...m,ref:s,style:{pointerEvents:"none",...r.style}})})},"CheckboxIndicator")),X1="CheckboxBubbleInput",Q1=M.forwardRef(ql(function({__scopeCheckbox:r,onClick:s,...o},d){const{control:m,userClick:g,checked:S,defaultChecked:O,required:x,disabled:z,name:h,value:R,form:D,bubbleInput:V,setBubbleInput:Z}=qs(X1,r),Y=pl(d,Z),K=D0(m),H=M.useRef(!1),F=M.useRef(S),ue=M.useRef(g),fe=M.useRef(null);M.useEffect(()=>{const X=V;if(!X)return;const B=window.HTMLInputElement.prototype,J=Object.getOwnPropertyDescriptor(B,"checked").set;if(!J)return;const de=F.current!==S;F.current=S;const Re=g!==null&&g!==ue.current;if(ue.current=g,Re)fe.current=de?null:g,de&&(X.indeterminate=Wt(S),J.call(X,Wt(S)?!1:S)),X.dispatchEvent(new Event("click",{bubbles:!g.hasConsumerStoppedPropagation}));else if(de){const He=fe.current;fe.current=null;const Xe=(He==null?void 0:He.requestedChecked)===S;H.current=!0,X.indeterminate=Wt(S),J.call(X,Wt(S)?!1:S),X.dispatchEvent(new Event("click",{bubbles:!(Xe&&He.hasConsumerStoppedPropagation)})),H.current=!1}},[V,S,g]);const ae=M.useRef(Wt(S)?!1:S);return be.jsx(Yl.input,{type:"checkbox","aria-hidden":!0,defaultChecked:O??ae.current,required:x,disabled:z,name:h,value:R,form:D,...o,tabIndex:-1,ref:Y,onClick:Yt(s,X=>{H.current&&X.stopPropagation()}),style:{...o.style,...K,position:"absolute",pointerEvents:"none",opacity:0,margin:0,transform:"translateX(-100%)"}})},"CheckboxBubbleInput"));function Y0(i){return typeof i=="function"}ql(Y0,"isFunction");function Wt(i){return i==="indeterminate"}ql(Wt,"isIndeterminate");function Ys(i){return Wt(i)?"indeterminate":i?"checked":"unchecked"}ql(Ys,"getState");/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Z1=i=>i.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),L0=(...i)=>i.filter((r,s,o)=>!!r&&r.trim()!==""&&o.indexOf(r)===s).join(" ").trim();/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */var k1={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const K1=M.forwardRef(({color:i="currentColor",size:r=24,strokeWidth:s=2,absoluteStrokeWidth:o,className:d="",children:m,iconNode:g,...S},O)=>M.createElement("svg",{ref:O,...k1,width:r,height:r,stroke:i,strokeWidth:o?Number(s)*24/Number(r):s,className:L0("lucide",d),...S},[...g.map(([x,z])=>M.createElement(x,z)),...Array.isArray(m)?m:[m]]));/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Jn=(i,r)=>{const s=M.forwardRef(({className:o,...d},m)=>M.createElement(K1,{ref:m,iconNode:r,className:L0(`lucide-${Z1(i)}`,o),...d}));return s.displayName=`${i}`,s};/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Tc=Jn("ArrowUpRight",[["path",{d:"M7 7h10v10",key:"1tivn9"}],["path",{d:"M7 17 17 7",key:"1vkiza"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const J1=Jn("BookOpen",[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const $1=Jn("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Zh=Jn("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const kh=Jn("FileText",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const Kh=Jn("FolderTree",[["path",{d:"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"hod4my"}],["path",{d:"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"w4yl2u"}],["path",{d:"M3 5a2 2 0 0 0 2 2h3",key:"f2jnh7"}],["path",{d:"M3 3v13a2 2 0 0 0 2 2h3",key:"k8epm1"}]]);/** + * @license lucide-react v0.468.0 - ISC + * + * This source code is licensed under the ISC license. + * See the LICENSE file in the root directory of this source tree. + */const I1=Jn("GitBranch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]),Ms=M.forwardRef(({className:i,...r},s)=>M.createElement(q0,{ref:s,className:pn("grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",i),...r},M.createElement(V1,{className:pn("grid place-content-center text-current")},M.createElement($1,{className:"h-4 w-4"}))));Ms.displayName=q0.displayName;const V0=M.forwardRef(({className:i,...r},s)=>M.createElement("textarea",{className:pn("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",i),ref:s,...r}));V0.displayName="Textarea";var F1=Object.defineProperty,tt=(i,r)=>F1(i,"name",{value:r,configurable:!0});function X0(i){const r=i+"CollectionProvider",[s,o]=Va(r),[d,m]=s(r,{collectionRef:{current:null},itemMap:new Map}),g=tt(Z=>{const{scope:Y,children:K}=Z,H=M.useRef(null),F=M.useRef(new Map).current;return be.jsx(d,{scope:Y,itemMap:F,collectionRef:H,children:K})},"CollectionProvider");g.displayName=r;const S=i+"CollectionSlot",O=Zn(S),x=M.forwardRef((Z,Y)=>{const{scope:K,children:H}=Z,F=m(S,K),ue=pl(Y,F.collectionRef);return be.jsx(O,{ref:ue,children:H})});x.displayName=S;const z=i+"CollectionItemSlot",h="data-radix-collection-item",R=Zn(z),D=M.forwardRef((Z,Y)=>{const{scope:K,children:H,...F}=Z,ue=M.useRef(null),fe=pl(Y,ue),ae=m(z,K);return M.useEffect(()=>(ae.itemMap.set(ue,{ref:ue,...F}),()=>void ae.itemMap.delete(ue))),be.jsx(R,{[h]:"",ref:fe,children:H})});D.displayName=z;function V(Z){const Y=m(i+"CollectionConsumer",Z);return M.useCallback(()=>{const H=Y.collectionRef.current;if(!H)return[];const F=Array.from(H.querySelectorAll(`[${h}]`));return Array.from(Y.itemMap.values()).sort((ae,X)=>F.indexOf(ae.ref.current)-F.indexOf(X.ref.current))},[Y.collectionRef,Y.itemMap])}return tt(V,"useCollection"),[{Provider:g,Slot:x,ItemSlot:D},V,o]}tt(X0,"createCollection");var Jh=new WeakMap,Ke,qt,_c=(qt=class extends Map{constructor(s){super(s);_h(this,Ke);hs(this,Ke,[...super.keys()]),Jh.set(this,!0)}set(s,o){return Jh.get(this)&&!this.has(s)&&mt(this,Ke).push(s),super.set(s,o),this}insert(s,o,d){const m=this.has(o),g=m?this.size:this.size+1,S=Ls(s),O=S>=0?Math.min(S,g-1):Math.max(g+S,0);if(m?mt(this,Ke).indexOf(o)===O:O===this.size)return this.set(o,d),this;const x=mt(this,Ke).filter(h=>h!==o);x.splice(O,0,o);const z=x.map(h=>[h,h===o?d:this.get(h)]);this.clear();for(const[h,R]of z)this.set(h,R);return this}with(s,o,d){const m=new qt(this);return m.insert(s,o,d),m}before(s){const o=mt(this,Ke).indexOf(s)-1;if(!(o<0))return this.entryAt(o)}setBefore(s,o,d){const m=mt(this,Ke).indexOf(s);if(m===-1)return this;const g=mt(this,Ke).indexOf(o),S=g!==-1&&g=this.size&&(m=this.size-1),this.at(m)}keyFrom(s,o){const d=this.indexOf(s);if(d===-1)return;let m=d+o;return m<0&&(m=0),m>=this.size&&(m=this.size-1),this.keyAt(m)}find(s,o){let d=0;for(const m of this){if(Reflect.apply(s,o,[m,d,this]))return m;d++}}findIndex(s,o){let d=0;for(const m of this){if(Reflect.apply(s,o,[m,d,this]))return d;d++}return-1}filter(s,o){const d=[];let m=0;for(const g of this)Reflect.apply(s,o,[g,m,this])&&d.push(g),m++;return new qt(d)}map(s,o){const d=[];let m=0;for(const g of this)d.push([g[0],Reflect.apply(s,o,[g,m,this])]),m++;return new qt(d)}reduce(...s){const[o,d]=s,m=s.length>1;if(!m&&this.size===0)throw new TypeError("Reduce of empty OrderedDict with no initial value");let g=0,S=d;for(const O of this)g===0&&!m?S=O:S=Reflect.apply(o,this,[S,O,g,this]),g++;return S}reduceRight(...s){const[o,d]=s,m=s.length>1;if(!m&&this.size===0)throw new TypeError("Reduce of empty OrderedDict with no initial value");let g=d;for(let S=this.size-1;S>=0;S--){const O=this.entryAt(S);S===this.size-1&&!m?g=O:g=Reflect.apply(o,this,[g,O,S,this])}return g}sort(s){if(typeof s!="function")throw new TypeError("OrderedDict.sort requires a compare function");const o=[...this.entries()].sort(s);this.clear();for(const[d,m]of o)this.set(d,m);return this}toSorted(s){if(typeof s!="function")throw new TypeError("OrderedDict.toSorted requires a compare function");const o=[...this.entries()].sort(s);return new qt(o)}toReversed(){const s=new qt;for(let o=this.size-1;o>=0;o--){const d=this.keyAt(o),m=this.get(d);s.set(d,m)}return s}toSpliced(...s){const o=[...this.entries()];return o.splice(...s),new qt(o)}slice(s,o){const d=new qt;for(const m of mt(this,Ke).slice(s,o))d.set(m,this.get(m));return d}every(s,o){let d=0;for(const m of this){if(!Reflect.apply(s,o,[m,d,this]))return!1;d++}return!0}some(s,o){let d=0;for(const m of this){if(Reflect.apply(s,o,[m,d,this]))return!0;d++}return!1}},Ke=new WeakMap,tt(qt,"OrderedDict"),qt);function Ac(i,r){if("at"in Array.prototype)return Array.prototype.at.call(i,r);const s=Q0(i,r);return s===-1?void 0:i[s]}tt(Ac,"at");function Q0(i,r){const s=i.length,o=Ls(r),d=o>=0?o:s+o;return d<0||d>=s?-1:d}tt(Q0,"toSafeIndex");function Ls(i){return i!==i||i===0?0:Math.trunc(i)}tt(Ls,"toSafeInteger");function W1(i){const r=i+"CollectionProvider",[s,o]=Va(r),[d,m]=s(r);d.displayName=i+"CollectionStableContextProvider";const[g,S]=s(r);g.displayName=i+"CollectionStatefulContextProvider";const O=tt(({state:ae,...X})=>ae?be.jsx(z,{...X,state:ae}):be.jsx(x,{...X}),"CollectionProvider");O.displayName=r;const x=tt(ae=>{const X=H();return be.jsx(z,{...ae,state:X})},"CollectionInit");x.displayName=i+"CollectionInit";const z=tt(ae=>{const{scope:X,children:B,state:L}=ae,J=M.useRef(null),[de,Re]=M.useState(null),He=pl(J,Re),[Xe,Ce]=L,q=M.useRef(new _c),$=M.useCallback(()=>{const le=q.current;return K0(le)||le.sort(Nc),le},[]);return M.useEffect(()=>{if(!de)return;const le=J0(()=>{Ce(he=>{const G=he.toSorted(Nc);return G.some(([We],ht)=>he.keyAt(ht)!==We)?G:he})});return le.observe(de,{childList:!0,subtree:!0}),()=>{le.disconnect()}},[de,Ce]),be.jsx(d,{scope:X,collectionElementRef:He,collectionElementRefObject:J,getCollection:$,setCollection:Ce,registryRef:q,children:be.jsx(g,{scope:X,collectionElement:de,collection:Xe,children:B})})},"CollectionProviderImpl");z.displayName=i+"CollectionProviderImpl";const h=i+"CollectionSlot",R=Zn(h),D=M.forwardRef((ae,X)=>{const{scope:B,children:L}=ae,J=m(h,B),de=pl(X,J.collectionElementRef);return be.jsx(R,{ref:de,children:L})});D.displayName=h;const V=i+"CollectionItemSlot",Z="data-radix-collection-item",Y=Zn(V),K=M.forwardRef((ae,X)=>{const{scope:B,children:L,...J}=ae,de=M.useRef(null),Re=m(V,B),{setCollection:He,registryRef:Xe}=Re,Ce=M.useRef(J);Z0(Ce.current,J)||(Ce.current=J);const q=Ce.current,$=M.useCallback(G=>{const ze=Xe.current;G?ze.set(G,{...Ce.current,element:G}):de.current&&ze.delete(de.current)},[Xe]),le=pl(X,$,de);Gl(()=>{const G=de.current,ze=Xe.current;G&&ze.has(G)&&ze.set(G,{...q,element:G})},[q,Xe]);const he=M.useRef(null);return M.useEffect(()=>{const G=de.current,ze=he.current;((ze==null?void 0:ze.element)??null)===G&&(!G||(ze==null?void 0:ze.itemData)===q)||(he.current=G?{element:G,itemData:q}:null,He(We=>{const ht=new _c(We);return ze&&ze.element!==G&&ht.delete(ze.element),G&&ht.set(G,{...q,element:G}),ht.sort(Nc)}))}),M.useEffect(()=>()=>{const G=he.current;he.current=null,G&&He(ze=>{if(!ze.has(G.element))return ze;const We=new _c(ze);return We.delete(G.element),We})},[He]),be.jsx(Y,{[Z]:"",ref:le,children:L})});K.displayName=V;function H(){return M.useState(new _c)}tt(H,"useInitCollection");function F(ae){const{collection:X}=S(i+"CollectionConsumer",ae);return X}tt(F,"useCollection");function ue(ae){const{getCollection:X}=m(i+"CollectionConsumer",ae);return X}return tt(ue,"useGetCollection"),[{Provider:O,Slot:D,ItemSlot:K},{createCollectionScope:o,useCollection:F,useGetCollection:ue,useInitCollection:H}]}tt(W1,"createCollection");function Z0(i,r){if(i===r)return!0;if(typeof i!="object"||typeof r!="object"||i==null||r==null)return!1;const s=Object.keys(i),o=Object.keys(r);if(s.length!==o.length)return!1;for(const d of s)if(!Object.prototype.hasOwnProperty.call(r,d)||i[d]!==r[d])return!1;return!0}tt(Z0,"shallowEqual");function k0(i,r){return!!(r.compareDocumentPosition(i)&Node.DOCUMENT_POSITION_PRECEDING)}tt(k0,"isElementPreceding");function K0(i){let r;for(const s of i.keys()){if(r){const o=r.compareDocumentPosition(s);if(!(o&Node.DOCUMENT_POSITION_DISCONNECTED)&&o&Node.DOCUMENT_POSITION_PRECEDING)return!1}r=s}return!0}tt(K0,"isInDocumentOrder");function Nc(i,r){return!i[1].element||!r[1].element?0:k0(i[1].element,r[1].element)?-1:1}tt(Nc,"sortByDocumentPosition");function J0(i){return new MutationObserver(s=>{for(const o of s)if(o.type==="childList"){i();return}})}tt(J0,"getChildListObserver");var P1=Object.defineProperty,eS=(i,r)=>P1(i,"name",{value:r,configurable:!0}),tS=kn[" useId ".trim().toString()]||(()=>{}),lS=0;function Vs(i){const[r,s]=M.useState(tS());return Gl(()=>{i||s(o=>o??String(lS++))},[i]),i||(r?`radix-${r}`:"")}eS(Vs,"useId");var nS=Object.defineProperty,aS=(i,r)=>nS(i,"name",{value:r,configurable:!0}),$h=kn[" useInsertionEffect ".trim().toString()];function $0(i){const r=M.useRef(i);return typeof $h=="function"?$h(()=>{r.current=i}):Gl(()=>{r.current=i}),M.useMemo(()=>((...s)=>{var o;return(o=r.current)==null?void 0:o.call(r,...s)}),[])}aS($0,"useCallbackRef");var uS=Object.defineProperty,iS=(i,r)=>uS(i,"name",{value:r,configurable:!0}),cS={LTR:"ltr"},oS=M.createContext(void 0);function Xs(i){const r=M.useContext(oS);return i||r||cS.LTR}iS(Xs,"useDirection");var rS=Object.defineProperty,Qs=(i,r)=>rS(i,"name",{value:r,configurable:!0}),_s=!1;function I0(){const[i,r]=M.useState(_s);return M.useEffect(()=>{_s||(_s=!0,r(!0))},[]),i}Qs(I0,"useIsHydrated");var F0=kn[" useSyncExternalStore ".trim().toString()];function W0(){return()=>{}}Qs(W0,"subscribe");function P0(){return F0(W0,()=>!0,()=>!1)}Qs(P0,"useIsHydratedModern");var sS=typeof F0=="function"?P0:I0,fS=Object.defineProperty,$n=(i,r)=>fS(i,"name",{value:r,configurable:!0}),Cs="rovingFocusGroup.onEntryFocus",dS={bubbles:!1,cancelable:!0},wc="RovingFocusGroup",[Ds,eg,mS]=X0(wc),[vS,tg]=Va(wc,[mS]),Ih={Vertical:"vertical",Horizontal:"horizontal"},hS={RTL:"rtl"},[gS,yS]=vS(wc),bS=M.forwardRef($n(function(r,s){return be.jsx(Ds.Provider,{scope:r.__scopeRovingFocusGroup,children:be.jsx(Ds.Slot,{scope:r.__scopeRovingFocusGroup,children:be.jsx(pS,{...r,ref:s})})})},"RovingFocusGroup")),pS=M.forwardRef($n(function(r,s){const{__scopeRovingFocusGroup:o,orientation:d,loop:m=!1,dir:g,currentTabStopId:S,defaultCurrentTabStopId:O,onCurrentTabStopIdChange:x,onEntryFocus:z,preventScrollOnEntryFocus:h=!1,...R}=r,D=M.useRef(null),V=pl(s,D),Z=Xs(g),[Y,K]=Dc({prop:S,defaultProp:O??null,onChange:x,caller:wc}),[H,F]=M.useState(!1),ue=$0(z),fe=eg(o),ae=M.useRef(!1),[X,B]=M.useState(0);return M.useEffect(()=>{const L=D.current;if(L)return L.addEventListener(Cs,ue),()=>L.removeEventListener(Cs,ue)},[ue]),be.jsx(gS,{scope:o,orientation:d,dir:Z,loop:m,currentTabStopId:Y,onItemFocus:M.useCallback(L=>K(L),[K]),onItemShiftTab:M.useCallback(()=>F(!0),[]),onFocusableItemAdd:M.useCallback(()=>B(L=>L+1),[]),onFocusableItemRemove:M.useCallback(()=>B(L=>L-1),[]),children:be.jsx(Yl.div,{tabIndex:H||X===0?-1:0,"data-orientation":d,...R,ref:V,style:{outline:"none",...r.style},onMouseDown:Yt(r.onMouseDown,()=>{ae.current=!0}),onFocus:Yt(r.onFocus,L=>{const J=!ae.current;if(L.target===L.currentTarget&&J&&!H){const de=new CustomEvent(Cs,dS);if(L.currentTarget.dispatchEvent(de),!de.defaultPrevented){const Re=fe().filter($=>$.focusable),He=Re.find($=>$.active),Xe=Re.find($=>$.id===Y),q=[He,Xe,...Re].filter(Boolean).map($=>$.ref.current);Zs(q,h)}}ae.current=!1}),onBlur:Yt(r.onBlur,()=>F(!1))})})},"RovingFocusGroupImpl")),SS="RovingFocusGroupItem",ES=M.forwardRef($n(function(r,s){const{__scopeRovingFocusGroup:o,focusable:d=!0,active:m=!1,tabStopId:g,children:S,...O}=r,x=Vs(),z=g||x,h=yS(SS,o),R=h.currentTabStopId===z,D=eg(o),{onFocusableItemAdd:V,onFocusableItemRemove:Z,currentTabStopId:Y}=h,K=sS();return Gl(()=>{if(!(!K||!d))return V(),()=>Z()},[K,d,V,Z]),M.useEffect(()=>{if(!(K||!d))return V(),()=>Z()},[K,d,V,Z]),be.jsx(Ds.ItemSlot,{scope:o,id:z,focusable:d,active:m,children:be.jsx(Yl.span,{tabIndex:R?0:-1,"data-orientation":h.orientation,...O,ref:s,onMouseDown:Yt(r.onMouseDown,H=>{d?h.onItemFocus(z):H.preventDefault()}),onFocus:Yt(r.onFocus,()=>h.onItemFocus(z)),onKeyDown:Yt(r.onKeyDown,H=>{if(H.key==="Tab"&&H.shiftKey){h.onItemShiftTab();return}if(H.target!==H.currentTarget)return;const F=ng(H,h.orientation,h.dir);if(F!==void 0){if(H.metaKey||H.ctrlKey||H.altKey||H.shiftKey)return;H.preventDefault();let fe=D().filter(ae=>ae.focusable).map(ae=>ae.ref.current);if(F==="last")fe.reverse();else if(F==="prev"||F==="next"){F==="prev"&&fe.reverse();const ae=fe.indexOf(H.currentTarget);fe=h.loop?ag(fe,ae+1):fe.slice(ae+1)}setTimeout(()=>Zs(fe))}}),children:typeof S=="function"?S({isCurrentTabStop:R,hasTabStop:Y!=null}):S})})},"RovingFocusGroupItem")),TS={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function lg(i,r){return r!==hS.RTL?i:i==="ArrowLeft"?"ArrowRight":i==="ArrowRight"?"ArrowLeft":i}$n(lg,"getDirectionAwareKey");function ng(i,r,s){const o=lg(i.key,s);if(!(r===Ih.Vertical&&["ArrowLeft","ArrowRight"].includes(o))&&!(r===Ih.Horizontal&&["ArrowUp","ArrowDown"].includes(o)))return TS[o]}$n(ng,"getFocusIntent");function Zs(i,r=!1){const s=document.activeElement;for(const o of i)if(o===s||(o.focus({preventScroll:r}),document.activeElement!==s))return}$n(Zs,"focusFirst");function ag(i,r){return i.map((s,o)=>i[(r+o)%i.length])}$n(ag,"wrapArray");var _S=Object.defineProperty,Qa=(i,r)=>_S(i,"name",{value:r,configurable:!0}),ug={Automatic:"automatic",Manual:"manual"},ks="Tabs",[CS,QS]=Va(ks,[tg]),ig=tg(),[zS,Ks]=CS(ks),AS=M.forwardRef(Qa(function(r,s){const{__scopeTabs:o,value:d,onValueChange:m,defaultValue:g,orientation:S="horizontal",dir:O,activationMode:x=ug.Automatic,...z}=r,h=Xs(O),[R,D]=Dc({prop:d,onChange:m,defaultProp:g??"",caller:ks});return be.jsx(zS,{scope:o,baseId:Vs(),value:R,onValueChange:D,orientation:S,dir:h,activationMode:x,children:be.jsx(Yl.div,{dir:h,"data-orientation":S,...z,ref:s})})},"Tabs")),NS="TabsList",cg=M.forwardRef(Qa(function(r,s){const{__scopeTabs:o,loop:d=!0,...m}=r,g=Ks(NS,o),S=ig(o);return be.jsx(bS,{asChild:!0,...S,orientation:g.orientation,dir:g.dir,loop:d,children:be.jsx(Yl.div,{role:"tablist","aria-orientation":g.orientation,...m,ref:s})})},"TabsList")),OS="TabsTrigger",og=M.forwardRef(Qa(function(r,s){const{__scopeTabs:o,value:d,disabled:m=!1,...g}=r,S=Ks(OS,o),O=ig(o),x=Js(S.baseId,d),z=$s(S.baseId,d),h=d===S.value;return be.jsx(ES,{asChild:!0,...O,focusable:!m,active:h,children:be.jsx(Yl.button,{type:"button",role:"tab","aria-selected":h,"aria-controls":z,"data-state":h?"active":"inactive","data-disabled":m?"":void 0,disabled:m,id:x,...g,ref:s,onMouseDown:Yt(r.onMouseDown,R=>{!m&&R.button===0&&R.ctrlKey===!1?(R.currentTarget.focus(),S.onValueChange(d)):R.preventDefault()}),onKeyDown:Yt(r.onKeyDown,R=>{m||R.target!==R.currentTarget||[" ","Enter"].includes(R.key)&&S.onValueChange(d)}),onFocus:Yt(r.onFocus,()=>{const R=S.activationMode!==ug.Manual;!h&&!m&&R&&S.onValueChange(d)})})})},"TabsTrigger")),xS="TabsContent",rg=M.forwardRef(Qa(function(r,s){const{__scopeTabs:o,value:d,forceMount:m,children:g,...S}=r,O=Ks(xS,o),x=Js(O.baseId,d),z=$s(O.baseId,d),h=d===O.value,R=M.useRef(h);return M.useEffect(()=>{const D=requestAnimationFrame(()=>R.current=!1);return()=>cancelAnimationFrame(D)},[]),be.jsx(U0,{present:m||h,children:({present:D})=>be.jsx(Yl.div,{"data-state":h?"active":"inactive","data-orientation":O.orientation,role:"tabpanel","aria-labelledby":x,hidden:!D,id:z,tabIndex:0,...S,ref:s,style:{...r.style,animationDuration:R.current?"0s":void 0},children:D&&g})})},"TabsContent"));function Js(i,r){return`${i}-trigger-${r}`}Qa(Js,"makeTriggerId");function $s(i,r){return`${i}-content-${r}`}Qa($s,"makeContentId");const RS=AS,sg=M.forwardRef(({className:i,...r},s)=>M.createElement(cg,{ref:s,className:pn("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",i),...r}));sg.displayName=cg.displayName;const Oc=M.forwardRef(({className:i,...r},s)=>M.createElement(og,{ref:s,className:pn("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",i),...r}));Oc.displayName=og.displayName;const xc=M.forwardRef(({className:i,...r},s)=>M.createElement(rg,{ref:s,className:pn("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",i),...r}));xc.displayName=rg.displayName;function MS(i){const r=i.trim().split(/\s+/).filter(Boolean);if(!r.length||r.length>3)throw Error("Enter one to three public GitHub repository URLs.");return[...new Set(r.map(s=>{const o=new URL(s),d=o.pathname.match(/^\/([\w.-]+)\/([\w.-]+)\/?$/);if(o.protocol!=="https:"||o.hostname!=="github.com"||o.username||o.password||o.search||o.hash||!d)throw Error("Use https://github.com/owner/repository URLs without branches or query strings.");return d[1]+"/"+d[2].replace(/\.git$/,"")}))]}function DS(i){return/(^|\/)(AGENTS|CLAUDE|CONTRIBUTING|copilot-instructions|instructions|rules)\.md$/i.test(i)||/(^|\/)\.cursor\/rules\/[^/]+\.mdc$/i.test(i)}function wS(i,r,s,o){let d=!1;const m=[];return i.split(/\r?\n/).forEach((g,S)=>{if(/^\s*(```|~~~)/.test(g)){d=!d;return}if(d)return;const O=g.replace(/^\s*(?:[-*+]\s+|\d+[.)]\s+)/,"").trim();if(O.length<15||O.length>800||/^\s*[#>|]/.test(g)||!(/\b(must|should|always|never|avoid|prefer|ensure|do not|don't|required)\b/i.test(O)||/^(use|run|keep|write|test|check|add|follow|make|include|read|verify)\b/i.test(O)))return;const x=s.includes("/")||/`|\b(npm|pnpm|yarn|cargo|pytest|docker|this repo|this project|directory|package|component)\b|\.[a-z]{1,4}\b|https?:\/\//i.test(O);m.push({text:g.trim(),repo:r,path:s,sha:o,line:S+1,kind:x?"project":"reusable",url:`https://github.com/${r}/blob/${o}/${s.split("/").map(encodeURIComponent).join("/")}#L${S+1}`,flags:[]})}),m}function US(i){const r=new Map;for(const s of i){const o=s.text.toLowerCase().replace(/[^a-z0-9 ]/g,"").replace(/\s+/g," ").trim();if(r.has(o)){s.flags.push("Duplicate");for(const d of r.get(o))d.flags.includes("Duplicate")||d.flags.push("Duplicate");r.get(o).push(s)}else r.set(o,[s])}for(let s=0;s/\b(never|not|avoid|don't)\b/i.test(h),S=h=>{var R;return new Set(((R=h.toLowerCase().match(/[a-z]{4,}/g))==null?void 0:R.filter(D=>!["never","always","should","must","avoid","prefer"].includes(D)))||[])},O=S(d.text),x=S(m.text),z=[...O].filter(h=>x.has(h)).length;if(g(d.text)!==g(m.text)&&z>=2&&z/Math.max(O.size,x.size)>.5)for(const h of[d,m])h.flags.includes("Possible conflict")||h.flags.push("Possible conflict")}return i}function HS(i){return!/(^|\/)(node_modules|vendor|\.git|logs?|conversations?|chats?|secrets?)(\/|$)|(^|\/)(\.env[^/]*|[^/]*\.(pem|key)|credentials[^/]*)$/i.test(i)}function jS(i){return i.split(` +`).map(r=>/\b(?:gh[pousr]_[A-Za-z0-9_]{15,}|github_pat_[A-Za-z0-9_]+|sk-[A-Za-z0-9_-]{12,}|AKIA[A-Z0-9]{16})|-----BEGIN .*PRIVATE KEY-----|\b(?:password|api[_-]?key|access[_-]?token|secret)\s*[:=]\s*["']?[^\s"']{8,}/i.test(r)?"[Sensitive-looking line withheld]":r).join(` +`)}function Fh(i){return/(^|\/)SKILL\.md$/i.test(i)?"skill":DS(i)?"instruction":/(^|\/)(docs?|guides?)\/.*\.md$|(^|\/)(README|ARCHITECTURE)\.md$/i.test(i)?"doc":/(^|\/)(\.husky\/[^/]+|\.githooks\/[^/]+|\.pre-commit-config\.yaml|\.claude\/settings\.json)$/.test(i)?"hook":null}const GS=(i,r,s)=>`https://github.com/${i}/blob/${r}/${s.split("/").map(encodeURIComponent).join("/")}`;async function Cc(i){const r=await fetch("https://api.github.com/"+i,{credentials:"omit",headers:{Accept:"application/vnd.github+json"}});if(!r.ok)throw Error(r.status===403||r.status===429?"GitHub public API rate limit reached. Try later.":`GitHub ${r.status}: unavailable.`);return r.json()}async function BS(i,r){const s=MS(i);if(s.length!==1)throw Error("Choose one target project per architecture proposal.");const o=s[0];r("Pinning the public repository…");const d=await Cc("repos/"+o);if(d.private)throw Error("Only public repositories are supported.");const g=(await Cc(`repos/${o}/commits/${encodeURIComponent(d.default_branch)}`)).sha,S=await Cc(`repos/${o}/git/trees/${g}?recursive=1`),O=S.tree.filter(H=>HS(H.path)),x=[];S.truncated&&x.push("GitHub returned a truncated tree. Recommendations have incomplete structural coverage.");const z=O.filter(H=>H.type==="blob"&&Fh(H.path)).map(H=>({...H,kind:Fh(H.path),url:GS(o,g,H.path)})),h={instruction:0,skill:1,doc:2,hook:3};z.sort((H,F)=>h[H.kind]-h[F.kind]||H.path.split("/").length-F.path.split("/").length||H.path.localeCompare(F.path));const R=[];let D=0;const V={instruction:12,skill:6,doc:6,hook:4},Z={instruction:0,skill:0,doc:0,hook:0};for(const H of z){if(Z[H.kind]>=V[H.kind]||H.size>65536||D+H.size>524288){H.omitted=!0;continue}Z[H.kind]++,r("Reading "+H.path+"…");try{const F=await Cc(`repos/${o}/git/blobs/${H.sha}`);if(F.encoding!=="base64"||F.size>65536)throw Error("Unsupported size/encoding");D+=F.size;const ue=new TextDecoder("utf-8",{fatal:!0}).decode(Uint8Array.from(atob(F.content.replace(/\s/g,"")),ae=>ae.charCodeAt(0))),fe=jS(ue);R.push({...H,text:fe,redacted:fe!==ue}),fe!==ue&&x.push(H.path+": sensitive-looking lines withheld.")}catch(F){H.omitted=!0,x.push(H.path+": "+F.message)}}const Y=z.filter(H=>H.omitted).length;Y&&x.push(`${Y} inventoried files not read (limits or read errors). Links are evidence of existence, not reviewed contents.`);let K=R.filter(H=>H.kind==="instruction"||H.kind==="skill").flatMap(H=>wS(H.text,o,H.path,g).map(F=>({...F,sourceKind:H.kind})));return K.length>240&&x.push(`${K.length-240} candidate lines omitted beyond 240-line limit.`),K=US(K.slice(0,240)),K.length||x.push("No instruction-like lines found in the supported files read. No project conventions will be invented."),{repo:o,sha:g,tree:O,inventory:z,files:R,rows:K,notes:x}}function zc(i){const r=i.path;if(i.sourceKind==="skill"||/^\.cursor\/rules\//.test(r))return null;if(!r.includes("/"))return"";const s=r.slice(0,r.lastIndexOf("/"));return/^\.github$|^\.cursor\/rules$/.test(s)?"":s}const zs=i=>` +${i.text} +`;function qS(i,r){const s=r.filter(D=>zc(D)!==null&&/\b(run|test|verify|check)\b/i.test(D.text)),o=[...new Set(r.filter(D=>D.sourceKind==="skill").map(D=>D.path))].map(D=>`- [${D}](${D}) — existing skill retained; review its trigger.`);s.length&&o.push("- [Project checks](agents/skills/project-checks/SKILL.md) — proposed workflow; review trigger and scope.");const d=[],m=r.filter(D=>zc(D)===""),g=[...new Set(r.map(zc).filter(Boolean))],S=(D,V,Z)=>{const Y=i.files.find(H=>H.path===D),K=i.tree.some(H=>H.path===D);d.push({path:D,content:V,reason:Z,original:(Y==null?void 0:Y.text)??null,exists:K,blocked:K&&(!Y||Y.redacted)})},x=i.inventory.filter(D=>D.kind==="doc").slice(0,8).map(D=>`- [${D.path}](${D.url}) — ${i.files.some(V=>V.path===D.path)?"read; retain as source of truth":"inventoried only; review before adoption"}`).join(` +`),z=` + +`;S("AGENTS.md",`# Project instructions + +${z}## Reviewed root conventions + +${m.length?m.map(zs).join(` +`):` +`} +## Scoped instructions + +${g.length?g.map(D=>`- [${D}/AGENTS.md](${D}/AGENTS.md) — applies inside ${D}/ only.`).join(` +`):"No scoped conventions selected."} + +## Source-of-truth documentation + +${x||"No supported documentation discovered in the tree returned."} + +## Task skills + +${o.length?o.join(` +`):"No workflow skill proposed without selected workflow evidence."} +`,"Root routing, selected root evidence, and linked documentation. Nested rules are not promoted to root.");for(const D of g)S(D+"/AGENTS.md",`# Instructions for ${D}/ + +${z}Scope: files below ${D}/. Read root AGENTS.md first; review any conflicting root and local rules explicitly. + +${r.filter(V=>zc(V)===D).map(zs).join(` +`)}`,"Original directory scope retained; review inherited conflicts.");const h=[...new Set(r.filter(D=>D.sourceKind==="skill"||/^\.cursor\/rules\//.test(D.path)).map(D=>D.path))];for(const D of h){const V=i.files.find(Z=>Z.path===D);S(D,V.text,"Existing skill or Cursor rule retained in place, including trigger/glob frontmatter. No assumptions about global scope.")}s.length&&S("agents/skills/project-checks/SKILL.md",`--- +name: project-checks +description: Review and perform the documented project checks when changing this repository. +--- + +${z}## Trigger and boundaries (proposed) + +Use when validating a change. Each excerpt retains its original scope; do not run commands outside that scope. Resolve possible conflicts before executing. This proposal is not an executable hook. + +## Reviewed workflow evidence + +${s.map(zs).join(` +`)}`,"Suggested task skill built only from selected check/workflow lines; trigger is generated and must be reviewed.");const R=i.files.find(D=>D.path==="CLAUDE.md");return S("CLAUDE.md",(R?R.text+` + +`:"")+` +@AGENTS.md +`,"Add a root reference while preserving any read existing CLAUDE.md."),d}function As(i){return i.blocked?"PREVIEW BLOCKED: existing file was not safely read. Do not replace it. Fetch and review its contents before applying.":i.original===i.content?"No change (existing skill retained).":`--- ${i.exists?"a/"+i.path:"/dev/null"} ++++ b/${i.path} +@@ -${i.original?`1,${i.original.split(` +`).length}`:"0,0"} +1,${i.content.split(` +`).length} @@ +`+(i.original?i.original.split(` +`).map(r=>"-"+r).join(` +`)+` +`:"")+i.content.split(` +`).map(r=>"+"+r).join(` +`)}function YS(i){const r=new TextEncoder,s=[];for(const o of i){const d=r.encode(o.content),m=new Uint8Array(512),g=(z,h,R)=>m.set(r.encode(z).slice(0,R),h);let S=o.path,O="";if(r.encode(S).length>100){const z=S.lastIndexOf("/");if(O=S.slice(0,z),S=S.slice(z+1),r.encode(S).length>100||r.encode(O).length>155)throw Error("Export path too long for tar: "+o.path)}g(S,0,100),g("0000644\0",100,8),g("0000000\0",108,8),g("0000000\0",116,8),g(d.length.toString(8).padStart(11,"0")+"\0",124,12),g("00000000000\0",136,12),m.fill(32,148,156),g("0",156,1),g("ustar\0",257,6),g("00",263,2),g(O,345,155);const x=m.reduce((z,h)=>z+h,0);g(x.toString(8).padStart(6,"0")+"\0 ",148,8),s.push(m,d,new Uint8Array((512-d.length%512)%512))}return s.push(new Uint8Array(1024)),new Blob(s,{type:"application/x-tar"})}function Wh(i,r){const s=URL.createObjectURL(i),o=document.createElement("a");o.href=s,o.download=r,o.click(),setTimeout(()=>URL.revokeObjectURL(s),2e3)}function LS(){const[i,r]=M.useState(""),[s,o]=M.useState(null),[d,m]=M.useState("Public GitHub only. Research stays in this browser."),[g,S]=M.useState(!1),[O,x]=M.useState(new Set),[z,h]=M.useState("evidence"),[R,D]=M.useState(0),[V,Z]=M.useState(!1),[Y,K]=M.useState("all"),H=(s==null?void 0:s.rows.filter((L,J)=>O.has(J)))||[],F=s?qS(s,H):[],ue=F[Math.min(R,Math.max(0,F.length-1))],fe=F.filter(L=>!L.blocked),ae=()=>{Z(!1),D(0)};async function X(L=i){S(!0),o(null),x(new Set),ae(),h("evidence");try{const J=await BS(L,m);o(J),m(`Research complete · ${J.files.length} files read · ${J.rows.length} candidate lines · review evidence below.`)}catch(J){m(J.message)}finally{S(!1)}}const B="https://github.com/teahubxyz/time/issues/new?"+new URLSearchParams({template:"early-access.yml",title:"Early access: AgentLore",venture:"agentlore",use:`Project: ${i} +Desired instruction architecture / use case: + +Coverage gaps: + +No private details or credentials included.`});return N.createElement(N.Fragment,null,N.createElement("header",{className:"masthead"},N.createElement("a",{className:"wordmark",href:"./"},N.createElement(J1,{size:22}),"AgentLore",N.createElement("span",null,"FIELDNOTES / 02")),N.createElement("a",{className:"gallery",href:"https://teahubxyz.github.io/time/ventures/",target:"_blank",rel:"noreferrer"},"A NotPlanned experiment ",N.createElement(Tc,{size:14}))),N.createElement("main",null,N.createElement("section",{className:"opening"},N.createElement("div",null,N.createElement("p",{className:"eyebrow"},"PROJECT KNOWLEDGE, GIVEN A HOME"),N.createElement("h1",null,"Every project has lore.",N.createElement("br",null),N.createElement("em",null,"Give yours a map.")),N.createElement("p",{className:"lede"},"From scattered instructions to a considered architecture. Research a repository, review the evidence, and shape the agent environment that belongs there."),N.createElement("div",{className:"principles"},N.createElement("span",null,"01 / Research"),N.createElement("span",null,"02 / Review"),N.createElement("span",null,"03 / Carry"))),N.createElement("div",{className:"specimen","aria-label":"Illustrative instruction architecture, not scan results"},N.createElement("div",{className:"specimen-label"},N.createElement(I1,{size:15}),"A POSSIBLE SHAPE"),N.createElement("pre",null,`project/ +├── AGENTS.md compass +├── frontend/ +│ └── AGENTS.md local lore +├── backend/ +│ └── AGENTS.md local lore +└── agents/skills/ + └── checks/SKILL.md ritual`),N.createElement("p",null,"Scope the rules. Link the knowledge.",N.createElement("br",null),"Keep the human in the loop."))),N.createElement("section",{className:"research-panel","aria-labelledby":"research-title"},N.createElement("div",{className:"panel-heading"},N.createElement("span",{className:"eyebrow"},"THE FIELD DESK"),N.createElement(Lu,{variant:"outline"},"Read-only taste test")),N.createElement("div",{className:"scan-layout"},N.createElement("div",null,N.createElement("h2",{id:"research-title"},"Start with one project."),N.createElement("p",null,"We inspect its structure, instructions, docs, skills, and supported hooks. No token. No installation.")),N.createElement("form",{onSubmit:L=>{L.preventDefault(),X()}},N.createElement("label",{htmlFor:"repository"},"Public GitHub repository URL"),N.createElement(V0,{id:"repository",rows:2,placeholder:"https://github.com/openai/codex",value:i,onChange:L=>r(L.target.value),required:!0,disabled:g}),N.createElement("div",{className:"actions"},N.createElement(jl,{type:"submit",disabled:g},g?"Researching…":"Research this project"," ",N.createElement(Tc,{size:16})),N.createElement(jl,{type:"button",variant:"outline",disabled:g,onClick:()=>{r("https://github.com/openai/codex"),X("https://github.com/openai/codex")}},"Try openai/codex")))),N.createElement("p",{className:"status",role:"status","aria-live":"polite"},d)),s&&N.createElement("section",{className:"findings"},N.createElement("div",{className:"findings-title"},N.createElement("div",null,N.createElement("span",{className:"eyebrow"},"YOUR PROJECT AT A GLANCE"),N.createElement("h2",null,s.repo)),N.createElement("a",{href:`https://github.com/${s.repo}/tree/${s.sha}`,target:"_blank",rel:"noreferrer",className:"commit"},s.sha.slice(0,12)," ↗")),N.createElement("div",{className:"stats"},N.createElement("span",null,N.createElement("strong",null,s.tree.filter(L=>L.type==="tree").length)," directories inventoried"),N.createElement("span",null,N.createElement("strong",null,s.files.length)," files read"),N.createElement("span",null,N.createElement("strong",null,O.size)," rules selected"),N.createElement("span",null,N.createElement("strong",null,F.length)," proposed files")),N.createElement(RS,{value:z,onValueChange:h},N.createElement(sg,{className:"desk-tabs","aria-label":"Research stages"},N.createElement(Oc,{value:"evidence"},"1. Evidence"),N.createElement(Oc,{value:"architecture"},"2. Architecture"),N.createElement(Oc,{value:"export"},"3. Review & export")),N.createElement(xc,{value:"evidence"},N.createElement("div",{className:"evidence-grid"},N.createElement("aside",{className:"inventory"},N.createElement("h3",null,"Coverage ledger"),["instruction","skill","doc","hook"].map(L=>N.createElement("div",{key:L},N.createElement("h4",null,L,"s ",N.createElement(Lu,{variant:"secondary"},s.inventory.filter(J=>J.kind===L).length)),s.inventory.filter(J=>J.kind===L).length?s.inventory.filter(J=>J.kind===L).map(J=>N.createElement("a",{key:J.path,href:J.url,target:"_blank",rel:"noreferrer"},J.path,N.createElement("small",null,s.files.some(de=>de.path===J.path)?"read":"not read"))):N.createElement("p",{className:"muted"},"No supported ",L,"s found in returned tree."))),N.createElement("h4",null,"Gaps & limitations"),s.notes.map(L=>N.createElement("p",{className:"note",key:L},L)),N.createElement("p",{className:"muted"},"Hooks are inventoried/read as evidence only. No hook is executed or generated. Conversation logs: not accessed; explicit opt-in and filtering are future work.")),N.createElement("div",{className:"candidates"},N.createElement("h3",null,"Select the durable conventions."),N.createElement("p",null,"Exact excerpts, not inferred truth. Classification and conflict detection are heuristic. Nested scope stays nested. Nothing starts selected."),N.createElement("div",{className:"actions"},N.createElement("label",{htmlFor:"filter"},"Show"),N.createElement("select",{id:"filter",value:Y,onChange:L=>K(L.target.value)},N.createElement("option",{value:"all"},"All candidates"),N.createElement("option",{value:"reusable"},"Likely reusable"),N.createElement("option",{value:"project"},"Project-specific")),N.createElement(jl,{variant:"outline",onClick:()=>{x(new Set),ae()}},"Clear selection")),!s.rows.length&&N.createElement("p",{className:"note"},"No candidates. The architecture contains routing scaffolds only; no invented project rules."),s.rows.map((L,J)=>(Y==="all"||L.kind===Y)&&N.createElement("article",{className:"rule",key:J},N.createElement(Ms,{id:"rule-"+J,checked:O.has(J),onCheckedChange:de=>{x(Re=>{const He=new Set(Re);return de?He.add(J):He.delete(J),He}),ae()}}),N.createElement("div",null,N.createElement("label",{htmlFor:"rule-"+J},L.text),N.createElement("div",{className:"rule-meta"},N.createElement(Lu,{variant:"outline"},L.kind==="reusable"?"Likely reusable":"Project-specific"),L.flags.map(de=>N.createElement(Lu,{className:"warning",key:de,variant:"secondary"},de)),N.createElement("a",{href:L.url,target:"_blank",rel:"noreferrer"},L.path,":",L.line," ↗"))))),N.createElement(jl,{className:"next-step",onClick:()=>h("architecture")},"Shape the architecture ",N.createElement(Kh,{size:16}))))),N.createElement(xc,{value:"architecture"},N.createElement("div",{className:"architecture-grid"},N.createElement("div",{className:"file-tree"},N.createElement("h3",null,N.createElement(Kh,{size:18}),"Proposed environment"),N.createElement("p",null,"Based on ",O.size," selected lines. Generated routing and skill triggers are labeled proposals."),F.map((L,J)=>N.createElement("button",{key:L.path,className:"file-node "+(J===R?"active":""),onClick:()=>D(J)},N.createElement(kh,{size:15}),N.createElement("span",null,L.path),N.createElement("small",null,L.blocked?"blocked":L.exists?"existing":"new"))),N.createElement("div",{className:"note"},"Only scopes with selected evidence receive nested AGENTS.md. Existing skills remain in place. Workflow skills require selected check evidence; no speculative commands.")),N.createElement("div",{className:"file-preview"},N.createElement("div",{className:"preview-heading"},N.createElement("h3",null,ue.path),N.createElement(Lu,{variant:"outline"},ue.blocked?"Needs source review":"Proposed file")),N.createElement("p",null,ue.reason),N.createElement("pre",{className:"code-preview"},ue.blocked?As(ue):ue.content),N.createElement(jl,{onClick:()=>h("export")},"Review changes ",N.createElement(Tc,{size:16}))))),N.createElement(xc,{value:"export"},N.createElement("div",{className:"architecture-grid"},N.createElement("div",{className:"file-tree"},N.createElement("h3",null,"Review every proposed change."),N.createElement("p",null,"Existing files show a full replacement diff, not a promise to preserve unselected lines. Check omissions and inherited conflicts."),F.map((L,J)=>N.createElement("button",{key:L.path,className:"file-node "+(J===R?"active":""),onClick:()=>{D(J),Z(!1)}},N.createElement(kh,{size:15}),N.createElement("span",null,L.path))),N.createElement("p",{className:"note"},F.filter(L=>L.blocked).length," files blocked from export because their existing source was not safely read. The receipt records exclusions.")),N.createElement("div",{className:"file-preview"},N.createElement("h3",null,ue.path),N.createElement("pre",{className:"code-preview diff"},As(ue)),N.createElement("div",{className:"approval"},N.createElement(Ms,{id:"approval",checked:V,onCheckedChange:L=>Z(L===!0)}),N.createElement("label",{htmlFor:"approval"},"I reviewed this proposal and its source/context. Download for manual review; this does not approve repository writes.")),N.createElement("div",{className:"actions"},N.createElement(jl,{disabled:!V||ue.blocked,variant:"outline",onClick:()=>Wh(new Blob([ue.content],{type:"text/markdown;charset=utf-8"}),ue.path.replaceAll("/","__"))},N.createElement(Zh,{size:16}),"Download this file"),N.createElement(jl,{disabled:!V,onClick:()=>{const L={project:s.repo,commit:s.sha,selectedSources:H.map(J=>J.url),limitations:s.notes,excluded:F.filter(J=>J.blocked).map(J=>J.path),mode:"Proposal only. No repository writes. Review all files and source licenses before manual adoption."};Wh(YS([...fe,{path:"AGENTLORE-REVIEW.json",content:JSON.stringify(L,null,2)},{path:"AGENTLORE-PREVIEW.diff",content:fe.map(As).join(` + +`)}]),"agentlore-proposal.tar")}},N.createElement(Zh,{size:16}),"Download proposal bundle")),N.createElement("p",{className:"muted"},"The TAR keeps directory paths and includes preview diffs and a provenance receipt. No PR, git push, hooks, or write API. Applying changes is a separate, approved next stage.")))))),N.createElement("section",{className:"closing"},N.createElement("div",null,N.createElement("p",{className:"eyebrow"},"THE NEXT CHAPTER"),N.createElement("h2",null,"Bring us a project",N.createElement("br",null),"with a little history.")),N.createElement("div",null,N.createElement("p",null,"Help shape AgentLore into a project-aware skill. Tell us where your instructions live and what your agents keep getting wrong."),N.createElement(jl,{asChild:!0,variant:"outline"},N.createElement("a",{href:B,target:"_blank",rel:"noreferrer"},"Request early access on GitHub ",N.createElement(Tc,{size:16}))),N.createElement("p",{className:"muted"},"GitHub account required. Review before submitting. A maintainer confirms next steps; no service is activated."))),N.createElement("footer",null,N.createElement("p",null,"Bounded research: 1 public project · 12 instruction files · 6 skills · 6 docs · 4 hooks · 64 KiB/file · 512 KiB total · 240 candidates. Unauthenticated GitHub limits apply. Docs are linked, not copied into rules. No private logs or secrets intentionally fetched; sensitive-looking lines are withheld by a heuristic filter, which cannot guarantee detection."),N.createElement("p",null,"NotPlanned / AgentLore 02 · React + actual shadcn/ui registry components · ",N.createElement("a",{href:"implementation.json",target:"_blank"},"Component provenance")))))}hp.createRoot(document.getElementById("root")).render(N.createElement(LS,null)); diff --git a/ventures/agentlore/assets/index-umuHN23p.css b/ventures/agentlore/assets/index-umuHN23p.css new file mode 100644 index 0000000..c18605a --- /dev/null +++ b/ventures/agentlore/assets/index-umuHN23p.css @@ -0,0 +1 @@ +/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--font-weight-medium:500;--font-weight-semibold:600;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.static{position:static}.mt-2{margin-top:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.min-h-\[60px\]{min-height:60px}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.shrink-0{flex-shrink:0}.place-content-center{place-content:center}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.rounded-lg{border-radius:.6rem}.rounded-md{border-radius:.4rem}.rounded-sm{border-radius:.2rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-input{border-color:var(--border)}.border-primary{border-color:var(--primary)}.border-transparent{border-color:#0000}.bg-background{background-color:var(--background)}.bg-destructive{background-color:#9b3535}.bg-muted{background-color:var(--muted)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.p-1{padding:var(--spacing)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-current{color:currentColor}.text-destructive-foreground{color:#fff}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--foreground)}.underline-offset-4{text-underline-offset:4px}.shadow,.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/80:hover{background-color:#9b3535cc}.hover\:bg-destructive\/90:hover{background-color:#9b3535e6}.hover\:bg-primary\/80:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--primary) 80%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--primary)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--primary)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--primary-foreground)}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}}:root{--background:#f6f3ed;--foreground:#282334;--primary:#6149aa;--primary-foreground:#fff;--secondary:#e9e3f5;--muted:#ede9e1;--muted-foreground:#696171;--accent:#e5ddf7;--border:#cdc5d5;color:var(--foreground);background:var(--background);font-synthesis:none;font-family:Arial,Helvetica,sans-serif;font-size:15px}*{box-sizing:border-box}body{margin:0}a{text-underline-offset:4px}button,a,input,textarea,select{touch-action:manipulation}button{cursor:pointer}button:disabled{cursor:default}.masthead{border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;max-width:1320px;margin:auto;padding:28px 40px;display:flex}.wordmark{align-items:center;gap:10px;font:700 25px Georgia,serif;text-decoration:none;display:flex}.wordmark span{letter-spacing:1.4px;color:var(--muted-foreground);margin-left:22px;font:10px monospace}.gallery{color:var(--muted-foreground);align-items:center;gap:5px;font-size:12px;display:flex}main{max-width:1320px;margin:auto;padding:0 40px}.opening{grid-template-columns:1.7fr 1fr;align-items:center;gap:70px;padding:70px 0 56px;display:grid}.eyebrow{letter-spacing:2px;color:var(--primary);font:10px/1.6 monospace}h1{letter-spacing:-2.7px;margin:22px 0;font:clamp(40px,5vw,70px)/1.05 Georgia,serif}h1 em{color:var(--primary);font-weight:400}h2{letter-spacing:-.8px;margin:15px 0;font:34px/1.15 Georgia,serif}h3{align-items:center;gap:8px;margin:0 0 14px;font:23px/1.3 Georgia,serif;display:flex}h4{text-transform:uppercase;letter-spacing:1px;margin:24px 0 12px;font:700 11px monospace}p{margin:12px 0;line-height:1.65}.lede{max-width:580px;color:var(--muted-foreground);font-size:17px}.principles{letter-spacing:1px;gap:28px;margin-top:32px;font:11px monospace;display:flex}.specimen{color:#ede7f9;background:#292334;border-radius:4px;padding:25px 26px;transform:rotate(1deg);box-shadow:9px 9px #ded6eb}.specimen-label{letter-spacing:1px;color:#c5b3f3;gap:8px;font:10px monospace;display:flex}.specimen pre{margin:20px 0;font:12px/2 monospace;overflow-x:auto}.specimen p{color:#cbbddc;border-top:1px solid #514660;padding-top:15px;font:italic 16px/1.6 Georgia,serif}.research-panel{border:1px solid var(--border);border-top:3px solid var(--primary);background:#ece6f4;padding:26px 30px 0}.panel-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.scan-layout{grid-template-columns:1fr 1.2fr;gap:70px;padding:22px 0;display:grid}.scan-layout h2{margin-top:0}.scan-layout p{max-width:330px;color:var(--muted-foreground)}label{font-size:13px;line-height:1.6}form>label{margin-bottom:9px;font-weight:700;display:block}textarea{resize:vertical;font:13px/1.7 monospace;background:#fcfaf7!important}.actions{flex-wrap:wrap;align-items:center;gap:10px;margin-top:15px;display:flex}.status{border-top:1px solid var(--border);overflow-wrap:anywhere;margin:0;padding:14px 0;font:12px/1.6 monospace}.findings{margin-top:56px}.findings-title{justify-content:space-between;align-items:center;gap:15px;display:flex}.findings-title h2{overflow-wrap:anywhere}.commit{color:var(--primary);font:12px monospace}.stats{border-top:1px solid var(--border);border-bottom:1px solid var(--border);flex-wrap:wrap;gap:28px;margin:16px 0 28px;padding:18px 0;font-size:12px;display:flex}.stats strong{margin-right:6px;font:24px Georgia,serif}.desk-tabs{background:#e5deee;flex-wrap:wrap;gap:4px;height:auto;margin-bottom:22px}.evidence-grid{grid-template-columns:280px minmax(0,1fr);gap:45px;display:grid}.inventory{border-right:1px solid var(--border);padding-right:25px}.inventory a{overflow-wrap:anywhere;margin:8px 0;font:11px/1.6 monospace;display:block}.inventory small{color:var(--muted-foreground);display:block}.muted{color:var(--muted-foreground);font-size:12px;line-height:1.65}.note{overflow-wrap:anywhere;background:#ebe5d8;border-left:2px solid #9c864d;margin:16px 0;padding:12px;font-size:12px;line-height:1.6}.rule{border-bottom:1px solid var(--border);grid-template-columns:20px minmax(0,1fr);gap:10px;padding:22px 0;display:grid}.rule>button{margin-top:5px}.rule label{white-space:pre-wrap;overflow-wrap:anywhere;cursor:pointer;font-size:14px}.rule-meta{flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;display:flex}.rule-meta a{color:var(--primary);overflow-wrap:anywhere;font:11px monospace}.warning{color:#664112;background:#f6dfbd}.next-step{margin-top:28px}.architecture-grid{border:1px solid var(--border);grid-template-columns:340px minmax(0,1fr);min-height:500px;display:grid}.file-tree{border-right:1px solid var(--border);background:#ede7f1;min-width:0;padding:24px}.file-tree p{color:var(--muted-foreground);font-size:13px}.file-node{text-align:left;border:1px solid #0000;border-bottom-color:var(--border);align-items:center;gap:8px;width:100%;padding:12px 10px;font:12px/1.5 monospace;display:flex}.file-node span{overflow-wrap:anywhere;flex:1;min-width:0}.file-node svg{flex-shrink:0}.file-node small{color:var(--muted-foreground);font-size:9px}.file-node:hover,.file-node.active{background:#f9f7fc;border-color:#b6a6d3}.file-preview{min-width:0;padding:28px}.preview-heading{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}.file-preview h3{overflow-wrap:anywhere;font:15px monospace}.file-preview p{font-size:13px}.code-preview{color:#e6dff0;white-space:pre-wrap;overflow-wrap:anywhere;background:#2b2535;border-radius:3px;max-height:540px;margin:20px 0;padding:22px;font:12px/1.8 monospace;overflow:auto}.diff{color:#c7e6ca}.approval{align-items:flex-start;gap:12px;padding:14px 0;display:flex}.approval button{margin-top:4px}.closing{border-top:1px solid var(--border);grid-template-columns:1fr 1fr;gap:80px;margin-top:70px;padding:40px 0;display:grid}.closing p{max-width:480px}footer{border-top:1px solid var(--border);color:var(--muted-foreground);padding:26px 0 35px;font-size:11px}footer p{max-width:960px}select{background:var(--background);border:1px solid var(--border);border-radius:4px;padding:8px;font-size:12px}a:focus-visible,.file-node:focus-visible{outline:2px solid var(--primary);outline-offset:3px}@media(max-width:850px){main{padding:0 22px}.masthead{padding:22px}.wordmark span{display:none}.opening{grid-template-columns:1fr 1fr;gap:28px;padding-top:45px}h1{letter-spacing:-1.7px;font-size:43px}.scan-layout{gap:25px}.evidence-grid{grid-template-columns:220px minmax(0,1fr);gap:24px}.architecture-grid{grid-template-columns:260px minmax(0,1fr)}}@media(max-width:600px){main{padding:0 16px}.masthead{padding:20px 16px}.gallery{max-width:100px;font-size:10px}.wordmark{font-size:23px}.opening{grid-template-columns:1fr;gap:30px;padding:35px 0}h1{font-size:43px}.lede{font-size:16px}.principles{gap:20px}.specimen{margin:0 7px 8px 0}.specimen pre{font-size:12px}.research-panel{padding:20px 18px 0}.scan-layout{grid-template-columns:1fr;gap:15px}.scan-layout p{max-width:none}.actions>button{white-space:normal;flex:1;height:auto;min-height:38px}.findings{margin-top:36px}.findings-title{flex-direction:column;align-items:flex-start;gap:0}.stats{gap:14px 22px}.desk-tabs{justify-content:space-between;width:100%}.desk-tabs button{padding:8px;font-size:11px}.evidence-grid,.architecture-grid,.closing{grid-template-columns:1fr;gap:25px}.inventory{border-right:0;border-bottom:1px solid var(--border);max-height:350px;padding:0 0 20px;overflow:auto}.architecture-grid{gap:0}.file-tree{border-right:0;border-bottom:1px solid var(--border);padding:20px}.file-preview{padding:20px}.code-preview{max-height:420px;padding:16px;font-size:11px}.closing{gap:5px;margin-top:45px;padding:30px 0}.panel-heading .eyebrow{letter-spacing:1px}.panel-heading{align-items:flex-start}h2{font-size:30px}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false} diff --git a/ventures/agentlore/implementation.json b/ventures/agentlore/implementation.json new file mode 100644 index 0000000..85e34cf --- /dev/null +++ b/ventures/agentlore/implementation.json @@ -0,0 +1,38 @@ +{ + "iteration": "AgentLore 02 / #87 follow-up", + "components": [ + { + "name": "button", + "registry": "https://ui.shadcn.com/r/styles/new-york/button.json", + "sha256": "c2b999a96781e6c932632bd089095368e973bf5602e1b1a62156b7d2b43f1e84", + "runtime": "Used in src/main.tsx; Tabs and Checkbox use Radix UI behavior." + }, + { + "name": "tabs", + "registry": "https://ui.shadcn.com/r/styles/new-york/tabs.json", + "sha256": "d41aded0394298102614635e15d709369c6bdae8fe79b918b8341ef39407ee03", + "runtime": "Used in src/main.tsx; Tabs and Checkbox use Radix UI behavior." + }, + { + "name": "checkbox", + "registry": "https://ui.shadcn.com/r/styles/new-york/checkbox.json", + "sha256": "c9e19d480a43172f9504ac9b22f4a9c149de1d916162f24c62395533b7be19f6", + "runtime": "Used in src/main.tsx; Tabs and Checkbox use Radix UI behavior." + }, + { + "name": "textarea", + "registry": "https://ui.shadcn.com/r/styles/new-york/textarea.json", + "sha256": "ec7c92aaed80f6923a7caa4bfe4eead395b50a7001504fd7fbb0b9381804dae9", + "runtime": "Used in src/main.tsx; Tabs and Checkbox use Radix UI behavior." + }, + { + "name": "badge", + "registry": "https://ui.shadcn.com/r/styles/new-york/badge.json", + "sha256": "dab689d836ad3292b41e7f4986b4e68e5d45c6903e4aeaae8972a82d4aebec29", + "runtime": "Used in src/main.tsx; Tabs and Checkbox use Radix UI behavior." + } + ], + "theme": "Ink / parchment / violet; custom shadcn CSS variables", + "source": "agentlore-source.tgz", + "repositoryWrites": false +} \ No newline at end of file diff --git a/ventures/agentlore/index.html b/ventures/agentlore/index.html new file mode 100644 index 0000000..fd0b205 --- /dev/null +++ b/ventures/agentlore/index.html @@ -0,0 +1,3 @@ +AgentLore — a home for project knowledge + +
diff --git a/ventures/agentlore/qa/codex-proposal.tar b/ventures/agentlore/qa/codex-proposal.tar new file mode 100644 index 0000000..40a5a1e Binary files /dev/null and b/ventures/agentlore/qa/codex-proposal.tar differ diff --git a/ventures/agentlore/qa/desktop-architecture.png b/ventures/agentlore/qa/desktop-architecture.png new file mode 100644 index 0000000..81195bb Binary files /dev/null and b/ventures/agentlore/qa/desktop-architecture.png differ diff --git a/ventures/agentlore/qa/desktop.png b/ventures/agentlore/qa/desktop.png new file mode 100644 index 0000000..c56aea7 Binary files /dev/null and b/ventures/agentlore/qa/desktop.png differ diff --git a/ventures/agentlore/qa/mobile-architecture.png b/ventures/agentlore/qa/mobile-architecture.png new file mode 100644 index 0000000..d3b357f Binary files /dev/null and b/ventures/agentlore/qa/mobile-architecture.png differ diff --git a/ventures/backlog.json b/ventures/backlog.json new file mode 100644 index 0000000..74baea2 --- /dev/null +++ b/ventures/backlog.json @@ -0,0 +1,105 @@ +{ + "source": "notplanned", + "updated_by": "scout", + "opportunities": [ + { + "heat": "hot", + "repo": "openai/codex", + "issue": 40046, + "name": "Browser Upload Bridge", + "title": "Hidden file-input fallback for agent browsers", + "thesis": "Agents still hit browser flows where the native file chooser never fires. Ship a tiny browser/MCP bridge that can target hidden file inputs directly and hand the agent a deterministic upload primitive.", + "signal": "Recent Codex request closed as not planned; the underlying Playwright primitive already exists.", + "move": "Wrap setInputFiles behind one safe tool + demo it against 5 common upload flows.", + "source": "https://github.com/openai/codex/issues/40046" + }, + { + "heat": "hot", + "repo": "openai/codex", + "issue": 46025, + "name": "Codex KeepWarm", + "title": "Tool calls stall after idle gaps on Windows", + "thesis": "If idle transitions are the trigger, a tiny watchdog/keepalive sidecar may remove minutes of dead time without changing Codex itself.", + "signal": "September blocker report; every post-idle tool call reportedly incurs ~30s latency and upstream closed it as not planned.", + "move": "Reproduce, then test whether a low-cost heartbeat prevents the stall. Kill immediately if it does not.", + "source": "https://github.com/openai/codex/issues/46025" + }, + { + "heat": "warm", + "repo": "openai/codex", + "issue": 26966, + "name": "Goalkeeper", + "title": "Persist goals across codex exec sessions", + "thesis": "A wrapper can own the durable goal, inject it into new/resumed runs, and expose goal state programmatically without waiting for first-class CLI support.", + "signal": "Two closely related programmatic-goal requests were closed as not planned.", + "move": "Build codex-goal with set/show/run; dogfood it on a multi-run task.", + "source": "https://github.com/openai/codex/issues/26966" + }, + { + "heat": "warm", + "repo": "openai/codex", + "issue": 14747, + "name": "Context Curator", + "title": "Scoped compaction for exploratory phases", + "thesis": "Treat transcripts as editable context: preserve conclusions, compress dead ends, and emit a clean continuation packet for the next agent/session.", + "signal": "Users explicitly want selective rather than whole-history compaction; Claude Code users are asking for priority-aware compaction too.", + "move": "Take a real long transcript, select one noisy span, produce a resumable compacted version, measure token savings.", + "source": "https://github.com/openai/codex/issues/14747" + }, + { + "heat": "warm", + "repo": "anthropics/claude-code", + "issue": 79948, + "name": "Finishline", + "title": "The project-management layer coding agents are missing", + "thesis": "External supervisor that tracks objective \u2192 evidence \u2192 acceptance, catches unfinished work, and refuses to equate agent completion with done.", + "signal": "The request is unusually explicit about sprawl, verification, multi-tier workflow, and agents claiming completion without evidence.", + "move": "Ship a repo-local supervisor card that reads task + git state + acceptance checks and produces DONE/WAIT/ANDON.", + "source": "https://github.com/anthropics/claude-code/issues/79948" + }, + { + "heat": "warm", + "repo": "anthropics/claude-code", + "issue": 53997, + "name": "Preview Sidecar", + "title": "Bring back local preview for agent-built apps", + "thesis": "A tiny localhost/port discovery sidecar can surface the app the agent is building without requiring the coding product itself to own preview UX.", + "signal": "Users describe preview removal as a major regression and specifically want localhost surfaced again.", + "move": "Detect active localhost ports and expose one-click preview + screenshot receipt.", + "source": "https://github.com/anthropics/claude-code/issues/53997" + }, + { + "heat": "warm", + "repo": "anthropics/claude-code", + "issue": 78197, + "name": "Context Priority", + "title": "Let users mark low-priority context before compaction", + "thesis": "A context sidecar can assign priority to transcript segments and generate a compacted continuation packet that preserves high-value state first.", + "signal": "Same underlying pain as scoped compaction, now expressed as explicit message-level priority.", + "move": "Prototype priority annotations + deterministic compaction on exported sessions.", + "source": "https://github.com/anthropics/claude-code/issues/78197" + }, + { + "heat": "warm", + "repo": "anthropics/claude-code", + "issue": 83489, + "name": "Model Presets", + "title": "Named model + effort presets", + "thesis": "One-click named presets are externally solvable today with a wrapper/menu that atomically selects model and effort and persists the choice.", + "signal": "Current product exposes the pieces but not the composed action users want.", + "move": "Ship a 3-preset CLI/menu-bar prototype: fast / think / max.", + "source": "https://github.com/anthropics/claude-code/issues/83489" + }, + { + "heat": "watch", + "repo": "vercel-labs/agent-browser", + "issue": 1184, + "name": "Browser Guardrail", + "title": "Per-task domain and form-submission constraints", + "thesis": "Put an authority layer in front of browser agents: task-scoped domains, submission policy, and receipts. The browser stays powerful; the delegation gets narrow.", + "signal": "The issue frames a real prompt-injection blast-radius problem and upstream closed the feature as not planned.", + "move": "Proxy three dangerous actions\u2014navigate, fill, submit\u2014through a task policy and prove denials are deterministic.", + "source": "https://github.com/vercel-labs/agent-browser/issues/1184" + } + ] +} \ No newline at end of file diff --git a/ventures/codex-goal/README.md b/ventures/codex-goal/README.md new file mode 100644 index 0000000..62e67f5 --- /dev/null +++ b/ventures/codex-goal/README.md @@ -0,0 +1,134 @@ +# codex-goal + +A tiny wrapper that remembers one objective per project across separate +`codex exec` invocations, and injects it as plain user-context text every +time you run or resume. Inspired by +[openai/codex#26966: Persist goals across codex exec sessions](https://github.com/openai/codex/issues/26966), +closed as not planned. This is **external memory bolted onto the outside of +Codex**, not a native goal mode: Codex itself is never changed, and never +gets an API to mark the goal "done" or rewrite it. + +## Problem + +`codex exec` is stateless about *why* you're running it. Resume brings back +the transcript, but nothing re-states the objective, so a long-running or +multi-session task slowly drifts as context gets summarized away. Upstream +closed the feature request; this reconstructs it from outside the agent. + +## Install + +Requires Python 3.9+, a POSIX host (macOS/Linux — matches the board's hb-5 +Mac and Colima container targets), and the `codex` CLI on `PATH` for real +use. No pip install, no dependencies: + +```sh +cp codex_goal.py ~/bin/codex_goal.py # or run it in place +chmod +x codex_goal.py +``` + +## Usage + +```sh +# Save (or replace) the objective for the current directory's project. +codex_goal.py set "Migrate the billing module to the new schema, keep tests green" + +# Inspect it any time. +codex_goal.py show +codex_goal.py show --json --history + +# Start a new codex exec session with the goal injected as user context. +codex_goal.py run + +# Resume the most recent session -- goal is re-injected, not just the transcript. +codex_goal.py run --last + +# Resume a specific session id, and forward real codex flags/an extra prompt. +codex_goal.py run --resume 3fae2b1e-... -- -s workspace-write "focus on the invoices table next" +``` + +Everything after `run`'s own flags is forwarded to `codex exec` (or +`codex exec resume ...`) untouched and in order — sandbox mode, model, +`-C`, etc. all still work exactly as they do calling `codex` directly. +A trailing bare argument (not starting with `-`) is treated as this turn's +extra instruction and appended after the injected goal; everything else is +passed straight through. + +`-C DIR` (default: cwd) on any subcommand selects the project. The project +key is a hash of its realpath, so `set`/`show`/`run` keep working no matter +which subdirectory you're standing in, and two projects never collide. + +## How persistence works + +- State lives under `$CODEX_GOAL_HOME` (default `~/.codex-goal`), **outside** + whatever directory `codex exec`'s sandbox would let the agent write to. + Codex running in its default `workspace-write` sandbox cannot see or + modify its own goal file — `set` is a human-run command, never something + the wrapper calls on Codex's behalf. +- Goal records are versioned: each `set` pushes the previous value into a + capped history (50 entries) instead of overwriting it silently. +- Writes are atomic (`tempfile` + `os.replace`) and guarded by an exclusive + file lock (`fcntl.flock`) around the whole read-modify-write, so a crash + or a concurrent `set` can't leave a half-written or torn JSON file. +- `run` never modifies the goal. It only appends one line to a separate + run-log (`$CODEX_GOAL_HOME/runs/.jsonl`) *after* the child process + exits, recording the mode, a goal preview, the exact argv, and the real + exit code. A run that crashes mid-flight (killed, SIGKILL, power loss) + leaves both the goal and the prior run-log lines untouched — there is no + "mark this goal complete" affordance for Codex or the wrapper to call, so + nothing can silently clear it. +- Codex is spawned via `subprocess.Popen([...])` with an argv list, never a + shell string — a goal containing `; rm -rf / #` is passed as one opaque + argv element, not executed. The child gets its own process group, and + `SIGINT`/`SIGTERM` sent to the wrapper are forwarded to it, so Ctrl-C + cancels a run the same way it would cancel `codex` directly. The + wrapper's own exit code is the child's exit code. + +## Limits and trust + +- One objective per project at a time. It is not a task list, not a + scheduler, and it does not talk to the Codex API directly — it only + shells out to the `codex` binary you already have configured and + authenticated. +- The injected text is plain, visible user context ("[codex-goal] Persisted + objective...") — it carries no special authority inside Codex's own + permission model. A model can still choose to ignore it, same as any + other instruction. +- No enforcement that the agent is *actually* working the stated goal; this + only guarantees the goal text is faithfully re-presented every run. It + does not inspect diffs, run checks, or grade progress — see + [finishline-supervisor](../finishline-supervisor/) for that kind of + evidence wrapper, which composes with this one but is a separate tool. +- `$CODEX_GOAL_HOME` is trusted local storage with your own file + permissions; this tool adds no encryption or extra access control. Don't + put secrets in goal text — it is written to disk in plain JSON. +- Locking is advisory (`flock`) and local-filesystem only; it does not work + over NFS/SMB and does not coordinate across machines. +- `run` passes through whatever `codex exec` flags you give it, including + `--dangerously-bypass-approvals-and-sandbox` if you ask for it — this + wrapper does not add or remove any safety behavior from Codex itself. + +## Develop and verify + +```sh +python3 -m unittest discover -s tests -p 'test_*.py' -v +python3 demo.py > demo.txt # recorded, runnable, no network/auth needed +``` + +Tests and the demo use `tests/fake_codex.py`, a deterministic stand-in for +the real `codex` binary (records the exact argv it received, exits with a +configurable code, optionally sleeps so cancellation can be tested) — no +model calls, no API key, nothing billed, per the board's preference for +deterministic, cheap, inspectable checks over live model calls. [Recorded +demo output](demo.txt) covers: `set`/`show` round trip, run 1 (fresh +session), run 2 (`--last` resume, same goal), and a `kill -9` mid-run +followed by a `show` proving the goal survived byte-for-byte. + +Verified: all 16 unit tests plus the demo on the local macOS (hb-5) host, +and inside the project's Colima Linux container (same Python 3, same +`tests/fake_codex.py`, no code changes needed — the tool has no +platform-specific dependency beyond POSIX `fcntl`/process groups). Real +`codex` binary integration (the actual CLI shown in Usage above) was +exercised manually against the installed `codex` CLI's `--help` output to +confirm the `exec`/`exec resume --last`/flag-forwarding argv shape this +wrapper builds matches the real CLI; it was not run against a live Codex +backend (that needs your own account/auth and would spend real requests). diff --git a/ventures/codex-goal/codex_goal.py b/ventures/codex-goal/codex_goal.py new file mode 100755 index 0000000..7983505 --- /dev/null +++ b/ventures/codex-goal/codex_goal.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +"""codex-goal: persist a per-project objective across `codex exec` sessions. + +External memory, not native Codex state: it stores the goal outside the +directory Codex is allowed to write to, and injects it as plain user-context +text on every `set`/`show`/`run` the human runs. Codex itself never sees a +"mark complete" affordance -- only `set` can change the stored goal, and +`set` is never invoked by codex-goal's own `run` command. + +Usage: + codex_goal.py set [-C DIR] GOAL_TEXT... + codex_goal.py show [-C DIR] [--json] [--history] + codex_goal.py run [-C DIR] [--codex-bin PATH] [--resume ID | --last] + [--dry-run] [-- CODEX_ARGS... [PROMPT]] +""" +from __future__ import annotations + +import argparse +import contextlib +import hashlib +import json +import os +import signal +import subprocess +import sys +import tempfile +import time +import uuid + +try: + import fcntl +except ImportError: # pragma: no cover - POSIX only, matches board brief hosts + fcntl = None + +SCHEMA_VERSION = 1 +MAX_GOAL_CHARS = 4000 +MAX_HISTORY = 50 +ENV_HOME = "CODEX_GOAL_HOME" + + +def state_home() -> str: + override = os.environ.get(ENV_HOME) + if override: + return override + return os.path.join(os.path.expanduser("~"), ".codex-goal") + + +def project_key(project_dir: str) -> str: + real = os.path.realpath(project_dir) + digest = hashlib.sha256(real.encode("utf-8")).hexdigest()[:16] + base = os.path.basename(real.rstrip("/")) or "root" + safe_base = "".join(c if c.isalnum() or c in "-_." else "-" for c in base) + return f"{safe_base}-{digest}" + + +def goal_path(home: str, key: str) -> str: + return os.path.join(home, "goals", f"{key}.json") + + +def runlog_path(home: str, key: str) -> str: + return os.path.join(home, "runs", f"{key}.jsonl") + + +def lock_path(home: str, key: str) -> str: + return os.path.join(home, "locks", f"{key}.lock") + + +@contextlib.contextmanager +def locked(home: str, key: str): + """Exclusive file lock guarding read-modify-write of one project's state.""" + path = lock_path(home, key) + os.makedirs(os.path.dirname(path), exist_ok=True) + fh = open(path, "a+") + try: + if fcntl is not None: + fcntl.flock(fh.fileno(), fcntl.LOCK_EX) + yield + finally: + if fcntl is not None: + fcntl.flock(fh.fileno(), fcntl.LOCK_UN) + fh.close() + + +def atomic_write_json(path: str, payload: dict) -> None: + os.makedirs(os.path.dirname(path), exist_ok=True) + fd, tmp = tempfile.mkstemp(prefix=".tmp-", dir=os.path.dirname(path)) + try: + with os.fdopen(fd, "w") as fh: + json.dump(payload, fh, indent=2, sort_keys=True) + fh.write("\n") + fh.flush() + os.fsync(fh.fileno()) + os.replace(tmp, path) # atomic on POSIX: a reader never sees a partial file + except Exception: + with contextlib.suppress(OSError): + os.remove(tmp) + raise + + +def append_jsonl(path: str, record: dict) -> None: + os.makedirs(os.path.dirname(path), exist_ok=True) + line = json.dumps(record, sort_keys=True) + "\n" + with open(path, "a") as fh: + fh.write(line) + fh.flush() + os.fsync(fh.fileno()) + + +def now_iso() -> str: + return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) + + +def load_state(path: str) -> dict | None: + if not os.path.exists(path): + return None + with open(path) as fh: + return json.load(fh) + + +def cmd_set(args: argparse.Namespace) -> int: + text = " ".join(args.goal).strip() + if not text: + print("codex-goal: refusing an empty goal", file=sys.stderr) + return 2 + if len(text) > MAX_GOAL_CHARS: + print(f"codex-goal: goal exceeds {MAX_GOAL_CHARS} characters", file=sys.stderr) + return 2 + + home = state_home() + key = project_key(args.project) + path = goal_path(home, key) + + with locked(home, key): + state = load_state(path) + ts = now_iso() + if state is None: + state = { + "schema_version": SCHEMA_VERSION, + "project": {"path": os.path.realpath(args.project), "key": key}, + "current": None, + "history": [], + } + if state["current"] is not None: + state["history"].append(state["current"]) + state["history"] = state["history"][-MAX_HISTORY:] + state["current"] = { + "goal_id": f"g-{uuid.uuid4().hex[:12]}", + "text": text, + "created_at": ts, + "updated_at": ts, + } + atomic_write_json(path, state) + + print(f"codex-goal: saved goal {state['current']['goal_id']} for {key}") + return 0 + + +def cmd_show(args: argparse.Namespace) -> int: + home = state_home() + key = project_key(args.project) + state = load_state(goal_path(home, key)) + + if state is None or state.get("current") is None: + if args.json: + print(json.dumps({"project_key": key, "current": None})) + else: + print(f"codex-goal: no goal set for {key}. Run: codex_goal.py set ") + return 1 + + if args.json: + payload = {"project_key": key, "current": state["current"]} + if args.history: + payload["history"] = state["history"] + print(json.dumps(payload, indent=2, sort_keys=True)) + else: + cur = state["current"] + print(f"project {key}") + print(f"goal_id {cur['goal_id']}") + print(f"updated {cur['updated_at']}") + print(f"text {cur['text']}") + if args.history and state["history"]: + print("\nhistory (oldest first):") + for h in state["history"]: + print(f" - [{h['updated_at']}] {h['goal_id']}: {h['text']}") + return 0 + + +INJECT_HEADER = "[codex-goal] Persisted objective for this project (external memory, injected by a wrapper -- not native Codex state):" +INJECT_FOOTER = "[/codex-goal] Continue working toward the objective above unless the user says otherwise." + + +def build_prompt(goal_text: str, extra_prompt: str | None) -> str: + block = f"{INJECT_HEADER}\n{goal_text}\n{INJECT_FOOTER}" + if extra_prompt: + return f"{block}\n\n{extra_prompt}" + return block + + +def cmd_run(args: argparse.Namespace) -> int: + home = state_home() + key = project_key(args.project) + state = load_state(goal_path(home, key)) + if state is None or state.get("current") is None: + print(f"codex-goal: no goal set for {key}. Run: codex_goal.py set ", file=sys.stderr) + return 2 + + goal = state["current"] + passthrough = list(args.codex_args) + extra_prompt = None + if passthrough and not passthrough[-1].startswith("-"): + # Last bare token (if any) is the user's extra instruction for this turn; + # everything else is forwarded to `codex exec` untouched. + extra_prompt = passthrough.pop() + + prompt = build_prompt(goal["text"], extra_prompt) + + argv = [args.codex_bin, "exec"] + mode = "new" + session_arg = None + if args.resume or args.last: + argv.append("resume") + mode = "resume" + if args.last: + argv.append("--last") + session_arg = "last" + else: + argv.append(args.resume) + session_arg = args.resume + argv.extend(passthrough) + argv.append(prompt) + + if args.dry_run: + print(json.dumps({"argv": argv, "mode": mode}, indent=2)) + return 0 + + record = { + "ts": now_iso(), + "mode": mode, + "session_arg": session_arg, + "goal_id": goal["goal_id"], + "goal_preview": goal["text"][:120], + "argv": argv, + } + + try: + proc = subprocess.Popen(argv, start_new_session=True) + except FileNotFoundError: + print(f"codex-goal: codex binary not found: {args.codex_bin}", file=sys.stderr) + record["exit_code"] = 127 + append_jsonl(runlog_path(home, key), record) + return 127 + + def forward_signal(signum, _frame): + with contextlib.suppress(ProcessLookupError): + os.killpg(proc.pid, signum) + + old_sigint = signal.signal(signal.SIGINT, forward_signal) + old_sigterm = signal.signal(signal.SIGTERM, forward_signal) + try: + exit_code = proc.wait() + finally: + signal.signal(signal.SIGINT, old_sigint) + signal.signal(signal.SIGTERM, old_sigterm) + + record["exit_code"] = exit_code + append_jsonl(runlog_path(home, key), record) + return exit_code + + +def main(argv: list[str]) -> int: + parser = argparse.ArgumentParser(prog="codex_goal.py", description=__doc__) + sub = parser.add_subparsers(dest="command", required=True) + + common = argparse.ArgumentParser(add_help=False) + common.add_argument("-C", "--project", default=os.getcwd(), help="project directory (default: cwd)") + + p_set = sub.add_parser("set", parents=[common], help="save/replace the goal for this project") + p_set.add_argument("goal", nargs="+", help="goal text") + p_set.set_defaults(func=cmd_set) + + p_show = sub.add_parser("show", parents=[common], help="print the current goal") + p_show.add_argument("--json", action="store_true") + p_show.add_argument("--history", action="store_true") + p_show.set_defaults(func=cmd_show) + + p_run = sub.add_parser("run", parents=[common], help="spawn `codex exec` with the goal injected") + p_run.add_argument("--codex-bin", default=os.environ.get("CODEX_GOAL_BIN", "codex")) + resume_group = p_run.add_mutually_exclusive_group() + resume_group.add_argument("--resume", metavar="SESSION_ID", help="resume this session id") + resume_group.add_argument("--last", action="store_true", help="resume the most recent session") + p_run.add_argument("--dry-run", action="store_true", help="print the argv that would run, do not spawn") + p_run.add_argument("codex_args", nargs=argparse.REMAINDER, metavar="-- CODEX_ARGS...") + p_run.set_defaults(func=cmd_run) + + args = parser.parse_args(argv) + if args.command == "run" and args.codex_args and args.codex_args[0] == "--": + args.codex_args = args.codex_args[1:] + return args.func(args) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/ventures/codex-goal/demo.txt b/ventures/codex-goal/demo.txt new file mode 100644 index 0000000..d4340b0 --- /dev/null +++ b/ventures/codex-goal/demo.txt @@ -0,0 +1,38 @@ +# 1. set + show +$ python3 codex_goal.py set -C '$PROJECT' 'Ship codex-goal'"'"'s two-run persistence demo' +codex-goal: saved goal g-a2c8350ac309 for myapp-58cda05ecfff4ec2 +[exit 0] goal saved + +$ python3 codex_goal.py show -C '$PROJECT' +project myapp-58cda05ecfff4ec2 +goal_id g-a2c8350ac309 +updated 2026-10-10T20:16:17Z +text Ship codex-goal's two-run persistence demo +[exit 0] goal shown + +# 2. run 1 -- fresh session (fake codex, exit 0) +$ python3 codex_goal.py run -C '$PROJECT' --codex-bin tests/fake_codex.py +[exit 0] run 1 done + +# 3. run 2 -- resume --last, in a *new* process, goal still there +$ python3 codex_goal.py run -C '$PROJECT' --last --codex-bin tests/fake_codex.py +[exit 0] run 2 done + +# 4. crash mid-run: kill -9 the wrapper while codex is 'working' +$ (background run) ; kill -9 35478 +[killed] simulated crash + +# 5. show again -- goal survived the crash, byte for byte +$ python3 codex_goal.py show -C '$PROJECT' --json +{ + "current": { + "created_at": "2026-10-10T20:16:17Z", + "goal_id": "g-a2c8350ac309", + "text": "Ship codex-goal's two-run persistence demo", + "updated_at": "2026-10-10T20:16:17Z" + }, + "project_key": "myapp-58cda05ecfff4ec2" +} +[exit 0] goal after crash + +ASSERTION PASSED: goal text identical before and after the crash. diff --git a/ventures/codex-goal/fonts/DSEG7Classic-Bold.woff2 b/ventures/codex-goal/fonts/DSEG7Classic-Bold.woff2 new file mode 100644 index 0000000..558eec4 Binary files /dev/null and b/ventures/codex-goal/fonts/DSEG7Classic-Bold.woff2 differ diff --git a/ventures/codex-goal/fonts/OFL.txt b/ventures/codex-goal/fonts/OFL.txt new file mode 100644 index 0000000..ad4c0bf --- /dev/null +++ b/ventures/codex-goal/fonts/OFL.txt @@ -0,0 +1,95 @@ +Copyright (c) 2017, keshikan (http://www.keshikan.net), +with Reserved Font Name "DSEG". + + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/ventures/codex-goal/index.html b/ventures/codex-goal/index.html new file mode 100644 index 0000000..0a3a350 --- /dev/null +++ b/ventures/codex-goal/index.html @@ -0,0 +1,345 @@ + + + + + + +codex-goal · notplanned + + + +
+ +
+
NOTPLANNED ARCADE
+
VENTURE 004 · LIVE
+
+ +
+
+
upstream call: openai/codex#26966 · closed · not planned
+

don't let the agent forget the goal.

+

codex exec resumes a transcript but never restates why. codex‑goal is a small wrapper that stores one objective per project outside Codex's own workspace, and hands it back as plain context on every new or resumed run — built anyway after upstream closed the request.

+ +
+
02
codex exec runs
+
01
goal, both runs
+
100
% intact after kill -9
+
+ +
+
★ join the roster — be first when hosted tiers ship
+
+ + +
+ + +
+
+ + +
+ +
+ + +
+
+
✓ ON THE ROSTER — thanks, you're in.We'll only email you about codex-goal. Never shared.
+

One line on your email: used only to reach you about codex-goal, never sold, never shared. The CLI below stays free no matter what you pick.

+
+
+ +
+

the matchup

+

Same two commands, two sessions apart. One remembers the assignment; one doesn't.

+
+
+
Stock codex execLOST
+
$ codex exec "migrate billing to new schema"
+… session ends, summarized …
+
+$ codex exec resume --last "continue"
+> continuing. what's the task again?
+  (transcript survived. the point of it didn't.)
+

Resume brings back messages, not the objective that framed them.

+
+
+
codex‑goal runWON
+
$ codex_goal.py set "migrate billing to new schema"
+$ codex_goal.py run
+> [codex-goal] persisted objective: migrate billing…
+
+… session ends …
+
+$ codex_goal.py run --last
+> [codex-goal] persisted objective: migrate billing…
+  (re-injected before Codex sees anything else.)
+

Every new or resumed run gets the same goal text, re-stated, every time.

+
+
+
+ +
+

instant replay

+

Real, runnable output from demo.py — a disposable project dir, a disposable $CODEX_GOAL_HOME, and a deterministic stand-in for the real codex binary (no network, no account, nothing billed). Two separate process runs see the same goal; a kill -9 mid-run doesn't touch it.

+
+
demo.py — full output in demo.txt
+
$ python3 codex_goal.py set -C $PROJECT 'Ship codex-goal's two-run persistence demo'
+codex-goal: saved goal g-a2c8350ac309 for myapp-58cda05ecfff4ec2
+[exit 0] goal saved
+
+$ python3 codex_goal.py run -C $PROJECT --codex-bin tests/fake_codex.py
+[exit 0] run 1 done              ← fresh session, goal injected
+
+$ python3 codex_goal.py run -C $PROJECT --last --codex-bin tests/fake_codex.py
+[exit 0] run 2 done              ← resumed, SAME goal injected again
+
+$ (background run) ; kill -9 35478
+[killed] simulated crash          ← mid-run, hard kill
+
+$ python3 codex_goal.py show -C $PROJECT --json
+{
+  "current": {
+    "text": "Ship codex-goal's two-run persistence demo",
+    "goal_id": "g-a2c8350ac309"
+  }
+}
+ASSERTION PASSED: goal text identical before and after the crash.
+
+

Full transcript: demo.txt · run it yourself: README

+
+ +
+

how it scores

+
    +
  • 01 Goal state lives under ~/.codex-goal — outside the directory Codex's own sandbox lets it write to. set is a human command; the wrapper never calls it on Codex's behalf.
  • +
  • 02 Every set is versioned: the previous goal moves to a capped history instead of being silently overwritten.
  • +
  • 03 Writes are atomic (temp file + rename) under an exclusive file lock — a crash mid-write can't leave torn JSON.
  • +
  • 04 run never edits the goal. It only appends one line to a separate run-log, after the child exits, with the real exit code.
  • +
  • 05 Codex is spawned via an argv list, never a shell string — a goal containing ; rm -rf / # is one opaque argument, not a command.
  • +
  • 06 Ctrl‑C / SIGTERM sent to the wrapper is forwarded to the Codex child, so cancellation behaves exactly like calling codex directly. The wrapper's exit code is the child's.
  • +
+
+ +
+

game passes

+

Free tier works offline, forever. Paid tiers are founding-price early access — there is no checkout yet.

+
+
+
Free
+
$0
+
anyone with their own Codex auth
+
  • Full CLI, source, tests, demo
  • Unlimited local projects
  • No account, no telemetry
+
forever free
+
+
+
Early Access
+
$6/mo
+
solo devs juggling several agent projects
+
  • Hosted goal + run-log viewer
  • Cross-machine goal sync
  • Email digest on run failures
+
founding price · waitlist, not billed yet
+
+
+
Team
+
$24/mo
+
teams sharing Codex objectives across a repo
+
  • Shared goals, per-teammate run history
  • Slack alert when a run fails
  • Audit log export
+
founding price · waitlist, not billed yet
+
+
+
+ +
+

rules of the game

+
    +
  • 1 goal One objective per project at a time. Not a task list, not a scheduler, not a replacement for your issue tracker.
  • +
  • no force The injected text is plain, visible user context — it carries no special authority inside Codex. A model can still choose to ignore it, same as any other instruction.
  • +
  • no grading This only guarantees the goal is faithfully re-stated every run. It does not inspect diffs or grade progress — pair it with finishline-supervisor for that.
  • +
  • plain json $CODEX_GOAL_HOME is ordinary local storage with your file permissions, no encryption. Don't put secrets in goal text.
  • +
  • local lock Locking is advisory and local-filesystem only — it doesn't coordinate over NFS/SMB or across machines.
  • +
  • your flags run forwards whatever codex exec flags you give it, including dangerous ones if you ask for them. This wrapper adds or removes none of Codex's own safety behavior.
  • +
+
+
+ + +
+ + + diff --git a/ventures/context-curator/README.md b/ventures/context-curator/README.md new file mode 100644 index 0000000..e628fc8 --- /dev/null +++ b/ventures/context-curator/README.md @@ -0,0 +1,48 @@ +# Context Curator + +A browser-only manual editor for a completed exploratory span in an agent transcript. Inspired by [openai/codex#14747](https://github.com/openai/codex/issues/14747), closed as not planned. It keeps the surrounding context and replaces one contiguous span with a conclusion you write. + +## Install and use + +Open `site/index.html` directly in a modern browser. No installation, dependencies, account, server, or model calls. The hosted page offers that same complete HTML as a free offline download. The initial interactive example is an **illustrative** debugging transcript, not a recorded execution or performance benchmark. + +1. Try the sample, open a JSON file, or paste JSON and press **Load this JSON**. +2. Choose first and last messages (1-based, both inclusive). Write the root cause, supporting evidence, unresolved questions, and next action. +3. Press **Replace selected span**. Read the complete message diff and expandable full JSON views. Size measurement compares compact UTF-8 JSON bytes, including conclusion metadata, not tokens, costs, or Markdown file size. A long conclusion can make the result larger. +4. Download the Markdown continuation packet or curated JSON. **Save untouched original** downloads the exact loaded text, including whitespace. **Undo replacement** restores the previous working result (one level). Replacements always target the loaded original, never accumulate silently. +5. Review the packet before manually handing it to a fresh session. All messages are quoted as JSON in Markdown, with fences safe for embedded backticks. No commands or transcript HTML are executed. + +## JSON transcript format (version 1) + +```json +{"version":1,"title":"Optional metadata","messages":[ + {"id":"m1","role":"system","content":"Keep the requirements."}, + {"id":"m2","role":"tool","content":"Exploratory evidence."}, + {"id":"m3","role":"user","content":"Next task."} +]} +``` + +Required: `version: 1`, 1–500 messages, each with a unique nonempty string `id`, `role` in `system|user|assistant|tool`, and string `content`. Limit: 2 MiB UTF-8 source JSON. Additional top-level and message fields survive. Retained messages are structurally identical; formatting in curated JSON is normalized. The original source string is preserved separately, byte-for-byte for valid UTF-8 input. Invalid imports leave the last loaded original and result available. Files must be valid UTF-8. + +`sample.json` is the example. The manual replacement is an assistant message tagged `curator.kind = "manual-conclusion"`, with `replacedIds` for the entire selected span and a unique generated ID. Selected messages and their metadata are absent from the curated export; they remain in the original. Selection may include any role: review carefully before removing requirements or instructions. + +## Privacy and limits + +Transcript processing stays in browser memory. No fetch, telemetry, third-party fonts/scripts, local storage, session edits, or configuration access. Closing or reloading loses working state; download the original and exports first. Only the optional signup form posts email, plan, and note to the existing `/api/signup` service. Offline signup is unavailable. `?joined=1#join` shows the thank-you state. + +This does not import native Codex/Claude session files, automatically summarize, resume a session, count model tokens, or guarantee a good conclusion. Convert an explicit transcript export into the documented format yourself. It is a handoff aid, not a compaction API. Do not include sensitive context in the signup note. A malicious transcript can still contain misleading instructions: quoted Markdown is not an agent security boundary. + +## Develop and verify + +From this directory: + +```sh +python3 build.py +node --test tests/core.test.cjs +# Browser checks require Playwright installed outside this repo: +NODE_PATH=/tmp/context-curator-browser/node_modules node tests/browser.cjs +``` + +`build.py` embeds `core.js`, the sample, and `site/app.js` into `site/template.html`, writes the standalone `site/index.html`, and copies the sample and README beside it. Libre Baskerville Latin regular/italic WOFF2 (Fontsource package, SIL OFL 1.1 in `site/fonts/OFL.txt`) is vendored and embedded as data URLs so the single-file download keeps its typography offline. No build dependency beyond Python 3; core tests require Node 18+. Browser tests accept `CHROME_PATH` (default hb-5 Chrome), `PAGE_URL` (default file://), and `EVIDENCE_DIR` (default /tmp/context-curator-evidence). They cover desktop/phone overflow, undo, imports, exports, escaping, form payload and thank-you state, and screenshots. Run `python3 tests/signup.py /path/to/existing/server.py` for signup acceptance: it imports the existing handler with temporary data, never the real signup list. Checked launch evidence is in `evidence/`; native macOS browser verification was blocked by this seat sandbox (Mach bootstrap permission denied). Node core tests did run on macOS. Container Chromium passed both file:// and a local HTTP `/v/context-curator/` route, including reopening the downloaded HTML offline. The public route is deliberately not polled: publication happens after the issue reply. + +Launch is confined to this venture directory; the factory runner publishes `site/` at `/v/context-curator/` after the issue reply. No shared deployment files are changed. diff --git a/ventures/context-curator/app.js b/ventures/context-curator/app.js new file mode 100644 index 0000000..bd1e3ba --- /dev/null +++ b/ventures/context-curator/app.js @@ -0,0 +1,83 @@ +'use strict'; +const $ = id => document.getElementById(id); +let original = SAMPLE_TEXT; +let applied = null; +let undoState = null; +let generation = 0; +const sampleConclusion = 'Root cause: preview_cache is keyed only by article ID, has no expiry, and is not invalidated on save. Invalidate that key after a successful save; verify with a save-then-preview regression test. Database writes and browser caching were ruled out. Keep the API response unchanged.'; +function report(message) { $('status').textContent = message; } +function downloadsEnabled(value) { + $('packet').disabled = !value; $('result').disabled = !value; +} +function renderSource(text) { + const data = Curator.parse(text); + original = text; applied = null; undoState = null; + $('source').value = text; + for (const id of ['first', 'last']) { + $(id).replaceChildren(...data.messages.map((m, i) => { + const option = document.createElement('option'); option.value = i; + option.textContent = `${i + 1} · ${m.role} · ${m.id}`; + return option; + })); + } + $('first').value = Math.min(2, data.messages.length - 1); + $('last').value = Math.min(7, data.messages.length - 1); + $('conclusion').value = text === SAMPLE_TEXT ? sampleConclusion : ''; + $('before').textContent = JSON.stringify(data, null, 2); + $('after').textContent = 'Apply a conclusion to see the complete result.'; + $('diff').textContent = 'Every message will appear here, including unchanged messages.'; + $('measure').textContent = `${Curator.bytes(JSON.stringify(data)).toLocaleString()} original JSON bytes`; + $('undo').disabled = true; downloadsEnabled(false); + report('Original preserved in memory. Nothing has been uploaded.'); +} +function apply() { + try { + const next = Curator.curate(original, Number($('first').value), Number($('last').value), $('conclusion').value); + undoState = applied; applied = next; + renderResult(); $('undo').disabled = false; + report('Span replaced in the working copy. Review the full diff before exporting.'); + } catch (e) { report(e.message); } +} +function renderResult() { + if (!applied) { + $('after').textContent = 'Working copy restored to the original.'; + $('diff').textContent = $('before').textContent; + $('measure').textContent = `${Curator.bytes(JSON.stringify(Curator.parse(original))).toLocaleString()} original JSON bytes`; + downloadsEnabled(false); return; + } + $('after').textContent = JSON.stringify(applied.result, null, 2); + $('diff').textContent = applied.diff; + const percent = (100 * applied.saved / applied.beforeBytes).toFixed(1); + $('measure').textContent = `${applied.beforeBytes.toLocaleString()} → ${applied.afterBytes.toLocaleString()} JSON bytes · ${percent}% ${applied.saved >= 0 ? 'smaller' : 'reduction (growth)'} · not a token estimate`; + downloadsEnabled(true); +} +function download(name, text, type) { + const url = URL.createObjectURL(new Blob([text], {type})); + const a = document.createElement('a'); a.href = url; a.download = name; + a.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); +} +$('apply').addEventListener('click', apply); +$('undo').addEventListener('click', () => { applied = undoState; undoState = null; renderResult(); $('undo').disabled = true; report('Last replacement undone. Original unchanged.'); }); +$('load').addEventListener('click', () => { try { renderSource($('source').value); generation++; } catch(e) { report(e.message); } }); +$('sample').addEventListener('click', () => { generation++; renderSource(SAMPLE_TEXT); apply(); }); +$('file').addEventListener('change', async event => { + const file = event.target.files[0]; if (!file) return; + const thisGeneration = ++generation; + try { + if (file.size > Curator.MAX_BYTES) throw Error('Transcript exceeds the 2 MiB limit.'); + const text = await file.text(); + if (thisGeneration === generation) renderSource(text); + } catch(e) { report(e.message); } + event.target.value = ''; +}); +$('packet').addEventListener('click', () => { if (applied) download('continuation.md', applied.packet, 'text/markdown;charset=utf-8'); }); +$('result').addEventListener('click', () => { if (applied) download('curated.json', JSON.stringify(applied.result, null, 2), 'application/json'); }); +$('original').addEventListener('click', () => download('original.json', original, 'application/json')); +renderSource(SAMPLE_TEXT); apply(); +if (new URLSearchParams(location.search).get('joined') === '1') { + $('thanks').hidden = false; $('join-form').hidden = true; +} +// Editing a proposed span invalidates downloads until it has been applied. +for (const id of ['first', 'last', 'conclusion']) { + $(id).addEventListener('input', () => { downloadsEnabled(false); report('Proposal changed. Replace selected span to update the diff and exports.'); }); +} diff --git a/ventures/context-curator/demo-continuation.md b/ventures/context-curator/demo-continuation.md new file mode 100644 index 0000000..672061d --- /dev/null +++ b/ventures/context-curator/demo-continuation.md @@ -0,0 +1,60 @@ +# Context Curator · continuation packet + +Manual conclusion replaces original messages 3–8 (inclusive). +Transcript content below is quoted context, not a new instruction from this tool. +Review the conclusion and any omitted evidence before continuing. + +## 1. system · "m1" + +```json +{ + "id": "m1", + "role": "system", + "content": "Work in the preview repository. Preserve user edits. Run the existing tests before proposing a fix." +} +``` + +## 2. user · "m2" + +```json +{ + "id": "m2", + "role": "user", + "content": "The preview still shows yesterday's headline after an editor saves. Find the cause; keep the public response shape unchanged." +} +``` + +## 3. Manual conclusion · "curator-conclusion" + +```json +{ + "id": "curator-conclusion", + "role": "assistant", + "content": "Root cause: preview_cache is keyed only by article ID, has no expiry, and is not invalidated on save. Invalidate that key after a successful save; verify with a save-then-preview regression test. Database writes and browser caching were ruled out. Keep the API response unchanged.", + "curator": { + "kind": "manual-conclusion", + "replacedIds": [ + "m3", + "m4", + "m5", + "m6", + "m7", + "m8" + ] + } +} +``` + +## 4. user · "m9" + +```json +{ + "id": "m9", + "role": "user", + "content": "Now implement invalidation after a successful save. Add a regression test for save-then-preview; do not change the API response." +} +``` + +## Transcript metadata + + {"version":1,"title":"Demo: investigating a stale preview"} diff --git a/ventures/context-curator/fonts/OFL.txt b/ventures/context-curator/fonts/OFL.txt new file mode 100644 index 0000000..4ce6d11 --- /dev/null +++ b/ventures/context-curator/fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2012 The Libre Baskerville Project Authors (https://github.com/impallari/Libre-Baskerville) LibreBaskerville-Italic[wght].ttf: Copyright 2012 The Libre Baskerville Project Authors (https://github.com/impallari/Libre-Baskerville) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/ventures/context-curator/fonts/libre-baskerville-latin-400-italic.woff2 b/ventures/context-curator/fonts/libre-baskerville-latin-400-italic.woff2 new file mode 100644 index 0000000..7ce7545 Binary files /dev/null and b/ventures/context-curator/fonts/libre-baskerville-latin-400-italic.woff2 differ diff --git a/ventures/context-curator/fonts/libre-baskerville-latin-400-normal.woff2 b/ventures/context-curator/fonts/libre-baskerville-latin-400-normal.woff2 new file mode 100644 index 0000000..c32fb72 Binary files /dev/null and b/ventures/context-curator/fonts/libre-baskerville-latin-400-normal.woff2 differ diff --git a/ventures/context-curator/index.html b/ventures/context-curator/index.html new file mode 100644 index 0000000..fac65a9 --- /dev/null +++ b/ventures/context-curator/index.html @@ -0,0 +1,182 @@ + + + + + +Context Curator — Keep the finding. + + + +
A notplanned publication · No. 003Local tools / better handoffs
Context CuratorA field guide to carrying less.
+
+

For developers with a long conversation behind them

Keep the finding.
Cut the detour.

Your agent explored six dead ends. The next session needs the conclusion — and everything that still matters around it.

Join the early access list →

Free local editor below. No account needed.

+

The working edition

Illustrative debugging transcript · editable, not a benchmark
+

The sample removes messages 3–8, retaining the requirements and next task. Try your own transcript using the documented version 1 format.

+
Paste JSON / inspect the sample format

Required: {"version":1,"messages":[{"id":"m1","role":"user","content":"…"}]}. Roles: system, user, assistant, tool. Unique string IDs. Extra metadata is retained.

+
+ +

+

Offline copy: download this complete editor. Open the saved HTML in your browser. Sample JSON · Demo packet · Usage & limits

+

Complete message diff · − removed · + manual conclusion · unmarked retained.
All message fields are shown. No hidden context.

Complete original JSON
Complete curated JSON
+

01 / Mark the detour.

Import a transcript you have explicitly exported or converted. Pick one contiguous span. Messages outside it stay unchanged, including their metadata.

02 / Write what survived.

State the finding, evidence, unresolved questions, and next step. Nothing is summarized by a model. You decide what can safely be left behind.

03 / Review & carry forward.

Read the full diff. Download the quoted Markdown context for a fresh session. No live agent sessions or configuration are modified. Byte reduction is not a token or cost promise.

+

An honest price list.

Paid ideas are early access. No checkout, no billing.
Local edition$0 · available todayComplete offline editor, sample, undo, diff and exports. No signup required.
Founding workshop$49 one-time · proposed founding priceEarly access idea: a guided transcript-conversion and handoff review. Register interest; not yet delivered.
+

The next edition

Less history.
More continuity.

Get release updates, or signal interest in a guided workshop. The free editor is already yours.

We use your email for Context Curator updates and your requested early access follow-up; we never share it. Do not put transcript content or secrets in the note.

Signup requires the hosted page and a connection. The editor works offline.

+
Context Curator · made at notplannedNo model calls. No trackers. No live-session access. Keep your original.
+ + diff --git a/ventures/context-curator/sample.json b/ventures/context-curator/sample.json new file mode 100644 index 0000000..b0d7a05 --- /dev/null +++ b/ventures/context-curator/sample.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "title": "Demo: investigating a stale preview", + "messages": [ + {"id":"m1","role":"system","content":"Work in the preview repository. Preserve user edits. Run the existing tests before proposing a fix."}, + {"id":"m2","role":"user","content":"The preview still shows yesterday's headline after an editor saves. Find the cause; keep the public response shape unchanged."}, + {"id":"m3","role":"assistant","content":"First hypothesis: the editor is not writing the new headline. Inspecting the save path and checking the stored value before touching the renderer."}, + {"id":"m4","role":"tool","content":"save_headline('A better morning') -> 200. SELECT headline FROM articles WHERE id=42 -> 'A better morning'. Storage is correct. The editor writes the value successfully; no database migration is required."}, + {"id":"m5","role":"assistant","content":"Second hypothesis: the browser caches the HTML. Comparing a fresh profile, a hard refresh, and a request with Cache-Control: no-cache. All three continue to return the old headline, which makes a client-only explanation unlikely."}, + {"id":"m6","role":"tool","content":"GET /preview/42 -> 200, headline 'Yesterday'. Fresh browser -> 'Yesterday'. Request with no-cache -> 'Yesterday'. The response headers contain no shared cache directives. The stale result is already in the server response."}, + {"id":"m7","role":"assistant","content":"Third hypothesis: a second database connection reads a replica. Checked connection configuration and request logs. Both save and preview use the same primary database. Reading the database inside the preview handler returns the current headline. Inspect the in-process memoization layer next."}, + {"id":"m8","role":"tool","content":"preview_cache key: article_id only. Cached entries have no expiry. Save path updates the article but never invalidates preview_cache. Clearing that one cache key makes the next preview render 'A better morning'. Root cause reproduced without modifying the database."}, + {"id":"m9","role":"user","content":"Now implement invalidation after a successful save. Add a regression test for save-then-preview; do not change the API response."} + ] +} diff --git a/ventures/context-curator/template.html b/ventures/context-curator/template.html new file mode 100644 index 0000000..abba249 --- /dev/null +++ b/ventures/context-curator/template.html @@ -0,0 +1,33 @@ + + + + + +Context Curator — Keep the finding. + + + +
A notplanned publication · No. 003Local tools / better handoffs
Context CuratorA field guide to carrying less.
+
+

For developers with a long conversation behind them

Keep the finding.
Cut the detour.

Your agent explored six dead ends. The next session needs the conclusion — and everything that still matters around it.

Join the early access list →

Free local editor below. No account needed.

+

The working edition

Illustrative debugging transcript · editable, not a benchmark
+

The sample removes messages 3–8, retaining the requirements and next task. Try your own transcript using the documented version 1 format.

+
Paste JSON / inspect the sample format

Required: {"version":1,"messages":[{"id":"m1","role":"user","content":"…"}]}. Roles: system, user, assistant, tool. Unique string IDs. Extra metadata is retained.

+
+ +

+

Offline copy: download this complete editor. Open the saved HTML in your browser. Sample JSON · Demo packet · Usage & limits

+

Complete message diff · − removed · + manual conclusion · unmarked retained.
All message fields are shown. No hidden context.

Complete original JSON
Complete curated JSON
+

01 / Mark the detour.

Import a transcript you have explicitly exported or converted. Pick one contiguous span. Messages outside it stay unchanged, including their metadata.

02 / Write what survived.

State the finding, evidence, unresolved questions, and next step. Nothing is summarized by a model. You decide what can safely be left behind.

03 / Review & carry forward.

Read the full diff. Download the quoted Markdown context for a fresh session. No live agent sessions or configuration are modified. Byte reduction is not a token or cost promise.

+

An honest price list.

Paid ideas are early access. No checkout, no billing.
Local edition$0 · available todayComplete offline editor, sample, undo, diff and exports. No signup required.
Founding workshop$49 one-time · proposed founding priceEarly access idea: a guided transcript-conversion and handoff review. Register interest; not yet delivered.
+

The next edition

Less history.
More continuity.

Get release updates, or signal interest in a guided workshop. The free editor is already yours.

We use your email for Context Curator updates and your requested early access follow-up; we never share it. Do not put transcript content or secrets in the note.

Signup requires the hosted page and a connection. The editor works offline.

+
Context Curator · made at notplannedNo model calls. No trackers. No live-session access. Keep your original.
+ + diff --git a/ventures/context-priority/context-priority.zip b/ventures/context-priority/context-priority.zip new file mode 100644 index 0000000..b729108 Binary files /dev/null and b/ventures/context-priority/context-priority.zip differ diff --git a/ventures/context-priority/demo.js b/ventures/context-priority/demo.js new file mode 100644 index 0000000..172dab5 --- /dev/null +++ b/ventures/context-priority/demo.js @@ -0,0 +1,44 @@ +'use strict'; +const sample = [ + {role:'user',content:'Ship a migration plan. Never delete customer records.'}, + {role:'assistant',content:'Constraint accepted: preserve every customer record.'}, + {role:'user',content:'Check the schema.'}, + {role:'assistant',content:'Reading schema.',tool_calls:[{id:'schema-1',type:'function',function:{name:'read_file',arguments:'schema.sql'}}]}, + {role:'tool',tool_call_id:'schema-1',content:'customers(id, email, created_at)'}, + {role:'assistant',content:'Add the index concurrently; retain all rows.'}, + {role:'user',content:'Aside: what should the mascot wear?'}, + {role:'assistant',content:'A very large green hat. This does not affect the migration.'}, + {role:'user',content:'Continue with the rollback checklist.'}, + {role:'assistant',content:'Rollback removes the new index only, never customer data.'} +].map(row=>JSON.stringify(row)).join('\n')+'\n'; +const engine = ContextPriority; +const exchanges = engine.parse(sample); +const priorities = {e001:'pinned',e002:'normal',e003:'aside',e004:'normal'}; +const labels = ['Customer data constraint','Schema + tool call/result','Mascot tangent','Rollback checklist']; +let result; +const list = document.querySelector('#exchanges'); +exchanges.forEach((exchange,index)=>{ + const row=document.createElement('label'); row.className='exchange'; + const text=document.createElement('span'); text.textContent=exchange.id+' / '+labels[index]; + const select=document.createElement('select'); select.setAttribute('aria-label',labels[index]+' priority'); select.dataset.id=exchange.id; + for(const value of ['pinned','normal','aside']) {const option=document.createElement('option');option.value=value;option.textContent=value;select.append(option);} + select.value=priorities[exchange.id]; select.addEventListener('change',()=>{priorities[exchange.id]=select.value;render();}); + row.append(text,select);list.append(row); +}); +function render(){ + result=null; document.querySelector('#download').disabled=true;document.querySelector('#manifest-download').disabled=true; + try { + result=engine.select(exchanges,priorities,Number(document.querySelector('#budget').value)); + document.querySelector('#packet').textContent=result.packet; + document.querySelector('#manifest').textContent=JSON.stringify(result.manifest,null,2); + document.querySelector('#status').textContent=result.manifest.packetBytes+' bytes / '+result.manifest.exchanges.filter(e=>e.selected).length+' of 4 exchanges kept'; + document.querySelector('#download').disabled=false; document.querySelector('#manifest-download').disabled=false; + }catch(error){document.querySelector('#packet').textContent='Export refused. Raise the budget or change your pins.';document.querySelector('#manifest').textContent='';document.querySelector('#status').textContent=error.message;} +} +function download(value,name,type){const url=URL.createObjectURL(new Blob([value],{type}));const a=document.createElement('a');a.href=url;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);} +document.querySelector('#budget').addEventListener('input',render); +document.querySelector('#download').addEventListener('click',()=>{if(result)download(result.packet,'continuation.md','text/markdown');}); +document.querySelector('#manifest-download').addEventListener('click',()=>{if(result)download(JSON.stringify(result.manifest,null,2),'omissions.json','application/json');}); +document.querySelector('#source').textContent=sample; +if(new URLSearchParams(location.search).get('joined')==='1'){document.querySelector('#thanks').hidden=false;document.querySelector('#join-form').hidden=true;} +render(); diff --git a/ventures/context-priority/engine.js b/ventures/context-priority/engine.js new file mode 100644 index 0000000..0a1b816 --- /dev/null +++ b/ventures/context-priority/engine.js @@ -0,0 +1,70 @@ +/* One deterministic engine, used by Node and the browser. No dependencies. */ +(function (root) { + 'use strict'; + const bytes = s => new TextEncoder().encode(s).length; + const header = '# Context priority continuation\n\nSelected complete exchanges in original order. JSONL payloads are verbatim.\n\n'; + function parse(source) { + if (typeof source !== 'string' || !source.trim()) throw Error('Empty transcript'); + const exchanges = []; let current; let pending = new Set(); let assistant = false; let lastRole; let seenCalls = new Set(); + function finish() { + if (!current) return; + if (!assistant || pending.size || lastRole !== 'assistant') throw Error('Incomplete exchange ' + current.id + ': missing assistant response or tool result'); + exchanges.push(current); + } + for (const [index, raw] of (source.match(/[^\n]*\n|[^\n]+$/g) || []).entries()) { + if (!raw.trim()) throw Error('Blank line at ' + (index + 1)); + let row; try { row = JSON.parse(raw); } catch { throw Error('Invalid JSON at line ' + (index + 1)); } + const msg = row.message || row; + const role = msg.role || row.type; + if (!['user', 'assistant', 'tool'].includes(role) || msg.content === undefined) throw Error('Unsupported record at line ' + (index + 1) + '; use user/assistant/tool JSONL'); + const blocks = Array.isArray(msg.content) ? msg.content : []; + const results = blocks.filter(b => b.type === 'tool_result'); + const resultOnly = role === 'tool' || (role === 'user' && blocks.length > 0 && results.length === blocks.length); + if (role === 'user' && !resultOnly) { + if (results.length) throw Error('Mixed user text and tool results: normalize this export first'); + finish(); current = {id: 'e' + String(exchanges.length + 1).padStart(3, '0'), raw: ''}; pending = new Set(); assistant = false; seenCalls = new Set(); + } + if (!current) throw Error('Transcript must start with a user prompt'); + if (role === 'assistant') { + assistant = true; + const calls = [...(msg.tool_calls || []).map(c => c.id), ...blocks.filter(b => b.type === 'tool_use').map(b => b.id)]; + for (const id of calls) { + if (typeof id !== 'string' || !id || seenCalls.has(id)) throw Error('Invalid or duplicate tool call'); + pending.add(id); seenCalls.add(id); + } + } + const ids = role === 'tool' ? [msg.tool_call_id] : results.map(b => b.tool_use_id); + for (const id of ids) { if (!pending.delete(id)) throw Error('Unmatched tool result at line ' + (index + 1)); } + current.raw += raw; lastRole = role; + } + finish(); return exchanges; + } + function block(exchange) { + let length = 3; + for (const match of exchange.raw.matchAll(/`+/g)) length = Math.max(length, match[0].length + 1); + const fence = '`'.repeat(length); + return '## ' + exchange.id + '\n\n' + fence + 'jsonl\n' + exchange.raw + (exchange.raw.endsWith('\n') ? '' : '\n') + fence + '\n\n'; + } + function select(exchanges, priorities, budget) { + if (!Number.isSafeInteger(budget) || budget < 0) throw Error('Budget must be a nonnegative integer of UTF-8 bytes'); + if (!priorities || typeof priorities !== 'object' || Array.isArray(priorities)) throw Error('Invalid priorities'); + const ids = new Set(exchanges.map(e => e.id)); + for (const [id, priority] of Object.entries(priorities)) { + if (!ids.has(id) || !['pinned', 'normal', 'aside'].includes(priority)) throw Error('Invalid priority entry: ' + id); + } + const priority = e => priorities[e.id] || 'normal'; + const selected = new Set(); const costs = new Map(exchanges.map(e => [e.id, bytes(block(e))])); + let used = bytes(header); + for (const e of exchanges.filter(e => priority(e) === 'pinned')) { selected.add(e.id); used += costs.get(e.id); } + if (used > budget) throw Error('Budget too small: pinned content and packet framing require ' + used + ' bytes'); + for (const tier of ['normal','aside']) for (const e of exchanges.filter(e => priority(e) === tier)) { + if (used + costs.get(e.id) <= budget) { selected.add(e.id); used += costs.get(e.id); } + } + const packet = header + exchanges.filter(e => selected.has(e.id)).map(block).join(''); + const manifest = {version: 1, budgetBytes: budget, packetBytes: bytes(packet), ordering: 'pinned first; normal next; aside last; oldest fitting first within tier; output chronological', exchanges: exchanges.map(e => ({id:e.id,priority:priority(e),bytes:costs.get(e.id),selected:selected.has(e.id),reason:selected.has(e.id)?'selected':'budget'}))}; + return {packet,manifest}; + } + const api = {parse,select,bytes,block}; + if (typeof module !== 'undefined' && module.exports) module.exports = api; + else root.ContextPriority = api; +})(typeof globalThis !== 'undefined' ? globalThis : this); diff --git a/ventures/context-priority/index.html b/ventures/context-priority/index.html new file mode 100644 index 0000000..fd0b937 --- /dev/null +++ b/ventures/context-priority/index.html @@ -0,0 +1,40 @@ + + + + + +Context Priority — KEEP THE IMPORTANT PART. + + + + +
CONTEXT PRIORITY / 001A NOTPLANNED TOOL
LOCAL. DETERMINISTIC. YOUR CALL.
+
+
+
CONTEXT IS A FINITE RESOURCE.

Keep the
important
part.

PINNED → NORMAL → ASIDE
ONE ENGINE. NO MODEL CALLS.
+
For people who work in long threads

The constraint you wrote an hour ago should survive the tangent you wrote five minutes ago.

Mark whole exchanges. Set a byte budget. Get a continuation packet you can inspect.

GET EARLY ACCESS ↗

Free CLI available below. Paid plans are ideas, not a checkout.

+
+
PINS STAY VERBATIM. TOOL PAIRS STAY TOGETHER. TOO SMALL A BUDGET? WE REFUSE THE EXPORT.
+
01 / Try the actual selection engine

Give the tangent
less room.

+

Four synthetic exchanges. Change a priority and watch the packet change. Pin everything, then lower the budget to see a hard refusal. No transcript uploads.

+

BEFORE / PRIORITIES

Oldest fitting exchange wins within each tier. Export restores chronology. This is a byte budget, not a model token count.

Inspect untouched source JSONL
Loading synthetic demo…
+
Inspect selection / omission manifest
+
+
02 / Run it locally

Your files. Your machine.

No install scripts. No API key. Unzip the free bundle and use Node.js 20 or newer. Annotations live in a separate sidecar tied to the source SHA-256.

DOWNLOAD FREE CLI (.zip) ↓

Includes source, sample, tests and README.
Verified on hb-5 macOS and Node 20 in Colima.

# From the extracted context-priority folder:
+node cli.cjs annotate sample.jsonl priorities.json \
+  e001=pinned e003=aside
+
+node cli.cjs export sample.jsonl priorities.json \
+  1000 ./out
+
+# out/continuation.md + out/omissions.json
+# Existing outputs require typing OVERWRITE.
+# Run the checks:
+node --test tests/*.test.cjs
+
03 / Founding plans — no checkout yet

Start free. Tell us what’s next.

LOCAL

$0

The CLI, synthetic demo, sidecars and packet export. Available today.

NO ACCOUNT REQUIRED

WORKBENCH

$12 / mo

Proposed saved workflows and richer local import adapters.

FOUNDING PRICE IDEA · NOT BUILT

TEAM

$39 / mo

Proposed shared priority policies and reviewable packet history.

FOUNDING PRICE IDEA · NOT BUILT
+
04 / Join the early access list

Help pick
the next
exchange.

Choose the tier you’re interested in. No payment, no commitment.

We use your email for Context Priority launch updates and early access invitations.

+
05 / The fine print, in normal-sized type

Selection. Not magic.

This is a standalone offline selector, not live compaction and not an integration with Claude Code, Fly or Boring. It accepts ordered user/assistant/tool JSONL and message-wrapped user/assistant records; metadata rows, branching histories and incomplete exchanges are rejected. Normalize unsupported exports first. There is no tokenizer, summarizer, secret scrubber or semantic dependency analysis. Inspect the packet before sharing it.

Pinned payloads remain verbatim inside Markdown JSONL blocks. Unpinned exchanges can be omitted. The manifest tells you exactly which ones. A selected exchange keeps all its tool calls and results. Selection does not guarantee an assistant will obey the continuation.

The board’s upstream reference is anthropics/claude-code #83489: named model + effort presets, closed as not planned. That issue asks for presets; this venture implements the board’s separate context-priority brief. It does not implement model presets and is not affiliated with Anthropic.

+
CONTEXT PRIORITY / BUILT BY NOTPLANNEDPIN IT. INSPECT IT. CARRY IT FORWARD.
+ diff --git a/ventures/finishline-supervisor/LAUNCH.md b/ventures/finishline-supervisor/LAUNCH.md new file mode 100644 index 0000000..23849e0 --- /dev/null +++ b/ventures/finishline-supervisor/LAUNCH.md @@ -0,0 +1,65 @@ +# Finishline Supervisor — launch iteration + +Synthesized from the board's submitted launch plans for this venture: **codex** and **claude**. +**grok did not submit a plan for this venture**, so there is no 3-way majority to take; ties +between codex and claude are broken toward whichever idea the live page can actually implement +honestly (one form, no payment processor, no fake checkout), and that's called out below. + +## Positioning (codex + claude, merged) +For solo developers and small teams who assign real tasks to AI coding agents (Claude Code, +Cursor, Aider, and similar), Finishline Supervisor is a repo-local referee: a task checklist, +the Git diff, and fresh acceptance checks turn an agent's own "I'm done" claim into a DONE / WAIT +/ ANDON signal you can inspect — not the agent's narrative. + +## Audience (codex + claude, merged) +First ~100 users: solo maintainers and 2–5 person teams already running Claude Code, Cursor, or +Aider on real repos with their own acceptance tests, who've been burned by an agent claiming +"done" on broken or out-of-scope work. Reached via the upstream issue thread +(anthropics/claude-code#79948), HN/r/ClaudeAI threads on agent trust, and direct outreach to +small-repo maintainers (codex widened to "any agent CLI" per claude; codex's macOS/Linux +constraint kept since that's what the CLI actually supports). + +## Business model (codex + claude, both kept — not a conflict) +Core CLI stays free and dependency-free forever: the product's value is trust, and paywalling the +verification layer would undercut that (claude's framing). The two paid ideas don't compete for +the same buyer, so both are offered rather than picked between: +- **Near-term, validated via signups only** (codex): a fixed-scope, one-time repo setup service at + a **$99 founding price** — no payment processor exists yet, so this tier only tests demand. +- **Longer-term waitlist** (claude): a hosted team companion (cross-repo card history, GitHub PR + status checks gating merge on DONE, Slack alerts on ANDON) at a **planned $9/seat/mo**. +Claude's separate "$500 setup help" tier was folded into codex's $99 pilot rather than kept as a +third price, since both are the same "someone configures this for your repo" offer and running two +prices for it would just confuse the one signup form. + +## Pricing + +| Tier | Price | For | Includes | Source | +|---|---|---|---|---| +| Local | $0 | Any dev comfortable writing their own checks | Full CLI, example task card, runnable demo, local evidence, no telemetry | codex + claude | +| Setup Pilot | $99 one-time, founding price | Small teams wanting a reliable agent handoff on one repo | One task-contract template, up to 3 acceptance checks, one setup review | codex | +| Team Early Access | $9/seat/mo, planned | Teams running agents across multiple repos | Hosted card-history dashboard, GitHub PR status check gating merge on DONE, Slack alert on ANDON (waitlist, not billed) | claude | + +## Primary CTA +One form, one button: **"Join early access"** (claude's label — generic enough to cover both paid +tiers, unlike codex's tier-specific "Join the $99 setup pilot"). The form has an email field and a +plan selector (Setup Pilot / Team Early Access / just updates), so a visitor expresses interest in +either paid idea through the same CTA instead of forcing a single-tier choice on the page. + +## Launch channels (drafts for chair approval — none sent by us) +1. Reply on anthropics/claude-code#79948 linking the launch page (claude) +2. Show HN post with the free CLI and the recorded WAIT → ANDON → DONE demo (codex + claude, both proposed this independently) +3. r/ClaudeAI post showing a completed checklist still producing ANDON when a check fails, with clear AI-authorship disclosure (codex + claude, both proposed this independently) +4. Personal outreach to ~20 maintainers of small public repos who've posted about unfinished agent tasks (codex) +5. Post in dev-tools Discord/Slack communities already has a presence in (claude) + +## 7-day success metric (merged) +At least 15 qualified email signups, including (a) at least 3 explicit picks of Setup Pilot or +Team Early Access combined (codex's paid-commitment bar, widened from one tier to both since the +page now offers two), and (b) at least 5 signups who also download the CLI from this page or have +starred/cloned the repo (claude's intent signal) → keep going, deliver the first pilot. + +## 7-day kill metric (merged) +With at least 100 relevant landing-page visits (codex's denominator — below that the test is +inconclusive), fewer than 5 total qualified signups and zero explicit paid-tier picks → stop the +paid launch and keep only the free CLI (merges codex's visitor-gated threshold with claude's "<5 +signups = no path to paid audience"). diff --git a/ventures/finishline-supervisor/README.md b/ventures/finishline-supervisor/README.md new file mode 100644 index 0000000..46e2dcc --- /dev/null +++ b/ventures/finishline-supervisor/README.md @@ -0,0 +1,71 @@ +# Finishline Supervisor + +A repo-local Finishline card: one JSON file and a dependency-free CLI that reports **DONE / WAIT / ANDON** from a task checklist, Git changes, and fresh acceptance checks. No model calls, agent changes, server, or package install. + +Inspired by [anthropics/claude-code#79948](https://github.com/anthropics/claude-code/issues/79948), closed as not planned: agents need to finish the assigned task and show evidence. This is a small evidence wrapper, not the native enforcement boundary requested upstream. + +## Install + +Requires Python 3.9+, Git, and a POSIX host (macOS/Linux). Copy `finishline.py` anywhere you keep tools, or use it from this checkout. No dependencies. Run inside the target Git repository, which needs at least one commit. Commands always run from the repository root, even when invoked in a subdirectory. + +```sh +# From the notplanned checkout: +python3 ventures/finishline-supervisor/demo.py +python3 -m unittest discover -s ventures/finishline-supervisor -p 'test_*.py' -v +``` + +For another repository, copy the script to a trusted location and invoke `python3 /path/to/finishline.py` there. + +## Usage + +Write `task.md` with concrete acceptance items: + +```markdown +- [ ] Build a greeting CLI +- [ ] Verify its exact output +- [ ] Document usage +``` + +Initialize before work starts; explicitly allow files or directories relative to the repo root. Directory scope includes descendants, not similarly named siblings. Acceptance checks are JSON argv arrays, never shell strings: + +```sh +python3 /path/to/finishline.py init \ + --allow task.md --allow app.py --allow README.md \ + --check '["python3","-c","import subprocess; assert subprocess.check_output([\"python3\",\"app.py\"], text=True).strip() == \"finish line\""]' + +# Inspect the card and its command argv before running checks. +python3 /path/to/finishline.py check +python3 /path/to/finishline.py check --run-checks +``` + +Repeat `--check` for more checks (up to 20). `--timeout 30` sets seconds per check (1–300). `--card another.json` precedes `init` or `check` and selects a new contract. Existing cards are never overwritten by `init`. If the task definition or scope changes, explicitly create a new reviewed card; a checkbox toggle is normal progress. + +Each check writes the latest evidence into `finishline.json`, retaining at most 20 runs. The card records the base commit, pinned task hashes, scope, command argv, timestamp, current HEAD, task line links, changed paths, and exit codes. Writes use atomic replacement. Put the card in Git if you want a portable handoff; only that exact card is exempt from the scope check. Prior passing runs never substitute for fresh checks. + +| Signal / exit | Meaning | +| --- | --- | +| DONE / 0 | A nonempty checklist is complete, task definition matches, changes fit scope, every acceptance check just passed, and checks did not change observed repository evidence. | +| WAIT / 1 | Checklist incomplete/missing, or checks have not been explicitly executed. | +| ANDON / 2 | Task/scope drift, failed/timed-out/unstartable check, evidence mutation, or invalid/unavailable input. Review the reason and repair the task or command. | + +ANDON takes priority over WAIT. Checks stop at the first failure. Output is JSON; init prints a short confirmation. Errors fail closed and do not echo exception contents. + +## Recorded dogfood + +`demo.py` creates a disposable Git repository and runs the CLI three separate times on the three-step greeting task. It asserts the signals, then removes only its own temporary repository: + +1. Build `app.py`, leaving verification and documentation pending: **WAIT**. +2. Write usage documentation; the actual output is still `almost`, so the acceptance check fails: **ANDON**. +3. Fix output to `finish line`, verify it, complete the checklist: **DONE**. + +[Recorded terminal output](demo.txt) and [full run evidence](demo-evidence.json) were generated by that runnable demo. Commit IDs/timestamps will differ when rerun. The landing page repeats the recorded output. + +## Limits and trust + +- This observes a repository; it does not orchestrate agents, merge, deploy, call models, edit their settings, or enforce a native permission boundary. An agent with write access can edit this script, the card, or the checks. Keep trusted contracts/checks outside that agent's authority if you need enforcement. +- `--run-checks` executes arbitrary trusted local programs with your permissions and environment. There is no sandbox, network restriction, or rollback. Review them first. The timeout kills their POSIX process group; a process that deliberately detaches can escape it. Checks should be read-only; evidence mutations trigger ANDON, but are not reverted. +- Git scope compares current tracked content to the pinned base and includes staged/untracked paths. It detects committed changes and renames. It excludes Git-ignored files, reverted changes, files outside the repo, and the selected card. This is current-state evidence, not a complete action audit. Large repositories cost time to hash. +- DONE proves only your checklist and checks at that instant. Weak tests can pass broken work. External state/deployment needs an explicit acceptance check; uncommitted work may be DONE. Nothing is automatically published by the tool. +- Child stdout/stderr are discarded, not saved or printed. Re-run a failed command directly to debug. Do not put secrets in task text, filenames, or argv: those values are evidence/card content. No log uploads or telemetry. +- One writer per card; atomic writes prevent partial JSON, but concurrent runs are unsupported. Interrupted checks leave the previous card intact. Run again for fresh evidence. +- Verified with all 14 tests and the three-run demo on the local Mac/Python host and in the existing `teahub-linux-runner:latest` Colima container, with network disabled and a read-only root filesystem. No claim that the CLI was run on Fly or Boring. diff --git a/ventures/finishline-supervisor/demo-evidence.json b/ventures/finishline-supervisor/demo-evidence.json new file mode 100644 index 0000000..a172b26 --- /dev/null +++ b/ventures/finishline-supervisor/demo-evidence.json @@ -0,0 +1,82 @@ +{ + "scenario": "Three-step greeting CLI, three separate supervisor invocations", + "runs": [ + { + "at": "2026-10-10T03:24:40.081191+00:00", + "head": "d5e4d8a80a91bcc784333207ace1bf4935324c38", + "task_sha256": "00b0c9d722db57e6094762e2baa5fa6a7fe3a65941bbd6b6bcf501fc2c6028ce", + "status": "WAIT", + "reasons": [ + "task checklist is incomplete", + "checks not executed; pass --run-checks after reviewing argv" + ], + "evidence": [ + "task.md#L1", + "task.md#L2", + "task.md#L3" + ], + "changed": [ + "app.py", + "task.md" + ], + "checks": [] + }, + { + "at": "2026-10-10T03:24:40.156618+00:00", + "head": "d5e4d8a80a91bcc784333207ace1bf4935324c38", + "task_sha256": "49ef3ee174c281ea60a5493131e3bec5228e24efd039eb4c6fcc722f0b227eb9", + "status": "ANDON", + "reasons": [ + "task checklist is incomplete", + "acceptance check failed" + ], + "evidence": [ + "task.md#L1", + "task.md#L2", + "task.md#L3" + ], + "changed": [ + "README.md", + "app.py", + "task.md" + ], + "checks": [ + { + "argv": [ + "/Library/Developer/CommandLineTools/usr/bin/python3", + "-c", + "import subprocess,sys; assert subprocess.check_output([sys.executable,\"app.py\"], text=True).strip() == \"finish line\"" + ], + "exit": 1 + } + ] + }, + { + "at": "2026-10-10T03:24:40.441378+00:00", + "head": "d5e4d8a80a91bcc784333207ace1bf4935324c38", + "task_sha256": "1706e7c498b2f84f5d702c308e5526ab5335eea6c54be881e5fc2443ae236c2e", + "status": "DONE", + "reasons": [], + "evidence": [ + "task.md#L1", + "task.md#L2", + "task.md#L3" + ], + "changed": [ + "README.md", + "app.py", + "task.md" + ], + "checks": [ + { + "argv": [ + "/Library/Developer/CommandLineTools/usr/bin/python3", + "-c", + "import subprocess,sys; assert subprocess.check_output([sys.executable,\"app.py\"], text=True).strip() == \"finish line\"" + ], + "exit": 0 + } + ] + } + ] +} diff --git a/ventures/finishline-supervisor/demo.txt b/ventures/finishline-supervisor/demo.txt new file mode 100644 index 0000000..7c961d6 --- /dev/null +++ b/ventures/finishline-supervisor/demo.txt @@ -0,0 +1,12 @@ +run 1: WAIT (exit 1) + task checklist is incomplete + checks not executed; pass --run-checks after reviewing argv + evidence: task.md#L1, task.md#L2, task.md#L3 +run 2: ANDON (exit 2) + task checklist is incomplete + acceptance check failed + acceptance exit: 1 + evidence: task.md#L1, task.md#L2, task.md#L3 +run 3: DONE (exit 0) + acceptance exit: 0 + evidence: task.md#L1, task.md#L2, task.md#L3 diff --git a/ventures/finishline-supervisor/finishline.py b/ventures/finishline-supervisor/finishline.py new file mode 100644 index 0000000..96fa1a9 --- /dev/null +++ b/ventures/finishline-supervisor/finishline.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +"""Repo-local evidence gate. Python 3.9+, Git, no dependencies.""" +import argparse +import datetime as dt +import hashlib +import json +import os +from pathlib import Path +import re +import signal +import subprocess +import tempfile + + +def git(root, *args): + return subprocess.check_output(['git', '-C', str(root), *args], stderr=subprocess.DEVNULL, timeout=30) + + +def digest(data): + return hashlib.sha256(data).hexdigest() + + +def local(root, name): + p = Path(name) + if p.is_absolute() or '..' in p.parts or not p.parts or p == Path('.'): + raise ValueError('paths must be relative, nonempty, and contain no ..') + resolved = (root / p).resolve() + if not resolved.is_relative_to(root): + raise ValueError('path escapes repository') + return resolved + + +def changed(root, base, card): + tracked = git(root, 'diff', '--no-renames', '--name-only', '-z', base) + others = git(root, 'ls-files', '--others', '--exclude-standard', '-z') + return sorted(set(os.fsdecode(p) for p in (tracked + others).split(b'\0') if p) - {card}) + + +def snapshot(root, base, card): + # Hash tracked and untracked contents; never persist command output or file contents. + h = hashlib.sha256(git(root, 'rev-parse', 'HEAD')) + for name in changed(root, base, card): + h.update(os.fsencode(name) + b'\0') + p = root / name + if p.is_symlink(): + h.update(os.fsencode(os.readlink(p))) + elif p.is_file(): + with p.open('rb') as f: + for block in iter(lambda: f.read(65536), b''): + h.update(block) + else: + h.update(b'') + # Include staged content, file modes, deletions and the pinned task even if unchanged. + h.update(git(root, 'diff', '--binary', base, '--', '.', ':(exclude)' + card)) + h.update(git(root, 'diff', '--cached', '--binary', base, '--', '.', ':(exclude)' + card)) + return h.hexdigest() + + +def save(path, data): + if path.is_symlink(): + raise ValueError('card must not be a symlink') + fd, name = tempfile.mkstemp(prefix='.finishline-', dir=path.parent) + try: + with os.fdopen(fd, 'w') as f: + json.dump(data, f, indent=2) + f.write('\n') + f.flush() + os.fsync(f.fileno()) + os.replace(name, path) + finally: + if os.path.exists(name): + os.unlink(name) + + +def validate(root, data): + if data.get('version') != 1: + raise ValueError('unsupported card version') + local(root, data['task']) + if not re.fullmatch(r'[0-9a-f]{64}', data['task_sha256']): + raise ValueError('invalid task hash') + if not re.fullmatch(r'[0-9a-f]{40,64}', data['base']): + raise ValueError('invalid base commit') + if (not isinstance(data['allow'], list) or not isinstance(data['checks'], list) + or not 1 <= len(data['allow']) <= 100 or not 1 <= len(data['checks']) <= 20): + raise ValueError('require 1..100 scope paths and 1..20 acceptance checks') + for path in data['allow']: + local(root, path) + if not isinstance(data['timeout'], int) or not 1 <= data['timeout'] <= 300: + raise ValueError('timeout must be 1..300 seconds') + for argv in data['checks']: + if not isinstance(argv, list) or not argv or not all(isinstance(s, str) and s for s in argv): + raise ValueError('each check must be a nonempty JSON argv array') + + +def run_check(root, argv, timeout): + # No shell. Checks are still arbitrary local code, explicitly opted into by the user. + with subprocess.Popen(argv, cwd=root, stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, start_new_session=True) as p: + try: + code = p.wait(timeout=timeout) + return {'argv': argv, 'exit': code} + except subprocess.TimeoutExpired: + try: + os.killpg(p.pid, signal.SIGKILL) + except ProcessLookupError: + pass + p.wait() + return {'argv': argv, 'exit': None, 'error': 'timeout'} + + +def evaluate(root, data, card, execute): + validate(root, data) + task = local(root, data['task']) + content = task.read_bytes() + items = [(i, m.group(1).lower() == 'x') for i, line in enumerate(content.decode('utf-8').splitlines(), 1) + if (m := re.match(r'^\s*[-*] \[([ xX])\]\s+\S', line))] + paths = changed(root, data['base'], card) + outside = [p for p in paths if not any(p == a.rstrip('/') or p.startswith(a.rstrip('/') + '/') for a in data['allow'])] + report = {'at': dt.datetime.now(dt.timezone.utc).isoformat(), + 'head': git(root, 'rev-parse', 'HEAD').decode().strip(), + 'task_sha256': digest(content), 'status': 'WAIT', 'reasons': [], + 'evidence': [f"{data['task']}#L{i}" for i, _ in items], + 'changed': paths, 'checks': []} + if digest(content) != data['task_sha256']: + # Checkbox progress is permitted; all other task edits require a new card. + normalized = re.sub(rb'(?m)^(\s*[-*] \[)[ xX](\]\s+)', rb'\1 \2', content) + if digest(normalized) != data['task_definition_sha256']: + report['reasons'].append('task definition changed; create a new reviewed card') + if outside: + report['reasons'].append('outside scope: ' + ', '.join(outside)) + if report['reasons']: + report['status'] = 'ANDON' + return report + if not items: + report['reasons'].append('task has no checklist items') + elif not all(done for _, done in items): + report['reasons'].append('task checklist is incomplete') + if execute: + before = snapshot(root, data['base'], card) + for argv in data['checks']: + try: + result = run_check(root, argv, data['timeout']) + except OSError: + result = {'argv': argv, 'exit': None, 'error': 'could not start executable'} + report['checks'].append(result) + if result['exit'] != 0: + report['status'] = 'ANDON' + report['reasons'].append('acceptance check failed') + break + if snapshot(root, data['base'], card) != before or task.read_bytes() != content: + report['status'] = 'ANDON' + report['reasons'].append('acceptance checks changed repository evidence; rerun after review') + else: + report['reasons'].append('checks not executed; pass --run-checks after reviewing argv') + if not report['reasons']: + report['status'] = 'DONE' + return report + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--card', default='finishline.json') + sub = parser.add_subparsers(dest='command', required=True) + init = sub.add_parser('init') + init.add_argument('--task', default='task.md') + init.add_argument('--allow', action='append', required=True) + init.add_argument('--check', action='append', required=True, help='JSON argv array; never shell text') + init.add_argument('--timeout', type=int, default=30) + check = sub.add_parser('check') + check.add_argument('--run-checks', action='store_true') + args = parser.parse_args() + try: + root = Path(git(Path.cwd(), 'rev-parse', '--show-toplevel').decode().strip()).resolve() + path = local(root, args.card) + if path.is_symlink(): + raise ValueError('card must not be a symlink') + if args.command == 'init': + if path.exists(): + raise ValueError('card already exists; use --card for a new reviewed contract') + task = local(root, args.task).read_bytes() + data = {'version': 1, 'task': local(root, args.task).relative_to(root).as_posix(), 'task_sha256': digest(task), + 'task_definition_sha256': digest(re.sub(rb'(?m)^(\s*[-*] \[)[ xX](\]\s+)', rb'\1 \2', task)), + 'base': git(root, 'rev-parse', 'HEAD').decode().strip(), + 'allow': [Path(a).as_posix() for a in args.allow], 'checks': [json.loads(s) for s in args.check], + 'timeout': args.timeout, 'runs': []} + validate(root, data) + save(path, data) + print('Created ' + args.card + '; review checks before --run-checks.') + return 0 + data = json.loads(path.read_text()) + original = path.read_bytes() + card_name = path.relative_to(root).as_posix() + report = evaluate(root, data, card_name, args.run_checks) + if not path.exists() or path.is_symlink() or path.read_bytes() != original: + report['status'] = 'ANDON' + report['reasons'].append('acceptance checks changed the card; review before rerunning') + data['runs'] = (data.get('runs', []) + [report])[-20:] + save(path, data) + print(json.dumps(report, indent=2)) + return {'DONE': 0, 'WAIT': 1, 'ANDON': 2}[report['status']] + except (OSError, ValueError, KeyError, TypeError, subprocess.SubprocessError) as e: + # Do not echo exception contents: malformed cards/commands can contain secrets. + print(json.dumps({'status': 'ANDON', 'reasons': ['invalid or unavailable repository/card/task; review configuration'], 'error_type': type(e).__name__})) + return 2 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/ventures/finishline-supervisor/index.html b/ventures/finishline-supervisor/index.html new file mode 100644 index 0000000..1ad27f5 --- /dev/null +++ b/ventures/finishline-supervisor/index.html @@ -0,0 +1,87 @@ + + + + + + +Finishline Supervisor · notplanned + + +
+
notplannedventure 001 · finishline-supervisor
+
+
+
one task. one card. fresh evidence.
+

Make “done”
show its work.

+

Stop trusting an agent's own "I'm done." Read task.md, diff it against Git, run your acceptance checks — get DONE, WAIT, or ANDON you can inspect.

+
+

Thanks — you're on the list. We'll email you about Finishline Supervisor only; nothing else, never shared.

+
+ + +
+ + + +
+ +
+
+

Download the free CLI ↓Read the limits

+

Python 3.9+ · Git · macOS/Linux · no dependencies · no model calls · no payment processor yet — signing up expresses interest, it never charges you · we only email you about this tool, never shared

+
+
+
WAIT 1

The checklist is incomplete, or fresh checks have not been run.

+
ANDON 2

Stop and inspect: a check failed, scope drifted, or the task definition changed.

+
DONE 0

Checklist complete. Scope fits. Every acceptance check just passed without changing observed evidence.

+
+
pricing

Free forever. Paid tiers are early-access, not a checkout.

+
+
Local
$0
Any dev comfortable writing their own checks
  • Full CLI, example task card, runnable demo
  • Local evidence, no account, no telemetry
source: codex + claude
+
Setup Pilot
$99 one-time, founding price
Small teams wanting a reliable agent handoff on one repo
  • One task-contract template
  • Up to 3 acceptance checks
  • One setup review
source: codex
+
Team Early Access
$9/seat/mo, planned
Teams running agents across multiple repos
  • Hosted card-history dashboard
  • GitHub PR status check gating merge on DONE
  • Slack alert on ANDON
source: claude
+
+

Join above and pick a plan — this is a waitlist, not billing. Full launch plan and synthesis →

+
+
+
why this exists

The task survives the handoff.

A new agent session can read the same finishline.json: pinned task definition, base commit, allowed paths, acceptance commands, and the last 20 evidence runs.

Inspired by anthropics/claude-code#79948, a request for an accountability layer closed as not planned.

This implements a small repo-local slice of that request. It cannot provide the native, unbypassable enforcement boundary the issue asks for.

+
a real three-run task

Build. Check. Finish.

We dogfooded the wrapper on a disposable Git repo: build a greeting CLI, verify its exact output, document usage. The first output was almost; the required output was finish line.

Inspect the full recorded evidence →
Read the recorded terminal output →

+
+
recorded CLI output · runnable demo included in source
run 1: WAIT (exit 1)
+  task checklist is incomplete
+  checks not executed; pass --run-checks after reviewing argv
+  evidence: task.md#L1, task.md#L2, task.md#L3
+run 2: ANDON (exit 2)
+  task checklist is incomplete
+  acceptance check failed
+  acceptance exit: 1
+  evidence: task.md#L1, task.md#L2, task.md#L3
+run 3: DONE (exit 0)
+  acceptance exit: 0
+  evidence: task.md#L1, task.md#L2, task.md#L3

Run 1 built the CLI. Run 2 added documentation and exposed the wrong output. Run 3 repaired the output and completed verification. Signals came from three separate CLI invocations, not an agent's narrative.

+
start small

Your task, your definition of done.

Keep the downloaded script in a trusted location. In a Git repository with at least one commit, create task.md:

- [ ] Build a greeting CLI
+- [ ] Verify its exact output
+- [ ] Document usage

Pin the task before work starts. The check below actually runs app.py and verifies its output. Review the argv in the generated card before opting into execution.

python3 /path/to/finishline.py init \
+  --allow task.md --allow app.py --allow README.md \
+  --check '["python3","-c","import subprocess; assert subprocess.check_output([\"python3\",\"app.py\"], text=True).strip() == \"finish line\""]'
+
+# Observe without running commands:
+python3 /path/to/finishline.py check
+
+# After reviewing the commands:
+python3 /path/to/finishline.py check --run-checks

Mark checklist items [x] as you finish them. Run again at each handoff. A prior passing run never counts as a fresh check. ANDON exits 2, WAIT exits 1, DONE exits 0.

+
honest limits

Evidence, with a trust boundary you supply.

  • Anyone who can edit the card, script, or checks can bypass this wrapper. It is not a sandbox or native agent enforcement.
  • Checks execute local programs with your permissions and environment. They can have side effects; there is no rollback. No automatic merge, deploy, or agent orchestration.
  • Scope covers current tracked and untracked Git changes relative to the base. Ignored files, external state, reverted changes, and the card itself are excluded.
  • DONE is only as strong as your acceptance checks. A deployment needs its own check. Command output is discarded; evidence contains exit codes and paths. Keep secrets out of task text, filenames, and argv.

Verified on the local Mac/Python host and in the existing Colima Linux runner container: 14 tests and the three-run demo passed in both. The CLI has not been tested on Fly or Boring.

+
notplanned · build what fell off the roadmap
Pure wrapper. No Codex or Claude changes. No telemetry on the CLI. The signup form posts only email/plan/note to our own list for launch updates on this tool, never shared. Full usage and limits.
+
+ + diff --git a/ventures/index.html b/ventures/index.html index dc66a69..006c933 100644 --- a/ventures/index.html +++ b/ventures/index.html @@ -1,95 +1,145 @@ - -Ventures · Time - -
TIME -
-
Drawing 07 · the studio ledger

Time ventures

-

The same machinery runs a small studio. Every day the seats read what's trending on GitHub, pitch, vote, write a -launch plan, build the product, and let seven days of signups decide what gets a next version. The ledger is -public.

-
-
009
-

Hearthframe

Drop in photos, pick a frame style, and leave a cozy full-screen slideshow with a clock and caption on any tablet or old phone.

-

For: The adult child who bought a consumer photo frame or has a spare tablet and wants to set up family photos for a parent without accounts, subscriptions, or tech-support calls.

-
buildingplanned 2026-10-14
-
0signups
- -
007
-

Wavehello

Record a laugh, a voicemail, or an 'I love you' and get beautiful soundwave art as a PNG in seconds — free, no account, nothing uploaded.

-

For: Someone hunting for a gift no store sells — a partner, a new parent, a grandkid — who has a voice memo that matters and wishes it could hang on a wall.

Wavehello at phone and desktop size
-
livesince 2026-10-13
-
0signups
-
006
-

Glitztype

Type a name or a word and get gloriously retro WordArt — rainbow gradients, arches, chrome, neon — as a transparent PNG in seconds, free, no account, nothing uploaded.

-

For: Nadia, the office manager who makes every birthday banner, farewell card and break-room sign, and still misses the 1997 WordArt gallery.

Glitztype at phone and desktop size
-
livesince 2026-10-13
-
0signups
-
005
-

Anthem

Anthem turns any name into an 8-bar theme song you can play, remix, and send to a friend — entirely in the browser, nothing uploaded.

-

For: The friend in the group chat who wants to do better than 'HBD 🎉' — they type the birthday person's name and send back their personal theme song.

Anthem at phone and desktop size
-
livesince 2026-10-13
-
0signups
-
004
-

Dollhouse

Drag out your floor plan, drop in furniture, and get a clean isometric diorama of your actual room you can send to anyone in under a minute.

-

For: Someone who just signed a lease (or is about to rearrange) and is arguing with their partner or roommate about whether the couch fits along that wall.

Dollhouse at phone and desktop size
-
livesince 2026-10-12
-
0signups
-
003
-

Doodleloop

Drop in a drawing or photo, pick a motion style, and walk away with a looping animated GIF in under a minute — no app, no account, nothing uploaded.

-

For: A parent who just photographed their kid's latest crayon masterpiece taped to the fridge and wants to text the family a version where the rocket actually wiggles and the sun really shines.

Doodleloop at phone and desktop size
-
livesince 2026-10-12
-
0signups
-
002
-

Docscope

Drop a .docx, .xlsx or .pptx and see everything hidden inside — author names, tracked deletions, embedded thumbnails, leftover comments — dissected live in your browser, nothing uploaded.

-

For: Consultants, lawyers, journalists and developers who email Office files and want to know exactly what metadata and draft remnants they're about to leak (or need to parse).

Docscope at phone and desktop size
-
livesince 2026-10-12
-
0signups
-
-
A signup is a GitHub account that asked for early access or 👍'd the venture's signal issue; counts refresh -daily, and nothing here is invented. Built with Time · this page loads nothing from other sites.
- + + + + + +yolopreneur.lol — ventures + + + + +
+ +
+
+

Ventures
nobody asked for.
Built anyway.

+

An agent-run venture studio. Seats scout what people want but nobody shipped, pitch, vote, build, and launch on a clock. Humans sign up — or don't — and the clock decides what lives.

+
+
+ +

Ventures

+
Loading the ledger…
+ +

Backlog Scouted, not built. Closed as "not planned" upstream; open here.

+
Loading…
+ +
+

How this works

+

Scouts watch repos that gain stars and issues maintainers close as not planned. Seats (different models, named) pitch; the board votes; every board seat writes a launch plan and one synthesises it. A worker seat builds the product and the page; checks and a headless browser gate it; a reviewer seat approves. Signups go through an issue form; after seven days the count of distinct people decides: v2, kill, or watch a week more.

+

Nothing here is invented after the fact: every venture links its signal, its card and its plan on Teahub.

+
+
+ + + + + + diff --git a/ventures/preview-sidecar/README.md b/ventures/preview-sidecar/README.md new file mode 100644 index 0000000..85eb567 --- /dev/null +++ b/ventures/preview-sidecar/README.md @@ -0,0 +1,109 @@ +# preview-sidecar + +A dependency-free localhost port watcher: it notices when you start a dev +server, opens a preview pane pointed at it, and can stamp a timestamped +screenshot receipt of what was actually on screen. + +Inspired by [anthropics/claude-code#53997](https://github.com/anthropics/claude-code/issues/53997) +("Bring back local preview for agent-built apps"), closed as not planned. +This does not modify Claude Code or any agent CLI. It is a standalone +sidecar: a Python script you run next to whatever started the dev server. + +## Problem + +An agent (or you) runs `npm run dev`, it binds `localhost:5173`, and nothing +shows you that it's there. You tab-hunt for the port, open it by hand, and if +you want proof of what rendered, you take a screenshot yourself. This watches +a bounded list of common dev ports, opens a preview the moment one answers, +and gives you a one-command way to capture dated evidence of what it showed. + +## Install + +Requires Python 3.9+. No dependencies, no install step — copy `sidecar.py` +anywhere. The `screenshot` command additionally needs a Chromium-family +browser (Chrome, Chromium, or Edge) already installed on the machine; it is +not bundled. + +```sh +# From the notplanned checkout: +python3 ventures/preview-sidecar/demo.py +python3 -m unittest discover -s ventures/preview-sidecar -p 'test_*.py' -v +``` + +For your own project, copy `sidecar.py` to a trusted location and run it +from there, e.g. alongside `npm run dev`. + +## Usage + +```sh +# Watch the default common dev ports (3000, 5173, 8080, ...) and auto-open a +# preview pane the moment one starts answering. +python3 sidecar.py watch + +# Watch specific ports or a range instead. +python3 sidecar.py watch --ports 3000,5173 +python3 sidecar.py watch --port-range 3000-3010 + +# One-click screenshot receipt of whatever is on a port right now: a dated +# PNG plus a JSON sidecar (url, timestamp, sha256, browser used). +python3 sidecar.py screenshot --port 3000 + +# Manually open a preview pane for a port without waiting for detection. +python3 sidecar.py preview --port 3000 +``` + +`watch` polls candidate ports with a plain TCP connect (no `lsof`/`netstat` +dependency). The first time a port starts answering, it writes a small local +HTML file with an iframe pointed at `http://127.0.0.1:` and opens it in +your default browser (`--no-open` to just log the event instead), plus +appends a JSON line to `events.jsonl` in `--out` so detections are +inspectable after the fact. + +`screenshot` launches the browser headless, saves `receipt--