@rizom/brain 0.2.0-alpha.121 → 0.2.0-alpha.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/brain.js CHANGED
@@ -519,7 +519,7 @@ Some entity actions are gated by policy beyond simple tool availability. Two cas
519
519
  hash text NOT NULL,
520
520
  created_at numeric
521
521
  )
522
- `;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let Y of B)if(!I||Number(I[2])<Y.folderMillis){for(let U of Y.sql)D.push(A.run(hA.raw(U)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var Pt=i(()=>{mX0();H$()});async function uX0(A,Q){let B=Q?.child("entity-migrate")??NQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=so(A);B.debug("Running entity database migrations...");try{await ao($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),await to($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var cX0=i(()=>{Pt();gYA();WA()});async function lX0(A,Q){let B=Q?.child("job-queue-migrate")??NQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ro(A);B.debug("Running job queue migrations...");try{await no($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var pX0=i(()=>{Pt();bYA();WA()});async function iX0(A,Q){let B=Q?.child("conversation-migrate")??NQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ys(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var rX0=i(()=>{Pt();NUA();WA()});class Kg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:hx,migrateEntities:uX0,migrateJobQueue:lX0,migrateConversations:iX0}}async runAllMigrations(A){this.logger.debug("Running database migrations...");let Q=await this.migrations.getStandardConfigWithDirectories();if(A?.database)Q.database.url=A.database;if(A?.jobQueueDatabase)Q.jobQueueDatabase.url=A.jobQueueDatabase;if(A?.conversationDatabase)Q.conversationDatabase.url=A.conversationDatabase;await this.migrateEntityDatabase(Q),await this.migrateJobQueueDatabase(Q),await this.migrateConversationDatabase(Q),this.logger.debug("All database migrations completed successfully")}async migrateEntityDatabase(A){this.logger.debug("Running entity database migrations..."),await this.migrations.migrateEntities({url:A.database.url,...A.database.authToken&&{authToken:A.database.authToken}},this.logger)}async migrateJobQueueDatabase(A){this.logger.debug("Running job queue database migrations..."),await this.migrations.migrateJobQueue({url:A.jobQueueDatabase.url,...A.jobQueueDatabase.authToken&&{authToken:A.jobQueueDatabase.authToken}},this.logger)}async migrateConversationDatabase(A){this.logger.debug("Running conversation database migrations..."),await this.migrations.migrateConversations({url:A.conversationDatabase.url,...A.conversationDatabase.authToken&&{authToken:A.conversationDatabase.authToken}},this.logger)}}var $NA=i(()=>{Rt();cX0();pX0();rX0()});function H52(){return process.env[W52]}function dX0(){return H52()!=="production"}var W52="NODE_ENV";var kt;var fNA=i(()=>{WA();kt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var oX0;var nX0=i(()=>{oX0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.121",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((K52,jt)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=TA&&IA[TA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function Y(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function U(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:U(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return U(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=U(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function L(){var IA=U(this.type);return e0[IA]||(e0[IA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),IA=this.props.ref,IA!==void 0?IA:null}function V(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:L}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=V(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function y(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(Y(IA.key),S(""+IA.key)):mA.toString(36)}function T(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+y(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(yA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||Y(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(yA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+y(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+y(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(T(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
522
+ `;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let Y of B)if(!I||Number(I[2])<Y.folderMillis){for(let U of Y.sql)D.push(A.run(hA.raw(U)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var Pt=i(()=>{mX0();H$()});async function uX0(A,Q){let B=Q?.child("entity-migrate")??NQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=so(A);B.debug("Running entity database migrations...");try{await ao($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),await to($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var cX0=i(()=>{Pt();gYA();WA()});async function lX0(A,Q){let B=Q?.child("job-queue-migrate")??NQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ro(A);B.debug("Running job queue migrations...");try{await no($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var pX0=i(()=>{Pt();bYA();WA()});async function iX0(A,Q){let B=Q?.child("conversation-migrate")??NQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=Ys(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await mb(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var rX0=i(()=>{Pt();NUA();WA()});class Kg{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:hx,migrateEntities:uX0,migrateJobQueue:lX0,migrateConversations:iX0}}async runAllMigrations(A){this.logger.debug("Running database migrations...");let Q=await this.migrations.getStandardConfigWithDirectories();if(A?.database)Q.database.url=A.database;if(A?.jobQueueDatabase)Q.jobQueueDatabase.url=A.jobQueueDatabase;if(A?.conversationDatabase)Q.conversationDatabase.url=A.conversationDatabase;await this.migrateEntityDatabase(Q),await this.migrateJobQueueDatabase(Q),await this.migrateConversationDatabase(Q),this.logger.debug("All database migrations completed successfully")}async migrateEntityDatabase(A){this.logger.debug("Running entity database migrations..."),await this.migrations.migrateEntities({url:A.database.url,...A.database.authToken&&{authToken:A.database.authToken}},this.logger)}async migrateJobQueueDatabase(A){this.logger.debug("Running job queue database migrations..."),await this.migrations.migrateJobQueue({url:A.jobQueueDatabase.url,...A.jobQueueDatabase.authToken&&{authToken:A.jobQueueDatabase.authToken}},this.logger)}async migrateConversationDatabase(A){this.logger.debug("Running conversation database migrations..."),await this.migrations.migrateConversations({url:A.conversationDatabase.url,...A.conversationDatabase.authToken&&{authToken:A.conversationDatabase.authToken}},this.logger)}}var $NA=i(()=>{Rt();cX0();pX0();rX0()});function H52(){return process.env[W52]}function dX0(){return H52()!=="production"}var W52="NODE_ENV";var kt;var fNA=i(()=>{WA();kt=H.object({theme:H.object({primaryColor:H.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:H.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var oX0;var nX0=i(()=>{oX0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.122",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{dev:"tsc --watch",typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*",chalk:"^5.4.1",ink:"^6.0.1","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",marked:"^12.0.0",react:"^19.2.6"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var wB=h((K52,jt)=>{(function(){function A(IA,mA){Object.defineProperty(w.prototype,IA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",mA[0],mA[1])}})}function Q(IA){if(IA===null||typeof IA!=="object")return null;return IA=TA&&IA[TA]||IA["@@iterator"],typeof IA==="function"?IA:null}function B(IA,mA){IA=(IA=IA.constructor)&&(IA.displayName||IA.name)||"ReactClass";var jA=IA+"."+mA;GA[jA]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",mA,IA),GA[jA]=!0)}function w(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function $(){}function f(IA,mA,jA){this.props=IA,this.context=mA,this.refs=cA,this.updater=jA||qA}function I(){}function D(IA){return""+IA}function Y(IA){try{D(IA);var mA=!1}catch(K0){mA=!0}if(mA){mA=console;var jA=mA.error,iA=typeof Symbol==="function"&&Symbol.toStringTag&&IA[Symbol.toStringTag]||IA.constructor.name||"Object";return jA.call(mA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",iA),D(IA)}}function U(IA){if(IA==null)return null;if(typeof IA==="function")return IA.$$typeof===I0?null:IA.displayName||IA.name||null;if(typeof IA==="string")return IA;switch(IA){case e:return"Fragment";case XA:return"Profiler";case s:return"StrictMode";case w0:return"Suspense";case fA:return"SuspenseList";case KA:return"Activity"}if(typeof IA==="object")switch(typeof IA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),IA.$$typeof){case l:return"Portal";case wA:return IA.displayName||"Context";case NA:return(IA._context.displayName||"Context")+".Consumer";case lA:var mA=IA.render;return IA=IA.displayName,IA||(IA=mA.displayName||mA.name||"",IA=IA!==""?"ForwardRef("+IA+")":"ForwardRef"),IA;case OA:return mA=IA.displayName||null,mA!==null?mA:U(IA.type)||"Memo";case kA:mA=IA._payload,IA=IA._init;try{return U(IA(mA))}catch(jA){}}return null}function J(IA){if(IA===e)return"<>";if(typeof IA==="object"&&IA!==null&&IA.$$typeof===kA)return"<...>";try{var mA=U(IA);return mA?"<"+mA+">":"<...>"}catch(jA){return"<...>"}}function X(){var IA=Q0.A;return IA===null?null:IA.getOwner()}function G(){return Error("react-stack-top-frame")}function Z(IA){if(bA.call(IA,"key")){var mA=Object.getOwnPropertyDescriptor(IA,"key").get;if(mA&&mA.isReactWarning)return!1}return IA.key!==void 0}function N(IA,mA){function jA(){DA||(DA=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",mA))}jA.isReactWarning=!0,Object.defineProperty(IA,"key",{get:jA,configurable:!0})}function L(){var IA=U(this.type);return e0[IA]||(e0[IA]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),IA=this.props.ref,IA!==void 0?IA:null}function V(IA,mA,jA,iA,K0,C0){var B0=jA.ref;return IA={$$typeof:c,type:IA,key:mA,props:jA,_owner:iA},(B0!==void 0?B0:null)!==null?Object.defineProperty(IA,"ref",{enumerable:!1,get:L}):Object.defineProperty(IA,"ref",{enumerable:!1,value:null}),IA._store={},Object.defineProperty(IA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(IA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(IA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:K0}),Object.defineProperty(IA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:C0}),Object.freeze&&(Object.freeze(IA.props),Object.freeze(IA)),IA}function M(IA,mA){return mA=V(IA.type,mA,IA.props,IA._owner,IA._debugStack,IA._debugTask),IA._store&&(mA._store.validated=IA._store.validated),mA}function O(IA){E(IA)?IA._store&&(IA._store.validated=1):typeof IA==="object"&&IA!==null&&IA.$$typeof===kA&&(IA._payload.status==="fulfilled"?E(IA._payload.value)&&IA._payload.value._store&&(IA._payload.value._store.validated=1):IA._store&&(IA._store.validated=1))}function E(IA){return typeof IA==="object"&&IA!==null&&IA.$$typeof===c}function S(IA){var mA={"=":"=0",":":"=2"};return"$"+IA.replace(/[=:]/g,function(jA){return mA[jA]})}function y(IA,mA){return typeof IA==="object"&&IA!==null&&IA.key!=null?(Y(IA.key),S(""+IA.key)):mA.toString(36)}function T(IA){switch(IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason;default:switch(typeof IA.status==="string"?IA.then(I,I):(IA.status="pending",IA.then(function(mA){IA.status==="pending"&&(IA.status="fulfilled",IA.value=mA)},function(mA){IA.status==="pending"&&(IA.status="rejected",IA.reason=mA)})),IA.status){case"fulfilled":return IA.value;case"rejected":throw IA.reason}}throw IA}function _(IA,mA,jA,iA,K0){var C0=typeof IA;if(C0==="undefined"||C0==="boolean")IA=null;var B0=!1;if(IA===null)B0=!0;else switch(C0){case"bigint":case"string":case"number":B0=!0;break;case"object":switch(IA.$$typeof){case c:case l:B0=!0;break;case kA:return B0=IA._init,_(B0(IA._payload),mA,jA,iA,K0)}}if(B0){B0=IA,K0=K0(B0);var a0=iA===""?"."+y(B0,0):iA;return Z0(K0)?(jA="",a0!=null&&(jA=a0.replace(yA,"$&/")+"/"),_(K0,mA,jA,"",function(m1){return m1})):K0!=null&&(E(K0)&&(K0.key!=null&&(B0&&B0.key===K0.key||Y(K0.key)),jA=M(K0,jA+(K0.key==null||B0&&B0.key===K0.key?"":(""+K0.key).replace(yA,"$&/")+"/")+a0),iA!==""&&B0!=null&&E(B0)&&B0.key==null&&B0._store&&!B0._store.validated&&(jA._store.validated=2),K0=jA),mA.push(K0)),1}if(B0=0,a0=iA===""?".":iA+":",Z0(IA))for(var g0=0;g0<IA.length;g0++)iA=IA[g0],C0=a0+y(iA,g0),B0+=_(iA,mA,jA,C0,K0);else if(g0=Q(IA),typeof g0==="function")for(g0===IA.entries&&(dA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),dA=!0),IA=g0.call(IA),g0=0;!(iA=IA.next()).done;)iA=iA.value,C0=a0+y(iA,g0++),B0+=_(iA,mA,jA,C0,K0);else if(C0==="object"){if(typeof IA.then==="function")return _(T(IA),mA,jA,iA,K0);throw mA=String(IA),Error("Objects are not valid as a React child (found: "+(mA==="[object Object]"?"object with keys {"+Object.keys(IA).join(", ")+"}":mA)+"). If you meant to render a collection of children, use an array instead.")}return B0}function x(IA,mA,jA){if(IA==null)return IA;var iA=[],K0=0;return _(IA,iA,"","",function(C0){return mA.call(jA,C0,K0++)}),iA}function g(IA){if(IA._status===-1){var mA=IA._ioInfo;mA!=null&&(mA.start=mA.end=performance.now()),mA=IA._result;var jA=mA();if(jA.then(function(K0){if(IA._status===0||IA._status===-1){IA._status=1,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="fulfilled",jA.value=K0)}},function(K0){if(IA._status===0||IA._status===-1){IA._status=2,IA._result=K0;var C0=IA._ioInfo;C0!=null&&(C0.end=performance.now()),jA.status===void 0&&(jA.status="rejected",jA.reason=K0)}}),mA=IA._ioInfo,mA!=null){mA.value=jA;var iA=jA.displayName;typeof iA==="string"&&(mA.name=iA)}IA._status===-1&&(IA._status=0,IA._result=jA)}if(IA._status===1)return mA=IA._result,mA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
523
523
 
524
524
  Your code should look like:
525
525
  const MyComponent = lazy(() => import('./MyComponent'))
@@ -1815,7 +1815,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
1815
1815
  Title: "${A.entityTitle??D}"
1816
1816
 
1817
1817
  Content:
1818
- ${U}`,rI2);Y=`${w.trim()} ${O.imagePrompt}`}catch(O){this.logger.warn("AI prompt distillation failed, using fallback",{error:T0(O)})}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Generating image"});let J=this.context.identity.get(),X=this.context.identity.getProfile(),Z=zZ0(J,X)+Y,N;try{N=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(O){return this.logger.error("Image generation failed",{jobId:Q,error:T0(O)}),$5.failure(O)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let L=X1(D),V=HY.createImageEntity({dataUrl:N.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:L}))this.logger.debug("Deleting existing image for regeneration",{imageId:L}),await this.context.entityService.deleteEntity({entityType:"image",id:L});if(await this.context.entityService.createEntity({entity:{...V,id:L}}),this.logger.debug("Created image entity",{imageId:L}),f&&I){await this.reportProgress(B,{progress:zQ.SAVE,message:`Updating ${f} with cover image`});let O=await CL(this.context.entityService,f,I,this.logger);if(!O)return $5.failure(Error(`Target entity not found: ${f}/${I}`));let E=UV(O,L);await this.context.entities.update(E),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:L}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:T0(Y)}),$5.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();H6();E7();var nI2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class LzA extends ZB{context;constructor(A,Q){super(Q,{schema:nI2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let Y=await this.findImageByDedupKey(A.dedupKey);if(Y)return await this.updateTarget(A,Y.id),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return $5.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return $5.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...HY.createImageEntity({dataUrl:aZA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},D=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(D)await this.context.entityService.updateEntity({entity:{...D,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){return this.logger.error("Source image render job failed",{jobId:Q,error:T0(w)}),$5.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await CL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Gg(B,Q):UV(B,Q);await this.context.entities.update($)}}aA();WA();E7();WA();var zP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function te(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function ee(A){let Q=oI2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function qZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function oI2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var sI2=H.object({uploadId:H.string().min(1),title:H.string().optional()});class VzA extends ZB{context;constructor(A,Q){super(A,{schema:sI2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(zP).read(A.uploadId);if(!te(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=ee({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let f=new Date().toISOString(),I=HY.createImageEntity({dataUrl:qZ0(w.record.mediaType,w.content),title:$.title}),D=await this.context.entityService.createEntity({entity:{id:$.id,...I,created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}var LZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.121",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var tI2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function XJ(A){let Q=A?.trim();if(!Q)return;return Q}function eI2(A){let Q=XJ(A.prompt);if(Q)return Q;let B=XJ(A.content);if(B&&!qzA(B))return B;return}function AD2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function VZ0(A){let Q=XJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function QD2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function EzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function BD2(A){let Q=encodeURIComponent(A.entityId);return{mediaType:A.mediaType,url:`/api/chat/attachments/image?id=${Q}`,downloadUrl:`/api/chat/attachments/image?id=${Q}&download=1`,filename:A.filename,source:{entityType:"image",entityId:A.entityId,attachmentType:"uploaded"}}}class MzA extends jQ{entityType=HY.entityType;schema=Wg;adapter=HY;constructor(A={}){super("image",LZ0,A,tI2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===zP.refKind)return this.promoteUpload(A,B);let w=eI2(A),$=XJ(A.targetEntityType),f=XJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=XJ(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}}),N=VZ0({prompt:w,...G&&{title:G}});return{kind:"handled",result:{success:!0,data:{entityId:N,status:"generating",jobId:Z,attachment:EzA(N)}}}}let Y=await $Y(B.entityService,$,f,this.logger,"Target entity");if(!Y.ok)return{kind:"handled",result:{success:!1,error:Y.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:Y.entity.id}};let U=se(Y.entity.content),J=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:Y.entity.id,entityTitle:typeof Y.entity.metadata.title==="string"?Y.entity.metadata.title:Y.entity.id,...U&&{entityContent:U}}}),X=VZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:Y.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:J,attachment:EzA(X)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==zP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(zP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!te($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=ee({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:BD2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=XJ(A.from.sourceEntityType),w=XJ(A.from.sourceEntityId),$=XJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await $Y(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=XJ(A.targetEntityType),D=XJ(A.targetEntityId),Y;if(I&&D){let Z=await $Y(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};Y=Z.entity.id}let U={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await QD2(Q,U),X=AD2(U),G=await Q.jobs.enqueue({type:"image-render-source",data:{...U,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...Y&&{targetEntityId:Y},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:EzA(X,$)}}}}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_create with entityType: "image", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a base entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new ae(A,this.logger)}async onRegister(A){let Q=new ae(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new LzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new VzA(this.logger.child("UploadPromotionJobHandler"),A))}}function Xh(A){return new MzA(A)}aA();import{StdioServerTransport as wD2}from"@modelcontextprotocol/sdk/server/stdio.js";function EZ0(){return{info:(A,...Q)=>console.error(`[STDIO MCP] ${A}`,...Q),debug:(A,...Q)=>console.error(`[STDIO MCP DEBUG] ${A}`,...Q),error:(A,...Q)=>console.error(`[STDIO MCP ERROR] ${A}`,...Q),warn:(A,...Q)=>console.error(`[STDIO MCP WARN] ${A}`,...Q)}}function CzA(){return{info:(A,...Q)=>console.log(`[HTTP MCP] ${A}`,...Q),debug:(A,...Q)=>console.debug(`[HTTP MCP DEBUG] ${A}`,...Q),error:(A,...Q)=>console.error(`[HTTP MCP ERROR] ${A}`,...Q),warn:(A,...Q)=>console.warn(`[HTTP MCP WARN] ${A}`,...Q)}}function AAA(A){if(A&&typeof A==="object"&&"info"in A&&"debug"in A&&"error"in A&&"warn"in A){let Q=A;return{info:(B,...w)=>Q.info(B,...w),debug:(B,...w)=>Q.debug(B,...w),error:(B,...w)=>Q.error(B,...w),warn:(B,...w)=>Q.warn(B,...w)}}return CzA()}class WJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return WJ.instance??=new WJ(A),WJ.instance}static resetInstance(){if(WJ.instance)WJ.instance.stop(),WJ.instance=null}static createFresh(A){return new WJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?AAA(this.config.logger):EZ0()}connectMCPServer(A){this.mcpServer=A,this.logger.debug("MCP server connected to stdio transport")}async start(){if(!this.mcpServer)throw Error("MCP server not connected. Call connectMCPServer() first.");if(this.transport)throw Error("Server is already running");this.logger.info("Starting stdio transport"),this.transport=new wD2,await this.mcpServer.connect(this.transport),this.logger.info("Stdio transport started successfully")}stop(){if(this.logger.info("Stopping stdio transport"),this.transport)this.transport=null;this.logger.info("Stdio transport stopped")}isRunning(){return this.transport!==null}}import{randomUUID as MZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as $D2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as fD2}from"@modelcontextprotocol/sdk/types.js";var ID2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function DD2(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class ZK{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?AAA(this.config.logger):CzA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return ZK.instance??=new ZK(A),ZK.instance}static resetInstance(){ZK.instance=null}static createFresh(A){return new ZK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ID2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${DD2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${YD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&fD2(B))w=new $D2({sessionIdGenerator:()=>MZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??MZ0();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let $=await this.agentService.confirmPendingAction(Q,B,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent confirm error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function YD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as JD2}from"crypto";import{mkdir as XD2,readFile as WD2,writeFile as HD2,chmod as GD2}from"fs/promises";import{dirname as KD2,join as FD2}from"path";function CZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function OZ0(A){try{return new URL(A)}catch{return}}function OzA(A,Q){if(A===Q)return!0;let B=OZ0(A),w=OZ0(Q);if(!B||!w)return!1;if(!CZ0(B.hostname)||!CZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&UD2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function UD2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function RzA(A,Q){return A.some((B)=>OzA(B,Q))}var ZD2="oauth-auth-codes.json",ND2=600;function RZ0(){return Math.floor(Date.now()/1000)}function zD2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function qD2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(zD2)}}async function LD2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class QAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=FD2(A.storageDir,A.storeFile??ZD2)}async createCode(A){let Q=RZ0(),B={code:`ocd_${JD2()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+ND2};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=RZ0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new HJ("Authorization code not found");if(f.consumed_at!==void 0)throw new HJ("Authorization code already consumed");if(f.expires_at<=Q)throw new HJ("Authorization code expired");if(f.client_id!==A.clientId)throw new HJ("Authorization code client mismatch");if(!OzA(f.redirect_uri,A.redirectUri))throw new HJ("Authorization code redirect URI mismatch");let I=await LD2(A.codeVerifier);if(f.code_challenge!==I)throw new HJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new HJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return qD2(JSON.parse(await WD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await XD2(KD2(this.storeFile),{recursive:!0,mode:448}),await HD2(this.storeFile,`${JSON.stringify(A,null,2)}
1818
+ ${U}`,rI2);Y=`${w.trim()} ${O.imagePrompt}`}catch(O){this.logger.warn("AI prompt distillation failed, using fallback",{error:T0(O)})}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Generating image"});let J=this.context.identity.get(),X=this.context.identity.getProfile(),Z=zZ0(J,X)+Y,N;try{N=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(O){return this.logger.error("Image generation failed",{jobId:Q,error:T0(O)}),$5.failure(O)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let L=X1(D),V=HY.createImageEntity({dataUrl:N.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:L}))this.logger.debug("Deleting existing image for regeneration",{imageId:L}),await this.context.entityService.deleteEntity({entityType:"image",id:L});if(await this.context.entityService.createEntity({entity:{...V,id:L}}),this.logger.debug("Created image entity",{imageId:L}),f&&I){await this.reportProgress(B,{progress:zQ.SAVE,message:`Updating ${f} with cover image`});let O=await CL(this.context.entityService,f,I,this.logger);if(!O)return $5.failure(Error(`Target entity not found: ${f}/${I}`));let E=UV(O,L);await this.context.entities.update(E),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:L}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:T0(Y)}),$5.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}aA();WA();H6();E7();var nI2=H.object({sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),imageId:H.string().min(1),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional(),targetImageField:H.enum(["coverImageId","ogImageId"]).optional()});class LzA extends ZB{context;constructor(A,Q){super(Q,{schema:nI2,jobTypeName:"image-render-source"});this.context=A}async process(A,Q,B){this.logger.debug("Starting source image render job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,imageId:A.imageId});try{if(A.replace!==!0&&A.dedupKey){let Y=await this.findImageByDedupKey(A.dedupKey);if(Y)return await this.updateTarget(A,Y.id),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:Y.id,reused:!0}}await this.reportProgress(B,{progress:zQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return $5.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return $5.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...HY.createImageEntity({dataUrl:aZA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},D=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(D)await this.context.entityService.updateEntity({entity:{...D,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Image render complete"}),{success:!0,imageId:A.imageId,reused:!1}}catch(w){return this.logger.error("Source image render job failed",{jobId:Q,error:T0(w)}),$5.failure(w)}}async findImageByDedupKey(A){return(await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async updateTarget(A,Q){if(!A.targetEntityType||!A.targetEntityId)return;let B=await CL(this.context.entityService,A.targetEntityType,A.targetEntityId,this.logger);if(!B)throw Error(`Target entity not found: ${A.targetEntityType}/${A.targetEntityId}`);let $=(A.targetImageField??"coverImageId")==="ogImageId"?Gg(B,Q):UV(B,Q);await this.context.entities.update($)}}aA();WA();E7();WA();var zP={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function te(A){return["image/png","image/jpeg","image/webp","image/gif"].includes(A.toLowerCase())}function ee(A){let Q=oI2(A.title,A.filename),B=X1(Q);if(!B)throw Error("Could not derive an image id from the uploaded filename. Provide a title.");return{id:B,title:Q}}function qZ0(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function oI2(A,Q){let B=A?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}var sI2=H.object({uploadId:H.string().min(1),title:H.string().optional()});class VzA extends ZB{context;constructor(A,Q){super(A,{schema:sI2,jobTypeName:"upload-promote"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded image"});let w=await this.context.uploads.scoped(zP).read(A.uploadId);if(!te(w.record.mediaType))throw Error("Only image uploads can be promoted to image entities");let $=ee({filename:w.record.filename,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:60,message:"Saving uploaded image"});let f=new Date().toISOString(),I=HY.createImageEntity({dataUrl:qZ0(w.record.mediaType,w.content),title:$.title}),D=await this.context.entityService.createEntity({entity:{id:$.id,...I,created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Uploaded image promoted"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}var LZ0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.122",description:"Plugin for AI-powered image generation and management",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var tI2=H.object({defaultAspectRatio:H.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function XJ(A){let Q=A?.trim();if(!Q)return;return Q}function eI2(A){let Q=XJ(A.prompt);if(Q)return Q;let B=XJ(A.content);if(B&&!qzA(B))return B;return}function AD2(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return X1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function VZ0(A){let Q=XJ(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return X1(Q)}async function QD2(A,Q){let B=`${Q.attachmentType}:${Q.sourceEntityType}:${Q.sourceEntityId}:resolved-attachment`,w=await A.entityService.getEntity({entityType:Q.sourceEntityType,id:Q.sourceEntityId});return w?`${B}:${w.contentHash}`:B}function EzA(A,Q="generated"){let B=encodeURIComponent(A);return{mediaType:"image/png",url:`/api/chat/attachments/image?id=${B}`,downloadUrl:`/api/chat/attachments/image?id=${B}&download=1`,filename:`${A}.png`,source:{entityType:"image",entityId:A,attachmentType:Q}}}function BD2(A){let Q=encodeURIComponent(A.entityId);return{mediaType:A.mediaType,url:`/api/chat/attachments/image?id=${Q}`,downloadUrl:`/api/chat/attachments/image?id=${Q}&download=1`,filename:A.filename,source:{entityType:"image",entityId:A.entityId,attachmentType:"uploaded"}}}class MzA extends jQ{entityType=HY.entityType;schema=Wg;adapter=HY;constructor(A={}){super("image",LZ0,A,tI2)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(A.from?.kind===zP.refKind)return this.promoteUpload(A,B);let w=eI2(A),$=XJ(A.targetEntityType),f=XJ(A.targetEntityId),I=$===this.entityType?f:void 0,D=A.from;if(D?.kind==="entity-attachment")return this.enqueueSourceImageRender({...A,from:D},B);if(!$||!f||I){if(!w)return{kind:"continue",input:A};let G=XJ(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...G&&{title:G}}}),N=VZ0({prompt:w,...G&&{title:G}});return{kind:"handled",result:{success:!0,data:{entityId:N,status:"generating",jobId:Z,attachment:EzA(N)}}}}let Y=await $Y(B.entityService,$,f,this.logger,"Target entity");if(!Y.ok)return{kind:"handled",result:{success:!1,error:Y.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:Y.entity.id}};let U=se(Y.entity.content),J=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:Y.entity.id,entityTitle:typeof Y.entity.metadata.title==="string"?Y.entity.metadata.title:Y.entity.id,...U&&{entityContent:U}}}),X=VZ0({prompt:w,...A.title&&{title:A.title},targetEntityId:Y.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:J,attachment:EzA(X)}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==zP.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w=B.id,$;try{$=await Q.uploads.scoped(zP).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(!te($.mediaType))return{kind:"handled",result:{success:!1,error:"Only image uploads can be promoted to image entities"}};let f;try{f=ee({filename:$.filename,...A.title!==void 0?{title:A.title}:{}})}catch(D){return{kind:"handled",result:{success:!1,error:D instanceof Error?D.message:String(D)}}}let I=await Q.jobs.enqueue({type:"upload-promote",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I,attachment:BD2({mediaType:$.mediaType,entityId:f.id,filename:$.filename})}}}}async enqueueSourceImageRender(A,Q){let B=XJ(A.from.sourceEntityType),w=XJ(A.from.sourceEntityId),$=XJ(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let f=await $Y(Q.entityService,B,w,this.logger,"Source entity");if(!f.ok)return{kind:"handled",result:{success:!1,error:f.error}};let I=XJ(A.targetEntityType),D=XJ(A.targetEntityId),Y;if(I&&D){let Z=await $Y(Q.entityService,I,D,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};Y=Z.entity.id}let U={sourceEntityType:B,sourceEntityId:f.entity.id,attachmentType:$},J=await QD2(Q,U),X=AD2(U),G=await Q.jobs.enqueue({type:"image-render-source",data:{...U,imageId:X,dedupKey:J,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...Y&&{targetEntityId:Y},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:X,status:"generating",jobId:G,attachment:EzA(X,$)}}}}async getInstructions(){return'For durable raw image saves/promotions from uploaded images, call system_create with entityType: "image", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the uploaded image file itself. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Describing or summarizing an uploaded image should use it as chat context, not create an image entity. Saving an image description, discussion, interpretation, or caption as a note should create a base entity with content from the conversation, not upload/transform. After a bare upload acknowledgement, a short label/title-only follow-up is ambiguous; ask what to do with the upload instead of turning that label into an AI image-generation prompt. For AI-generated images and cover images, call system_create with entityType: "image" and a prompt, and omit upload/sourceAttachment entirely unless the user explicitly asks to reuse the uploaded image file.'}createGenerationHandler(A){return new ae(A,this.logger)}async onRegister(A){let Q=new ae(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new LzA(A,this.logger)),A.jobs.registerHandler("upload-promote",new VzA(this.logger.child("UploadPromotionJobHandler"),A))}}function Xh(A){return new MzA(A)}aA();import{StdioServerTransport as wD2}from"@modelcontextprotocol/sdk/server/stdio.js";function EZ0(){return{info:(A,...Q)=>console.error(`[STDIO MCP] ${A}`,...Q),debug:(A,...Q)=>console.error(`[STDIO MCP DEBUG] ${A}`,...Q),error:(A,...Q)=>console.error(`[STDIO MCP ERROR] ${A}`,...Q),warn:(A,...Q)=>console.error(`[STDIO MCP WARN] ${A}`,...Q)}}function CzA(){return{info:(A,...Q)=>console.log(`[HTTP MCP] ${A}`,...Q),debug:(A,...Q)=>console.debug(`[HTTP MCP DEBUG] ${A}`,...Q),error:(A,...Q)=>console.error(`[HTTP MCP ERROR] ${A}`,...Q),warn:(A,...Q)=>console.warn(`[HTTP MCP WARN] ${A}`,...Q)}}function AAA(A){if(A&&typeof A==="object"&&"info"in A&&"debug"in A&&"error"in A&&"warn"in A){let Q=A;return{info:(B,...w)=>Q.info(B,...w),debug:(B,...w)=>Q.debug(B,...w),error:(B,...w)=>Q.error(B,...w),warn:(B,...w)=>Q.warn(B,...w)}}return CzA()}class WJ{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return WJ.instance??=new WJ(A),WJ.instance}static resetInstance(){if(WJ.instance)WJ.instance.stop(),WJ.instance=null}static createFresh(A){return new WJ(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?AAA(this.config.logger):EZ0()}connectMCPServer(A){this.mcpServer=A,this.logger.debug("MCP server connected to stdio transport")}async start(){if(!this.mcpServer)throw Error("MCP server not connected. Call connectMCPServer() first.");if(this.transport)throw Error("Server is already running");this.logger.info("Starting stdio transport"),this.transport=new wD2,await this.mcpServer.connect(this.transport),this.logger.info("Stdio transport started successfully")}stop(){if(this.logger.info("Stopping stdio transport"),this.transport)this.transport=null;this.logger.info("Stdio transport stopped")}isRunning(){return this.transport!==null}}import{randomUUID as MZ0}from"crypto";import{WebStandardStreamableHTTPServerTransport as $D2}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as fD2}from"@modelcontextprotocol/sdk/types.js";var ID2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Session-Id, MCP-Protocol-Version, Last-Event-ID","Access-Control-Allow-Private-Network":"true","X-Content-Type-Options":"nosniff"};function DD2(A){let Q=new URL(A.url),w=A.headers.get("x-forwarded-proto")?.split(",")[0]?.trim(),$=A.headers.get("x-forwarded-host")??A.headers.get("host");if(!$)return Q.origin;return`${w??Q.protocol.replace(":","")}://${$}`}class ZK{static instance=null;transports={};mcpServer=null;mcpTransport=null;agentService=null;server=null;boundPort=null;config;logger;authConfig;constructor(A={}){if(this.config=A,this.logger=this.config.logger?AAA(this.config.logger):CzA(),this.authConfig=A.auth??{},!this.authConfig.disabled&&!this.authConfig.token&&!this.authConfig.verifyBearerToken)throw Error("MCP HTTP transport requires an auth token or bearer token verifier. Set MCP_AUTH_TOKEN, configure OAuth verification, or pass auth: { disabled: true } for local dev.")}static getInstance(A){return ZK.instance??=new ZK(A),ZK.instance}static resetInstance(){ZK.instance=null}static createFresh(A){return new ZK(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ID2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}createJsonResponse(A,Q=200){return this.withCors(new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json"}}))}createTextResponse(A,Q=200){return this.withCors(new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8"}}))}getAuthErrorResponse(A,Q=401,B){let w=this.createJsonResponse({jsonrpc:"2.0",error:{code:-32001,message:A},id:null},Q);if(!B)return w;let $=new Headers(w.headers);return $.set("WWW-Authenticate",B),new Response(w.body,{status:w.status,statusText:w.statusText,headers:$})}getBearerChallenge(A,Q={}){let w={resource_metadata:`${DD2(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${YD2(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&fD2(B))w=new $D2({sessionIdGenerator:()=>MZ0(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??MZ0();this.logger.debug(`POST /api/chat - conversation: ${w}`);try{let $=await this.agentService.chat(Q,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent chat error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleAgentConfirmRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{conversationId:Q,confirmed:B,approvalId:w}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'conversationId' field"},400);if(typeof B!=="boolean")return this.createJsonResponse({error:"Missing or invalid 'confirmed' field"},400);if(typeof w!=="string"||w.length===0)return this.createJsonResponse({error:"Missing or invalid 'approvalId' field"},400);this.logger.debug(`POST /api/chat/confirm - conversation: ${Q}`);try{let $=await this.agentService.confirmPendingAction(Q,B,w);return this.createJsonResponse($)}catch($){return this.logger.error("Agent confirm error:",$),this.createJsonResponse({error:$ instanceof Error?$.message:"Internal error"},500)}}async handleRequest(A){let Q=new URL(A.url);this.logger.debug(`${A.method} ${Q.pathname}`);let B=await this.authenticate(A);if(B)return B;if(Q.pathname==="/health")return this.createJsonResponse({status:"ok",transport:"streamable-http",timestamp:new Date().toISOString()});if(Q.pathname==="/status")return this.createJsonResponse({sessions:Object.keys(this.transports).length,uptime:process.uptime(),memory:process.memoryUsage(),port:this.boundPort??this.config.port??3333});if(Q.pathname==="/mcp")return this.handleMcpRequest(A);if(Q.pathname==="/api/chat"&&A.method==="POST")return this.handleAgentChatRequest(A);if(Q.pathname==="/api/chat/confirm"&&A.method==="POST")return this.handleAgentConfirmRequest(A);return this.createTextResponse("Not Found",404)}connectMCPServer(A,Q){this.mcpServer=A,this.mcpTransport=Q??null,this.logger.debug("MCP server connected to StreamableHTTP transport")}connectAgentService(A){this.agentService=A,this.logger.debug("Agent service connected to StreamableHTTP transport")}async start(){if(this.server)throw Error("Server is already running");let A=Number(this.config.port??3333),Q=this.config.host??"0.0.0.0";try{this.server=Bun.serve({port:A,hostname:Q,fetch:(B)=>this.handleRequest(B)}),this.boundPort=this.server.port??A,this.logger.info(`StreamableHTTP server listening on http://${Q}:${this.boundPort}/mcp`)}catch(B){if(B.code==="EADDRINUSE")this.logger.error(`Port ${A} is already in use`);throw B}}async stop(){for(let A in this.transports)try{let Q=this.transports[A];if(Q)this.logger.debug(`Closing transport for session ${A}`),await Q.close(),delete this.transports[A]}catch(Q){this.logger.error(`Error closing transport for session ${A}:`,Q)}if(this.server)await this.server.stop(),this.logger.info("StreamableHTTP server stopped"),this.server=null,this.boundPort=null}getPort(){if(this.boundPort===null)throw Error("Server is not running");return this.boundPort}getApp(){return{fetch:(A)=>this.handleRequest(A)}}isRunning(){return this.server!==null}getSessionCount(){return Object.keys(this.transports).length}}function YD2(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as JD2}from"crypto";import{mkdir as XD2,readFile as WD2,writeFile as HD2,chmod as GD2}from"fs/promises";import{dirname as KD2,join as FD2}from"path";function CZ0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function OZ0(A){try{return new URL(A)}catch{return}}function OzA(A,Q){if(A===Q)return!0;let B=OZ0(A),w=OZ0(Q);if(!B||!w)return!1;if(!CZ0(B.hostname)||!CZ0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&UD2(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function UD2(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function RzA(A,Q){return A.some((B)=>OzA(B,Q))}var ZD2="oauth-auth-codes.json",ND2=600;function RZ0(){return Math.floor(Date.now()/1000)}function zD2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.code==="string"&&typeof Q.client_id==="string"&&typeof Q.redirect_uri==="string"&&typeof Q.code_challenge==="string"&&Q.code_challenge_method==="S256"&&typeof Q.subject==="string"&&typeof Q.created_at==="number"&&typeof Q.expires_at==="number"}function qD2(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(zD2)}}async function LD2(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class QAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=FD2(A.storageDir,A.storeFile??ZD2)}async createCode(A){let Q=RZ0(),B={code:`ocd_${JD2()}`,client_id:A.clientId,redirect_uri:A.redirectUri,code_challenge:A.codeChallenge,code_challenge_method:"S256",...A.scope?{scope:A.scope}:{},subject:A.subject,created_at:Q,expires_at:Q+ND2};return await this.enqueueWrite(async()=>{let w=await this.readStore();w.codes=w.codes.filter(($)=>$.expires_at>Q),w.codes.push(B),await this.writeStore(w)}),B}async consumeCode(A){let Q=RZ0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new HJ("Authorization code not found");if(f.consumed_at!==void 0)throw new HJ("Authorization code already consumed");if(f.expires_at<=Q)throw new HJ("Authorization code expired");if(f.client_id!==A.clientId)throw new HJ("Authorization code client mismatch");if(!OzA(f.redirect_uri,A.redirectUri))throw new HJ("Authorization code redirect URI mismatch");let I=await LD2(A.codeVerifier);if(f.code_challenge!==I)throw new HJ("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new HJ("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return qD2(JSON.parse(await WD2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await XD2(KD2(this.storeFile),{recursive:!0,mode:448}),await HD2(this.storeFile,`${JSON.stringify(A,null,2)}
1819
1819
  `,{mode:384}),await GD2(this.storeFile,384)}}class HJ extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}WA();import{randomUUID as bZ0}from"crypto";import{mkdir as VD2,readFile as ED2,writeFile as MD2,chmod as CD2}from"fs/promises";import{dirname as OD2,join as RD2}from"path";var bD2="oauth-clients.json",PD2=H.enum(["none","client_secret_basic","client_secret_post"]),kD2=H.object({redirect_uris:H.array(H.string().url()).min(1),token_endpoint_auth_method:PD2.default("none"),grant_types:H.array(H.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:H.array(H.literal("code")).default(["code"]),scope:H.string().optional(),client_name:H.string().optional(),client_uri:H.string().url().optional(),logo_uri:H.string().url().optional(),contacts:H.array(H.string()).optional()});function jD2(){return Math.floor(Date.now()/1000)}function _D2(){return`ocs_${bZ0().replaceAll("-","")}`}function vD2(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(TD2)}}function TD2(A){if(!A||typeof A!=="object")return!1;let Q=A;return typeof Q.client_id==="string"&&Array.isArray(Q.redirect_uris)&&Q.redirect_uris.every((B)=>typeof B==="string")&&typeof Q.client_id_issued_at==="number"}class BAA{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=RD2(A.storageDir,A.storeFile??bD2)}async registerClient(A){let Q=kD2.safeParse(A);if(!Q.success)throw new Wh(Q.error.message);let B=Q.data,w=jD2(),$=`oc_${bZ0()}`,f=B.token_endpoint_auth_method==="none",I={client_id:$,client_id_issued_at:w,redirect_uris:B.redirect_uris,token_endpoint_auth_method:B.token_endpoint_auth_method,grant_types:B.grant_types,response_types:B.response_types,...B.scope?{scope:B.scope}:{},...B.client_name?{client_name:B.client_name}:{},...B.client_uri?{client_uri:B.client_uri}:{},...B.logo_uri?{logo_uri:B.logo_uri}:{},...B.contacts?{contacts:B.contacts}:{},...!f?{client_secret:_D2(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(I),await this.writeStore(D)}),I}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return vD2(JSON.parse(await ED2(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await VD2(OD2(this.storeFile),{recursive:!0,mode:448}),await MD2(this.storeFile,`${JSON.stringify(A,null,2)}
1820
1820
  `,{mode:384}),await CD2(this.storeFile,384)}}class Wh extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}import{createHash as yD2}from"crypto";import{mkdir as xD2,readFile as SD2,writeFile as gD2,chmod as hD2}from"fs/promises";import{dirname as mD2,join as uD2}from"path";var cD2="oauth-signing-key.jwk";function PZ0(A){if(!A||typeof A!=="object")return!1;let Q=A;return Q.kty==="EC"&&Q.crv==="P-256"&&typeof Q.x==="string"&&typeof Q.y==="string"&&typeof Q.d==="string"}function kZ0(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return yD2("sha256").update(Q).digest("base64url")}function lD2(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function pD2(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!PZ0(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=kZ0(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class wAA{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=uD2(A.storageDir,A.keyFile??cD2)}async getPrivateJwk(){if(this.cachedKey)return this.cachedKey;this.loadPromise??=this.loadOrCreateKey();try{return this.cachedKey=await this.loadPromise,this.cachedKey}catch(A){throw this.loadPromise=void 0,A}}async loadOrCreateKey(){let A=await this.readExistingKey();if(A)return A;let Q=await pD2();return await xD2(mD2(this.keyFile),{recursive:!0,mode:448}),await gD2(this.keyFile,`${JSON.stringify(Q,null,2)}
1821
1821
  `,{mode:384}),await hD2(this.keyFile,384),Q}async getPublicJwk(){return lD2(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await SD2(this.keyFile,"utf8"));if(!PZ0(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:kZ0(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var s2={};SB(s2,{trimPadding:()=>_Z0,toUTF8String:()=>eD2,toBuffer:()=>oD2,toBase64:()=>aD2,isBase64URL:()=>QY2,isBase64:()=>AY2,fromUTF8String:()=>tD2,fromBuffer:()=>sD2});var jZ0=(A)=>{let Q=typeof Uint8Array>"u"?[]:new Uint8Array(256),B=64;for(let w=0;w<64;w++)Q[A.charCodeAt(w)]=w;return Q},iD2=jZ0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),rD2=jZ0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),dD2=/^[-A-Za-z0-9\-_]*$/,nD2=/^[-A-Za-z0-9+/]*={0,3}$/,LW={};LW.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,Y,U;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let J=new ArrayBuffer(w),X=new Uint8Array(J),G=Q?rD2:iD2;for($=0;$<B;$+=4)I=G[A.charCodeAt($)],D=G[A.charCodeAt($+1)],Y=G[A.charCodeAt($+2)],U=G[A.charCodeAt($+3)],X[f++]=I<<2|D>>4,X[f++]=(D&15)<<4|Y>>2,X[f++]=(Y&3)<<6|U&63;return J};LW.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",f=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<f;w+=3)$+=I[B[w]>>2],$+=I[(B[w]&3)<<4|B[w+1]>>4],$+=I[(B[w+1]&15)<<2|B[w+2]>>6],$+=I[B[w+2]&63];let D=f%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};LW.toString=(A,Q)=>{return new TextDecoder().decode(LW.toArrayBuffer(A,Q))};LW.fromString=(A,Q)=>{return LW.fromArrayBuffer(new TextEncoder().encode(A),Q)};LW.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?dD2.test(A):nD2.test(A)}catch(B){return!1}};LW.base64=LW;var NK=LW;function oD2(A,Q="base64url"){let B=NK.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function sD2(A,Q="base64url"){let B=new Uint8Array(A);return NK.fromArrayBuffer(B.buffer,Q==="base64url")}function aD2(A){let Q=NK.toArrayBuffer(A,!0);return NK.fromArrayBuffer(Q)}function tD2(A){return NK.fromString(A,!0)}function eD2(A){return NK.toString(A,!0)}function AY2(A){return NK.validate(A,!1)}function QY2(A){return A=_Z0(A),NK.validate(A,!0)}function _Z0(A){return A.replace(/=/g,"")}var q4={};SB(q4,{encode:()=>VY2,decodeFirst:()=>LY2});function qP(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),f,I=0;switch(Q){case 24:{if(w>0)f=$.getUint8(0),I=2;break}case 25:{if(w>1)f=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)f=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let D=$.getBigUint64(0,!1);if(D>=24n&&D<=Number.MAX_SAFE_INTEGER)return[Number(D),9]}break}}if(f&&f>=24)return[f,I];throw Error("Length not supported or not well formed")}var $AA=0,Hh=1,bzA=2,PzA=3,kzA=4,jzA=5,_zA=6,vZ0=7;function VW(A,Q){let B=A<<5;if(Q<0)throw Error("CBOR Data Item argument must not be negative");let w;if(typeof Q=="number"){if(!Number.isInteger(Q))throw Error("CBOR Data Item argument must be an integer");w=BigInt(Q)}else w=Q;if(A==Hh){if(w==0n)throw Error("CBOR Data Item argument cannot be zero when negative");w=w-1n}if(w>18446744073709551615n)throw Error("CBOR number out of range");let $=new Uint8Array(8);if(new DataView($.buffer).setBigUint64(0,w,!1),w<=23)return[B|$[7]];else if(w<=255)return[B|24,$[7]];else if(w<=65535)return[B|25,...$.slice(6)];else if(w<=4294967295)return[B|26,...$.slice(4)];else return[B|27,...$]}class IAA{constructor(A,Q){Object.defineProperty(this,"tagId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"tagValue",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.tagId=A,this.tagValue=Q}get tag(){return this.tagId}get value(){return this.tagValue}}function TZ0(A,Q,B){return qP(A,Q,B)}function BY2(A,Q,B){let[w,$]=TZ0(A,Q,B);return[-w-1,$]}function yZ0(A,Q,B){let[w,$]=qP(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var wY2=new TextDecoder;function $Y2(A,Q,B){let[w,$]=yZ0(A,Q,B);return[wY2.decode(w),$]}function fY2(A,Q,B){if(Q===0)return[[],1];let[w,$]=qP(A,Q,B),f=$,I=[];for(let D=0;D<w;D++){if(A.byteLength-B-f<=0)throw Error("array is not supported or well formed");let[U,J]=RV(A,B+f);I.push(U),f+=J}return[I,f]}var fAA="Map is not supported or well formed";function IY2(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=qP(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let Y=A.byteLength-B-f;if(Y<=0)throw Error(fAA);let[U,J]=RV(A,B+f);if(f+=J,Y-=J,Y<=0)throw Error(fAA);if(typeof U!=="string"&&typeof U!=="number")throw Error(fAA);if(I.has(U))throw Error(fAA);let[X,G]=RV(A,B+f);f+=G,I.set(U,X)}return[I,f]}function DY2(A,Q){if(Q+3>A.byteLength)throw Error("CBOR stream ended before end of Float 16");let B=A.getUint16(Q+1,!1);if(B==31744)return[1/0,3];else if(B==32256)return[NaN,3];else if(B==64512)return[-1/0,3];throw Error("Float16 data is unsupported")}function YY2(A,Q){if(Q+5>A.byteLength)throw Error("CBOR stream ended before end of Float 32");return[A.getFloat32(Q+1,!1),5]}function UY2(A,Q){if(Q+9>A.byteLength)throw Error("CBOR stream ended before end of Float 64");return[A.getFloat64(Q+1,!1),9]}function JY2(A,Q,B){let[w,$]=qP(A,Q,B),[f,I]=RV(A,B+$);return[new IAA(w,f),$+I]}function RV(A,Q){if(Q>=A.byteLength)throw Error("CBOR stream ended before tag value");let B=A.getUint8(Q),w=B>>5,$=B&31;switch(w){case $AA:return TZ0(A,$,Q);case Hh:return BY2(A,$,Q);case bzA:return yZ0(A,$,Q);case PzA:return $Y2(A,$,Q);case kzA:return fY2(A,$,Q);case jzA:return IY2(A,$,Q);case _zA:return JY2(A,$,Q);case vZ0:switch($){case 20:return[!1,1];case 21:return[!0,1];case 22:return[null,1];case 23:return[void 0,1];case 25:return DY2(A,Q);case 26:return YY2(A,Q);case 27:return UY2(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function XY2(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function WY2(A){if(Math.fround(A)==A||!Number.isFinite(A)||Number.isNaN(A)){let Q=new Uint8Array(5);return Q[0]=250,new DataView(Q.buffer).setFloat32(1,A,!1),Q}else{let Q=new Uint8Array(9);return Q[0]=251,new DataView(Q.buffer).setFloat64(1,A,!1),Q}}function HY2(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return VW(Hh,Math.abs(A));else return VW($AA,A);return[WY2(A)]}else if(A<0n)return VW(Hh,A*-1n);else return VW($AA,A)}var GY2=new TextEncoder;function KY2(A,Q){Q.push(...VW(PzA,A.length)),Q.push(GY2.encode(A))}function FY2(A,Q){Q.push(...VW(bzA,A.length)),Q.push(A)}function ZY2(A,Q){Q.push(...VW(kzA,A.length));for(let B of A)Gh(B,Q)}function NY2(A,Q){Q.push(new Uint8Array(VW(jzA,A.size)));for(let[B,w]of A.entries())Gh(B,Q),Gh(w,Q)}function zY2(A,Q){Q.push(...VW(_zA,A.tag)),Gh(A.value,Q)}function Gh(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(XY2(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...HY2(A));return}if(typeof A=="string"){KY2(A,Q);return}if(A instanceof Uint8Array){FY2(A,Q);return}if(Array.isArray(A)){ZY2(A,Q);return}if(A instanceof Map){NY2(A,Q);return}if(A instanceof IAA){zY2(A,Q);return}throw Error("Not implemented")}function vzA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return RV(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return RV(new DataView(A),Q);return RV(A,Q)}function TzA(A){let Q=[];Gh(A,Q);let B=0;for(let f of Q)if(typeof f=="number")B+=1;else B+=f.length;let w=new Uint8Array(B),$=0;for(let f of Q)if(typeof f=="number")w[$]=f,$+=1;else w.set(f,$),$+=f.length;return w}function LY2(A){let Q=new Uint8Array(A),B=vzA(Q,0),[w]=B;return w}function VY2(A){return TzA(A)}var MW={};SB(MW,{verify:()=>FL0,getRandomValues:()=>mZ0,digest:()=>hZ0});function xZ0(A){let Q=A.get(d2.kty);return yzA(Q)&&Q===gI.OKP}function lN(A){let Q=A.get(d2.kty);return yzA(Q)&&Q===gI.EC2}function LP(A){let Q=A.get(d2.kty);return yzA(Q)&&Q===gI.RSA}var d2;(function(A){A[A.kty=1]="kty",A[A.alg=3]="alg",A[A.crv=-1]="crv",A[A.x=-2]="x",A[A.y=-3]="y",A[A.n=-1]="n",A[A.e=-2]="e"})(d2||(d2={}));var gI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(gI||(gI={}));function yzA(A){return Object.values(gI).indexOf(A)>=0}var C7;(function(A){A[A.P256=1]="P256",A[A.P384=2]="P384",A[A.P521=3]="P521",A[A.ED25519=6]="ED25519",A[A.SECP256K1=8]="SECP256K1"})(C7||(C7={}));function SZ0(A){return Object.values(C7).indexOf(A)>=0}var EQ;(function(A){A[A.ES256=-7]="ES256",A[A.EdDSA=-8]="EdDSA",A[A.ES384=-35]="ES384",A[A.ES512=-36]="ES512",A[A.PS256=-37]="PS256",A[A.PS384=-38]="PS384",A[A.PS512=-39]="PS512",A[A.ES256K=-47]="ES256K",A[A.RS256=-257]="RS256",A[A.RS384=-258]="RS384",A[A.RS512=-259]="RS512",A[A.RS1=-65535]="RS1"})(EQ||(EQ={}));function EW(A){return Object.values(EQ).indexOf(A)>=0}function pN(A){if([EQ.RS1].indexOf(A)>=0)return"SHA-1";else if([EQ.ES256,EQ.PS256,EQ.RS256].indexOf(A)>=0)return"SHA-256";else if([EQ.ES384,EQ.PS384,EQ.RS384].indexOf(A)>=0)return"SHA-384";else if([EQ.ES512,EQ.PS512,EQ.RS512,EQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var Kh=void 0;function Ff(){return new Promise((Q,B)=>{if(Kh)return Q(Kh);let w=MY2.stubThisGlobalThisCrypto();if(w)return Kh=w,Q(Kh);return B(new gZ0)})}class gZ0 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var MY2={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{Kh=A}};async function hZ0(A,Q){let B=await Ff(),w=pN(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function mZ0(A){return(await Ff()).getRandomValues(A),A}async function VP(A){let Q=await Ff(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function DAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Ff(),I=Q.get(d2.alg),D=Q.get(d2.crv),Y=Q.get(d2.x),U=Q.get(d2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!Y)throw Error("Public key was missing x (EC2)");if(!U)throw Error("Public key was missing y (EC2)");let J;if(D===C7.P256)J="P-256";else if(D===C7.P384)J="P-384";else if(D===C7.P521)J="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let X={kty:"EC",crv:J,x:s2.fromBuffer(Y),y:s2.fromBuffer(U),ext:!1},Z=await VP({keyData:X,algorithm:{name:"ECDSA",namedCurve:J}}),N=pN(I);if($)N=pN($);let L={name:"ECDSA",hash:{name:N}};return f.subtle.verify(L,Z,B,w)}function xzA(A){if([EQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([EQ.ES256,EQ.ES384,EQ.ES512,EQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([EQ.RS256,EQ.RS384,EQ.RS512,EQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([EQ.PS256,EQ.PS384,EQ.PS512].indexOf(A)>=0)return"RSA-PSS";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto key alg name`)}async function YAA(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Ff(),I=Q.get(d2.alg),D=Q.get(d2.n),Y=Q.get(d2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!EW(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!Y)throw Error("Public key was missing e (RSA)");let U={kty:"RSA",alg:"",n:s2.fromBuffer(D),e:s2.fromBuffer(Y),ext:!1},J={name:xzA(I),hash:{name:pN(I)}},X={name:xzA(I)};if($)J.hash.name=pN($);if(J.name==="RSASSA-PKCS1-v1_5"){if(J.hash.name==="SHA-256")U.alg="RS256";else if(J.hash.name==="SHA-384")U.alg="RS384";else if(J.hash.name==="SHA-512")U.alg="RS512";else if(J.hash.name==="SHA-1")U.alg="RS1"}else if(J.name==="RSA-PSS"){let Z=0;if(J.hash.name==="SHA-256")U.alg="PS256",Z=32;else if(J.hash.name==="SHA-384")U.alg="PS384",Z=48;else if(J.hash.name==="SHA-512")U.alg="PS512",Z=64;X.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${J.name})`);let G=await VP({keyData:U,algorithm:J});return f.subtle.verify(X,G,B,w)}function UAA(A){let Q=G2.toHex(A);return[Q.slice(0,8),Q.slice(8,12),Q.slice(12,16),Q.slice(16,20),Q.slice(20,32)].join("-")}function p5(A){let Q;if(typeof A==="string")if(s2.isBase64URL(A))Q=s2.toBase64(A);else if(s2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=s2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
@@ -2394,8 +2394,8 @@ ${M}`)}if(w!==void 0&&f?.algorithms!==void 0){let V=f.algorithms.map((M)=>M.alg)
2394
2394
  </form>
2395
2395
  </main>
2396
2396
  </body>
2397
- </html>`}function Au(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(aVA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hW(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}import{randomUUID as BW2}from"crypto";function PV0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function QW2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,Y=Q.slice(D,D+I);return new Uint8Array([...kV0(f),...kV0(Y)])}function kV0(A){let Q=A;while(Q.length>32&&Q[0]===0)Q=Q.slice(1);if(Q.length>32)throw Error("Invalid P-256 signature component length");if(Q.length===32)return Q;let B=new Uint8Array(32);return B.set(Q,32-Q.length),B}async function eVA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${PV0(B)}.${PV0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(QW2(f)).toString("base64url")}`}var wW2=600;class AEA{clientStore;authCodeStore;refreshTokenStore;sessionStore;keyStore;authorizationApprovalTokens=new Map;constructor(A){this.clientStore=A.clientStore,this.authCodeStore=A.authCodeStore,this.refreshTokenStore=A.refreshTokenStore,this.sessionStore=A.sessionStore,this.keyStore=A.keyStore}async handleAuthorizePage(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ck(bV0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(dVA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${BW2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+wW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let Y=await this.clientStore.getClient(B);if(!Y)return{success:!1,error:"Unknown client_id"};if(!RzA(Y.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let U=I??Y.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...U?{scope:U}:{},...D?{state:D}:{},clientName:Y.client_name??Y.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return N6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return rI(B,201)}catch(B){if(B instanceof Wh)return N6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await rVA(A),w=B.get("grant_type"),$=oVA(A,B),f=$.clientId??B.get("client_id");if($.error)return N6("invalid_client",$.error);if(!f)return N6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=nVA(I,$);if(D)return N6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return N6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return N6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!RzA(I.redirect_uris,$))return N6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof HJ)return N6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return N6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof uK)return N6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await eVA(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return rI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await rVA(A),B=oVA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return N6("invalid_client",B.error);if(!$)return N6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=nVA(f,B);if(I)return N6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class QEA{passkeyService;sessionStore;setupFlow;constructor(A){this.passkeyService=A.passkeyService,this.sessionStore=A.sessionStore,this.setupFlow=A.setupFlow}async handleRegistrationOptions(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(u0A(A));return rI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),u0A(A));if(!Q.verified)return N6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return N6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(u0A(A));return rI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),u0A(A));if(!Q.verified)return N6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}}function u0A(A){let Q=yk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as $W2}from"crypto";var Qu=86400;class BEA{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??Qu}async ensureSetupToken(){let A=this.getValidSetupToken();if(A)return A;let Q=await this.setupStateStore.getValidSetupToken(Math.floor(Date.now()/1000));if(Q)return this.setupToken=Q,Q;return this.createSetupToken()}async createSetupToken(){return this.setupToken={token:`setup_${$W2()}`,expiresAt:Math.floor(Date.now()/1000)+this.setupTokenTtlSeconds},await this.setupStateStore.saveSetupToken(this.setupToken),this.setupToken}getValidSetupToken(){if(!this.setupToken)return;if(this.setupToken.expiresAt<=Math.floor(Date.now()/1000)){this.setupToken=void 0;return}return this.setupToken}hasValidSetupToken(A){let Q=this.getValidSetupToken();if(!Q)return!1;let B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return gW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:gW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:CVA(Q.token)}}async handleSetupPage(A){if(await this.passkeyService.hasCredentials())return new Response("Setup already completed",{status:404});if(!this.hasValidSetupToken(A))return new Response("Not Found",{status:404});let Q=new URL(A.url).searchParams.get("token")??"";return ck(OV0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class c0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=MJ(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>MJ(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??Tk(this.issuer),this.keyStore=new wAA({storageDir:A.storageDir}),this.clientStore=new BAA({storageDir:A.storageDir}),this.authCodeStore=new QAA({storageDir:A.storageDir}),this.sessionStore=new x0A({storageDir:A.storageDir}),this.passkeyService=new j0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new BEA({setupStateStore:new OVA({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??Qu}),this.oauthEndpoints=new AEA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new v0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new QEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(Tk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=MJ(A);return{issuer:Q,authorization_endpoint:gW(Q,"/authorize"),token_endpoint:gW(Q,"/token"),registration_endpoint:gW(Q,"/register"),revocation_endpoint:gW(Q,"/revoke"),jwks_uri:gW(Q,"/.well-known/jwks.json"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none","client_secret_basic","client_secret_post"],scopes_supported:["openid","profile","email","offline_access","mcp"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["ES256"]}}getProtectedResourceMetadata(A,Q=this.issuer){return{resource:A,authorization_servers:[MJ(Q)],bearer_methods_supported:["header"],resource_signing_alg_values_supported:["ES256"],scopes_supported:["mcp"]}}async registerClient(A){return this.clientStore.registerClient(A)}async getRegisteredClient(A){return this.clientStore.getClient(A)}async createOperatorSession(A="single-operator",Q={}){return this.sessionStore.createSession(A,Q)}async getOperatorSession(A){return this.sessionStore.getSessionFromRequest(A)}createOperatorLoginResponse(A){return Au(A)}async verifyBearerToken(A,Q={}){let B=iVA(A);if(!B)return;let w=Q.issuer?MJ(Q.issuer):this.resolveRequestIssuer(A);return pVA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&EV0(B))return MV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return z3(rI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return z3(rI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return z3(rI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return z3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return z3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return z3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=yk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&Tk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=sVA(new URL(A.url).searchParams.get("return_to"));return ck(aVA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=sVA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":PVA(sm(A)),"Cache-Control":"no-store"}})}}WA();var l0A="email:send",jV0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var _V0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.121",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var wEA="notifications:send",IW2=H.object({}),DW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),YW2=H.object({recipient:DW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),vV0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class TV0 extends UB{constructor(A={}){super("notifications",_V0,A,IW2)}async onRegister(A){A.messaging.subscribe(wEA,async(Q)=>{let B=YW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:l0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function p0A(A={}){return new TV0(A)}aA();WA();var yV0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.121",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var JW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),XW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupTokenTtlSeconds:H.number().int().positive().default(Qu),setupEmail:JW2.optional()}),WW2=H.object({}),i0A;function RY(){return i0A}class $EA extends UB{service;constructor(A={}){super("auth-service",yV0,A,XW2)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new c0A({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},setupTokenTtlSeconds:this.config.setupTokenTtlSeconds,logger:A.logger}),await this.service.initialize(),i0A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(i0A===this.service)i0A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",WW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return Y8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return Y8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return Y8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=HW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:wEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=vV0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function HW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
2398
- `)}}return{to:A.to,subject:xV0(A.subject,Q),body:xV0(A.body,Q)}}function xV0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Bu(A){return new $EA(A)}WA();var fEA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function SV0(A,Q){return[]}aA();function IEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=FR.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var gV0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.121",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class q3 extends eX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",gV0,Q,fEA)}async getTools(){return SV0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});IEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=RY();return this.httpServer=ZK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||RY()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=WJ.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){WJ.resetInstance(),ZK.resetInstance()}}aA();WA();var eI=Y1(be0(),1);WA();aA();var uPA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...yx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var Pe0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.121",description:"Discord interface for Brains",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.14.1"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest"}};var nQA=2000,Pd2=8000,kd2=100;function oQA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Qz extends iG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",Pe0,A,uPA);this.fetchText=Q.fetchText??Qo}async onRegister(A){await super.onRegister(A),this.client=new eI.Client({intents:[eI.GatewayIntentBits.Guilds,eI.GatewayIntentBits.GuildMessages,eI.GatewayIntentBits.MessageContent,eI.GatewayIntentBits.DirectMessages],partials:[eI.Partials.Channel]}),this.client.on(eI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(eI.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(eI.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!oQA(B))return;let w=uy(Q,nQA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!oQA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=uy(Q,nQA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!oQA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,nQA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let Y=Q||$||!this.config.requireMention||w;if(I&&(!Y||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!Y){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let U=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,L=Z.contentType??void 0,V=Z.size;if(!this.isUploadableTextFile(N,L))continue;if(!this.isFileSizeAllowed(V))continue;try{let M=await this.fetchText(Z.url);U+=`
2397
+ </html>`}function Au(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(aVA(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hW(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}import{randomUUID as BW2}from"crypto";function PV0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function QW2(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,Y=Q.slice(D,D+I);return new Uint8Array([...kV0(f),...kV0(Y)])}function kV0(A){let Q=A;while(Q.length>32&&Q[0]===0)Q=Q.slice(1);if(Q.length>32)throw Error("Invalid P-256 signature component length");if(Q.length===32)return Q;let B=new Uint8Array(32);return B.set(Q,32-Q.length),B}async function eVA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${PV0(B)}.${PV0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(QW2(f)).toString("base64url")}`}var wW2=600;class AEA{clientStore;authCodeStore;refreshTokenStore;sessionStore;keyStore;authorizationApprovalTokens=new Map;constructor(A){this.clientStore=A.clientStore,this.authCodeStore=A.authCodeStore,this.refreshTokenStore=A.refreshTokenStore,this.sessionStore=A.sessionStore,this.keyStore=A.keyStore}async handleAuthorizePage(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await this.validateAuthorizationRequest(new URL(A.url).searchParams);if(!B.success)return new Response(B.error,{status:400});let w=this.createAuthorizationApprovalToken(Q,B.params);return ck(bV0(B.params,w))}async handleAuthorizeApproval(A){let Q=await this.sessionStore.getSessionFromRequest(A);if(!Q)return Au(A);let B=await A.formData(),w=await this.validateAuthorizationRequest(new URLSearchParams(dVA(B)));if(!w.success)return new Response(w.error,{status:400});let $=B.get("approval_token"),f=typeof $==="string"?$:void 0;if(!f||!this.consumeAuthorizationApprovalToken(f,Q,w.params))return new Response("Invalid authorization approval token",{status:400});let I=await this.authCodeStore.createCode({clientId:w.params.clientId,redirectUri:w.params.redirectUri,codeChallenge:w.params.codeChallenge,...w.params.scope?{scope:w.params.scope}:{},subject:Q.subject}),D=new URL(w.params.redirectUri);if(D.searchParams.set("code",I.code),w.params.state)D.searchParams.set("state",w.params.state);return Response.redirect(D.toString(),302)}createAuthorizationApprovalToken(A,Q){this.pruneExpiredAuthorizationApprovalTokens();let B=`oat_${BW2()}`;return this.authorizationApprovalTokens.set(B,{token:B,sessionId:A.id,clientId:Q.clientId,redirectUri:Q.redirectUri,codeChallenge:Q.codeChallenge,...Q.scope?{scope:Q.scope}:{},...Q.state?{state:Q.state}:{},expiresAt:Math.floor(Date.now()/1000)+wW2}),B}consumeAuthorizationApprovalToken(A,Q,B){this.pruneExpiredAuthorizationApprovalTokens();let w=this.authorizationApprovalTokens.get(A);if(!w)return!1;return this.authorizationApprovalTokens.delete(A),w.sessionId===Q.id&&w.clientId===B.clientId&&w.redirectUri===B.redirectUri&&w.codeChallenge===B.codeChallenge&&w.scope===B.scope&&w.state===B.state}pruneExpiredAuthorizationApprovalTokens(){let A=Math.floor(Date.now()/1000);for(let[Q,B]of this.authorizationApprovalTokens.entries())if(B.expiresAt<=A)this.authorizationApprovalTokens.delete(Q)}async validateAuthorizationRequest(A){let Q=A.get("response_type"),B=A.get("client_id"),w=A.get("redirect_uri"),$=A.get("code_challenge"),f=A.get("code_challenge_method"),I=A.get("scope")??void 0,D=A.get("state")??void 0;if(Q!=="code")return{success:!1,error:"Unsupported response_type"};if(!B)return{success:!1,error:"Missing client_id"};if(!w)return{success:!1,error:"Missing redirect_uri"};if(!$)return{success:!1,error:"Missing code_challenge"};if(f!=="S256")return{success:!1,error:"Unsupported code_challenge_method"};let Y=await this.clientStore.getClient(B);if(!Y)return{success:!1,error:"Unknown client_id"};if(!RzA(Y.redirect_uris,w))return{success:!1,error:"Unregistered redirect_uri"};let U=I??Y.scope;return{success:!0,params:{clientId:B,redirectUri:w,codeChallenge:$,...U?{scope:U}:{},...D?{state:D}:{},clientName:Y.client_name??Y.client_id}}}async handleClientRegistration(A){let Q;try{Q=await A.json()}catch{return N6("invalid_client_metadata","Request body must be JSON")}try{let B=await this.clientStore.registerClient(Q);return rI(B,201)}catch(B){if(B instanceof Wh)return N6("invalid_client_metadata",B.message);throw B}}async handleTokenRequest(A,Q){let B=await rVA(A),w=B.get("grant_type"),$=oVA(A,B),f=$.clientId??B.get("client_id");if($.error)return N6("invalid_client",$.error);if(!f)return N6("invalid_request","client_id is required");let I=await this.clientStore.getClient(f),D=nVA(I,$);if(D)return N6("invalid_client",D);if(w==="authorization_code")return this.handleAuthorizationCodeGrant(B,f,Q);if(w==="refresh_token")return this.handleRefreshTokenGrant(B,f,Q);return N6("unsupported_grant_type","Only authorization_code and refresh_token are supported")}async handleAuthorizationCodeGrant(A,Q,B){let w=A.get("code"),$=A.get("redirect_uri"),f=A.get("code_verifier");if(!w||!$||!f)return N6("invalid_request","code, redirect_uri, and code_verifier are required");let I=await this.clientStore.getClient(Q);if(!I||!RzA(I.redirect_uris,$))return N6("invalid_grant","Unregistered redirect_uri");try{let D=await this.authCodeStore.consumeCode({code:w,clientId:Q,redirectUri:$,codeVerifier:f});return await this.createTokenResponse({issuer:B,clientId:Q,subject:D.subject,...D.scope?{scope:D.scope}:{}})}catch(D){if(D instanceof HJ)return N6("invalid_grant",D.message);throw D}}async handleRefreshTokenGrant(A,Q,B){let w=A.get("refresh_token");if(!w)return N6("invalid_request","refresh_token is required");try{let $=await this.refreshTokenStore.rotateToken(w,Q);return await this.createTokenResponse({issuer:B,clientId:Q,subject:$.consumed.subject,...$.consumed.scope?{scope:$.consumed.scope}:{},refreshToken:$.replacement.token})}catch($){if($ instanceof uK)return N6("invalid_grant",$.message);throw $}}async createTokenResponse(A){let Q=Math.floor(Date.now()/1000),B=900,w=await eVA(await this.keyStore.getPrivateJwk(),{iss:A.issuer,sub:A.subject,aud:A.clientId,iat:Q,exp:Q+900,...A.scope?{scope:A.scope}:{}}),$=A.refreshToken??(await this.refreshTokenStore.issueToken({clientId:A.clientId,subject:A.subject,...A.scope?{scope:A.scope}:{}})).token;return rI({access_token:w,token_type:"Bearer",expires_in:900,...A.scope?{scope:A.scope}:{},refresh_token:$})}async handleRevokeRequest(A){let Q=await rVA(A),B=oVA(A,Q),w=B.clientId??Q.get("client_id")??void 0,$=Q.get("token");if(B.error)return N6("invalid_client",B.error);if(!$)return N6("invalid_request","token is required");if(w){let f=await this.clientStore.getClient(w),I=nVA(f,B);if(I)return N6("invalid_client",I)}return await this.refreshTokenStore.revokeToken($,w),new Response(null,{status:200})}}class QEA{passkeyService;sessionStore;setupFlow;constructor(A){this.passkeyService=A.passkeyService,this.sessionStore=A.sessionStore,this.setupFlow=A.setupFlow}async handleRegistrationOptions(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.generateRegistrationOptions(u0A(A));return rI(Q)}async handleRegistrationVerify(A){if(await this.passkeyService.hasCredentials())return N6("access_denied","Passkey setup already completed");if(!this.setupFlow.hasValidSetupToken(A))return N6("access_denied","Invalid setup token");let Q=await this.passkeyService.verifyRegistrationResponse(await A.json(),u0A(A));if(!Q.verified)return N6("access_denied","Passkey registration failed");await this.setupFlow.clearSetupState();let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}async handleAuthenticationOptions(A){if(!await this.passkeyService.hasCredentials())return N6("access_denied","No passkey registered");let Q=await this.passkeyService.generateAuthenticationOptions(u0A(A));return rI(Q)}async handleAuthenticationVerify(A){let Q=await this.passkeyService.verifyAuthenticationResponse(await A.json(),u0A(A));if(!Q.verified)return N6("access_denied","Passkey authentication failed");let B=await this.sessionStore.createSession(Q.subject??"single-operator",{secure:sm(A)});return rI({verified:!0},200,{"Set-Cookie":B.cookie})}}function u0A(A){let Q=yk(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}import{randomUUID as $W2}from"crypto";var Qu=86400;class BEA{setupStateStore;passkeyService;setupTokenTtlSeconds;setupToken;constructor(A){this.setupStateStore=A.setupStateStore,this.passkeyService=A.passkeyService,this.setupTokenTtlSeconds=A.setupTokenTtlSeconds??Qu}async ensureSetupToken(){let A=this.getValidSetupToken();if(A)return A;let Q=await this.setupStateStore.getValidSetupToken(Math.floor(Date.now()/1000));if(Q)return this.setupToken=Q,Q;return this.createSetupToken()}async createSetupToken(){return this.setupToken={token:`setup_${$W2()}`,expiresAt:Math.floor(Date.now()/1000)+this.setupTokenTtlSeconds},await this.setupStateStore.saveSetupToken(this.setupToken),this.setupToken}getValidSetupToken(){if(!this.setupToken)return;if(this.setupToken.expiresAt<=Math.floor(Date.now()/1000)){this.setupToken=void 0;return}return this.setupToken}hasValidSetupToken(A){let Q=this.getValidSetupToken();if(!Q)return!1;let B=new URL(A.url);return(B.searchParams.get("setup_token")??B.searchParams.get("token"))===Q.token}async clearSetupState(){this.setupToken=void 0,await this.setupStateStore.clearSetupState()}getSetupUrl(A){let Q=this.getValidSetupToken();if(!Q)return;return gW(A,`/setup?token=${encodeURIComponent(Q.token)}`)}async getOperatorSetupRequired(A){if(await this.passkeyService.hasCredentials())return;let Q=this.getValidSetupToken();if(!Q)return;return{setupUrl:gW(A,`/setup?token=${encodeURIComponent(Q.token)}`),expiresAt:Q.expiresAt,setupTokenId:CVA(Q.token)}}async handleSetupPage(A){if(await this.passkeyService.hasCredentials())return new Response("Setup already completed",{status:404});if(!this.hasValidSetupToken(A))return new Response("Not Found",{status:404});let Q=new URL(A.url).searchParams.get("token")??"";return ck(OV0(Q))}async hasSetupEmailDelivery(A,Q){return this.setupStateStore.hasDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupStateStore.recordDelivery(A,Q,B)}}class c0A{issuer;trustedIssuers;allowLocalhostIssuers;keyStore;clientStore;authCodeStore;sessionStore;passkeyService;setupFlow;oauthEndpoints;webauthnEndpoints;logger;constructor(A){this.issuer=MJ(A.issuer),this.trustedIssuers=new Set([this.issuer,...(A.trustedIssuers??[]).map((Q)=>MJ(Q))]),this.allowLocalhostIssuers=A.allowLocalhostIssuers??Tk(this.issuer),this.keyStore=new wAA({storageDir:A.storageDir}),this.clientStore=new BAA({storageDir:A.storageDir}),this.authCodeStore=new QAA({storageDir:A.storageDir}),this.sessionStore=new x0A({storageDir:A.storageDir}),this.passkeyService=new j0A({storageDir:A.storageDir,...A.logger?{logger:A.logger}:{}}),this.setupFlow=new BEA({setupStateStore:new OVA({storageDir:A.storageDir}),passkeyService:this.passkeyService,setupTokenTtlSeconds:A.setupTokenTtlSeconds??Qu}),this.oauthEndpoints=new AEA({clientStore:this.clientStore,authCodeStore:this.authCodeStore,refreshTokenStore:new v0A({storageDir:A.storageDir}),sessionStore:this.sessionStore,keyStore:this.keyStore}),this.webauthnEndpoints=new QEA({passkeyService:this.passkeyService,sessionStore:this.sessionStore,setupFlow:this.setupFlow}),this.logger=A.logger}getIssuer(){return this.issuer}async initialize(){if(await this.keyStore.getPrivateJwk(),this.logger?.debug("Auth service signing key loaded"),!await this.hasPasskeyCredentials()){await this.setupFlow.ensureSetupToken();let A=this.getSetupUrl();if(A)if(Tk(this.issuer))this.logger?.warn(`Passkey setup required: ${A}`);else this.logger?.warn("Passkey setup required. Ask through an anchor-visible interface for the setup URL.")}}async hasPasskeyCredentials(){return this.passkeyService.hasCredentials()}async getJwks(){return{keys:[await this.keyStore.getPublicJwk()]}}getAuthorizationServerMetadata(A=this.issuer){let Q=MJ(A);return{issuer:Q,authorization_endpoint:gW(Q,"/authorize"),token_endpoint:gW(Q,"/token"),registration_endpoint:gW(Q,"/register"),revocation_endpoint:gW(Q,"/revoke"),jwks_uri:gW(Q,"/.well-known/jwks.json"),response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none","client_secret_basic","client_secret_post"],scopes_supported:["openid","profile","email","offline_access","mcp"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["ES256"]}}getProtectedResourceMetadata(A,Q=this.issuer){return{resource:A,authorization_servers:[MJ(Q)],bearer_methods_supported:["header"],resource_signing_alg_values_supported:["ES256"],scopes_supported:["mcp"]}}async registerClient(A){return this.clientStore.registerClient(A)}async getRegisteredClient(A){return this.clientStore.getClient(A)}async createOperatorSession(A="single-operator",Q={}){return this.sessionStore.createSession(A,Q)}async getOperatorSession(A){return this.sessionStore.getSessionFromRequest(A)}createOperatorLoginResponse(A){return Au(A)}async verifyBearerToken(A,Q={}){let B=iVA(A);if(!B)return;let w=Q.issuer?MJ(Q.issuer):this.resolveRequestIssuer(A);return pVA(B,await this.getJwks(),{issuer:w,...Q.audience?{audience:Q.audience}:{}})}getSetupUrl(A=this.issuer){return this.setupFlow.getSetupUrl(A)}async getOperatorSetupRequired(A=this.issuer){return this.setupFlow.getOperatorSetupRequired(A)}async hasSetupEmailDelivery(A,Q){return this.setupFlow.hasSetupEmailDelivery(A,Q)}async recordSetupEmailDelivery(A,Q,B={}){await this.setupFlow.recordSetupEmailDelivery(A,Q,B)}async handleRequest(A){let Q;try{Q=this.resolveRequestIssuer(A)}catch(w){return this.logger?.warn("Rejected OAuth request from untrusted issuer",{error:w instanceof Error?w.message:String(w)}),new Response("Untrusted OAuth issuer",{status:400})}let B=new URL(A.url).pathname;if(A.method==="OPTIONS"&&EV0(B))return MV0();if(A.method==="GET"){if(B==="/.well-known/oauth-authorization-server")return z3(rI(this.getAuthorizationServerMetadata(Q)));if(B==="/.well-known/jwks.json")return z3(rI(await this.getJwks()));if(B==="/.well-known/oauth-protected-resource")return z3(rI(this.getProtectedResourceMetadata(Q,Q)))}if(A.method==="GET"&&B==="/setup")return this.setupFlow.handleSetupPage(A);if(A.method==="GET"&&B==="/login")return this.handleLoginPage(A);if((A.method==="GET"||A.method==="POST")&&B==="/logout")return this.handleLogout(A);if(A.method==="POST"&&B==="/webauthn/register/options")return this.webauthnEndpoints.handleRegistrationOptions(A);if(A.method==="POST"&&B==="/webauthn/register/verify")return this.webauthnEndpoints.handleRegistrationVerify(A);if(A.method==="POST"&&B==="/webauthn/auth/options")return this.webauthnEndpoints.handleAuthenticationOptions(A);if(A.method==="POST"&&B==="/webauthn/auth/verify")return this.webauthnEndpoints.handleAuthenticationVerify(A);if(A.method==="GET"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizePage(A);if(A.method==="POST"&&B==="/authorize")return this.oauthEndpoints.handleAuthorizeApproval(A);if(A.method==="POST"&&B==="/register")return z3(await this.oauthEndpoints.handleClientRegistration(A));if(A.method==="POST"&&B==="/token")return z3(await this.oauthEndpoints.handleTokenRequest(A,Q));if(A.method==="POST"&&B==="/revoke")return z3(await this.oauthEndpoints.handleRevokeRequest(A));return new Response("Not Found",{status:404})}async handleWellKnownRequest(A){return this.handleRequest(A)}resolveRequestIssuer(A){let Q=yk(A,this.issuer);if(this.trustedIssuers.has(Q)||this.allowLocalhostIssuers&&Tk(Q))return Q;throw Error(`Request issuer ${Q} is not in trusted issuers`)}handleLoginPage(A){let Q=sVA(new URL(A.url).searchParams.get("return_to"));return ck(aVA(Q))}async handleLogout(A){await this.sessionStore.revokeSessionFromRequest(A);let Q=sVA(new URL(A.url).searchParams.get("return_to"));return new Response(null,{status:302,headers:{Location:Q,"Set-Cookie":PVA(sm(A)),"Cache-Control":"no-store"}})}}WA();var l0A="email:send",jV0=H.object({to:H.string().email(),subject:H.string().min(1),text:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict();aA();WA();var _V0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.122",description:"Generic notification routing for transactional and administrative messages",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var wEA="notifications:send",IW2=H.object({}),DW2=H.discriminatedUnion("type",[H.object({type:H.literal("email"),address:H.string().email()}).strict()]),YW2=H.object({recipient:DW2,title:H.string().min(1),body:H.string().min(1),html:H.string().min(1).optional(),sensitivity:H.enum(["normal","secret"]).default("normal")}).strict(),vV0=H.discriminatedUnion("status",[H.object({status:H.literal("sent"),deliveryId:H.string().optional()}).strict(),H.object({status:H.literal("failed")}).strict()]);class TV0 extends UB{constructor(A={}){super("notifications",_V0,A,IW2)}async onRegister(A){A.messaging.subscribe(wEA,async(Q)=>{let B=YW2.parse(Q.payload),w={to:B.recipient.address,subject:B.title,text:B.body,...B.html?{html:B.html}:{},sensitivity:B.sensitivity},$=await A.messaging.send({type:l0A,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function p0A(A={}){return new TV0(A)}aA();WA();var yV0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.122",description:"Embedded OAuth/OIDC auth service for brain operator authentication",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@simplewebauthn/server":"^13.3.0",jose:"^6.2.3"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},files:["src"]};var JW2=H.union([H.string().email(),H.object({to:H.string().email(),subject:H.string().min(1),body:H.string().min(1)}).strict()]),XW2=H.object({issuer:H.string().optional(),trustedIssuers:H.array(H.string()).default([]),allowLocalhostIssuers:H.boolean().optional(),storageDir:H.string().default("./data/auth"),setupTokenTtlSeconds:H.number().int().positive().default(Qu),setupEmail:JW2.optional()}),WW2=H.object({}),i0A;function RY(){return i0A}class $EA extends UB{service;constructor(A={}){super("auth-service",yV0,A,XW2)}async onRegister(A){await super.onRegister(A);let Q=this.config.issuer??(A.preferLocalUrls?A.localSiteUrl??A.siteUrl:A.siteUrl??A.localSiteUrl);this.service=new c0A({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},setupTokenTtlSeconds:this.config.setupTokenTtlSeconds,logger:A.logger}),await this.service.initialize(),i0A=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(i0A===this.service)i0A=void 0;this.service=void 0}async getTools(){return[oQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",WW2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return Y8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return Y8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return Y8({status:"unavailable",reason:"Passkey setup URL is not available."})},{visibility:"anchor"})]}getWebRoutes(){let A=(Q)=>this.getService().handleRequest(Q);return[{path:"/.well-known/oauth-authorization-server",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-authorization-server",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"GET",public:!0,handler:A},{path:"/.well-known/jwks.json",method:"OPTIONS",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"GET",public:!0,handler:A},{path:"/.well-known/oauth-protected-resource",method:"OPTIONS",public:!0,handler:A},{path:"/setup",method:"GET",public:!0,handler:A},{path:"/login",method:"GET",public:!0,handler:A},{path:"/logout",method:"GET",public:!0,handler:A},{path:"/logout",method:"POST",public:!0,handler:A},{path:"/authorize",method:"GET",public:!0,handler:A},{path:"/authorize",method:"POST",public:!0,handler:A},{path:"/register",method:"POST",public:!0,handler:A},{path:"/register",method:"OPTIONS",public:!0,handler:A},{path:"/token",method:"POST",public:!0,handler:A},{path:"/token",method:"OPTIONS",public:!0,handler:A},{path:"/revoke",method:"POST",public:!0,handler:A},{path:"/revoke",method:"OPTIONS",public:!0,handler:A},{path:"/webauthn/register/options",method:"POST",public:!0,handler:A},{path:"/webauthn/register/verify",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/options",method:"POST",public:!0,handler:A},{path:"/webauthn/auth/verify",method:"POST",public:!0,handler:A}]}getService(){if(!this.service)throw Error("AuthServicePlugin has not been registered");return this.service}async requestSetupEmailIfNeeded(A){if(!this.config.setupEmail)return;let Q=this.getService();if(await Q.hasPasskeyCredentials())return;let B=await Q.getOperatorSetupRequired();if(!B)return;let w=HW2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:wEA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=vV0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function HW2(A,Q){if(typeof A==="string"){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return{to:A,subject:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",Q.setupUrl,"",`This link expires at ${B}.`,`Dashboard: ${w}/`,`MCP endpoint: ${w}/mcp`,"The first successful passkey registration completes setup and closes this link."].join(`
2398
+ `)}}return{to:A.to,subject:xV0(A.subject,Q),body:xV0(A.body,Q)}}function xV0(A,Q){let B=new Date(Q.expiresAt*1000).toISOString(),w=new URL(Q.setupUrl).origin;return A.replaceAll("{{setupUrl}}",Q.setupUrl).replaceAll("{{expiresAt}}",B).replaceAll("{{origin}}",w)}function Bu(A){return new $EA(A)}WA();var fEA=H.object({transport:H.enum(["stdio","http"]).default("http"),httpPort:H.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:H.string().describe("Bearer token for HTTP transport authentication").optional()});function SV0(A,Q){return[]}aA();function IEA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=FR.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var gV0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.122",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@brains/auth-service":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@modelcontextprotocol/sdk":"^1.24.0",cors:"^2.8.5",express:"^4.18.0","express-async-handler":"^1.2.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/cors":"^2.8.17","@types/express":"^4.17.21",typescript:"^5.3.3"}};class q3 extends eX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",gV0,Q,fEA)}async getTools(){return SV0(this.id,()=>this.context)}async getResources(){return[]}async onRegister(A){if(this.domain=A.domain,this.config.transport==="http"&&!A.plugins.has("webserver"))throw Error("MCP HTTP transport requires the webserver interface. Standalone HTTP listeners have been removed.");if(this.logger.debug(`MCP interface initialized with ${this.config.transport} transport`),this.config.transport==="http")A.endpoints.register({label:"MCP",url:"/mcp",priority:30,visibility:"trusted"}),A.interactions.register({id:"mcp",label:"MCP",description:"Connect a trusted client through the Model Context Protocol.",href:"/mcp",kind:"protocol",priority:30,visibility:"trusted"});IEA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=RY();return this.httpServer=ZK.createFresh({port:this.config.httpPort,logger:this.logger,auth:this.config.authToken?{token:this.config.authToken}:A?{requiredScopes:["mcp"],verifyBearerToken:async(Q)=>A.verifyBearerToken(Q)}:{disabled:!0}}),this.httpServer}getWebRoutes(){if(this.config.transport!=="http")return[];let A=(Q)=>this.getOrCreateHttpServer().handleRequest(Q);return[{path:"/status",method:"GET",public:!0,handler:A},{path:"/mcp",method:"GET",public:!0,handler:A},{path:"/mcp",method:"POST",public:!0,handler:A},{path:"/mcp",method:"DELETE",public:!0,handler:A},{path:"/mcp",method:"OPTIONS",public:!0,handler:A}]}createDaemon(){return{start:async()=>{await this.startServer()},stop:async()=>{await this.stopServer()},healthCheck:async()=>{let A=this.isServerRunning(),Q="MCP server not running";if(A)if(this.config.transport==="http")Q=`MCP HTTP: ${this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp"}`;else Q="MCP stdio server running";return{status:A?"healthy":"error",message:Q,lastCheck:new Date,details:{transport:this.config.transport,url:this.config.transport==="http"?this.domain?`https://${this.domain}/mcp`:"http://localhost:8080/mcp":void 0,running:A}}}}}isServerRunning(){if(this.config.transport==="stdio")return this.stdioServer!==void 0&&this.mcpTransport!==void 0;else return this.httpServer!==void 0&&this.mcpTransport!==void 0}async startServer(){if(!this.context)throw Error("Context not initialized");let A=this.context;this.mcpTransport=A.mcpTransport;let Q=this.config.transport==="stdio"?"stdio":"http",B=this.context.permissions.getUserLevel("mcp",Q);if(this.config.transport==="http"&&(this.config.authToken||RY()))B="anchor",this.logger.debug("HTTP authentication configured - authenticated users will have anchor permissions");if(this.mcpTransport.setPermissionLevel(B),this.logger.debug(`Starting MCP ${this.config.transport} transport with ${B} permissions`),this.config.transport==="stdio"){this.stdioServer=WJ.createFresh();let w=this.mcpTransport.getMcpServer();this.stdioServer.connectMCPServer(w),await this.stdioServer.start(),this.logger.debug("MCP STDIO transport started")}else{this.httpServer=this.getOrCreateHttpServer();let w=this.mcpTransport.getMcpServer();this.httpServer.connectMCPServer(w,this.mcpTransport),this.httpServer.connectAgentService(A.agent),this.logger.debug("MCP HTTP transport mounted on shared webserver host")}}async stopServer(){if(this.logger.debug(`Stopping MCP ${this.config.transport} transport`),this.stdioServer)this.stdioServer.stop(),this.stdioServer=void 0;if(this.httpServer)await this.httpServer.stop(),this.httpServer=void 0;this.mcpTransport=void 0}async handleProgressEvent(A,Q){}async onShutdown(){WJ.resetInstance(),ZK.resetInstance()}}aA();WA();var eI=Y1(be0(),1);WA();aA();var uPA=H.object({botToken:H.string().min(1).describe("Discord bot token"),allowedChannels:H.array(H.string()).default([]),requireMention:H.boolean().default(!0),allowDMs:H.boolean().default(!0),showTypingIndicator:H.boolean().default(!0),statusMessage:H.string().default("Mention me to chat"),useThreads:H.boolean().default(!0),threadAutoArchive:H.union([H.literal(60),H.literal(1440),H.literal(4320),H.literal(10080)]).default(1440),...yx.shape,captureUrlEmoji:H.string().default("\uD83D\uDD16")});var Pe0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.122",description:"Discord interface for Brains",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",test:"bun test"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","discord.js":"^14.14.1"},devDependencies:{"@brains/core":"workspace:*","@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest"}};var nQA=2000,Pd2=8000,kd2=100;function oQA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class Qz extends iG{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",Pe0,A,uPA);this.fetchText=Q.fetchText??Qo}async onRegister(A){await super.onRegister(A),this.client=new eI.Client({intents:[eI.GatewayIntentBits.Guilds,eI.GatewayIntentBits.GuildMessages,eI.GatewayIntentBits.MessageContent,eI.GatewayIntentBits.DirectMessages],partials:[eI.Partials.Channel]}),this.client.on(eI.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.on(eI.Events.InteractionCreate,(Q)=>{this.handleInteraction(Q)}),this.client.once(eI.Events.ClientReady,()=>{this.logger.info("Discord bot connected",{tag:this.client?.user?.tag})})}createDaemon(){return{start:async()=>{if(!this.client)throw Error("Discord client not initialized");await this.client.login(this.config.botToken)},stop:async()=>{for(let A of this.typingIntervals.values())clearInterval(A);if(this.typingIntervals.clear(),this.client)await this.client.destroy(),this.client=null},healthCheck:async()=>({status:this.client?.user?"healthy":"error",message:this.client?.user?`Connected as ${this.client.user.tag}`:"Not connected",lastCheck:new Date})}}sendMessageToChannel({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!oQA(B))return;let w=uy(Q,nQA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),f=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,f)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!oQA(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=uy(Q,nQA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!oQA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,nQA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let Y=Q||$||!this.config.requireMention||w;if(I&&(!Y||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((X)=>this.logger.error("Passive Discord space capture failed",{error:X,channelId:f}));if(!Y){if(this.config.captureUrls){let X=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(X.length>0){await A.react(this.config.captureUrlEmoji).catch((G)=>this.logger.debug("React failed",{error:G}));for(let G of X)await this.captureUrlViaAgent(G,A.channel.id,A.author.id,"discord",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:G}))}}return}let U=this.stripMention(A.content);if(A.attachments.size>0){let X=this.context.permissions.getUserLevel("discord",A.author.id,D);if(X==="anchor"||X==="trusted")for(let Z of A.attachments.values()){let N=Z.name,L=Z.contentType??void 0,V=Z.size;if(!this.isUploadableTextFile(N,L))continue;if(!this.isFileSizeAllowed(V))continue;try{let M=await this.fetchText(Z.url);U+=`
2399
2399
 
2400
2400
  `+this.formatFileUploadMessage(N,M)}catch(M){this.logger.error("Failed to download attachment",{error:M,filename:N})}}}if(U=U.trim(),!U)return;let J=A.channel.id;await this.routeToAgent(U,J,A,D)}async handleInteraction(A){if(!this.context||!A.isButton())return;let Q=this.parseApprovalButtonCustomId(A.customId);if(!Q)return;let B=`discord-${A.channelId}`;if(!this.pendingConfirmations.get(B)?.has(Q.approvalId)){await A.reply({content:"This approval is no longer pending or has changed.",ephemeral:!0}).catch((f)=>this.logger.debug("Failed to reply to stale approval button",{error:f}));return}await A.deferUpdate().catch((f)=>this.logger.debug("Failed to defer approval button",{error:f})),this.removePendingApproval(B,Q.approvalId);let $=await this.context.agent.confirmPendingAction(B,Q.confirmed,Q.approvalId);await this.sendApprovalResultMessage({channelId:A.channelId,response:$})}async capturePassiveSpaceMessage(A,Q){if(!this.context)return;let B=this.stripMention(A.content).trim();if(!B)return;let w=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:w,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:w,role:"user",content:B,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,B,w){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{f=(await B.startThread({name:H7(A,kd2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(U){this.logger.error("Failed to create thread",{error:U})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),Y=this.getChannelName(B);this.startProcessingInput(f);try{let U=this.client?.channels.cache.get(f);if(oQA(U))this.startTypingIndicator(U);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,f);return}let J=await $.chat(A,I,{userPermissionLevel:D,interfaceType:"discord",channelId:f,channelName:Y,...this.buildUserMessageMetadata(B,Q,Y,{threadId:f!==Q||B.channel.isThread()?f:void 0})}),X=this.getPendingApprovalCards(J.cards);if(X.length>0)this.pendingConfirmations.set(I,new Set(X.map((Z)=>Z.id)));else if(J.pendingConfirmations)this.pendingConfirmations.set(I,new Set(J.pendingConfirmations.map((Z)=>Z.id)));let G=await this.sendMessageWithId({channelId:f,message:this.formatAgentResponseText(J.text,X),approvalCards:X});if(G&&J.toolResults){for(let Z of J.toolResults)if(Z.jobId)this.trackAgentResponseForJob(Z.jobId,G,f)}}catch(U){this.logger.error("Error handling message",{error:U,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${U instanceof Error?U.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}buildApprovalMessagePayload(A,Q){let B=Q.length>1;return{content:H7(A.trim().length>0?`${A}
2401
2401
 
@@ -2466,7 +2466,7 @@ Use the buttons below${B?" for the matching action":", or reply **yes** / **no**
2466
2466
  <p>Once built, this page will be replaced with your actual website.</p>
2467
2467
  </div>
2468
2468
  </body>
2469
- </html>`;var YA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.121",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.0",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};class Bz extends eX{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",YA1,A,BkA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10}),A.interactions.register({id:"site",label:"Public site",description:"Visit the published public site for this brain.",href:this.siteUrl,kind:"human",priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20,visibility:"anchor"}),A.interactions.register({id:"preview",label:"Preview site",description:"Open the private preview build.",href:this.previewUrl,kind:"admin",priority:20,visibility:"anchor"});this.serverManager=new DBA({logger:A.logger,productionDistDir:this.config.productionDistDir,sharedImagesDir:this.config.sharedImagesDir,productionPort:this.config.productionPort,...this.config.enablePreview&&this.config.previewDistDir&&{previewDistDir:this.config.previewDistDir},...this.config.enablePreview&&this.config.previewPort&&{previewPort:this.config.previewPort},getHealthData:()=>A.appInfo(),getWebRoutes:()=>A.webRoutes.getRoutes(),getApiRoutes:()=>A.apiRoutes.getRoutes(),messageBus:A.apiRoutes.getMessageBus()})}getServerManager(){if(!this.serverManager)throw Error("ServerManager not initialized \u2014 onRegister not called");return this.serverManager}requiresDaemonStartup(){return!0}createDaemon(){return{start:async()=>{await this.ensureDistDirectories(),await this.getServerManager().start()},stop:async()=>{await this.serverManager?.stop()},healthCheck:async()=>{let A=this.serverManager?.getStatus(),Q=A?.running??!1,B=this.siteUrl??A?.productionUrl??`http://localhost:${this.config.productionPort}`,w=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,$=[];if(Q){if($.push(`Production: ${B}`),A?.previewUrl)$.push(`Preview: ${w}`)}return{status:Q?"healthy":"error",message:Q?$.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?w:void 0,productionUrl:Q?B:void 0}}}}}async handleProgressEvent(A,Q){}async ensureDistDirectories(){let{mkdir:A,writeFile:Q}=await import("fs/promises");if(this.config.enablePreview&&this.config.previewDistDir&&!UA1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(JA1(this.config.previewDistDir,"index.html"),wkA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!UA1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(JA1(this.config.productionDistDir,"index.html"),wkA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}aA();var hA1="vercel.ai.error",zn2=Symbol.for(hA1),XA1,WA1,bB=class A extends(WA1=Error,XA1=zn2,WA1){constructor({name:Q,message:B,cause:w}){super(B);this[XA1]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,hA1)}static hasMarker(Q,B){let w=Symbol.for(B);return Q!=null&&typeof Q==="object"&&w in Q&&typeof Q[w]==="boolean"&&Q[w]===!0}},mA1="AI_APICallError",uA1=`vercel.ai.error.${mA1}`,qn2=Symbol.for(uA1),HA1,GA1,NZw=class extends(GA1=bB,HA1=qn2,GA1){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:f,cause:I,isRetryable:D=w!=null&&(w===408||w===409||w===429||w>=500),data:Y}){super({name:mA1,message:A,cause:I});this[HA1]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=f,this.isRetryable=D,this.data=Y}static isInstance(A){return bB.hasMarker(A,uA1)}},cA1="AI_EmptyResponseBodyError",lA1=`vercel.ai.error.${cA1}`,Ln2=Symbol.for(lA1),KA1,FA1,zZw=class extends(FA1=bB,KA1=Ln2,FA1){constructor({message:A="Empty response body"}={}){super({name:cA1,message:A});this[KA1]=!0}static isInstance(A){return bB.hasMarker(A,lA1)}};function pA1(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}var iA1="AI_InvalidArgumentError",rA1=`vercel.ai.error.${iA1}`,Vn2=Symbol.for(rA1),ZA1,NA1,dA1=class extends(NA1=bB,ZA1=Vn2,NA1){constructor({message:A,cause:Q,argument:B}){super({name:iA1,message:A,cause:Q});this[ZA1]=!0,this.argument=B}static isInstance(A){return bB.hasMarker(A,rA1)}},nA1="AI_InvalidPromptError",oA1=`vercel.ai.error.${nA1}`,En2=Symbol.for(oA1),zA1,qA1,qZw=class extends(qA1=bB,zA1=En2,qA1){constructor({prompt:A,message:Q,cause:B}){super({name:nA1,message:`Invalid prompt: ${Q}`,cause:B});this[zA1]=!0,this.prompt=A}static isInstance(A){return bB.hasMarker(A,oA1)}},sA1="AI_InvalidResponseDataError",aA1=`vercel.ai.error.${sA1}`,Mn2=Symbol.for(aA1),LA1,VA1,LZw=class extends(VA1=bB,LA1=Mn2,VA1){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:sA1,message:Q});this[LA1]=!0,this.data=A}static isInstance(A){return bB.hasMarker(A,aA1)}},tA1="AI_JSONParseError",eA1=`vercel.ai.error.${tA1}`,Cn2=Symbol.for(eA1),EA1,MA1,$kA=class extends(MA1=bB,EA1=Cn2,MA1){constructor({text:A,cause:Q}){super({name:tA1,message:`JSON parsing failed: Text: ${A}.
2469
+ </html>`;var YA1={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.122",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@brains/plugins":"workspace:*","@hono/bun-compress":"^0.1.0",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/messaging-service":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};class Bz extends eX{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",YA1,A,BkA)}async onRegister(A){if(this.siteUrl=A.siteUrl,this.previewUrl=A.previewUrl,this.siteUrl)A.endpoints.register({label:"Site",url:this.siteUrl,priority:10}),A.interactions.register({id:"site",label:"Public site",description:"Visit the published public site for this brain.",href:this.siteUrl,kind:"human",priority:10});if(this.config.enablePreview&&this.previewUrl)A.endpoints.register({label:"Preview",url:this.previewUrl,priority:20,visibility:"anchor"}),A.interactions.register({id:"preview",label:"Preview site",description:"Open the private preview build.",href:this.previewUrl,kind:"admin",priority:20,visibility:"anchor"});this.serverManager=new DBA({logger:A.logger,productionDistDir:this.config.productionDistDir,sharedImagesDir:this.config.sharedImagesDir,productionPort:this.config.productionPort,...this.config.enablePreview&&this.config.previewDistDir&&{previewDistDir:this.config.previewDistDir},...this.config.enablePreview&&this.config.previewPort&&{previewPort:this.config.previewPort},getHealthData:()=>A.appInfo(),getWebRoutes:()=>A.webRoutes.getRoutes(),getApiRoutes:()=>A.apiRoutes.getRoutes(),messageBus:A.apiRoutes.getMessageBus()})}getServerManager(){if(!this.serverManager)throw Error("ServerManager not initialized \u2014 onRegister not called");return this.serverManager}requiresDaemonStartup(){return!0}createDaemon(){return{start:async()=>{await this.ensureDistDirectories(),await this.getServerManager().start()},stop:async()=>{await this.serverManager?.stop()},healthCheck:async()=>{let A=this.serverManager?.getStatus(),Q=A?.running??!1,B=this.siteUrl??A?.productionUrl??`http://localhost:${this.config.productionPort}`,w=this.previewUrl??A?.previewUrl??`http://localhost:${this.config.previewPort}`,$=[];if(Q){if($.push(`Production: ${B}`),A?.previewUrl)$.push(`Preview: ${w}`)}return{status:Q?"healthy":"error",message:Q?$.join(", "):"Webserver not running",lastCheck:new Date,details:{preview:!!A?.previewUrl,production:Q,previewUrl:A?.previewUrl?w:void 0,productionUrl:Q?B:void 0}}}}}async handleProgressEvent(A,Q){}async ensureDistDirectories(){let{mkdir:A,writeFile:Q}=await import("fs/promises");if(this.config.enablePreview&&this.config.previewDistDir&&!UA1(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(JA1(this.config.previewDistDir,"index.html"),wkA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!UA1(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(JA1(this.config.productionDistDir,"index.html"),wkA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}aA();var hA1="vercel.ai.error",zn2=Symbol.for(hA1),XA1,WA1,bB=class A extends(WA1=Error,XA1=zn2,WA1){constructor({name:Q,message:B,cause:w}){super(B);this[XA1]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,hA1)}static hasMarker(Q,B){let w=Symbol.for(B);return Q!=null&&typeof Q==="object"&&w in Q&&typeof Q[w]==="boolean"&&Q[w]===!0}},mA1="AI_APICallError",uA1=`vercel.ai.error.${mA1}`,qn2=Symbol.for(uA1),HA1,GA1,NZw=class extends(GA1=bB,HA1=qn2,GA1){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:f,cause:I,isRetryable:D=w!=null&&(w===408||w===409||w===429||w>=500),data:Y}){super({name:mA1,message:A,cause:I});this[HA1]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=f,this.isRetryable=D,this.data=Y}static isInstance(A){return bB.hasMarker(A,uA1)}},cA1="AI_EmptyResponseBodyError",lA1=`vercel.ai.error.${cA1}`,Ln2=Symbol.for(lA1),KA1,FA1,zZw=class extends(FA1=bB,KA1=Ln2,FA1){constructor({message:A="Empty response body"}={}){super({name:cA1,message:A});this[KA1]=!0}static isInstance(A){return bB.hasMarker(A,lA1)}};function pA1(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}var iA1="AI_InvalidArgumentError",rA1=`vercel.ai.error.${iA1}`,Vn2=Symbol.for(rA1),ZA1,NA1,dA1=class extends(NA1=bB,ZA1=Vn2,NA1){constructor({message:A,cause:Q,argument:B}){super({name:iA1,message:A,cause:Q});this[ZA1]=!0,this.argument=B}static isInstance(A){return bB.hasMarker(A,rA1)}},nA1="AI_InvalidPromptError",oA1=`vercel.ai.error.${nA1}`,En2=Symbol.for(oA1),zA1,qA1,qZw=class extends(qA1=bB,zA1=En2,qA1){constructor({prompt:A,message:Q,cause:B}){super({name:nA1,message:`Invalid prompt: ${Q}`,cause:B});this[zA1]=!0,this.prompt=A}static isInstance(A){return bB.hasMarker(A,oA1)}},sA1="AI_InvalidResponseDataError",aA1=`vercel.ai.error.${sA1}`,Mn2=Symbol.for(aA1),LA1,VA1,LZw=class extends(VA1=bB,LA1=Mn2,VA1){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:sA1,message:Q});this[LA1]=!0,this.data=A}static isInstance(A){return bB.hasMarker(A,aA1)}},tA1="AI_JSONParseError",eA1=`vercel.ai.error.${tA1}`,Cn2=Symbol.for(eA1),EA1,MA1,$kA=class extends(MA1=bB,EA1=Cn2,MA1){constructor({text:A,cause:Q}){super({name:tA1,message:`JSON parsing failed: Text: ${A}.
2470
2470
  Error message: ${pA1(Q)}`,cause:Q});this[EA1]=!0,this.text=A}static isInstance(A){return bB.hasMarker(A,eA1)}},A01="AI_LoadAPIKeyError",Q01=`vercel.ai.error.${A01}`,On2=Symbol.for(Q01),CA1,OA1,VZw=class extends(OA1=bB,CA1=On2,OA1){constructor({message:A}){super({name:A01,message:A});this[CA1]=!0}static isInstance(A){return bB.hasMarker(A,Q01)}},B01="AI_LoadSettingError",w01=`vercel.ai.error.${B01}`,Rn2=Symbol.for(w01),RA1,bA1,EZw=class extends(bA1=bB,RA1=Rn2,bA1){constructor({message:A}){super({name:B01,message:A});this[RA1]=!0}static isInstance(A){return bB.hasMarker(A,w01)}},$01="AI_NoContentGeneratedError",f01=`vercel.ai.error.${$01}`,bn2=Symbol.for(f01),PA1,kA1,MZw=class extends(kA1=bB,PA1=bn2,kA1){constructor({message:A="No content generated."}={}){super({name:$01,message:A});this[PA1]=!0}static isInstance(A){return bB.hasMarker(A,f01)}},I01="AI_NoSuchModelError",D01=`vercel.ai.error.${I01}`,Pn2=Symbol.for(D01),jA1,_A1,CZw=class extends(_A1=bB,jA1=Pn2,_A1){constructor({errorName:A=I01,modelId:Q,modelType:B,message:w=`No such ${B}: ${Q}`}){super({name:A,message:w});this[jA1]=!0,this.modelId=Q,this.modelType=B}static isInstance(A){return bB.hasMarker(A,D01)}},Y01="AI_TooManyEmbeddingValuesForCallError",U01=`vercel.ai.error.${Y01}`,kn2=Symbol.for(U01),vA1,TA1,OZw=class extends(TA1=bB,vA1=kn2,TA1){constructor(A){super({name:Y01,message:`Too many values for a single embedding call. The ${A.provider} model "${A.modelId}" can only embed up to ${A.maxEmbeddingsPerCall} values per call, but ${A.values.length} values were provided.`});this[vA1]=!0,this.provider=A.provider,this.modelId=A.modelId,this.maxEmbeddingsPerCall=A.maxEmbeddingsPerCall,this.values=A.values}static isInstance(A){return bB.hasMarker(A,U01)}},J01="AI_TypeValidationError",X01=`vercel.ai.error.${J01}`,jn2=Symbol.for(X01),yA1,xA1,AH=class A extends(xA1=bB,yA1=jn2,xA1){constructor({value:Q,cause:B,context:w}){let $="Type validation failed";if(w==null?void 0:w.field)$+=` for ${w.field}`;if((w==null?void 0:w.entityName)||(w==null?void 0:w.entityId)){$+=" (";let f=[];if(w.entityName)f.push(w.entityName);if(w.entityId)f.push(`id: "${w.entityId}"`);$+=f.join(", "),$+=")"}super({name:J01,message:`${$}: Value: ${JSON.stringify(Q)}.
2471
2471
  Error message: ${pA1(B)}`,cause:B});this[yA1]=!0,this.value=Q,this.context=w}static isInstance(Q){return bB.hasMarker(Q,X01)}static wrap({value:Q,cause:B,context:w}){var $,f,I;if(A.isInstance(B)&&B.value===Q&&(($=B.context)==null?void 0:$.field)===(w==null?void 0:w.field)&&((f=B.context)==null?void 0:f.entityName)===(w==null?void 0:w.entityName)&&((I=B.context)==null?void 0:I.entityId)===(w==null?void 0:w.entityId))return B;return new A({value:Q,cause:B,context:w})}},W01="AI_UnsupportedFunctionalityError",H01=`vercel.ai.error.${W01}`,_n2=Symbol.for(H01),SA1,gA1,RZw=class extends(gA1=bB,SA1=_n2,gA1){constructor({functionality:A,message:Q=`'${A}' functionality not supported.`}){super({name:W01,message:Q});this[SA1]=!0,this.functionality=A}static isInstance(A){return bB.hasMarker(A,H01)}};G1();fW();fW();fW();var z01="AI_DownloadError",q01=`vercel.ai.error.${z01}`,vn2=Symbol.for(q01),G01,K01,SY=class extends(K01=bB,G01=vn2,K01){constructor({url:A,statusCode:Q,statusText:B,cause:w,message:$=w==null?`Failed to download ${A}: ${Q} ${B}`:`Failed to download ${A}: ${w}`}){super({name:z01,message:$,cause:w});this[G01]=!0,this.url=A,this.statusCode=Q,this.statusText=B}static isInstance(A){return bB.hasMarker(A,q01)}},JkA=2147483648;async function L01({response:A,url:Q,maxBytes:B=JkA}){let w=A.headers.get("content-length");if(w!=null){let J=parseInt(w,10);if(!isNaN(J)&&J>B)throw new SY({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes (Content-Length: ${J}).`})}let $=A.body;if($==null)return new Uint8Array(0);let f=$.getReader(),I=[],D=0;try{while(!0){let{done:J,value:X}=await f.read();if(J)break;if(D+=X.length,D>B)throw new SY({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes.`});I.push(X)}}finally{try{await f.cancel()}finally{f.releaseLock()}}let Y=new Uint8Array(D),U=0;for(let J of I)Y.set(J,U),U+=J.length;return Y}function XkA(A){let Q;try{Q=new URL(A)}catch(w){throw new SY({url:A,message:`Invalid URL: ${A}`})}if(Q.protocol==="data:")return;if(Q.protocol!=="http:"&&Q.protocol!=="https:")throw new SY({url:A,message:`URL scheme must be http, https, or data, got ${Q.protocol}`});let B=Q.hostname;if(!B)throw new SY({url:A,message:"URL must have a hostname"});if(B==="localhost"||B.endsWith(".local")||B.endsWith(".localhost"))throw new SY({url:A,message:`URL with hostname ${B} is not allowed`});if(B.startsWith("[")&&B.endsWith("]")){let w=B.slice(1,-1);if(Tn2(w))throw new SY({url:A,message:`URL with IPv6 address ${B} is not allowed`});return}if(V01(B)){if(DkA(B))throw new SY({url:A,message:`URL with IP address ${B} is not allowed`});return}}function V01(A){let Q=A.split(".");if(Q.length!==4)return!1;return Q.every((B)=>{let w=Number(B);return Number.isInteger(w)&&w>=0&&w<=255&&String(w)===B})}function DkA(A){let Q=A.split(".").map(Number),[B,w]=Q;if(B===0)return!0;if(B===10)return!0;if(B===127)return!0;if(B===169&&w===254)return!0;if(B===172&&w>=16&&w<=31)return!0;if(B===192&&w===168)return!0;return!1}function Tn2(A){let Q=A.toLowerCase();if(Q==="::1")return!0;if(Q==="::")return!0;if(Q.startsWith("::ffff:")){let B=Q.slice(7);if(V01(B))return DkA(B);let w=B.split(":");if(w.length===2){let $=parseInt(w[0],16),f=parseInt(w[1],16);if(!isNaN($)&&!isNaN(f)){let I=$>>8&255,D=$&255,Y=f>>8&255,U=f&255;return DkA(`${I}.${D}.${Y}.${U}`)}}}if(Q.startsWith("fc")||Q.startsWith("fd"))return!0;if(Q.startsWith("fe80"))return!0;return!1}var fF=({prefix:A,size:Q=16,alphabet:B="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",separator:w="-"}={})=>{let $=()=>{let f=B.length,I=Array(Q);for(let D=0;D<Q;D++)I[D]=B[Math.random()*f|0];return I.join("")};if(A==null)return $;if(B.includes(w))throw new dA1({argument:"separator",message:`The separator "${w}" must not be part of the alphabet "${B}".`});return()=>`${A}${w}${$()}`},E01=fF();function WkA(A){if(A==null)return"unknown error";if(typeof A==="string")return A;if(A instanceof Error)return A.message;return JSON.stringify(A)}function M01(A=globalThis){var Q,B,w;if(A.window)return"runtime/browser";if((Q=A.navigator)==null?void 0:Q.userAgent)return`runtime/${A.navigator.userAgent.toLowerCase()}`;if((w=(B=A.process)==null?void 0:B.versions)==null?void 0:w.node)return`runtime/node.js/${A.process.version.substring(0)}`;if(A.EdgeRuntime)return"runtime/vercel-edge";return"runtime/unknown"}function yn2(A){if(A==null)return{};let Q={};if(A instanceof Headers)A.forEach((B,w)=>{Q[w.toLowerCase()]=B});else{if(!Array.isArray(A))A=Object.entries(A);for(let[B,w]of A)if(w!=null)Q[B.toLowerCase()]=w}return Q}function YBA(A,...Q){let B=new Headers(yn2(A)),w=B.get("user-agent")||"";return B.set("user-agent",[w,...Q].filter(Boolean).join(" ")),Object.fromEntries(B.entries())}var xn2=/"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/,Sn2=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;function F01(A){let Q=JSON.parse(A);if(Q===null||typeof Q!=="object")return Q;if(xn2.test(A)===!1&&Sn2.test(A)===!1)return Q;return gn2(Q)}function gn2(A){let Q=[A];while(Q.length){let B=Q;Q=[];for(let w of B){if(Object.prototype.hasOwnProperty.call(w,"__proto__"))throw SyntaxError("Object contains forbidden prototype property");if(Object.prototype.hasOwnProperty.call(w,"constructor")&&w.constructor!==null&&typeof w.constructor==="object"&&Object.prototype.hasOwnProperty.call(w.constructor,"prototype"))throw SyntaxError("Object contains forbidden prototype property");for(let $ in w){let f=w[$];if(f&&typeof f==="object")Q.push(f)}}}return A}function hn2(A){let{stackTraceLimit:Q}=Error;try{Error.stackTraceLimit=0}catch(B){return F01(A)}try{return F01(A)}finally{Error.stackTraceLimit=Q}}function HkA(A){if(A.type==="object"||Array.isArray(A.type)&&A.type.includes("object")){A.additionalProperties=!1;let{properties:B}=A;if(B!=null)for(let w of Object.keys(B))B[w]=BM(B[w])}if(A.items!=null)A.items=Array.isArray(A.items)?A.items.map(BM):BM(A.items);if(A.anyOf!=null)A.anyOf=A.anyOf.map(BM);if(A.allOf!=null)A.allOf=A.allOf.map(BM);if(A.oneOf!=null)A.oneOf=A.oneOf.map(BM);let{definitions:Q}=A;if(Q!=null)for(let B of Object.keys(Q))Q[B]=BM(Q[B]);return A}function BM(A){if(typeof A==="boolean")return A;return HkA(A)}var mn2=Symbol("Let zodToJsonSchema decide on which parser to use"),Z01={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",strictUnions:!1,definitions:{},errorMessages:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref"},un2=(A)=>typeof A==="string"?{...Z01,name:A}:{...Z01,...A};function AD(){return{}}function cn2(A,Q){var B,w,$;let f={type:"array"};if(((B=A.type)==null?void 0:B._def)&&(($=(w=A.type)==null?void 0:w._def)==null?void 0:$.typeName)!==W0.ZodAny)f.items=kw(A.type._def,{...Q,currentPath:[...Q.currentPath,"items"]});if(A.minLength)f.minItems=A.minLength.value;if(A.maxLength)f.maxItems=A.maxLength.value;if(A.exactLength)f.minItems=A.exactLength.value,f.maxItems=A.exactLength.value;return f}function ln2(A){let Q={type:"integer",format:"int64"};if(!A.checks)return Q;for(let B of A.checks)switch(B.kind){case"min":if(B.inclusive)Q.minimum=B.value;else Q.exclusiveMinimum=B.value;break;case"max":if(B.inclusive)Q.maximum=B.value;else Q.exclusiveMaximum=B.value;break;case"multipleOf":Q.multipleOf=B.value;break}return Q}function pn2(){return{type:"boolean"}}function C01(A,Q){return kw(A.type._def,Q)}var in2=(A,Q)=>{return kw(A.innerType._def,Q)};function O01(A,Q,B){let w=B!=null?B:Q.dateStrategy;if(Array.isArray(w))return{anyOf:w.map(($,f)=>O01(A,Q,$))};switch(w){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return rn2(A)}}var rn2=(A)=>{let Q={type:"integer",format:"unix-time"};for(let B of A.checks)switch(B.kind){case"min":Q.minimum=B.value;break;case"max":Q.maximum=B.value;break}return Q};function dn2(A,Q){return{...kw(A.innerType._def,Q),default:A.defaultValue()}}function nn2(A,Q){return Q.effectStrategy==="input"?kw(A.schema._def,Q):AD()}function on2(A){return{type:"string",enum:Array.from(A.values)}}var sn2=(A)=>{if("type"in A&&A.type==="string")return!1;return"allOf"in A};function an2(A,Q){let B=[kw(A.left._def,{...Q,currentPath:[...Q.currentPath,"allOf","0"]}),kw(A.right._def,{...Q,currentPath:[...Q.currentPath,"allOf","1"]})].filter(($)=>!!$),w=[];return B.forEach(($)=>{if(sn2($))w.push(...$.allOf);else{let f=$;if("additionalProperties"in $&&$.additionalProperties===!1){let{additionalProperties:I,...D}=$;f=D}w.push(f)}}),w.length?{allOf:w}:void 0}function tn2(A){let Q=typeof A.value;if(Q!=="bigint"&&Q!=="number"&&Q!=="boolean"&&Q!=="string")return{type:Array.isArray(A.value)?"array":"object"};return{type:Q==="bigint"?"integer":Q,const:A.value}}var fkA=void 0,SJ={cuid:/^[cC][^\s-]{8,}$/,cuid2:/^[0-9a-z]+$/,ulid:/^[0-9A-HJKMNP-TV-Z]{26}$/,email:/^(?!\.)(?!.*\.\.)([a-zA-Z0-9_'+\-\.]*)[a-zA-Z0-9_+-]@([a-zA-Z0-9][a-zA-Z0-9\-]*\.)+[a-zA-Z]{2,}$/,emoji:()=>{if(fkA===void 0)fkA=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u");return fkA},uuid:/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,ipv4:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ipv4Cidr:/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,ipv6:/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,ipv6Cidr:/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,base64:/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,base64url:/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,nanoid:/^[a-zA-Z0-9_-]{21}$/,jwt:/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/};function R01(A,Q){let B={type:"string"};if(A.checks)for(let w of A.checks)switch(w.kind){case"min":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value;break;case"max":B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"email":switch(Q.emailStrategy){case"format:email":gJ(B,"email",w.message,Q);break;case"format:idn-email":gJ(B,"idn-email",w.message,Q);break;case"pattern:zod":x4(B,SJ.email,w.message,Q);break}break;case"url":gJ(B,"uri",w.message,Q);break;case"uuid":gJ(B,"uuid",w.message,Q);break;case"regex":x4(B,w.regex,w.message,Q);break;case"cuid":x4(B,SJ.cuid,w.message,Q);break;case"cuid2":x4(B,SJ.cuid2,w.message,Q);break;case"startsWith":x4(B,RegExp(`^${IkA(w.value,Q)}`),w.message,Q);break;case"endsWith":x4(B,RegExp(`${IkA(w.value,Q)}$`),w.message,Q);break;case"datetime":gJ(B,"date-time",w.message,Q);break;case"date":gJ(B,"date",w.message,Q);break;case"time":gJ(B,"time",w.message,Q);break;case"duration":gJ(B,"duration",w.message,Q);break;case"length":B.minLength=typeof B.minLength==="number"?Math.max(B.minLength,w.value):w.value,B.maxLength=typeof B.maxLength==="number"?Math.min(B.maxLength,w.value):w.value;break;case"includes":{x4(B,RegExp(IkA(w.value,Q)),w.message,Q);break}case"ip":{if(w.version!=="v6")gJ(B,"ipv4",w.message,Q);if(w.version!=="v4")gJ(B,"ipv6",w.message,Q);break}case"base64url":x4(B,SJ.base64url,w.message,Q);break;case"jwt":x4(B,SJ.jwt,w.message,Q);break;case"cidr":{if(w.version!=="v6")x4(B,SJ.ipv4Cidr,w.message,Q);if(w.version!=="v4")x4(B,SJ.ipv6Cidr,w.message,Q);break}case"emoji":x4(B,SJ.emoji(),w.message,Q);break;case"ulid":{x4(B,SJ.ulid,w.message,Q);break}case"base64":{switch(Q.base64Strategy){case"format:binary":{gJ(B,"binary",w.message,Q);break}case"contentEncoding:base64":{B.contentEncoding="base64";break}case"pattern:zod":{x4(B,SJ.base64,w.message,Q);break}}break}case"nanoid":x4(B,SJ.nanoid,w.message,Q);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return B}function IkA(A,Q){return Q.patternStrategy==="escape"?Ao2(A):A}var en2=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function Ao2(A){let Q="";for(let B=0;B<A.length;B++){if(!en2.has(A[B]))Q+="\\";Q+=A[B]}return Q}function gJ(A,Q,B,w){var $;if(A.format||(($=A.anyOf)==null?void 0:$.some((f)=>f.format))){if(!A.anyOf)A.anyOf=[];if(A.format)A.anyOf.push({format:A.format}),delete A.format;A.anyOf.push({format:Q,...B&&w.errorMessages&&{errorMessage:{format:B}}})}else A.format=Q}function x4(A,Q,B,w){var $;if(A.pattern||(($=A.allOf)==null?void 0:$.some((f)=>f.pattern))){if(!A.allOf)A.allOf=[];if(A.pattern)A.allOf.push({pattern:A.pattern}),delete A.pattern;A.allOf.push({pattern:N01(Q,w),...B&&w.errorMessages&&{errorMessage:{pattern:B}}})}else A.pattern=N01(Q,w)}function N01(A,Q){var B;if(!Q.applyRegexFlags||!A.flags)return A.source;let w={i:A.flags.includes("i"),m:A.flags.includes("m"),s:A.flags.includes("s")},$=w.i?A.source.toLowerCase():A.source,f="",I=!1,D=!1,Y=!1;for(let U=0;U<$.length;U++){if(I){f+=$[U],I=!1;continue}if(w.i){if(D){if($[U].match(/[a-z]/)){if(Y)f+=$[U],f+=`${$[U-2]}-${$[U]}`.toUpperCase(),Y=!1;else if($[U+1]==="-"&&((B=$[U+2])==null?void 0:B.match(/[a-z]/)))f+=$[U],Y=!0;else f+=`${$[U]}${$[U].toUpperCase()}`;continue}}else if($[U].match(/[a-z]/)){f+=`[${$[U]}${$[U].toUpperCase()}]`;continue}}if(w.m){if($[U]==="^"){f+=`(^|(?<=[\r
2472
2472
  ]))`;continue}else if($[U]==="$"){f+=`($|(?=[\r
@@ -2476,7 +2476,7 @@ Error message: ${pA1(B)}`,cause:B});this[yA1]=!0,this.value=Q,this.context=w}sta
2476
2476
 
2477
2477
  `)},flush(A){A.enqueue(`data: [DONE]
2478
2478
 
2479
- `)}})}},Za2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function c01({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new Fa2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Ka2(B,Za2)})}var rc=K.record(K.string(),wM.optional()),FNw=UBA(()=>ic(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Na2(A){return A.type.startsWith("data-")}function KkA(A){return A.type.startsWith("tool-")}function za2(A){return A.type==="dynamic-tool"}function P01(A){return KkA(A)||za2(A)}function k01(A){return A.type.split("-").slice(1).join("-")}function qa2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function La2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,Y){await w(async({state:U,write:J})=>{var X,G,Z,N;function L(E){let y=U.message.parts.filter(P01).find((T)=>T.toolCallId===E);if(y==null)throw new oj({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return y}function V(E){var S;let y=U.message.parts.find((x)=>KkA(x)&&x.toolCallId===E.toolCallId),T=E,_=y;if(y!=null){if(y.state=E.state,_.input=T.input,_.output=T.output,_.errorText=T.errorText,_.rawInput=T.rawInput,_.preliminary=T.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=T.providerExecuted)!=null?S:y.providerExecuted;let x=T.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=y;g.resultProviderMetadata=x}else y.callProviderMetadata=x}else U.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:T.input,output:T.output,rawInput:T.rawInput,errorText:T.errorText,providerExecuted:T.providerExecuted,preliminary:T.preliminary,...T.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:T.providerMetadata}:{},...T.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:T.providerMetadata}:{}})}function M(E){var S,y;let T=U.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=T;if(T!=null){if(T.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(y=_.providerExecuted)!=null?y:T.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=T;n.resultProviderMetadata=g}else T.callProviderMetadata=g}else U.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=U.message.metadata!=null?u01(U.message.metadata,E):E;if(Q!=null)await WBA({value:S,schema:Q,context:{field:"message.metadata",entityId:U.message.id}});U.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};U.activeTextParts[D.id]=E,U.message.parts.push(E),J();break}case"text-delta":{let E=U.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=U.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete U.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};U.activeReasoningParts[D.id]=E,U.message.parts.push(E),J();break}case"reasoning-delta":{let E=U.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=U.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete U.activeReasoningParts[D.id],J();break}case"file":{U.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{U.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{U.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=U.message.parts.filter(KkA);if(U.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=U.partialToolCalls[D.toolCallId];if(E==null)throw new oj({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await dc(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=U.message.parts.filter(P01).find((y)=>y.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=L(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=L(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:k01(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:k01(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{U.message.parts.push({type:"step-start"});break}case"finish-step":{U.activeTextParts={},U.activeReasoningParts={};break}case"start":{if(D.messageId!=null)U.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)U.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Na2(D)){if((B==null?void 0:B[D.type])!=null){let y=U.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),T=y>=0?y:U.message.parts.length;await WBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${T}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?U.message.parts.find((y)=>E.type===y.type&&E.id===y.id):void 0;if(S!=null)S.data=E.data;else U.message.parts.push(E);I==null||I(E),J()}}Y.enqueue(D)})}}))}function Va2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,Y=f.pipeThrough(new TransformStream({transform(N,L){if(N.type==="start"){let V=N;if(V.messageId==null&&A!=null)V.messageId=A}if(N.type==="abort")D=!0;L.enqueue(N)}}));if(w==null&&B==null)return Y;let U=qa2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:U,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=U.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:U.message,messages:[...N?Q.slice(0,-1):Q,U.message],finishReason:U.finishReason})},Z=async()=>{if(!B)return;let N=U.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(U.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(U.message)]})}catch(L){$(L)}};return La2({stream:Y,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,L){if(N.type==="finish-step")await Z();L.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var ZNw=fF({prefix:"aitxt",size:24});function l01({execute:A,onError:Q=WkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=E01}){let I,D=[],Y=new ReadableStream({start(X){I=X}});function U(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){U(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:L}=await Z.read();if(N)break;U(L)}})().catch((Z)=>{U({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{U({type:"error",errorText:Q(G)})}))}catch(X){U({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),Va2({stream:Y,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var _f=K.record(K.string(),wM.optional()),LNw=UBA(()=>ic(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var ENw=fF({prefix:"aiobj",size:24});function p01(A){return({url:Q,abortSignal:B})=>as2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var CNw=fF({prefix:"aiobj",size:24});var ONw=p01();var Ea2="AI_NoSuchProviderError",Ma2=`vercel.ai.error.${Ea2}`,Ca2=Symbol.for(Ma2),Oa2;Oa2=Ca2;var RNw=p01();var i01={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.121",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function r01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=ba2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=ka2($.metadata,w);return n01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function d01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Pa2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=ja2($.metadata,w,f.mimeType);return n01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function n01(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${_a2(A.filename)}"`});return new Response(A.data,{headers:Q})}function o01(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function ba2(A){let Q=o01(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Pa2(A){return o01(A,/^image\/[a-z0-9.+-]+$/i)}function ka2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function ja2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function _a2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var nc="upload",s01=TR;var va2={namespace:"upload",refKind:nc,routePath:"/api/chat/uploads"};function HBA(){return va2}aA();var t01="upload.txt";var e01=5000000,Ta2=[".md",".txt",".markdown"],ya2=["text/plain","text/markdown","text/x-markdown"],FkA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),xa2=new Set(FkA.values());function KBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function A11(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function Q11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=A11(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of FkA)if(f.endsWith(I))return D;return"application/octet-stream"}function B11(A,Q){if(Q&&ya2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return Ta2.some((B)=>A.toLowerCase().endsWith(B))}function Sa2(A){return A<=1e5}function ga2(A){return A<=5000000}function ha2(A,Q){let B=Q11(A,Q);if(xa2.has(B))return!0;return FkA.has(ca2(A))}function ma2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function ua2(A){let Q=KBA(A.filename),B=A11(Q,A.mediaType);if(!B11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!Sa2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ma2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function FBA(A){let Q=KBA(A.filename),B=Q11(Q,A.mediaType);if(B11(Q,B)){let w=ua2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!ha2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!ga2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!la2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function ca2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function la2(A,Q){switch(Q){case"image/png":return a01(A,[137,80,78,71]);case"image/jpeg":return a01(A,[255,216,255]);case"image/gif":return GBA(A,"GIF87a")||GBA(A,"GIF89a");case"image/webp":return GBA(A,"RIFF")&&w11(A,"WEBP",8);case"application/pdf":return GBA(A,"%PDF-");default:return!1}}function a01(A,Q){return Q.every((B,w)=>A[w]===B)}function GBA(A,Q){return w11(A,Q,0)}function w11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var pa2="file",ia2=16384;async function $11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>e01+ia2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(pa2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=FBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),Y=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(Y),{status:201})}async function f11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await Y11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=U11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",Y=new Uint8Array(f).buffer;return new Response(Y,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${na2($.filename)}"`}})}function I11(A){let Q=KBA(A.filename??t01),B=da2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=FBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return J11(w,B.buffer)}async function D11(A,Q){let B=await Y11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=U11(w,$);if(f instanceof Response)return f;return J11(f,$,{kind:nc,id:A})}async function Y11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof AW)return ra2(B);throw B}}function U11(A,Q){let B=FBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function J11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function ra2(A){switch(A.code){case"invalid_ref":return new Response("Invalid upload ref",{status:400});case"invalid_metadata":return new Response("Invalid upload metadata",{status:500});case"not_found":return new Response("Upload not found",{status:404})}}function da2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function na2(A){return A.replace(/["\\\r\n]/g,"_")}var oa2=H.object({type:H.literal("text"),text:H.string()}),sa2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),aa2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),ta2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),X11=H.object({id:H.string().optional(),messages:H.array(ta2).min(1),trigger:H.string().optional()}),ea2=H.object({kind:H.literal(nc),id:H.string().regex(s01)}),At2=H.object({type:H.literal("data-upload"),data:H.object({ref:ea2})});async function W11(A,Q){let B=Qt2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=oa2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let Y=sa2.safeParse(I);if(Y.success){let J=I11(Y.data);if(J instanceof Response)return J;$.push(J);continue}let U=At2.safeParse(I);if(U.success){let J=await D11(U.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(Bt2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
2479
+ `)}})}},Za2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function c01({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let f=w.pipeThrough(new Fa2);if($){let[I,D]=f.tee();f=I,$({stream:D})}return new Response(f.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Ka2(B,Za2)})}var rc=K.record(K.string(),wM.optional()),FNw=UBA(()=>ic(K.union([K.strictObject({type:K.literal("text-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("text-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("error"),errorText:K.string()}),K.strictObject({type:K.literal("tool-input-start"),toolCallId:K.string(),toolName:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-delta"),toolCallId:K.string(),inputTextDelta:K.string()}),K.strictObject({type:K.literal("tool-input-available"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-input-error"),toolCallId:K.string(),toolName:K.string(),input:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),errorText:K.string(),title:K.string().optional()}),K.strictObject({type:K.literal("tool-approval-request"),approvalId:K.string(),toolCallId:K.string()}),K.strictObject({type:K.literal("tool-output-available"),toolCallId:K.string(),output:K.unknown(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional(),preliminary:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-error"),toolCallId:K.string(),errorText:K.string(),providerExecuted:K.boolean().optional(),providerMetadata:N2.optional(),toolMetadata:rc.optional(),dynamic:K.boolean().optional()}),K.strictObject({type:K.literal("tool-output-denied"),toolCallId:K.string()}),K.strictObject({type:K.literal("reasoning-start"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-delta"),id:K.string(),delta:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("reasoning-end"),id:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.strictObject({type:K.literal("file"),url:K.string(),mediaType:K.string(),providerMetadata:N2.optional()}),K.strictObject({type:K.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:K.string().optional(),data:K.unknown(),transient:K.boolean().optional()}),K.strictObject({type:K.literal("start-step")}),K.strictObject({type:K.literal("finish-step")}),K.strictObject({type:K.literal("start"),messageId:K.string().optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("finish"),finishReason:K.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:K.unknown().optional()}),K.strictObject({type:K.literal("abort"),reason:K.string().optional()}),K.strictObject({type:K.literal("message-metadata"),messageMetadata:K.unknown()})])));function Na2(A){return A.type.startsWith("data-")}function KkA(A){return A.type.startsWith("tool-")}function za2(A){return A.type==="dynamic-tool"}function P01(A){return KkA(A)||za2(A)}function k01(A){return A.type.split("-").slice(1).join("-")}function qa2({lastMessage:A,messageId:Q}){return{message:(A==null?void 0:A.role)==="assistant"?A:{id:Q,metadata:void 0,role:"assistant",parts:[]},activeTextParts:{},activeReasoningParts:{},partialToolCalls:{}}}function La2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:f,onData:I}){return A.pipeThrough(new TransformStream({async transform(D,Y){await w(async({state:U,write:J})=>{var X,G,Z,N;function L(E){let y=U.message.parts.filter(P01).find((T)=>T.toolCallId===E);if(y==null)throw new oj({chunkType:"tool-invocation",chunkId:E,message:`No tool invocation found for tool call ID "${E}".`});return y}function V(E){var S;let y=U.message.parts.find((x)=>KkA(x)&&x.toolCallId===E.toolCallId),T=E,_=y;if(y!=null){if(y.state=E.state,_.input=T.input,_.output=T.output,_.errorText=T.errorText,_.rawInput=T.rawInput,_.preliminary=T.preliminary,E.title!==void 0)_.title=E.title;if(E.toolMetadata!==void 0)_.toolMetadata=E.toolMetadata;_.providerExecuted=(S=T.providerExecuted)!=null?S:y.providerExecuted;let x=T.providerMetadata;if(x!=null)if(E.state==="output-available"||E.state==="output-error"){let g=y;g.resultProviderMetadata=x}else y.callProviderMetadata=x}else U.message.parts.push({type:`tool-${E.toolName}`,toolCallId:E.toolCallId,state:E.state,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},input:T.input,output:T.output,rawInput:T.rawInput,errorText:T.errorText,providerExecuted:T.providerExecuted,preliminary:T.preliminary,...T.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:T.providerMetadata}:{},...T.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:T.providerMetadata}:{}})}function M(E){var S,y;let T=U.message.parts.find((g)=>g.type==="dynamic-tool"&&g.toolCallId===E.toolCallId),_=E,x=T;if(T!=null){if(T.state=E.state,x.toolName=E.toolName,x.input=_.input,x.output=_.output,x.errorText=_.errorText,x.rawInput=(S=_.rawInput)!=null?S:x.rawInput,x.preliminary=_.preliminary,E.title!==void 0)x.title=E.title;if(E.toolMetadata!==void 0)x.toolMetadata=E.toolMetadata;x.providerExecuted=(y=_.providerExecuted)!=null?y:T.providerExecuted;let g=_.providerMetadata;if(g!=null)if(E.state==="output-available"||E.state==="output-error"){let n=T;n.resultProviderMetadata=g}else T.callProviderMetadata=g}else U.message.parts.push({type:"dynamic-tool",toolName:E.toolName,toolCallId:E.toolCallId,state:E.state,input:_.input,output:_.output,errorText:_.errorText,preliminary:_.preliminary,providerExecuted:_.providerExecuted,title:E.title,...E.toolMetadata!==void 0?{toolMetadata:E.toolMetadata}:{},..._.providerMetadata!=null&&(E.state==="output-available"||E.state==="output-error")?{resultProviderMetadata:_.providerMetadata}:{},..._.providerMetadata!=null&&!(E.state==="output-available"||E.state==="output-error")?{callProviderMetadata:_.providerMetadata}:{}})}async function O(E){if(E!=null){let S=U.message.metadata!=null?u01(U.message.metadata,E):E;if(Q!=null)await WBA({value:S,schema:Q,context:{field:"message.metadata",entityId:U.message.id}});U.message.metadata=S}}switch(D.type){case"text-start":{let E={type:"text",text:"",providerMetadata:D.providerMetadata,state:"streaming"};U.activeTextParts[D.id]=E,U.message.parts.push(E),J();break}case"text-delta":{let E=U.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-delta",chunkId:D.id,message:`Received text-delta for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(X=D.providerMetadata)!=null?X:E.providerMetadata,J();break}case"text-end":{let E=U.activeTextParts[D.id];if(E==null)throw new oj({chunkType:"text-end",chunkId:D.id,message:`Received text-end for missing text part with ID "${D.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});E.state="done",E.providerMetadata=(G=D.providerMetadata)!=null?G:E.providerMetadata,delete U.activeTextParts[D.id],J();break}case"reasoning-start":{let E={type:"reasoning",text:"",providerMetadata:D.providerMetadata,state:"streaming"};U.activeReasoningParts[D.id]=E,U.message.parts.push(E),J();break}case"reasoning-delta":{let E=U.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-delta",chunkId:D.id,message:`Received reasoning-delta for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});E.text+=D.delta,E.providerMetadata=(Z=D.providerMetadata)!=null?Z:E.providerMetadata,J();break}case"reasoning-end":{let E=U.activeReasoningParts[D.id];if(E==null)throw new oj({chunkType:"reasoning-end",chunkId:D.id,message:`Received reasoning-end for missing reasoning part with ID "${D.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});E.providerMetadata=(N=D.providerMetadata)!=null?N:E.providerMetadata,E.state="done",delete U.activeReasoningParts[D.id],J();break}case"file":{U.message.parts.push({type:"file",mediaType:D.mediaType,url:D.url,...D.providerMetadata!=null?{providerMetadata:D.providerMetadata}:{}}),J();break}case"source-url":{U.message.parts.push({type:"source-url",sourceId:D.sourceId,url:D.url,title:D.title,providerMetadata:D.providerMetadata}),J();break}case"source-document":{U.message.parts.push({type:"source-document",sourceId:D.sourceId,mediaType:D.mediaType,title:D.title,filename:D.filename,providerMetadata:D.providerMetadata}),J();break}case"tool-input-start":{let E=U.message.parts.filter(KkA);if(U.partialToolCalls[D.toolCallId]={text:"",toolName:D.toolName,index:E.length,dynamic:D.dynamic,title:D.title,toolMetadata:D.toolMetadata},D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-streaming",input:void 0,providerExecuted:D.providerExecuted,title:D.title,toolMetadata:D.toolMetadata,providerMetadata:D.providerMetadata});J();break}case"tool-input-delta":{let E=U.partialToolCalls[D.toolCallId];if(E==null)throw new oj({chunkType:"tool-input-delta",chunkId:D.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${D.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});E.text+=D.inputTextDelta;let{value:S}=await dc(E.text);if(E.dynamic)M({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:E.toolName,state:"input-streaming",input:S,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-input-available":{if(D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"input-available",input:D.input,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:D.title,toolMetadata:D.toolMetadata});if(J(),f&&!D.providerExecuted)await f({toolCall:D});break}case"tool-input-error":{let E=U.message.parts.filter(P01).find((y)=>y.toolCallId===D.toolCallId);if(E!=null?E.type==="dynamic-tool":!!D.dynamic)M({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});else V({toolCallId:D.toolCallId,toolName:D.toolName,state:"output-error",input:void 0,rawInput:D.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,toolMetadata:D.toolMetadata});J();break}case"tool-approval-request":{let E=L(D.toolCallId);E.state="approval-requested",E.approval={id:D.approvalId},J();break}case"tool-output-denied":{let E=L(D.toolCallId);E.state="output-denied",J();break}case"tool-output-available":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-available",input:E.input,output:D.output,preliminary:D.preliminary,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:k01(E),state:"output-available",input:E.input,output:D.output,providerExecuted:D.providerExecuted,preliminary:D.preliminary,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"tool-output-error":{let E=L(D.toolCallId);if(E.type==="dynamic-tool")M({toolCallId:D.toolCallId,toolName:E.toolName,state:"output-error",input:E.input,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});else V({toolCallId:D.toolCallId,toolName:k01(E),state:"output-error",input:E.input,rawInput:E.rawInput,errorText:D.errorText,providerExecuted:D.providerExecuted,providerMetadata:D.providerMetadata,title:E.title,toolMetadata:E.toolMetadata});J();break}case"start-step":{U.message.parts.push({type:"step-start"});break}case"finish-step":{U.activeTextParts={},U.activeReasoningParts={};break}case"start":{if(D.messageId!=null)U.message.id=D.messageId;if(await O(D.messageMetadata),D.messageId!=null||D.messageMetadata!=null)J();break}case"finish":{if(D.finishReason!=null)U.finishReason=D.finishReason;if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"message-metadata":{if(await O(D.messageMetadata),D.messageMetadata!=null)J();break}case"error":{$==null||$(Error(D.errorText));break}default:if(Na2(D)){if((B==null?void 0:B[D.type])!=null){let y=U.message.parts.findIndex((_)=>("id"in _)&&("data"in _)&&_.id===D.id&&_.type===D.type),T=y>=0?y:U.message.parts.length;await WBA({value:D.data,schema:B[D.type],context:{field:`message.parts[${T}].data`,entityName:D.type,entityId:D.id}})}let E=D;if(E.transient){I==null||I(E);break}let S=E.id!=null?U.message.parts.find((y)=>E.type===y.type&&E.id===y.id):void 0;if(S!=null)S.data=E.data;else U.message.parts.push(E);I==null||I(E),J()}}Y.enqueue(D)})}}))}function Va2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:f}){let I=Q==null?void 0:Q[Q.length-1];if((I==null?void 0:I.role)!=="assistant")I=void 0;else A=I.id;let D=!1,Y=f.pipeThrough(new TransformStream({transform(N,L){if(N.type==="start"){let V=N;if(V.messageId==null&&A!=null)V.messageId=A}if(N.type==="abort")D=!0;L.enqueue(N)}}));if(w==null&&B==null)return Y;let U=qa2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),J=async(N)=>{await N({state:U,write:()=>{}})},X=!1,G=async()=>{if(X||!w)return;X=!0;let N=U.message.id===(I==null?void 0:I.id);await w({isAborted:D,isContinuation:N,responseMessage:U.message,messages:[...N?Q.slice(0,-1):Q,U.message],finishReason:U.finishReason})},Z=async()=>{if(!B)return;let N=U.message.id===(I==null?void 0:I.id);try{await B({isContinuation:N,responseMessage:structuredClone(U.message),messages:[...N?Q.slice(0,-1):Q,structuredClone(U.message)]})}catch(L){$(L)}};return La2({stream:Y,runUpdateMessageJob:J,onError:$}).pipeThrough(new TransformStream({async transform(N,L){if(N.type==="finish-step")await Z();L.enqueue(N)},async cancel(){await G()},async flush(){await G()}}))}var ZNw=fF({prefix:"aitxt",size:24});function l01({execute:A,onError:Q=WkA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:f=E01}){let I,D=[],Y=new ReadableStream({start(X){I=X}});function U(X){try{I.enqueue(X)}catch(G){}}try{let X=A({writer:{write(G){U(G)},merge(G){D.push((async()=>{let Z=G.getReader();while(!0){let{done:N,value:L}=await Z.read();if(N)break;U(L)}})().catch((Z)=>{U({type:"error",errorText:Q(Z)})}))},onError:Q}});if(X)D.push(X.catch((G)=>{U({type:"error",errorText:Q(G)})}))}catch(X){U({type:"error",errorText:Q(X)})}return new Promise(async(X)=>{while(D.length>0)await D.shift();X()}).finally(()=>{try{I.close()}catch(X){}}),Va2({stream:Y,messageId:f(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var _f=K.record(K.string(),wM.optional()),LNw=UBA(()=>ic(K.array(K.object({id:K.string(),role:K.enum(["system","user","assistant"]),metadata:K.unknown().optional(),parts:K.array(K.union([K.object({type:K.literal("text"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("reasoning"),text:K.string(),state:K.enum(["streaming","done"]).optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-url"),sourceId:K.string(),url:K.string(),title:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("source-document"),sourceId:K.string(),mediaType:K.string(),title:K.string(),filename:K.string().optional(),providerMetadata:N2.optional()}),K.object({type:K.literal("file"),mediaType:K.string(),filename:K.string().optional(),url:K.string(),providerMetadata:N2.optional()}),K.object({type:K.literal("step-start")}),K.object({type:K.string().startsWith("data-"),id:K.string().optional(),data:K.unknown()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),input:K.unknown().optional(),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),input:K.unknown().optional(),rawInput:K.unknown().optional(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.literal("dynamic-tool"),toolName:K.string(),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-streaming"),providerExecuted:K.boolean().optional(),callProviderMetadata:N2.optional(),input:K.unknown().optional(),output:K.never().optional(),errorText:K.never().optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("input-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.never().optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-requested"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.never().optional(),reason:K.never().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("approval-responded"),input:K.unknown(),providerExecuted:K.boolean().optional(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.boolean(),reason:K.string().optional()})}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-available"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.unknown(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),preliminary:K.boolean().optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-error"),providerExecuted:K.boolean().optional(),input:K.unknown().optional(),rawInput:K.unknown().optional(),output:K.never().optional(),errorText:K.string(),callProviderMetadata:N2.optional(),resultProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!0),reason:K.string().optional()}).optional()}),K.object({type:K.string().startsWith("tool-"),toolCallId:K.string(),toolMetadata:_f.optional(),state:K.literal("output-denied"),providerExecuted:K.boolean().optional(),input:K.unknown(),output:K.never().optional(),errorText:K.never().optional(),callProviderMetadata:N2.optional(),approval:K.object({id:K.string(),approved:K.literal(!1),reason:K.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var ENw=fF({prefix:"aiobj",size:24});function p01(A){return({url:Q,abortSignal:B})=>as2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var CNw=fF({prefix:"aiobj",size:24});var ONw=p01();var Ea2="AI_NoSuchProviderError",Ma2=`vercel.ai.error.${Ea2}`,Ca2=Symbol.for(Ma2),Oa2;Oa2=Ca2;var RNw=p01();var i01={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.122",description:"Web chat interface for Brains",type:"module",exports:{".":"./src/index.ts"},files:["src","dist","package.json"],scripts:{build:"bun scripts/build-ui.ts","build:ui":"bun scripts/build-ui.ts",typecheck:"tsc --noEmit && tsc --noEmit -p ui-react/tsconfig.json",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",test:"bun test"},dependencies:{"@ai-sdk/react":"^3.0.116","@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@streamdown/cjk":"^1.0.3","@streamdown/code":"^1.1.1","@streamdown/math":"^1.0.2","@streamdown/mermaid":"^1.0.2",ai:"^6.0.86","class-variance-authority":"^0.7.0",cmdk:"^1.1.1","lucide-react":"^1.16.0",nanoid:"^5.0.4","radix-ui":"^1.4.3",react:"^19.2.6","react-dom":"^19.2.6",shiki:"^4.1.0",streamdown:"^2.5.0","use-stick-to-bottom":"^1.1.4"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/react":"^19.0.3","@types/react-dom":"^19.0.3",typescript:"^5.3.3",vite:"^7.2.4"}};async function r01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing document id",{status:400});let $=await Q.entityService.getEntity({entityType:"document",id:w});if(!$)return new Response("Document not found",{status:404});let f=ba2($.content);if(!f)return new Response("Document content is not a PDF",{status:415});let I=ka2($.metadata,w);return n01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}async function d01(A,Q){if(!await Q.resolveOperatorSession(A))return Q.createOperatorLoginRequiredResponse(A);let B=new URL(A.url),w=B.searchParams.get("id")?.trim();if(!w)return new Response("Missing image id",{status:400});let $=await Q.entityService.getEntity({entityType:"image",id:w});if(!$)return new Response("Image not found",{status:404});let f=Pa2($.content);if(!f)return new Response("Image content is not an image",{status:415});let I=ja2($.metadata,w,f.mimeType);return n01({requestUrl:B,data:f.data,mediaType:f.mimeType,filename:I})}function n01(A){let Q=new Headers({"Content-Type":A.mediaType,"Content-Length":String(A.data.byteLength),"Content-Disposition":`${A.requestUrl.searchParams.has("download")?"attachment":"inline"}; filename="${_a2(A.filename)}"`});return new Response(A.data,{headers:Q})}function o01(A,Q){let B=A.match(/^data:([^;]+);base64,(.+)$/i);if(!B)return null;let[,w,$]=B;if(!w||!$||!Q.test(w))return null;let f=Buffer.from($,"base64"),I=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);return{mimeType:w,data:I}}function ba2(A){let Q=o01(A,/^application\/pdf$/i);if(Q?.mimeType.toLowerCase()!=="application/pdf")return null;return{mimeType:"application/pdf",data:Q.data}}function Pa2(A){return o01(A,/^image\/[a-z0-9.+-]+$/i)}function ka2(A,Q){let B=A?.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}function ja2(A,Q,B){let w=A?.filename;if(typeof w==="string"&&w.length>0)return w;let $=A?.format;if(typeof $==="string"&&$.length>0)return`${Q}.${$==="jpeg"?"jpg":$}`;let f=B.split("/")[1];return`${Q}.${f&&f.length>0?f:"png"}`}function _a2(A){return A.replace(/["\\\r\n]/g,"_")}WA();aA();var nc="upload",s01=TR;var va2={namespace:"upload",refKind:nc,routePath:"/api/chat/uploads"};function HBA(){return va2}aA();var t01="upload.txt";var e01=5000000,Ta2=[".md",".txt",".markdown"],ya2=["text/plain","text/markdown","text/x-markdown"],FkA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),xa2=new Set(FkA.values());function KBA(A){let Q=A.split(/[\\/]/).at(-1)?.trim()??"",B=Array.from(Q).filter((w)=>{let $=w.charCodeAt(0);return $>31&&$!==127}).join("").slice(0,160);return B.length>0?B:"upload.txt"}function A11(A,Q){let B=Q?.trim()??"";if(B.length>0)return B;let w=A.toLowerCase();if(w.endsWith(".md")||w.endsWith(".markdown"))return"text/markdown";if(w.endsWith(".txt"))return"text/plain";return"application/octet-stream"}function Q11(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=A11(A,void 0);if($!=="application/octet-stream")return $;let f=A.toLowerCase();for(let[I,D]of FkA)if(f.endsWith(I))return D;return"application/octet-stream"}function B11(A,Q){if(Q&&ya2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return Ta2.some((B)=>A.toLowerCase().endsWith(B))}function Sa2(A){return A<=1e5}function ga2(A){return A<=5000000}function ha2(A,Q){let B=Q11(A,Q);if(xa2.has(B))return!0;return FkA.has(ca2(A))}function ma2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function ua2(A){let Q=KBA(A.filename),B=A11(Q,A.mediaType);if(!B11(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!Sa2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!ma2(A.content))return{ok:!1,code:"binary_content",message:`Unsupported file upload type: ${Q}`};return{ok:!0,filename:Q,mediaType:B,sizeBytes:A.content.byteLength,text:new TextDecoder("utf-8").decode(A.content).replace(/^\uFEFF/,"")}}function FBA(A){let Q=KBA(A.filename),B=Q11(Q,A.mediaType);if(B11(Q,B)){let w=ua2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!ha2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!ga2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!la2(A.content,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};return{ok:!0,kind:"file",filename:Q,mediaType:B,sizeBytes:A.content.byteLength}}function ca2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function la2(A,Q){switch(Q){case"image/png":return a01(A,[137,80,78,71]);case"image/jpeg":return a01(A,[255,216,255]);case"image/gif":return GBA(A,"GIF87a")||GBA(A,"GIF89a");case"image/webp":return GBA(A,"RIFF")&&w11(A,"WEBP",8);case"application/pdf":return GBA(A,"%PDF-");default:return!1}}function a01(A,Q){return Q.every((B,w)=>A[w]===B)}function GBA(A,Q){return w11(A,Q,0)}function w11(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var pa2="file",ia2=16384;async function $11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=Number(A.headers.get("content-length"));if(Number.isFinite(B)&&B>e01+ia2)return new Response("File upload too large",{status:400});let w;try{w=await A.formData()}catch{return new Response("Invalid multipart upload",{status:400})}let $=w.get(pa2);if(!($ instanceof File))return new Response("Missing upload file",{status:400});let f=Buffer.from(await $.arrayBuffer()),I=FBA({filename:$.name,mediaType:$.type,content:f});if(!I.ok)return new Response(I.message,{status:400});let D=Q.getUploadStore(),Y=await D.save({filename:I.filename,mediaType:I.mediaType,content:f});return Response.json(D.toResponseBody(Y),{status:201})}async function f11(A,Q){if(!await Q.resolveOperatorSession(A))return new Response("Forbidden",{status:403});let B=new URL(A.url).searchParams.get("id")?.trim();if(!B)return new Response("Missing upload id",{status:400});let w=await Y11(B,Q.getUploadStore());if(w instanceof Response)return w;let{record:$,content:f}=w,I=U11($,f);if(I instanceof Response)return I;let D=new URL(A.url).searchParams.has("download")?"attachment":"inline",Y=new Uint8Array(f).buffer;return new Response(Y,{headers:{"Content-Type":$.mediaType,"Content-Length":String(f.byteLength),"Content-Disposition":`${D}; filename="${na2($.filename)}"`}})}function I11(A){let Q=KBA(A.filename??t01),B=da2(A.url);if(!B)return new Response(`Unsupported file upload URL: ${Q}`,{status:400});let w=FBA({filename:Q,mediaType:A.mediaType,content:B.buffer});if(!w.ok)return new Response(w.message,{status:400});return J11(w,B.buffer)}async function D11(A,Q){let B=await Y11(A,Q);if(B instanceof Response)return B;let{record:w,content:$}=B,f=U11(w,$);if(f instanceof Response)return f;return J11(f,$,{kind:nc,id:A})}async function Y11(A,Q){try{return await Q.read(A)}catch(B){if(B instanceof AW)return ra2(B);throw B}}function U11(A,Q){let B=FBA({filename:A.filename,mediaType:A.mediaType,content:Q});if(!B.ok)return new Response(B.message,{status:400});return B}function J11(A,Q,B){if(A.kind==="text")return{kind:"text",filename:A.filename,mediaType:A.mediaType,content:A.text,sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}};return{kind:"file",filename:A.filename,mediaType:A.mediaType,data:new Uint8Array(Q),sizeBytes:A.sizeBytes,...B!==void 0?{source:B}:{}}}function ra2(A){switch(A.code){case"invalid_ref":return new Response("Invalid upload ref",{status:400});case"invalid_metadata":return new Response("Invalid upload metadata",{status:500});case"not_found":return new Response("Upload not found",{status:404})}}function da2(A){let Q=/^data:[^,]*,(.*)$/s.exec(A);if(!Q)return null;let w=A.slice(5,A.indexOf(",")).split(";").some(($)=>$.toLowerCase()==="base64");try{let $=w?Buffer.from(Q[1]??"","base64"):Buffer.from(decodeURIComponent(Q[1]??""),"utf8");return{buffer:$,byteLength:$.byteLength}}catch{return null}}function na2(A){return A.replace(/["\\\r\n]/g,"_")}var oa2=H.object({type:H.literal("text"),text:H.string()}),sa2=H.object({type:H.literal("file"),mediaType:H.string().optional(),filename:H.string().optional(),url:H.string()}),aa2=H.object({state:H.literal("approval-responded"),approval:H.object({id:H.string(),approved:H.boolean()})}).passthrough(),ta2=H.object({role:H.string(),parts:H.array(H.unknown()).optional(),content:H.string().optional()}),X11=H.object({id:H.string().optional(),messages:H.array(ta2).min(1),trigger:H.string().optional()}),ea2=H.object({kind:H.literal(nc),id:H.string().regex(s01)}),At2=H.object({type:H.literal("data-upload"),data:H.object({ref:ea2})});async function W11(A,Q){let B=Qt2(A);if(!B)return{message:"",attachments:[]};let w=[],$=[];for(let I of B.parts??[]){let D=oa2.safeParse(I);if(D.success){if(D.data.text.length>0)w.push(D.data.text);continue}let Y=sa2.safeParse(I);if(Y.success){let J=I11(Y.data);if(J instanceof Response)return J;$.push(J);continue}let U=At2.safeParse(I);if(U.success){let J=await D11(U.data.data.ref.id,Q.uploadStore);if(J instanceof Response)return J;$.push(J);continue}if(Bt2(I)==="data-upload")return new Response("Invalid upload ref",{status:400})}return{message:w.length>0?w.join(`
2480
2480
 
2481
2481
  `):B.content??"",attachments:$}}function H11(A){let Q=A.messages.at(-1);if(!Q||Q.role==="user")return[];return(Q.parts??[]).map((B)=>aa2.safeParse(B)).filter((B)=>B.success).map((B)=>B.data.approval)}function Qt2(A){for(let Q=A.messages.length-1;Q>=0;Q-=1){let B=A.messages[Q];if(B?.role==="user")return B}return}function Bt2(A){if(typeof A!=="object"||A===null||!("type"in A))return;let Q=A.type;return typeof Q==="string"?Q:void 0}function G11(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}function wt2(A){return G11(A)&&A.kind==="upload"&&typeof A.id==="string"}function oc(A){if(wt2(A))return"uploaded file";if(Array.isArray(A))return A.map((Q)=>oc(Q));if(!G11(A))return A;return K11(A)}function K11(A){return Object.fromEntries(Object.entries(A).map(([Q,B])=>[Q,oc(B)]))}function $t2(A){if(A.kind!=="tool-approval")return A;return{...A,...A.input!==void 0?{input:K11(A.input)}:{},...A.output!==void 0?{output:oc(A.output)}:{}}}function F11(A,Q,B){A.write({type:"text-start",id:Q}),A.write({type:"text-delta",id:Q,delta:B}),A.write({type:"text-end",id:Q})}function ZkA(A,Q){for(let B of Q){let w=$t2(B);if(w.kind==="attachment"){A.write({type:"data-attachment",id:w.id,data:w});continue}if(w.kind==="sources"){A.write({type:"data-sources",id:w.id,data:w});continue}if(w.kind==="actions"){A.write({type:"data-actions",id:w.id,data:w});continue}let $=w.toolCallId??w.id,f=w.input??{};switch(A.write({type:"tool-input-available",toolCallId:$,toolName:w.toolName,input:f,dynamic:!0,title:w.preview?`${w.summary}
2482
2482
 
@@ -4630,7 +4630,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
4630
4630
 
4631
4631
  `);$=I.pop()??"";for(let D of I){let Y=D.split(`
4632
4632
  `).find((V)=>V.startsWith("data: "));if(!Y)continue;let U;try{U=JSON.parse(Y.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let J=U.result;if(!J)continue;if(J.final!==!0)continue;B.cancel().catch(()=>{});let G=J.status,Z=G?.state??"unknown",L=(G?.message?.parts??[]).filter((V)=>V.kind==="text"&&typeof V.text==="string").map((V)=>V.text).join(`
4633
- `)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await c11(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class sc extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class ac extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function St2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new sc(w))},w)})])}catch(I){if(I instanceof sc)throw I;if($.signal.aborted)throw new sc(w);throw I}finally{if(f)clearTimeout(f)}}async function c11(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new ac(Q)),Q)})])}catch(w){if(w instanceof ac)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function gt2(A){if(A instanceof sc||A instanceof ac)return!0;return A instanceof Error}function ht2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof ac)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function p11(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??kt2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??jt2,maxNetworkAttempts:A.maxNetworkAttempts??_t2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. Use only a saved agent id such as yeehaa.io or docs.rizom.ai. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:u11,visibility:"anchor",handler:async(w)=>{let $=H.object(u11).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=vt2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:n$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let U=`https://${D}`,J=await Tt2(U,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${U}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return yt2(X,I,Q,G,B)}}}var CkA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.121",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@a2a-js/sdk":"^0.3.12","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"}};var ut2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class aj extends eX{agentCard;taskManager=new EkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",CkA,A,v11)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>RI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=T11({character:Q,profile:B,version:CkA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ut2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new ij;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=S11.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=h11.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=m11(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await g11(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[p11({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io` or `docs.rizom.ai`). Never pass a full URL or a display name like `Brain`.\n- If the user names an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Do not create, capture, or generate a note containing the user's question in the same turn as a saved-agent contact request. The user asked to ask the saved agent, not to persist the question.\n- If `a2a_call` fails because auth, re-authentication, network, or the remote agent is unavailable, report that failure directly. Do not answer from memory, local docs, onboarding docs, or general knowledge; the saved agent was the requested source.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}aA();class OkA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),Y=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var YB1=Y1(fB1(),1);import{extname as h2Q}from"path";var SBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function DM(A){let Q=h2Q(A).toLowerCase();return SBA.includes(Q)}function IB1(A){switch(A.toLowerCase().replace(".","")){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"gif":return"image/gif";case"webp":return"image/webp";case"svg":return"image/svg+xml";default:return"image/png"}}function CjA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as m2Q,relative as u2Q,sep as DB1,join as c2Q}from"path";function gY(A,Q){return m2Q(Q)?Q:c2Q(A,Q)}function $_(A,Q){let B=gY(A,Q),w=u2Q(A,B);return DB1==="/"?w:w.split(DB1).join("/")}function l2Q(A,Q){if(!$_(Q,A).startsWith("image/"))return!1;return DM(A)}function p2Q(A,Q){if($_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return l2Q(A,Q)}class OjA{watcher;watchCallback;pendingChanges=new Map;batchTimeout;syncPath;watchInterval;logger;onFileChange;constructor(A){this.syncPath=A.syncPath,this.watchInterval=A.watchInterval,this.logger=A.logger,this.onFileChange=A.onFileChange}async start(){if(this.watcher){this.logger.debug("Already watching directory");return}if(this.logger.debug("Starting directory watch",{path:this.syncPath,interval:this.watchInterval}),this.watcher=YB1.default.watch(this.syncPath,{ignored:/(^|[/\\])\../,persistent:!0,interval:this.watchInterval,awaitWriteFinish:{stabilityThreshold:2000,pollInterval:100}}),this.watcher.on("add",(A)=>void this.handleFileChange("add",A)).on("change",(A)=>void this.handleFileChange("change",A)).on("unlink",(A)=>void this.handleFileChange("delete",A)).on("error",(A)=>this.logger.error("Watcher error",A)),this.watchCallback)this.watcher.on("all",this.watchCallback)}stop(){if(this.watcher)this.watcher.close(),this.watcher=void 0,this.logger.info("Stopped directory watch");if(this.batchTimeout)clearTimeout(this.batchTimeout),this.batchTimeout=void 0}setCallback(A){if(this.watchCallback=A,this.watcher)this.watcher.on("all",A)}async handleFileChange(A,Q){if(!p2Q(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=$_(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=gY(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function UB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return i2Q(Q)}function JB1(A){if(A)A.stop();return}function XB1(A,Q){if(A)A.setCallback(Q)}async function i2Q(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,Y=new OkA(Q,$,f,I,D),U=new OjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await Y.handleFileChange(J,X)}});return await U.start(),U}async function WB1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let B=await A.importEntities(),w=await A.removeOrphanedEntities(),$=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:$,imported:B.imported,orphansDeleted:w.deleted}),{export:{exported:0,failed:0,errors:[]},import:B,duration:$}}aA();class RjA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??J$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class bjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new RjA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class PjA{options;constructor(A){this.options=A}createExportDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImportDeps(A){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,quarantine:this.options.quarantine,imageJobQueue:this.createImageJobQueueDeps(),entityTypes:A}}createCleanupDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImageJobQueueDeps(){return{logger:this.options.logger,syncPath:this.options.syncPath,jobQueueCallback:this.options.getJobQueueCallback(),coverImageConverter:this.options.coverImageConverter,inlineImageConverter:this.options.inlineImageConverter}}}import{basename as a2Q,dirname as t2Q,extname as e2Q}from"path";import{extname as r2Q}from"path";var gBA=[".pdf"],HB1=".meta.json";function YM(A){let Q=r2Q(A).toLowerCase();return gBA.includes(Q)}function GB1(A){return A.toLowerCase().endsWith(HB1)}function kjA(A){return`${A}${HB1}`}function KB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as d2Q,join as hBA}from"path";function mBA(A,Q){let w=$_(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=FB1(D);I=f.join(":")}else I=FB1(f[0]??"");return{entityType:$,id:I}}function ZB1(A,Q,B,w=".md"){let $=Q.split(":").filter((U)=>U.length>0),f=B==="base";if($.length===1)return f?hBA(A,`${$[0]}${w}`):hBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],Y=I.slice(0,-1);if(f)return hBA(A,...Y,`${D}${w}`);return hBA(A,B,...Y,`${D}${w}`)}function NB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return CjA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?CjA(B[1]):".md"}function FB1(A){let Q=d2Q(A).toLowerCase();return Q===".md"||SBA.includes(Q)||gBA.includes(Q)?A.slice(0,-Q.length):A}wY();import{mkdir as AQQ,readFile as f_,writeFile as _jA,stat as QQQ,utimes as BQQ}from"fs/promises";import{join as uBA}from"path";import{mkdir as zB1,readdir as o2Q,stat as s2Q}from"fs/promises";import{access as n2Q}from"fs/promises";async function X5(A){try{return await n2Q(A),!0}catch{return!1}}async function jjA(A,Q){return EB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function qB1(A,Q){return EB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function LB1(A,Q){if(!await X5(A))await zB1(A,{recursive:!0});for(let B of Q)if(B!=="base")await zB1(uBA(A,B),{recursive:!0})}async function VB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await X5(A))return{files:B,stats:w};let $=await jjA(A,Q);for(let f of $)try{let I=uBA(A,f),D=await s2Q(I),{entityType:Y}=mBA(A,f);B.push({path:f,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function EB1(A,Q,B){let w=[];if(!await X5(A))return w;let $=async(f,I="",D=!1,Y=!1)=>{let U=await o2Q(f,{withFileTypes:!0});for(let J of U){let X=I?uBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!GB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&DM(J.name))w.push(X);else if(B.includeDocuments&&Y&&YM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=uBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,Y||N)}}};return await $(A),w}function wQQ(A){return typeof A==="object"&&A!==null}class vjA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return mBA(this.syncPath,A)}async readEntity(A){let Q=gY(this.syncPath,A),B=await QQQ(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,Y;if(DM(A)||YM(A)){let X=(await f_(Q)).toString("base64"),G=e2Q(A);if(D=`data:${YM(A)?KB1(G):IB1(G)};base64,${X}`,YM(A))Y=await this.readDocumentSidecar(Q,A)}else D=await f_(Q,"utf-8");let U={entityType:w,id:$,content:D,created:f,updated:I};if(Y)U.metadata=Y;return U}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:a2Q(Q)},w=kjA(A);if(!await X5(w))return B;try{let $=await f_(w,"utf-8"),f=JSON.parse($),I=wQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),Y=!1;if(await X5(Q)){let U=await f_(Q),J=gB(U.toString("base64")),X=gB(D.toString("base64"));if(J===X)Y=!0}if(!Y)await this.ensureEntityDirectory(A,Q),await _jA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(Y)return}else{let f=this.entityService.serializeEntity(A);if(await X5(Q)){let I=await f_(Q,"utf-8"),D=gB(I),Y=gB(f);if(D===Y)return}await this.ensureEntityDirectory(A,Q),await _jA(Q,f,"utf-8")}let $=new Date(A.updated);await BQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await AQQ(t2Q(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=kjA(Q),f=`${JSON.stringify(w,null,2)}
4633
+ `)||"No response text";return{success:!0,data:{state:Z,response:L}}}f=await c11(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class sc extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class ac extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function St2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new sc(w))},w)})])}catch(I){if(I instanceof sc)throw I;if($.signal.aborted)throw new sc(w);throw I}finally{if(f)clearTimeout(f)}}async function c11(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new ac(Q)),Q)})])}catch(w){if(w instanceof ac)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function gt2(A){if(A instanceof sc||A instanceof ac)return!0;return A instanceof Error}function ht2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof ac)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function p11(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??kt2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??jt2,maxNetworkAttempts:A.maxNetworkAttempts??_t2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. Use this when the user asks what a saved agent has to say or asks a saved agent for its skills/capabilities. Use only a saved agent id such as yeehaa.io or docs.rizom.ai. Never pass a display name like Brain, never pass a full URL, and do not use this tool to probe whether an agent exists. If the user gives a URL, an unsaved agent, or an ambiguous name, ask them to add/save or clarify the agent first.",inputSchema:u11,visibility:"anchor",handler:async(w)=>{let $=H.object(u11).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=vt2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D,visibilityScope:n$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let U=`https://${D}`,J=await Tt2(U,Q);if(!J)return{success:!1,error:`Could not fetch Agent Card from ${U}`};let X=J.url,G;if(A.outboundTokens)try{let Z=new URL(X).hostname;G=A.outboundTokens[Z]}catch{}return yt2(X,I,Q,G,B)}}}var CkA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.122",type:"module",main:"./src/index.ts",module:"./src/index.ts",types:"./src/index.ts",files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint --max-warnings 0 .","lint:fix":"eslint --fix .",test:"bun test"},dependencies:{"@a2a-js/sdk":"^0.3.12","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",hono:"^4.7.10"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"}};var ut2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class aj extends eX{agentCard;taskManager=new EkA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",CkA,A,v11)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)f=I.map((D)=>RI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=T11({character:Q,profile:B,version:CkA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(ut2))Q.set(B,w);return new Response(A.body,{status:A.status,statusText:A.statusText,headers:Q})}getOrCreateApp(){if(this.app)return this.app;let A=new ij;return A.get("/.well-known/agent-card.json",(Q)=>{if(!this.agentCard)return this.withCors(Q.json({error:"Agent Card not ready"},503));return this.withCors(Q.json(this.agentCard))}),A.get("/a2a",(Q)=>{return this.withCors(Q.json({error:"Use POST with JSON-RPC 2.0 requests.",agentCard:"/.well-known/agent-card.json"},405))}),A.options("/a2a",()=>this.withCors(new Response(null,{status:204}))),A.post("/a2a",async(Q)=>{if(!this.agentService)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32603,message:"Agent service not ready"},id:null},503));let B;try{B=await Q.req.json()}catch{return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32700,message:"Parse error"},id:null}))}let w=S11.safeParse(B);if(!w.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32600,message:"Invalid request"},id:null}));let $=this.resolveCallerPermission(Q.req.header("Authorization"));if(w.data.method==="message/stream"){let I=h11.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=m11(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await g11(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[p11({outboundTokens:this.config.outboundTokens,requestTimeoutMs:this.config.requestTimeoutMs,streamIdleTimeoutMs:this.config.streamIdleTimeoutMs,maxNetworkAttempts:this.config.maxNetworkAttempts,entityService:this.getContext().entityService})]}async getInstructions(){return"## Agent-to-agent calls\n- Use `a2a_call` only for agents already saved in the local `agent` directory.\n- Pass only the saved local agent id to `a2a_call` (for example `yeehaa.io` or `docs.rizom.ai`). Never pass a full URL or a display name like `Brain`.\n- If the user names an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, call `a2a_call` directly with that id. Do not preflight with `system_list` or `system_get`; the tool validates saved/approved status and reports errors.\n- If the user asks you to ask, message, contact, hear what a saved agent has to say, or ask a saved agent for its own skills/capabilities, treat that as an agent-directory request first and call `a2a_call` in the same turn. Do not stop after listing the agent, drafting the question, searching general content locally, or reading the saved agent entity metadata.\n- After `a2a_call` returns within a turn, answer that turn from its response. Do **not** supplement with `system_get` (or any other read tool) on the agent entity, unless the user explicitly asks for directory/profile details about the agent itself.\n- Do not create, capture, or generate a note containing the user's question in the same turn as a saved-agent contact request. The user asked to ask the saved agent, not to persist the question.\n- If `a2a_call` fails because auth, re-authentication, network, or the remote agent is unavailable, report that failure directly. Do not answer from memory, local docs, onboarding docs, or general knowledge; the saved agent was the requested source.\n- Each new turn that asks the same saved agent something \u2014 including short follow-ups like \"what skills does it have\", \"and what about X\", \"tell me more\" \u2014 is a **new** contact request and needs its **own** fresh `a2a_call`. Do not assume the previous turn's a2a response already covers a new question, and do not substitute `system_list`/`system_get` or a no-tool answer for the fresh call. If the previous turn targeted an exact saved local id such as `yeehaa.io`, use that same id again for the follow-up even if the previous response was a refusal or error; let `a2a_call` validate the current directory state again.\n- If the user gives a full URL for an agent, do not pass that URL to `a2a_call`. Use a saved local agent id only. If that URL is not already saved in the local directory, tell the user to add it first.\n- If the user refers to an agent by name, first make sure that name resolves to exactly one saved agent id. If multiple saved agents could match, ask a concise clarification question naming the matching saved agent ids and do not call any agent yet. Never choose the first match.\n- After asking that clarification question, end the turn. Do not call `a2a_call` later in the same turn.\n- If the target agent is not in the directory, do not create a wish, reminder, todo, note, fallback task, or any new entity. Tell the user to add it first.\n- In these invalid agent-target cases, do not call any tool unless the user explicitly asks you to add/save the agent.\n- Only use creation tools for an agent if the user explicitly asks you to add or save that agent.\n- If the target agent is discovered but not approved yet, do not call it and do not create a wish. Tell the user it must be approved first."}createDaemon(){return{start:async()=>{if(this.hasWebserver)this.logger.info("A2A mounted on shared webserver host");else this.logger.info("A2A running without webserver routes")},stop:async()=>{this.logger.info("A2A server stopped")}}}}aA();class OkA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),Y=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var YB1=Y1(fB1(),1);import{extname as h2Q}from"path";var SBA=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function DM(A){let Q=h2Q(A).toLowerCase();return SBA.includes(Q)}function IB1(A){switch(A.toLowerCase().replace(".","")){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"gif":return"image/gif";case"webp":return"image/webp";case"svg":return"image/svg+xml";default:return"image/png"}}function CjA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as m2Q,relative as u2Q,sep as DB1,join as c2Q}from"path";function gY(A,Q){return m2Q(Q)?Q:c2Q(A,Q)}function $_(A,Q){let B=gY(A,Q),w=u2Q(A,B);return DB1==="/"?w:w.split(DB1).join("/")}function l2Q(A,Q){if(!$_(Q,A).startsWith("image/"))return!1;return DM(A)}function p2Q(A,Q){if($_(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return l2Q(A,Q)}class OjA{watcher;watchCallback;pendingChanges=new Map;batchTimeout;syncPath;watchInterval;logger;onFileChange;constructor(A){this.syncPath=A.syncPath,this.watchInterval=A.watchInterval,this.logger=A.logger,this.onFileChange=A.onFileChange}async start(){if(this.watcher){this.logger.debug("Already watching directory");return}if(this.logger.debug("Starting directory watch",{path:this.syncPath,interval:this.watchInterval}),this.watcher=YB1.default.watch(this.syncPath,{ignored:/(^|[/\\])\../,persistent:!0,interval:this.watchInterval,awaitWriteFinish:{stabilityThreshold:2000,pollInterval:100}}),this.watcher.on("add",(A)=>void this.handleFileChange("add",A)).on("change",(A)=>void this.handleFileChange("change",A)).on("unlink",(A)=>void this.handleFileChange("delete",A)).on("error",(A)=>this.logger.error("Watcher error",A)),this.watchCallback)this.watcher.on("all",this.watchCallback)}stop(){if(this.watcher)this.watcher.close(),this.watcher=void 0,this.logger.info("Stopped directory watch");if(this.batchTimeout)clearTimeout(this.batchTimeout),this.batchTimeout=void 0}setCallback(A){if(this.watchCallback=A,this.watcher)this.watcher.on("all",A)}async handleFileChange(A,Q){if(!p2Q(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=$_(this.syncPath,Q);if(this.pendingChanges.set(B,A),this.batchTimeout)clearTimeout(this.batchTimeout);this.batchTimeout=setTimeout(()=>{this.processPendingChanges()},500)}async processPendingChanges(){if(this.pendingChanges.size===0)return;let A=new Map(this.pendingChanges);this.pendingChanges.clear(),this.batchTimeout=void 0,this.logger.debug("Processing batched file changes",{changeCount:A.size});for(let[Q,B]of A){let w=gY(this.syncPath,Q);try{if(this.onFileChange)await this.onFileChange(B,w)}catch($){this.logger.error("Error processing file change",{path:Q,event:B,error:$})}}}isWatching(){return!!this.watcher}getPendingChangesCount(){return this.pendingChanges.size}}async function UB1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return i2Q(Q)}function JB1(A){if(A)A.stop();return}function XB1(A,Q){if(A)A.setCallback(Q)}async function i2Q(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,Y=new OkA(Q,$,f,I,D),U=new OjA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(J,X)=>{await Y.handleFileChange(J,X)}});return await U.start(),U}async function WB1(A){let Q=Date.now();A.logger.debug("Starting sync (import only)");let B=await A.importEntities(),w=await A.removeOrphanedEntities(),$=Date.now()-Q;return A.markSynced(new Date),A.logger.debug("Sync completed",{duration:$,imported:B.imported,orphansDeleted:w.deleted}),{export:{exported:0,failed:0,errors:[]},import:B,duration:$}}aA();class RjA{logger;syncPath;deleteOnFileRemoval;constructor(A){this.logger=A.logger,this.syncPath=A.syncPath,this.deleteOnFileRemoval=A.deleteOnFileRemoval}prepareBatchOperations(A){let Q=[],B=this.createImportOperations(A);Q.push(...B);let w=B.length;if(this.deleteOnFileRemoval)Q.push({type:"directory-cleanup",data:{}});let $=A.length;return this.logger.debug("Prepared batch operations",{exportOperationsCount:0,importOperationsCount:w,totalFiles:$}),{operations:Q,exportOperationsCount:0,importOperationsCount:w,totalFiles:$}}async queueSyncBatch(A,Q,B,w){let $=this.prepareBatchOperations(B);if($.operations.length===0)return this.logger.debug("No sync operations needed",{source:Q}),null;return{batchId:await A.jobs.enqueueBatch($.operations,{source:Q,rootJobId:w?.rootJobId??J$(),metadata:{progressToken:w?.progressToken,operationType:"file_operations",operationTarget:this.syncPath,pluginId:w?.pluginId??"directory-sync",interfaceType:w?.interfaceType,channelId:w?.channelId}}),operationCount:$.operations.length,exportOperationsCount:$.exportOperationsCount,importOperationsCount:$.importOperationsCount,totalFiles:$.totalFiles}}createImportOperations(A){if(A.length===0)return[];let Q=50,B=[];for(let w=0;w<A.length;w+=Q){let $=A.slice(w,w+Q);B.push({type:"directory-import",data:{batchIndex:Math.floor(w/Q),paths:$,batchSize:$.length}})}return B}}class bjA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new RjA({logger:A.logger,syncPath:A.syncPath,deleteOnFileRemoval:A.deleteOnFileRemoval})}async queueSyncBatch(A,Q,B){if(this.syncInProgress)return this.logger.debug("Sync already in progress, skipping",{source:Q}),null;this.syncInProgress=!0;try{let w=await this.fileOperations.getAllSyncFiles();return await this.batchOperationsManager.queueSyncBatch(A,Q,w,B)}finally{this.syncInProgress=!1}}}class PjA{options;constructor(A){this.options=A}createExportDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImportDeps(A){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,quarantine:this.options.quarantine,imageJobQueue:this.createImageJobQueueDeps(),entityTypes:A}}createCleanupDeps(A,Q){return{entityService:this.options.entityService,logger:this.options.logger,fileOperations:this.options.fileOperations,deleteOnFileRemoval:A,entityTypes:Q}}createImageJobQueueDeps(){return{logger:this.options.logger,syncPath:this.options.syncPath,jobQueueCallback:this.options.getJobQueueCallback(),coverImageConverter:this.options.coverImageConverter,inlineImageConverter:this.options.inlineImageConverter}}}import{basename as a2Q,dirname as t2Q,extname as e2Q}from"path";import{extname as r2Q}from"path";var gBA=[".pdf"],HB1=".meta.json";function YM(A){let Q=r2Q(A).toLowerCase();return gBA.includes(Q)}function GB1(A){return A.toLowerCase().endsWith(HB1)}function kjA(A){return`${A}${HB1}`}function KB1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as d2Q,join as hBA}from"path";function mBA(A,Q){let w=$_(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=FB1(D);I=f.join(":")}else I=FB1(f[0]??"");return{entityType:$,id:I}}function ZB1(A,Q,B,w=".md"){let $=Q.split(":").filter((U)=>U.length>0),f=B==="base";if($.length===1)return f?hBA(A,`${$[0]}${w}`):hBA(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],Y=I.slice(0,-1);if(f)return hBA(A,...Y,`${D}${w}`);return hBA(A,B,...Y,`${D}${w}`)}function NB1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return CjA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?CjA(B[1]):".md"}function FB1(A){let Q=d2Q(A).toLowerCase();return Q===".md"||SBA.includes(Q)||gBA.includes(Q)?A.slice(0,-Q.length):A}wY();import{mkdir as AQQ,readFile as f_,writeFile as _jA,stat as QQQ,utimes as BQQ}from"fs/promises";import{join as uBA}from"path";import{mkdir as zB1,readdir as o2Q,stat as s2Q}from"fs/promises";import{access as n2Q}from"fs/promises";async function X5(A){try{return await n2Q(A),!0}catch{return!1}}async function jjA(A,Q){return EB1(A,Q,{includeDocuments:!1,includeImages:!1})}async function qB1(A,Q){return EB1(A,Q,{includeDocuments:!0,includeImages:!0})}async function LB1(A,Q){if(!await X5(A))await zB1(A,{recursive:!0});for(let B of Q)if(B!=="base")await zB1(uBA(A,B),{recursive:!0})}async function VB1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await X5(A))return{files:B,stats:w};let $=await jjA(A,Q);for(let f of $)try{let I=uBA(A,f),D=await s2Q(I),{entityType:Y}=mBA(A,f);B.push({path:f,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function EB1(A,Q,B){let w=[];if(!await X5(A))return w;let $=async(f,I="",D=!1,Y=!1)=>{let U=await o2Q(f,{withFileTypes:!0});for(let J of U){let X=I?uBA(I,J.name):J.name;if(J.isFile()&&!J.name.endsWith(".invalid")&&!GB1(J.name)){if(J.name.endsWith(".md"))w.push(X);else if(B.includeImages&&D&&DM(J.name))w.push(X);else if(B.includeDocuments&&Y&&YM(J.name))w.push(X)}else if(J.isDirectory()&&!J.name.startsWith(".")){if(I===""&&!Q.hasEntityType(J.name))continue;let G=uBA(f,J.name),Z=J.name==="image"&&I==="",N=J.name==="document"&&I==="";await $(G,X,D||Z,Y||N)}}};return await $(A),w}function wQQ(A){return typeof A==="object"&&A!==null}class vjA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return mBA(this.syncPath,A)}async readEntity(A){let Q=gY(this.syncPath,A),B=await QQQ(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,Y;if(DM(A)||YM(A)){let X=(await f_(Q)).toString("base64"),G=e2Q(A);if(D=`data:${YM(A)?KB1(G):IB1(G)};base64,${X}`,YM(A))Y=await this.readDocumentSidecar(Q,A)}else D=await f_(Q,"utf-8");let U={entityType:w,id:$,content:D,created:f,updated:I};if(Y)U.metadata=Y;return U}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:a2Q(Q)},w=kjA(A);if(!await X5(w))return B;try{let $=await f_(w,"utf-8"),f=JSON.parse($),I=wQQ(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),Y=!1;if(await X5(Q)){let U=await f_(Q),J=gB(U.toString("base64")),X=gB(D.toString("base64"));if(J===X)Y=!0}if(!Y)await this.ensureEntityDirectory(A,Q),await _jA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(Y)return}else{let f=this.entityService.serializeEntity(A);if(await X5(Q)){let I=await f_(Q,"utf-8"),D=gB(I),Y=gB(f);if(D===Y)return}await this.ensureEntityDirectory(A,Q),await _jA(Q,f,"utf-8")}let $=new Date(A.updated);await BQQ(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await AQQ(t2Q(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=kjA(Q),f=`${JSON.stringify(w,null,2)}
4634
4634
  `;if(await X5($)){if(await f_($,"utf-8")===f)return}await this.ensureEntityDirectory(A,$),await _jA($,f,"utf-8")}getFilePath(A,Q,B=".md"){return ZB1(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,NB1(A))}async getAllMarkdownFiles(){return jjA(this.syncPath,this.entityService)}async getAllSyncFiles(){return qB1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await LB1(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=gB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return VB1(this.syncPath,this.entityService)}async syncDirectoryExists(){return X5(this.syncPath)}async fileExists(A){return X5(A)}}E7();WA();E7();async function cBA(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=RN(I),Y=YV(D),U=bN(D);if(!Y||!U)throw Error("Could not detect image format or dimensions");let J=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:Y,width:U.width,height:U.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:J.entityId}),J.entityId}var MB1=H.object({title:H.string(),slug:H.string().optional(),coverImageUrl:H.string().url(),coverImageId:H.string().optional(),coverImageAlt:H.string().optional()});class TjA{entityService;fetcher;logger;constructor(A,Q,B=WY){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=jB(A)}catch{return null}let{frontmatter:B}=Q,w=MB1.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!jG(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??X1($),customAlt:D}}async convert(A){let Q;try{Q=jB(A)}catch(U){return this.logger.debug("Parse failed",{error:U}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=MB1.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!jG(I))return{content:A,converted:!1};let Y={postTitle:$,postSlug:f??X1($),sourceUrl:I,customAlt:D};try{let U=await this.createImageEntity(Y),J={...B};return delete J.coverImageUrl,delete J.coverImageAlt,J.coverImageId=U,{content:bG(J,Q.content),converted:!0,imageId:U}}catch(U){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:T0(U)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return cBA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}E7();WA();class Xl{entityService;fetcher;logger;constructor(A,Q,B=WY){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=QNA(A);for(let $ of w){if(!jG($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return`![${A.alt}](${A.url} "${A.title}")`;return`![${A.alt}](${A.url})`}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),Y=`![${I.alt}](entity://image/${D})`;w=w.replace(I.originalMarkdown,Y),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:T0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return cBA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class yjA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let Y=f.slice(D,D+B),U=await w(Y);$.imported+=U.imported,$.skipped+=U.skipped,$.failed+=U.failed,$.quarantined+=U.quarantined,$.errors.push(...U.errors),$.quarantinedFiles.push(...U.quarantinedFiles),$.jobIds.push(...U.jobIds);let J=Math.min(D+B,I),X=Math.round(J/I*40);await Q.report({progress:X,message:`Imported ${J}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}WA();import{rename as $QQ,appendFile as fQQ,readFile as IQQ,writeFile as DQQ,access as YQQ}from"fs/promises";import{join as CB1}from"path";class xjA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof H.ZodError)return!0;let Q=T0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await $QQ($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=CB1(this.syncPath,".import-errors.log"),D=new Date().toISOString(),Y=T0(Q),U=`${D} - ${A}: ${Y}
4635
4635
  \u2192 ${A}.invalid
4636
4636
 
@@ -4658,7 +4658,7 @@ details.web-chat-data-part[open] > summary > .web-chat-data-part-chevron {
4658
4658
  *...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
4659
4659
  ## Getting Started
4660
4660
  `),Q.push("Your sync directory is empty. Entities will be organized as follows:"),Q.push("- Base entities: `/<entity-id>.md`"),Q.push("- Other types: `/<entity-type>/<entity-id>.md`");return Q.join(`
4661
- `)}}aA();class KwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:x_A,jobTypeName:"directory-export"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,B,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}aA();class FwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:y_A,jobTypeName:"directory-import"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,B,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}aA();class ZwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:v_A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let Y=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let U=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(U*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class NwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:T_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),w6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function w6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class zwA extends ZB{context;constructor(A,Q,B){super(A,{schema:HwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=HwA.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}),await B.report({progress:0,total:1,message:`Deleting ${w.entityType}:${w.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:w.entityType,id:w.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:w.entityId,entityType:w.entityType});else this.logger.warn("Entity not found in database",{entityId:w.entityId,entityType:w.entityType});return await B.report({progress:1,total:1,message:`Deleted ${w.entityType}:${w.entityId}`}),{deleted:$,entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:w.entityId,entityType:w.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}aA();WA();var $6Q=H.object({});class qwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:$6Q,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,B){await B.report({progress:0,message:"Removing orphaned entities"});let w=await this.directorySync.removeOrphanedEntities();return await B.report({progress:100,message:`Cleanup complete: ${w.deleted} orphans removed`}),w}}aA();E7();WA();H6();E7();import{readFile as f6Q,writeFile as I6Q}from"fs/promises";var D6Q=S_A;class LwA extends ZB{context;fetcher;constructor(A,Q,B=WY){super(Q,{schema:D6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let Y;try{Y=await f6Q(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:T0(L)}),$5.failure(L)}let U;try{U=jB(Y)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:T0(L)}),$5.failure(L)}let J=U.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:zQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:zQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(y){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:T0(y)}),$5.failure(y)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let{base64:V}=RN(L),M=YV(V),O=bN(V);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),$5.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:L,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:zQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=bG(Z,U.content);try{await I6Q(w,N,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:T0(L)}),$5.failure(L)}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:T0(Y)}),$5.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();E7();WA();H6();import{readFile as Y6Q,writeFile as U6Q}from"fs/promises";class VwA extends ZB{converter;constructor(A,Q,B=WY){super(Q,{schema:g_A,jobTypeName:"inline-image-convert"});this.converter=new Xl(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let f;try{f=await Y6Q(w,"utf-8")}catch(Y){let U=T0(Y);return this.logger.error("Failed to read file",{filePath:w,error:U}),{success:!1,error:U}}await this.reportProgress(B,{progress:zQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:zQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:zQ.SAVE,message:"Writing updated file"});try{await U6Q(w,D.content,"utf-8")}catch(Y){let U=T0(Y);return this.logger.error("Failed to write file",{filePath:w,error:U}),{success:!1,error:U}}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=T0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function w51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new ZwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new KwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new FwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new zwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new qwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new LwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new VwA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as J6Q,access as X6Q}from"fs/promises";function $51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:Y}=I.payload;try{let U=await f.getEntity({entityType:D,id:Y});if(!U)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(U),B.debug("Auto-exported updated entity",{id:U.id,entityType:U.entityType})}catch(U){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:Y}=I.payload,U=Q.fileOps.getFilePath(D,Y);if(await X6Q(U).then(()=>!0,()=>!1))await J6Q(U),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:U});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function f51(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:J$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as Y51,mkdir as H6Q,copyFile as G6Q}from"fs/promises";import{join as D51,resolve as h_A}from"path";import{join as W6Q}from"path";async function I51(A){if(!await X5(W6Q(A,".git")))return!1;try{return await mJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function K6Q(A,Q){if(!await X5(A))return!0;if((await Y51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await I51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function U51(A,Q){let B=await Y51(A,{withFileTypes:!0});for(let w of B){let $=D51(A,w.name),f=D51(Q,w.name);if(w.isDirectory()){if(!await X5(f))await H6Q(f,{recursive:!0});await U51($,f)}else await G6Q($,f)}}async function J51(A,Q,B){let w=h_A(process.cwd(),A);B=B?h_A(B):h_A(process.cwd(),"seed-content");let $=await K6Q(w,Q);if($&&await X5(B))Q.debug("Copying seed content to brain-data directory"),await U51(B,w),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function X51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await J51(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let U=await $.pull();if(U.files.length>0)w.info("Pulled changes from remote",{filesChanged:U.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!1,error:T0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(jL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function W51(A,Q,B,w){let $=new GL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(Y)}return()=>{$.dispose();for(let D of I)D()}}function H51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:U,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(U.length>0)$.info("Periodic sync: pulled changes",{filesChanged:U.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(U){$.error("Periodic git sync failed",{error:U})}finally{I=!1}},Y=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as K51}from"child_process";import{cpSync as F6Q,existsSync as G51,mkdirSync as Z6Q,mkdtempSync as N6Q,rmSync as z6Q}from"fs";import{tmpdir as q6Q}from"os";import{fileURLToPath as L6Q}from"url";import{join as V6Q,resolve as E6Q}from"path";function Yz(A,Q){let B=K51("git",Q,{cwd:A,stdio:"pipe"});if(B.status!==0){let w=B.stderr.toString().trim(),$=B.stdout.toString().trim();throw Error(w||$||`git ${Q.join(" ")} failed`)}}function M6Q(A){return A.startsWith("file://")}function C6Q(A){return L6Q(A)}function O6Q(A,Q){return K51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function F51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!M6Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=C6Q(A.gitUrl),w=E6Q(A.seedContentPath);if(!G51(w))throw Error(`Seed content path not found: ${w}`);if(!G51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),Z6Q(B,{recursive:!0}),Yz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(O6Q(B,Q)){A.logger.debug("Content remote already initialized",{remotePath:B,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:B,seedPath:w,branch:Q});let $=N6Q(V6Q(q6Q(),"directory-sync-seed-"));try{Yz($,["init",`--initial-branch=${Q}`]),Yz($,["config","user.name",A.authorName??"Brain"]),Yz($,["config","user.email",A.authorEmail??"brain@localhost"]),F6Q(w,$,{recursive:!0}),Yz($,["add","."]),Yz($,["commit","-m","seed content remote"]),Yz($,["remote","add","origin",A.gitUrl]),Yz($,["push","-u","origin",Q])}finally{z6Q($,{recursive:!0,force:!0})}}function Z51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),Y=I.payload.paths,U=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:U}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function N51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return Y8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return Y8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return Y8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return X$($ instanceof Error?$.message:"History lookup failed")}})}function z51(A,Q,B,w){let $=[oQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,Y={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:Y.interfaceType,channelId:Y.channelId},toolContext:I});return Y8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: pulling from git and scanning files")}let U=await A.queueSyncBatch(Q,D,Y);if(!U)return Y8({gitPulled:!1},"No files to sync");return Y8({batchId:U.batchId,importOperations:U.importOperationsCount,totalFiles:U.totalFiles,gitPulled:!1},`Sync started: ${U.importOperationsCount} import jobs queued for ${U.totalFiles} files`)}catch(D){return X$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return Y8(I)}catch(f){return X$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(N51(B,w));return $}var q51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.121",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class m_A extends UB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",q51,A,Ml)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:Cl,basePrompt:"",formatter:new GwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new Wl({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if($51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)f51(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await F51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new __A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new NwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(W51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(H51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)X51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Z51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return z51(A,this.getContext(),this.id,this.gitSync)}async onShutdown(){for(let A of this.gitCleanups)A();this.gitCleanups=[],this.directorySync?.stopWatching(),this.gitSync?.cleanup()}getDirectorySync(){return this.directorySync}async configure(A){this.requireDirectorySync();let Q=this.getContext();this.directorySync=new Wl({...this.config,syncPath:A.syncPath,entityService:Q.entityService,logger:Q.logger}),await this.directorySync.initialize(),this.logger.info("Directory sync reconfigured",{path:A.syncPath})}async registerJobHandlers(A){w51(A,this.requireDirectorySync(),this.logger)}}function WM(A={}){return new m_A(A)}aA();WA();var L51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.121",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var P6Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class V51 extends UB{fetchImpl;constructor(A={},Q={}){super("email-resend",L51,A,P6Q);this.fetchImpl=Q.fetchImpl??fetch}async onRegister(A){if(!this.config.apiKey||!this.config.from){this.logger.warn("Email Resend adapter is disabled because apiKey or from is missing");return}let Q=this.logger;A.messaging.subscribe(l0A,async(B)=>{let w=jV0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function EwA(A={}){return new V51(A)}aA();import{render as yG1}from"preact-render-to-string";import{h as oM}from"preact";function E51(A){var Q,B,w="";if(typeof A=="string"||typeof A=="number")w+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(B=E51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function W_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=E51(A))&&(w&&(w+=" "),w+=Q);return w}var k6Q=(A)=>{let Q=_6Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return b51(D,Q)||j6Q(I)},getConflictingClassGroupIds:(I,D)=>{let Y=B[I]||[];if(D&&w[I])return[...Y,...w[I]];return Y}}},b51=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?b51(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},M51=/^\[(.+)\]$/,j6Q=(A)=>{if(M51.test(A)){let Q=M51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},_6Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return T6Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{c_A(I,w,f,Q)}),w},c_A=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:C51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(v6Q($)){c_A($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{c_A(I,C51(Q,f),B,w)})})},C51=(A,Q)=>{let B=A;return Q.split("-").forEach((w)=>{if(!B.nextPart.has(w))B.nextPart.set(w,{nextPart:new Map,validators:[]});B=B.nextPart.get(w)}),B},v6Q=(A)=>A.isThemeGetter,T6Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},y6Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var x6Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let Y=[],U=0,J=0,X;for(let V=0;V<D.length;V++){let M=D[V];if(U===0){if(M===$&&(w||D.slice(V,V+f)===Q)){Y.push(D.slice(J,V)),J=V+f;continue}if(M==="/"){X=V;continue}}if(M==="[")U++;else if(M==="]")U--}let G=Y.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,L=X&&X>J?X-J:void 0;return{modifiers:Y,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},S6Q=(A)=>{if(A.length<=1)return A;let Q=[],B=[];return A.forEach((w)=>{if(w[0]==="[")Q.push(...B.sort(),w),B=[];else B.push(w)}),Q.push(...B.sort()),Q},g6Q=(A)=>({cache:y6Q(A.cacheSize),parseClassName:x6Q(A),...k6Q(A)}),h6Q=/\s+/,m6Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(h6Q),D="";for(let Y=I.length-1;Y>=0;Y-=1){let U=I[Y],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(U),N=Boolean(Z),L=w(N?G.substring(0,Z):G);if(!L){if(!N){D=U+(D.length>0?" "+D:D);continue}if(L=w(G),!L){D=U+(D.length>0?" "+D:D);continue}N=!1}let V=S6Q(J).join(":"),M=X?V+"!":V,O=M+L;if(f.includes(O))continue;f.push(O);let E=$(L,N);for(let S=0;S<E.length;++S){let y=E[S];f.push(M+y)}D=U+(D.length>0?" "+D:D)}return D};function u6Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=P51(Q))w&&(w+=" "),w+=B}return w}var P51=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=P51(A[w]))B&&(B+=" "),B+=Q}return B};function O51(A,...Q){let B,w,$,f=I;function I(Y){let U=Q.reduce((J,X)=>X(J),A());return B=g6Q(U),w=B.cache.get,$=B.cache.set,f=D,D(Y)}function D(Y){let U=w(Y);if(U)return U;let J=m6Q(Y,B);return $(Y,J),J}return function(){return f(u6Q.apply(null,arguments))}}var y8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},k51=/^\[(?:([a-z-]+):)?(.+)\]$/i,c6Q=/^\d+\/\d+$/,l6Q=new Set(["px","full","screen"]),p6Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,i6Q=/\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$/,r6Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,d6Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,n6Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,UF=(A)=>H_(A)||l6Q.has(A)||c6Q.test(A),Uz=(A)=>G_(A,"length",B5Q),H_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),u_A=(A)=>G_(A,"number",H_),Ol=(A)=>Boolean(A)&&Number.isInteger(Number(A)),o6Q=(A)=>A.endsWith("%")&&H_(A.slice(0,-1)),rQ=(A)=>k51.test(A),Jz=(A)=>p6Q.test(A),s6Q=new Set(["length","size","percentage"]),a6Q=(A)=>G_(A,s6Q,j51),t6Q=(A)=>G_(A,"position",j51),e6Q=new Set(["image","url"]),A5Q=(A)=>G_(A,e6Q,$5Q),Q5Q=(A)=>G_(A,"",w5Q),Rl=()=>!0,G_=(A,Q,B)=>{let w=k51.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},B5Q=(A)=>i6Q.test(A)&&!r6Q.test(A),j51=()=>!1,w5Q=(A)=>d6Q.test(A),$5Q=(A)=>n6Q.test(A);var R51=()=>{let A=y8("colors"),Q=y8("spacing"),B=y8("blur"),w=y8("brightness"),$=y8("borderColor"),f=y8("borderRadius"),I=y8("borderSpacing"),D=y8("borderWidth"),Y=y8("contrast"),U=y8("grayscale"),J=y8("hueRotate"),X=y8("invert"),G=y8("gap"),Z=y8("gradientColorStops"),N=y8("gradientColorStopPositions"),L=y8("inset"),V=y8("margin"),M=y8("opacity"),O=y8("padding"),E=y8("saturate"),S=y8("scale"),y=y8("sepia"),T=y8("skew"),_=y8("space"),x=y8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",UF,Uz],j=()=>["auto",H_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[H_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Rl],spacing:[UF,Uz],blur:["none","",Jz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Jz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[o6Q,Uz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Jz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"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"],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:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[L]}],"inset-x":[{"inset-x":[L]}],"inset-y":[{"inset-y":[L]}],start:[{start:[L]}],end:[{end:[L]}],top:[{top:[L]}],right:[{right:[L]}],bottom:[{bottom:[L]}],left:[{left:[L]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",Ol,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Ol,rQ]}],"grid-cols":[{"grid-cols":[Rl]}],"col-start-end":[{col:["auto",{span:["full",Ol,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Rl]}],"row-start-end":[{row:["auto",{span:[Ol,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[V]}],mx:[{mx:[V]}],my:[{my:[V]}],ms:[{ms:[V]}],me:[{me:[V]}],mt:[{mt:[V]}],mr:[{mr:[V]}],mb:[{mb:[V]}],ml:[{ml:[V]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Jz]},Jz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Jz,Uz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",u_A]}],"font-family":[{font:[Rl]}],"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:["tighter","tight","normal","wide","wider","widest",rQ]}],"line-clamp":[{"line-clamp":["none",H_,u_A]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",UF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",UF,Uz]}],"underline-offset":[{"underline-offset":["auto",UF,rQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),t6Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",a6Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},A5Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[M]}],"divide-style":[{divide:P()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...P()]}],"outline-offset":[{"outline-offset":[UF,rQ]}],"outline-w":[{outline:[UF,Uz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[UF,Uz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Jz,Q5Q]}],"shadow-color":[{shadow:[Rl]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[Y]}],"drop-shadow":[{"drop-shadow":["","none",Jz,rQ]}],grayscale:[{grayscale:[U]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[y]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[U]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[y]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[Ol,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],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",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"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",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[UF,Uz,u_A]}],stroke:[{stroke:[A,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["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-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},f5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{bl(A,"cacheSize",Q),bl(A,"prefix",B),bl(A,"separator",w),bl(A,"experimentalParseClassName",$);for(let D in I)I5Q(A[D],I[D]);for(let D in f)D5Q(A[D],f[D]);return A},bl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},I5Q=(A,Q)=>{if(Q)for(let B in Q)bl(A,B,Q[B])},D5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},MwA=(A,...Q)=>typeof A==="function"?O51(R51,A,...Q):O51(()=>f5Q(R51(),A),...Q);var Y5Q=MwA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function B2(...A){return Y5Q(W_(A))}var _51=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,v51=W_,rw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return v51(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((U)=>{let J=B===null||B===void 0?void 0:B[U],X=f===null||f===void 0?void 0:f[U];if(J===null)return null;let G=_51(J)||_51(X);return $[U][G]}),D=B&&Object.entries(B).reduce((U,J)=>{let[X,G]=J;if(G===void 0)return U;return U[X]=G,U},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((U,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[L,V]=N;return Array.isArray(V)?V.includes({...f,...D}[L]):{...f,...D}[L]===V})?[...U,X,G]:U},[]);return v51(A,I,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as l_A}from"preact/jsx-dev-runtime";var T51=rw("p-4 rounded-lg border",{variants:{variant:{warning:"bg-warning border-warning text-warning",error:"bg-error border-error text-error",success:"bg-success border-success text-success",info:"bg-info border-info text-info"}},defaultVariants:{variant:"info"}});function p_A({variant:A,title:Q,children:B,className:w}){return l_A("div",{className:B2(T51({variant:A}),w),role:"alert",children:[Q&&l_A("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),l_A("div",{className:B2(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as U5Q}from"preact/jsx-dev-runtime";var y51=rw("inline-flex items-center justify-center font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",{variants:{variant:{default:"bg-brand hover:bg-brand-dark text-theme-inverse",secondary:"bg-theme-muted hover:bg-theme-subtle text-theme border border-theme",ghost:"hover:bg-theme-subtle text-theme"},size:{sm:"h-8 px-3 text-sm rounded-md",md:"h-10 px-4 py-2 text-sm rounded-lg",lg:"h-12 px-6 text-base rounded-lg"}},defaultVariants:{variant:"default",size:"md"}});function HM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return U5Q("button",{type:f,className:B2(y51({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as J5Q}from"preact/jsx-dev-runtime";var x51=rw("inline-flex items-center justify-center font-semibold transition-all text-center",{variants:{variant:{primary:"bg-brand text-theme-inverse hover:bg-brand-dark focus:ring-brand/20 focus:outline-none focus:ring-4",accent:"bg-accent text-theme-inverse hover:bg-accent-dark focus:ring-accent/20 focus:outline-none focus:ring-4",secondary:"bg-theme-muted text-theme hover:bg-theme-muted-dark focus:outline-none focus:ring-4",outline:"border-2 border-brand text-brand hover:bg-brand hover:text-theme-inverse focus:ring-brand/20 focus:outline-none focus:ring-4","outline-light":"border-2 border-theme-light text-theme-inverse hover:bg-theme-inverse hover:text-brand hover:border-theme-inverse focus:outline-none focus:ring-4",unstyled:""},size:{icon:"w-10 h-10 rounded-full",sm:"px-3 py-1.5 text-sm rounded-lg",md:"px-4 py-2 text-sm rounded-lg",lg:"px-6 py-3 text-base rounded-xl",xl:"px-8 py-4 text-lg rounded-xl","2xl":"px-10 py-5 text-lg rounded-2xl"}},defaultVariants:{size:"md"}});function L$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return J5Q("a",{href:A,className:B2(x51({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as CwA}from"preact/jsx-dev-runtime";var S51=rw("transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2",{variants:{variant:{default:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent hover:border-brand/40",light:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent",dark:"rounded-[10px] bg-theme-dark hover:bg-theme-muted text-theme-inverse",footer:"rounded-full bg-theme-toggle hover:bg-theme-toggle-hover text-theme-toggle-icon"},size:{sm:"p-1.5",md:"p-2",lg:"p-3"}},defaultVariants:{variant:"default",size:"md"}}),X5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function K_({variant:A,size:Q,className:B}){let w=X5Q[Q??"md"];return CwA("button",{onclick:"toggleTheme()",type:"button",className:B2(S51({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:CwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[CwA("path",{className:"sun-icon",strokeLinecap:"round",strokeLinejoin:"round",d:"M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"},void 0,!1,void 0,this),CwA("path",{className:"moon-icon",strokeLinecap:"round",strokeLinejoin:"round",d:"M20.354 15.354A9 9 0 018.646 3.646 9 9 0 1020.354 15.354z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{jsxDEV as i_A}from"preact/jsx-dev-runtime";var g51=rw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function OwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return i_A("ul",{className:B2(g51({orientation:w}),Q),children:[f.map((I)=>i_A("li",{children:i_A("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as IOw}from"preact/jsx-dev-runtime";import{jsxDEV as UOw}from"preact/jsx-dev-runtime";import{createContext as W5Q,h as H5Q}from"preact";import{useContext as G5Q}from"preact/hooks";var r_A=W5Q(null);function F_({headCollector:A,children:Q}){return H5Q(r_A.Provider,{value:A},Q)}function h51(){return G5Q(r_A)}function KQ(A){let Q=h51();if(Q)Q.setHeadProps(A);return null}import{createContext as lIQ,h as pIQ}from"preact";import{useContext as iIQ}from"preact/hooks";AzA();var o41=Y1(n41(),1),uIQ=new fh({gfm:!0,breaks:!0}),cIQ={allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","ul","ol","li","blockquote","cite","code","pre","em","strong","del","ins","sub","sup","a","img","span","table","thead","tbody","tr","th","td","div"],allowedAttributes:{a:["href","title","name"],img:["src","srcset","sizes","alt","title","width","height","class","loading","decoding"],code:["class"],pre:["class"],span:["class"],cite:["class"],div:["class"],th:["align","colspan","rowspan","scope"],td:["align","colspan","rowspan"]},allowedSchemes:["http","https","mailto","tel"],allowedSchemesByTag:{img:["http","https","entity"]},allowProtocolRelative:!1,disallowedTagsMode:"discard"};function KTA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new fh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):uIQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
4661
+ `)}}aA();class KwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:x_A,jobTypeName:"directory-export"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory export job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.exportEntitiesWithProgress(A.entityTypes,B,A.batchSize??100);return this.logger.debug("Directory export job completed",{jobId:Q,exported:$.exported,failed:$.failed,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory export job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{entityTypes:A.entityTypes??"all",batchSize:A.batchSize}}}aA();class FwA extends ZB{directorySync;constructor(A,Q,B){super(A,{schema:y_A,jobTypeName:"directory-import"});this.directorySync=B}async process(A,Q,B){this.logger.debug("Processing directory import job",{jobId:Q,data:A});let w=Date.now();try{let $=await this.directorySync.importEntitiesWithProgress(A.paths,B,A.batchSize??100);return this.logger.debug("Directory import job completed",{jobId:Q,imported:$.imported,skipped:$.skipped,failed:$.failed,quarantined:$.quarantined,duration:Date.now()-w}),$}catch($){throw this.logger.error("Directory import job failed",{jobId:Q,error:$}),$}}summarizeDataForLog(A){return{pathCount:A.paths?.length??"all",batchSize:A.batchSize}}}aA();class ZwA extends ZB{directorySync;context;constructor(A,Q,B){super(A,{schema:v_A,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let Y=(await Promise.all(A.map((J)=>B.getAsyncJobStatus(J)))).filter((J)=>J&&(J.status==="completed"||J.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let U=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(U*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((J)=>setTimeout(J,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}aA();class NwA extends ZB{context;directorySync;gitSync;constructor(A,Q,B,w){super(A,{schema:T_A,jobTypeName:"sync-request"});this.context=Q;this.directorySync=B;this.gitSync=w}async process(A,Q,B){await B.report({progress:5,message:"Pulling latest content from git"});let w=await this.gitSync.withLock(async()=>{return await this.gitSync.pull(),await B.report({progress:35,message:"Scanning pulled content for sync changes"}),this.directorySync.queueSyncBatch(this.context,A.source,{rootJobId:Q,interfaceType:A.interfaceType,channelId:A.channelId})});if(!w)return await B.report({progress:100,message:"Sync complete: no files to import"}),{gitPulled:!0,batchQueued:!1};return await B.report({progress:100,message:`Sync queued: ${w.importOperationsCount} import jobs for ${w.totalFiles} files`}),w6Q(w)}summarizeDataForLog(A){return{source:A.source,interfaceType:A.interfaceType,channelId:A.channelId}}}function w6Q(A){return{gitPulled:!0,batchQueued:!0,batchId:A.batchId,importOperations:A.importOperationsCount,totalFiles:A.totalFiles}}aA();class zwA extends ZB{context;constructor(A,Q,B){super(A,{schema:HwA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=HwA.parse(A);this.logger.info("Processing entity deletion for removed file",{entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}),await B.report({progress:0,total:1,message:`Deleting ${w.entityType}:${w.entityId}`});try{let $=await this.context.entityService.deleteEntity({entityType:w.entityType,id:w.entityId});if($)this.logger.info("Successfully deleted entity for removed file",{entityId:w.entityId,entityType:w.entityType});else this.logger.warn("Entity not found in database",{entityId:w.entityId,entityType:w.entityType});return await B.report({progress:1,total:1,message:`Deleted ${w.entityType}:${w.entityId}`}),{deleted:$,entityId:w.entityId,entityType:w.entityType,filePath:w.filePath}}catch($){throw this.logger.error("Failed to delete entity",{entityId:w.entityId,entityType:w.entityType,error:$}),$}}summarizeDataForLog(A){return{entityId:A.entityId,entityType:A.entityType,filePath:A.filePath}}}aA();WA();var $6Q=H.object({});class qwA extends ZB{directorySync;constructor(A,Q){super(A,{schema:$6Q,jobTypeName:"directory-cleanup"});this.directorySync=Q}async process(A,Q,B){await B.report({progress:0,message:"Removing orphaned entities"});let w=await this.directorySync.removeOrphanedEntities();return await B.report({progress:100,message:`Cleanup complete: ${w.deleted} orphans removed`}),w}}aA();E7();WA();H6();E7();import{readFile as f6Q,writeFile as I6Q}from"fs/promises";var D6Q=S_A;class LwA extends ZB{context;fetcher;constructor(A,Q,B=WY){super(Q,{schema:D6Q,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let Y;try{Y=await f6Q(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:T0(L)}),$5.failure(L)}let U;try{U=jB(Y)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:T0(L)}),$5.failure(L)}let J=U.frontmatter;if(J.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:zQ.FETCH,message:"Checking for existing image"});let X=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),G;if(X[0])G=X[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:G}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Reusing existing image: ${G}`});else{await this.reportProgress(B,{progress:zQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(y){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:T0(y)}),$5.failure(y)}await this.reportProgress(B,{progress:zQ.GENERATE,message:"Creating image entity"});let{base64:V}=RN(L),M=YV(V),O=bN(V);if(!M||!O)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),$5.failure(Error("Could not detect image format or dimensions"));G=`${I}-cover`;let E=`Cover image for ${f}`,S=D??E;await this.context.entityService.createEntity({entity:{id:G,entityType:"image",content:L,metadata:{title:E,alt:S,format:M,width:O.width,height:O.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:G,sourceUrl:$}),await this.reportProgress(B,{progress:zQ.EXTRACT,message:`Created image: ${G}`})}await this.reportProgress(B,{progress:zQ.SAVE,message:"Updating file"});let Z={...J};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=G;let N=bG(Z,U.content);try{await I6Q(w,N,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:T0(L)}),$5.failure(L)}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:G,sourceUrl:$}),{success:!0,imageId:G}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:T0(Y)}),$5.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}aA();E7();WA();H6();import{readFile as Y6Q,writeFile as U6Q}from"fs/promises";class VwA extends ZB{converter;constructor(A,Q,B=WY){super(Q,{schema:g_A,jobTypeName:"inline-image-convert"});this.converter=new Xl(A.entityService,Q,B)}async process(A,Q,B){let{filePath:w,postSlug:$}=A;this.logger.debug("Starting inline image conversion job",{jobId:Q,filePath:w,postSlug:$});try{await this.reportProgress(B,{progress:zQ.INIT,message:`Reading file: ${w}`});let f;try{f=await Y6Q(w,"utf-8")}catch(Y){let U=T0(Y);return this.logger.error("Failed to read file",{filePath:w,error:U}),{success:!1,error:U}}await this.reportProgress(B,{progress:zQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images to convert"}),{success:!0,skipped:!0,convertedCount:0};this.logger.debug("Found inline images to convert",{filePath:w,count:I.length}),await this.reportProgress(B,{progress:zQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:zQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:zQ.SAVE,message:"Writing updated file"});try{await U6Q(w,D.content,"utf-8")}catch(Y){let U=T0(Y);return this.logger.error("Failed to write file",{filePath:w,error:U}),{success:!1,error:U}}return await this.reportProgress(B,{progress:zQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=T0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function w51(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new ZwA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new KwA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new FwA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new zwA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new qwA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new LwA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new VwA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}aA();import{unlink as J6Q,access as X6Q}from"fs/promises";function $51(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:Y}=I.payload;try{let U=await f.getEntity({entityType:D,id:Y});if(!U)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(U),B.debug("Auto-exported updated entity",{id:U.id,entityType:U.entityType})}catch(U){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:U instanceof Error?U.message:String(U),stack:U instanceof Error?U.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:Y}=I.payload,U=Q.fileOps.getFilePath(D,Y);if(await X6Q(U).then(()=>!0,()=>!1))await J6Q(U),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:U});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function f51(A,Q,B){Q.setJobQueueCallback(async(w)=>{let $=[{type:w.type,data:w.data}];return A.jobs.enqueueBatch($,{priority:5,source:"directory-sync-watcher",rootJobId:J$(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}WA();aA();import{readdir as Y51,mkdir as H6Q,copyFile as G6Q}from"fs/promises";import{join as D51,resolve as h_A}from"path";import{join as W6Q}from"path";async function I51(A){if(!await X5(W6Q(A,".git")))return!1;try{return await mJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function K6Q(A,Q){if(!await X5(A))return!0;if((await Y51(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await I51(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function U51(A,Q){let B=await Y51(A,{withFileTypes:!0});for(let w of B){let $=D51(A,w.name),f=D51(Q,w.name);if(w.isDirectory()){if(!await X5(f))await H6Q(f,{recursive:!0});await U51($,f)}else await G6Q($,f)}}async function J51(A,Q,B){let w=h_A(process.cwd(),A);B=B?h_A(B):h_A(process.cwd(),"seed-content");let $=await K6Q(w,Q);if($&&await X5(B))Q.debug("Copying seed content to brain-data directory"),await U51(B,w),Q.debug("Seed content copied successfully");else if($)Q.debug("No seed content directory found, starting with empty brain-data");else Q.debug("brain-data directory not empty, skipping seed content")}function X51(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await J51(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let U=await $.pull();if(U.files.length>0)w.info("Pulled changes from remote",{filesChanged:U.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:jL.initialSyncCompleted,payload:{success:!1,error:T0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(jL.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}WA();function W51(A,Q,B,w){let $=new GL(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(Y)}return()=>{$.dispose();for(let D of I)D()}}function H51(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:U,result:J}=await A.withLock(async()=>{let X=await A.pull();if(X.files.length===0)return{files:[],result:null};let G=await Q.queueSyncBatch(B,"periodic-sync");return{files:X.files,result:G}});if(U.length>0)$.info("Periodic sync: pulled changes",{filesChanged:U.length});if(J)$.debug("Periodic sync: queued imports",{importOperations:J.importOperationsCount,totalFiles:J.totalFiles})}catch(U){$.error("Periodic git sync failed",{error:U})}finally{I=!1}},Y=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as K51}from"child_process";import{cpSync as F6Q,existsSync as G51,mkdirSync as Z6Q,mkdtempSync as N6Q,rmSync as z6Q}from"fs";import{tmpdir as q6Q}from"os";import{fileURLToPath as L6Q}from"url";import{join as V6Q,resolve as E6Q}from"path";function Yz(A,Q){let B=K51("git",Q,{cwd:A,stdio:"pipe"});if(B.status!==0){let w=B.stderr.toString().trim(),$=B.stdout.toString().trim();throw Error(w||$||`git ${Q.join(" ")} failed`)}}function M6Q(A){return A.startsWith("file://")}function C6Q(A){return L6Q(A)}function O6Q(A,Q){return K51("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function F51(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!M6Q(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=C6Q(A.gitUrl),w=E6Q(A.seedContentPath);if(!G51(w))throw Error(`Seed content path not found: ${w}`);if(!G51(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),Z6Q(B,{recursive:!0}),Yz(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(O6Q(B,Q)){A.logger.debug("Content remote already initialized",{remotePath:B,branch:Q});return}A.logger.debug("Seeding local content remote",{remotePath:B,seedPath:w,branch:Q});let $=N6Q(V6Q(q6Q(),"directory-sync-seed-"));try{Yz($,["init",`--initial-branch=${Q}`]),Yz($,["config","user.name",A.authorName??"Brain"]),Yz($,["config","user.email",A.authorEmail??"brain@localhost"]),F6Q(w,$,{recursive:!0}),Yz($,["add","."]),Yz($,["commit","-m","seed content remote"]),Yz($,["remote","add","origin",A.gitUrl]),Yz($,["push","-u","origin",Q])}finally{z6Q($,{recursive:!0,force:!0})}}function Z51(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),Y=I.payload.paths,U=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:U}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}aA();WA();aA();WA();function N51(A,Q){return oQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",H.object({entityType:H.string().describe("Entity type (e.g. post, note, link)"),id:H.string().describe("Entity ID"),sha:H.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:H.number().int().positive().optional().default(10).describe("Max commits to return (list mode only)")}),async(B)=>{let w=`${B.entityType}/${B.id}.md`;try{if(B.sha){let f=await Q.show(B.sha,w);return Y8({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return Y8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return Y8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return X$($ instanceof Error?$.message:"History lookup failed")}})}function z51(A,Q,B,w){let $=[oQ(B,"sync","Sync brain entities with the filesystem. Use this for refresh, pull, sync, or backup-to-git requests. Pulls from git if configured, then imports files. Git commit and push happen automatically after imports complete.",H.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,Y={interfaceType:I.interfaceType,channelId:I.channelId};if(w){let J=await Q.jobs.enqueue({type:"sync-request",data:{source:D,interfaceType:Y.interfaceType,channelId:Y.channelId},toolContext:I});return Y8({jobId:J,status:"queued",gitPulled:!0},"Sync queued: pulling from git and scanning files")}let U=await A.queueSyncBatch(Q,D,Y);if(!U)return Y8({gitPulled:!1},"No files to sync");return Y8({batchId:U.batchId,importOperations:U.importOperationsCount,totalFiles:U.totalFiles,gitPulled:!1},`Sync started: ${U.importOperationsCount} import jobs queued for ${U.totalFiles} files`)}catch(D){return X$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),oQ(B,"status","Get sync and git repository status \u2014 last sync time, watching state, pending git changes. Use this for status questions, not for actually syncing or backing up.",H.object({}),async()=>{try{let f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return Y8(I)}catch(f){return X$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(N51(B,w));return $}var q51={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.122",description:"Directory-based entity synchronization plugin for Brains",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":{types:"./src/index.ts",import:"./src/index.ts"}},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",clean:"rm -rf .turbo"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",chokidar:"^3.5.3","simple-git":"^3.21.0"},devDependencies:{"@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class m_A extends UB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",q51,A,Ml)}requireDirectorySync(){if(!this.directorySync)throw Error("DirectorySync service not initialized");return this.directorySync}hasGitSync(){return this.gitSync!==void 0}async onRegister(A){let{logger:Q,entityService:B}=A;A.templates.register({status:{name:"status",description:"Directory synchronization status",schema:Cl,basePrompt:"",formatter:new GwA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new Wl({syncPath:w,autoSync:this.config.autoSync,watchInterval:this.config.watchInterval,includeMetadata:this.config.includeMetadata,entityTypes:this.config.entityTypes,deleteOnFileRemoval:this.config.deleteOnFileRemoval,entityService:B,logger:Q});try{await this.directorySync.initializeDirectory(),this.logger.debug("Directory structure initialized",{path:w})}catch(I){throw this.logger.error("Failed to initialize directory",I),I}await this.registerJobHandlers(A);let $=this.requireDirectorySync();if($51(A,$,this.logger,this.config.entityTypes),this.config.autoSync)f51(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await F51({gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,seedContentPath:this.config.seedContentPath,bootstrapFromSeed:this.config.git.bootstrapFromSeed,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail,logger:this.logger.child("ContentRemoteBootstrap")});let I=this.config.syncPath??A.dataDir;if(this.gitSync=new __A({logger:this.logger.child("GitSync"),dataDir:I,repo:this.config.git.repo,gitUrl:this.config.git.gitUrl,branch:this.config.git.branch,authToken:this.config.git.authToken,authorName:this.config.git.authorName,authorEmail:this.config.git.authorEmail}),await this.gitSync.initialize(),this.logger.info("Git integration enabled",{repo:this.config.git.repo}),A.jobs.registerHandler("sync-request",new NwA(this.logger.child("DirectorySyncRequestJobHandler"),A,this.requireDirectorySync(),this.gitSync)),this.gitCleanups.push(W51(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(H51(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)X51(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Z51(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return z51(A,this.getContext(),this.id,this.gitSync)}async onShutdown(){for(let A of this.gitCleanups)A();this.gitCleanups=[],this.directorySync?.stopWatching(),this.gitSync?.cleanup()}getDirectorySync(){return this.directorySync}async configure(A){this.requireDirectorySync();let Q=this.getContext();this.directorySync=new Wl({...this.config,syncPath:A.syncPath,entityService:Q.entityService,logger:Q.logger}),await this.directorySync.initialize(),this.logger.info("Directory sync reconfigured",{path:A.syncPath})}async registerJobHandlers(A){w51(A,this.requireDirectorySync(),this.logger)}}function WM(A={}){return new m_A(A)}aA();WA();var L51={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.122",description:"Generic email delivery adapter for Resend",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/email-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var P6Q=H.object({apiKey:H.string().min(1).optional(),from:H.string().min(1).optional()});class V51 extends UB{fetchImpl;constructor(A={},Q={}){super("email-resend",L51,A,P6Q);this.fetchImpl=Q.fetchImpl??fetch}async onRegister(A){if(!this.config.apiKey||!this.config.from){this.logger.warn("Email Resend adapter is disabled because apiKey or from is missing");return}let Q=this.logger;A.messaging.subscribe(l0A,async(B)=>{let w=jV0.parse(B.payload);try{return{success:!0,data:await this.sendWithResend(w)}}catch($){if(w.sensitivity==="secret")Q.warn("Email delivery failed for a secret message");else Q.warn("Email delivery failed",{to:w.to,subject:w.subject,error:$ instanceof Error?$.message:String($)});return{success:!1,error:"Email delivery failed"}}})}async sendWithResend(A){let Q=this.config.apiKey,B=this.config.from;if(!Q||!B)return{status:"failed"};let w=await this.fetchImpl("https://api.resend.com/emails",{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},body:JSON.stringify({from:B,to:A.to,subject:A.subject,text:A.text,...A.html?{html:A.html}:{}})});if(!w.ok)throw Error("Resend email request failed");let $=await w.json();return $.id?{status:"sent",id:$.id}:{status:"sent"}}}function EwA(A={}){return new V51(A)}aA();import{render as yG1}from"preact-render-to-string";import{h as oM}from"preact";function E51(A){var Q,B,w="";if(typeof A=="string"||typeof A=="number")w+=A;else if(typeof A=="object")if(Array.isArray(A)){var $=A.length;for(Q=0;Q<$;Q++)A[Q]&&(B=E51(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function W_(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=E51(A))&&(w&&(w+=" "),w+=Q);return w}var k6Q=(A)=>{let Q=_6Q(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return b51(D,Q)||j6Q(I)},getConflictingClassGroupIds:(I,D)=>{let Y=B[I]||[];if(D&&w[I])return[...Y,...w[I]];return Y}}},b51=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?b51(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},M51=/^\[(.+)\]$/,j6Q=(A)=>{if(M51.test(A)){let Q=M51.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},_6Q=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return T6Q(Object.entries(A.classGroups),B).forEach(([f,I])=>{c_A(I,w,f,Q)}),w},c_A=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:C51(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(v6Q($)){c_A($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{c_A(I,C51(Q,f),B,w)})})},C51=(A,Q)=>{let B=A;return Q.split("-").forEach((w)=>{if(!B.nextPart.has(w))B.nextPart.set(w,{nextPart:new Map,validators:[]});B=B.nextPart.get(w)}),B},v6Q=(A)=>A.isThemeGetter,T6Q=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},y6Q=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var x6Q=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let Y=[],U=0,J=0,X;for(let V=0;V<D.length;V++){let M=D[V];if(U===0){if(M===$&&(w||D.slice(V,V+f)===Q)){Y.push(D.slice(J,V)),J=V+f;continue}if(M==="/"){X=V;continue}}if(M==="[")U++;else if(M==="]")U--}let G=Y.length===0?D:D.substring(J),Z=G.startsWith("!"),N=Z?G.substring(1):G,L=X&&X>J?X-J:void 0;return{modifiers:Y,hasImportantModifier:Z,baseClassName:N,maybePostfixModifierPosition:L}};if(B)return(D)=>B({className:D,parseClassName:I});return I},S6Q=(A)=>{if(A.length<=1)return A;let Q=[],B=[];return A.forEach((w)=>{if(w[0]==="[")Q.push(...B.sort(),w),B=[];else B.push(w)}),Q.push(...B.sort()),Q},g6Q=(A)=>({cache:y6Q(A.cacheSize),parseClassName:x6Q(A),...k6Q(A)}),h6Q=/\s+/,m6Q=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(h6Q),D="";for(let Y=I.length-1;Y>=0;Y-=1){let U=I[Y],{modifiers:J,hasImportantModifier:X,baseClassName:G,maybePostfixModifierPosition:Z}=B(U),N=Boolean(Z),L=w(N?G.substring(0,Z):G);if(!L){if(!N){D=U+(D.length>0?" "+D:D);continue}if(L=w(G),!L){D=U+(D.length>0?" "+D:D);continue}N=!1}let V=S6Q(J).join(":"),M=X?V+"!":V,O=M+L;if(f.includes(O))continue;f.push(O);let E=$(L,N);for(let S=0;S<E.length;++S){let y=E[S];f.push(M+y)}D=U+(D.length>0?" "+D:D)}return D};function u6Q(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=P51(Q))w&&(w+=" "),w+=B}return w}var P51=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=P51(A[w]))B&&(B+=" "),B+=Q}return B};function O51(A,...Q){let B,w,$,f=I;function I(Y){let U=Q.reduce((J,X)=>X(J),A());return B=g6Q(U),w=B.cache.get,$=B.cache.set,f=D,D(Y)}function D(Y){let U=w(Y);if(U)return U;let J=m6Q(Y,B);return $(Y,J),J}return function(){return f(u6Q.apply(null,arguments))}}var y8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},k51=/^\[(?:([a-z-]+):)?(.+)\]$/i,c6Q=/^\d+\/\d+$/,l6Q=new Set(["px","full","screen"]),p6Q=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,i6Q=/\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$/,r6Q=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,d6Q=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,n6Q=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,UF=(A)=>H_(A)||l6Q.has(A)||c6Q.test(A),Uz=(A)=>G_(A,"length",B5Q),H_=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),u_A=(A)=>G_(A,"number",H_),Ol=(A)=>Boolean(A)&&Number.isInteger(Number(A)),o6Q=(A)=>A.endsWith("%")&&H_(A.slice(0,-1)),rQ=(A)=>k51.test(A),Jz=(A)=>p6Q.test(A),s6Q=new Set(["length","size","percentage"]),a6Q=(A)=>G_(A,s6Q,j51),t6Q=(A)=>G_(A,"position",j51),e6Q=new Set(["image","url"]),A5Q=(A)=>G_(A,e6Q,$5Q),Q5Q=(A)=>G_(A,"",w5Q),Rl=()=>!0,G_=(A,Q,B)=>{let w=k51.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},B5Q=(A)=>i6Q.test(A)&&!r6Q.test(A),j51=()=>!1,w5Q=(A)=>d6Q.test(A),$5Q=(A)=>n6Q.test(A);var R51=()=>{let A=y8("colors"),Q=y8("spacing"),B=y8("blur"),w=y8("brightness"),$=y8("borderColor"),f=y8("borderRadius"),I=y8("borderSpacing"),D=y8("borderWidth"),Y=y8("contrast"),U=y8("grayscale"),J=y8("hueRotate"),X=y8("invert"),G=y8("gap"),Z=y8("gradientColorStops"),N=y8("gradientColorStopPositions"),L=y8("inset"),V=y8("margin"),M=y8("opacity"),O=y8("padding"),E=y8("saturate"),S=y8("scale"),y=y8("sepia"),T=y8("skew"),_=y8("space"),x=y8("translate"),g=()=>["auto","contain","none"],n=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",rQ,Q],BA=()=>[rQ,Q],a=()=>["",UF,Uz],j=()=>["auto",H_,rQ],R=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],P=()=>["solid","dashed","dotted","double","none"],c=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],l=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",rQ],s=()=>["auto","avoid","all","avoid-page","page","left","right","column"],XA=()=>[H_,rQ];return{cacheSize:500,separator:":",theme:{colors:[Rl],spacing:[UF,Uz],blur:["none","",Jz,rQ],brightness:XA(),borderColor:[A],borderRadius:["none","","full",Jz,rQ],borderSpacing:BA(),borderWidth:a(),contrast:XA(),grayscale:e(),hueRotate:XA(),invert:e(),gap:BA(),gradientColorStops:[A],gradientColorStopPositions:[o6Q,Uz],inset:m(),margin:m(),opacity:XA(),padding:BA(),saturate:XA(),scale:XA(),sepia:e(),skew:XA(),space:BA(),translate:BA()},classGroups:{aspect:[{aspect:["auto","square","video",rQ]}],container:["container"],columns:[{columns:[Jz]}],"break-after":[{"break-after":s()}],"break-before":[{"break-before":s()}],"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"],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:[...R(),rQ]}],overflow:[{overflow:n()}],"overflow-x":[{"overflow-x":n()}],"overflow-y":[{"overflow-y":n()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[L]}],"inset-x":[{"inset-x":[L]}],"inset-y":[{"inset-y":[L]}],start:[{start:[L]}],end:[{end:[L]}],top:[{top:[L]}],right:[{right:[L]}],bottom:[{bottom:[L]}],left:[{left:[L]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",Ol,rQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",rQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",Ol,rQ]}],"grid-cols":[{"grid-cols":[Rl]}],"col-start-end":[{col:["auto",{span:["full",Ol,rQ]},rQ]}],"col-start":[{"col-start":j()}],"col-end":[{"col-end":j()}],"grid-rows":[{"grid-rows":[Rl]}],"row-start-end":[{row:["auto",{span:[Ol,rQ]},rQ]}],"row-start":[{"row-start":j()}],"row-end":[{"row-end":j()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",rQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",rQ]}],gap:[{gap:[G]}],"gap-x":[{"gap-x":[G]}],"gap-y":[{"gap-y":[G]}],"justify-content":[{justify:["normal",...l()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...l(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...l(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[O]}],px:[{px:[O]}],py:[{py:[O]}],ps:[{ps:[O]}],pe:[{pe:[O]}],pt:[{pt:[O]}],pr:[{pr:[O]}],pb:[{pb:[O]}],pl:[{pl:[O]}],m:[{m:[V]}],mx:[{mx:[V]}],my:[{my:[V]}],ms:[{ms:[V]}],me:[{me:[V]}],mt:[{mt:[V]}],mr:[{mr:[V]}],mb:[{mb:[V]}],ml:[{ml:[V]}],"space-x":[{"space-x":[_]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[_]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",rQ,Q]}],"min-w":[{"min-w":[rQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[rQ,Q,"none","full","min","max","fit","prose",{screen:[Jz]},Jz]}],h:[{h:[rQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[rQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[rQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",Jz,Uz]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",u_A]}],"font-family":[{font:[Rl]}],"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:["tighter","tight","normal","wide","wider","widest",rQ]}],"line-clamp":[{"line-clamp":["none",H_,u_A]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",UF,rQ]}],"list-image":[{"list-image":["none",rQ]}],"list-style-type":[{list:["none","disc","decimal",rQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[M]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[M]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...P(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",UF,Uz]}],"underline-offset":[{"underline-offset":["auto",UF,rQ]}],"text-decoration-color":[{decoration:[A]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:BA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",rQ]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",rQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[M]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...R(),t6Q]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",a6Q]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},A5Q]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[N]}],"gradient-via-pos":[{via:[N]}],"gradient-to-pos":[{to:[N]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[M]}],"border-style":[{border:[...P(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[M]}],"divide-style":[{divide:P()}],"border-color":[{border:[$]}],"border-color-x":[{"border-x":[$]}],"border-color-y":[{"border-y":[$]}],"border-color-s":[{"border-s":[$]}],"border-color-e":[{"border-e":[$]}],"border-color-t":[{"border-t":[$]}],"border-color-r":[{"border-r":[$]}],"border-color-b":[{"border-b":[$]}],"border-color-l":[{"border-l":[$]}],"divide-color":[{divide:[$]}],"outline-style":[{outline:["",...P()]}],"outline-offset":[{"outline-offset":[UF,rQ]}],"outline-w":[{outline:[UF,Uz]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:a()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[M]}],"ring-offset-w":[{"ring-offset":[UF,Uz]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",Jz,Q5Q]}],"shadow-color":[{shadow:[Rl]}],opacity:[{opacity:[M]}],"mix-blend":[{"mix-blend":[...c(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":c()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[Y]}],"drop-shadow":[{"drop-shadow":["","none",Jz,rQ]}],grayscale:[{grayscale:[U]}],"hue-rotate":[{"hue-rotate":[J]}],invert:[{invert:[X]}],saturate:[{saturate:[E]}],sepia:[{sepia:[y]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[U]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[J]}],"backdrop-invert":[{"backdrop-invert":[X]}],"backdrop-opacity":[{"backdrop-opacity":[M]}],"backdrop-saturate":[{"backdrop-saturate":[E]}],"backdrop-sepia":[{"backdrop-sepia":[y]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[I]}],"border-spacing-x":[{"border-spacing-x":[I]}],"border-spacing-y":[{"border-spacing-y":[I]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",rQ]}],duration:[{duration:XA()}],ease:[{ease:["linear","in","out","in-out",rQ]}],delay:[{delay:XA()}],animate:[{animate:["none","spin","ping","pulse","bounce",rQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[S]}],"scale-x":[{"scale-x":[S]}],"scale-y":[{"scale-y":[S]}],rotate:[{rotate:[Ol,rQ]}],"translate-x":[{"translate-x":[x]}],"translate-y":[{"translate-y":[x]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",rQ]}],accent:[{accent:["auto",A]}],appearance:[{appearance:["none","auto"]}],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",rQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":BA()}],"scroll-mx":[{"scroll-mx":BA()}],"scroll-my":[{"scroll-my":BA()}],"scroll-ms":[{"scroll-ms":BA()}],"scroll-me":[{"scroll-me":BA()}],"scroll-mt":[{"scroll-mt":BA()}],"scroll-mr":[{"scroll-mr":BA()}],"scroll-mb":[{"scroll-mb":BA()}],"scroll-ml":[{"scroll-ml":BA()}],"scroll-p":[{"scroll-p":BA()}],"scroll-px":[{"scroll-px":BA()}],"scroll-py":[{"scroll-py":BA()}],"scroll-ps":[{"scroll-ps":BA()}],"scroll-pe":[{"scroll-pe":BA()}],"scroll-pt":[{"scroll-pt":BA()}],"scroll-pr":[{"scroll-pr":BA()}],"scroll-pb":[{"scroll-pb":BA()}],"scroll-pl":[{"scroll-pl":BA()}],"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",rQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[UF,Uz,u_A]}],stroke:[{stroke:[A,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["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-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},f5Q=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{bl(A,"cacheSize",Q),bl(A,"prefix",B),bl(A,"separator",w),bl(A,"experimentalParseClassName",$);for(let D in I)I5Q(A[D],I[D]);for(let D in f)D5Q(A[D],f[D]);return A},bl=(A,Q,B)=>{if(B!==void 0)A[Q]=B},I5Q=(A,Q)=>{if(Q)for(let B in Q)bl(A,B,Q[B])},D5Q=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},MwA=(A,...Q)=>typeof A==="function"?O51(R51,A,...Q):O51(()=>f5Q(R51(),A),...Q);var Y5Q=MwA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function B2(...A){return Y5Q(W_(A))}var _51=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,v51=W_,rw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return v51(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((U)=>{let J=B===null||B===void 0?void 0:B[U],X=f===null||f===void 0?void 0:f[U];if(J===null)return null;let G=_51(J)||_51(X);return $[U][G]}),D=B&&Object.entries(B).reduce((U,J)=>{let[X,G]=J;if(G===void 0)return U;return U[X]=G,U},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((U,J)=>{let{class:X,className:G,...Z}=J;return Object.entries(Z).every((N)=>{let[L,V]=N;return Array.isArray(V)?V.includes({...f,...D}[L]):{...f,...D}[L]===V})?[...U,X,G]:U},[]);return v51(A,I,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as l_A}from"preact/jsx-dev-runtime";var T51=rw("p-4 rounded-lg border",{variants:{variant:{warning:"bg-warning border-warning text-warning",error:"bg-error border-error text-error",success:"bg-success border-success text-success",info:"bg-info border-info text-info"}},defaultVariants:{variant:"info"}});function p_A({variant:A,title:Q,children:B,className:w}){return l_A("div",{className:B2(T51({variant:A}),w),role:"alert",children:[Q&&l_A("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),l_A("div",{className:B2(Q&&"mt-1","text-sm text-current opacity-75"),children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{jsxDEV as U5Q}from"preact/jsx-dev-runtime";var y51=rw("inline-flex items-center justify-center font-bold transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed",{variants:{variant:{default:"bg-brand hover:bg-brand-dark text-theme-inverse",secondary:"bg-theme-muted hover:bg-theme-subtle text-theme border border-theme",ghost:"hover:bg-theme-subtle text-theme"},size:{sm:"h-8 px-3 text-sm rounded-md",md:"h-10 px-4 py-2 text-sm rounded-lg",lg:"h-12 px-6 text-base rounded-lg"}},defaultVariants:{variant:"default",size:"md"}});function HM({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return U5Q("button",{type:f,className:B2(y51({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as J5Q}from"preact/jsx-dev-runtime";var x51=rw("inline-flex items-center justify-center font-semibold transition-all text-center",{variants:{variant:{primary:"bg-brand text-theme-inverse hover:bg-brand-dark focus:ring-brand/20 focus:outline-none focus:ring-4",accent:"bg-accent text-theme-inverse hover:bg-accent-dark focus:ring-accent/20 focus:outline-none focus:ring-4",secondary:"bg-theme-muted text-theme hover:bg-theme-muted-dark focus:outline-none focus:ring-4",outline:"border-2 border-brand text-brand hover:bg-brand hover:text-theme-inverse focus:ring-brand/20 focus:outline-none focus:ring-4","outline-light":"border-2 border-theme-light text-theme-inverse hover:bg-theme-inverse hover:text-brand hover:border-theme-inverse focus:outline-none focus:ring-4",unstyled:""},size:{icon:"w-10 h-10 rounded-full",sm:"px-3 py-1.5 text-sm rounded-lg",md:"px-4 py-2 text-sm rounded-lg",lg:"px-6 py-3 text-base rounded-xl",xl:"px-8 py-4 text-lg rounded-xl","2xl":"px-10 py-5 text-lg rounded-2xl"}},defaultVariants:{size:"md"}});function L$({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return J5Q("a",{href:A,className:B2(x51({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as CwA}from"preact/jsx-dev-runtime";var S51=rw("transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2",{variants:{variant:{default:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent hover:border-brand/40",light:"rounded-[10px] bg-theme-subtle border border-theme text-theme-muted hover:text-accent",dark:"rounded-[10px] bg-theme-dark hover:bg-theme-muted text-theme-inverse",footer:"rounded-full bg-theme-toggle hover:bg-theme-toggle-hover text-theme-toggle-icon"},size:{sm:"p-1.5",md:"p-2",lg:"p-3"}},defaultVariants:{variant:"default",size:"md"}}),X5Q={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function K_({variant:A,size:Q,className:B}){let w=X5Q[Q??"md"];return CwA("button",{onclick:"toggleTheme()",type:"button",className:B2(S51({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:CwA("svg",{className:B2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[CwA("path",{className:"sun-icon",strokeLinecap:"round",strokeLinejoin:"round",d:"M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"},void 0,!1,void 0,this),CwA("path",{className:"moon-icon",strokeLinecap:"round",strokeLinejoin:"round",d:"M20.354 15.354A9 9 0 018.646 3.646 9 9 0 1020.354 15.354z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}import{jsxDEV as i_A}from"preact/jsx-dev-runtime";var g51=rw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function OwA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return i_A("ul",{className:B2(g51({orientation:w}),Q),children:[f.map((I)=>i_A("li",{children:i_A("a",{href:I.href,className:B,children:I.label},void 0,!1,void 0,this)},I.href,!1,void 0,this)),$]},void 0,!0,void 0,this)}import{jsxDEV as IOw}from"preact/jsx-dev-runtime";import{jsxDEV as UOw}from"preact/jsx-dev-runtime";import{createContext as W5Q,h as H5Q}from"preact";import{useContext as G5Q}from"preact/hooks";var r_A=W5Q(null);function F_({headCollector:A,children:Q}){return H5Q(r_A.Provider,{value:A},Q)}function h51(){return G5Q(r_A)}function KQ(A){let Q=h51();if(Q)Q.setHeadProps(A);return null}import{createContext as lIQ,h as pIQ}from"preact";import{useContext as iIQ}from"preact/hooks";AzA();var o41=Y1(n41(),1),uIQ=new fh({gfm:!0,breaks:!0}),cIQ={allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","ul","ol","li","blockquote","cite","code","pre","em","strong","del","ins","sub","sup","a","img","span","table","thead","tbody","tr","th","td","div"],allowedAttributes:{a:["href","title","name"],img:["src","srcset","sizes","alt","title","width","height","class","loading","decoding"],code:["class"],pre:["class"],span:["class"],cite:["class"],div:["class"],th:["align","colspan","rowspan","scope"],td:["align","colspan","rowspan"]},allowedSchemes:["http","https","mailto","tel"],allowedSchemesByTag:{img:["http","https","entity"]},allowProtocolRelative:!1,disallowedTagsMode:"discard"};function KTA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new fh({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):uIQ).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
4662
4662
  <cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),o41.default($,cIQ)}var s41=lIQ(null);function v_({imageRenderer:A,children:Q}){return pIQ(s41.Provider,{value:A??null},Q)}function a41(){return iIQ(s41)}function NF(){let A=a41();return(Q)=>KTA(Q,A?{imageRenderer:A}:void 0)}var rIQ=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,dIQ={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"},nIQ=/&(?:amp|lt|gt|quot|#39);/g;function oIQ(A){return A.replace(nIQ,(Q)=>dIQ[Q]??Q)}function FTA(A){return A.replace(rIQ,(Q,B)=>{return`<div class="mermaid">${oIQ(B)}</div>`})}var t41=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function e41(A){let Q={};for(let w of A.matchAll(t41)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],Y=I[2];if(D&&Y!==void 0)Q[D]=Y}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let I of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let D=I[1];if(D)Q[D]="true"}}let B=A.replace(t41,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
4663
4663
 
4664
4664
  `).trim();return{attributes:Q,markdown:B}}var sIQ=/<!--\s*\.break\s*-->/;function Af1(A){let Q=A.split(sIQ);return Q.length>1?Q:null}import{jsxDEV as YH}from"preact/jsx-dev-runtime";var ZTA=({markdown:A,deck:Q})=>{let B=NF(),$=A.split(/^---$/gm).map((J)=>J.trim()).map((J)=>{let{attributes:X,markdown:G}=e41(J),Z=Af1(G),N;if(Z)N=`<div class="slide-columns">${Z.map((V)=>`<div class="slide-column">${FTA(B(V.trim()))}</div>`).join("")}</div>`;else N=FTA(B(G));return{attributes:X,htmlContent:N}}),f=$.some((J)=>J.htmlContent.includes('class="mermaid"')),I=Q?.frontmatter?.title??Q?.metadata?.title,D=Q?.frontmatter?.description??Q?.metadata?.description,Y=Q?.ogImageUrl??Q?.coverImageUrl,U=$.map(({attributes:J,htmlContent:X},G)=>YH("section",{...J,dangerouslySetInnerHTML:{__html:X}},G,!1,void 0,this));return YH("section",{className:"presentation-section",children:[I&&YH(KQ,{title:I,...D?{description:D}:{},...Y?{ogImage:Y}:{},ogType:"article"},void 0,!1,void 0,this),YH("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),YH("div",{className:"reveal",children:YH("div",{className:"slides",children:U},void 0,!1,void 0,this)},void 0,!1,void 0,this),YH("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),f&&YH("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),YH("script",{dangerouslySetInnerHTML:{__html:`
@@ -5645,13 +5645,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
5645
5645
  `+$:B,I=qH(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await d9.readFile(I,"utf-8"),Y=w.length>0?w:Q;if(Y.length>0){let U=Y.join(`
5646
5646
  `)+`
5647
5647
 
5648
- `+D;await d9.writeFile(I,U,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=qH(process.cwd(),"public");try{await d9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=qH(A,B.name),$=qH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=qH(this.outputDir,$);await d9.mkdir(ALQ(f),{recursive:!0}),await d9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d9.mkdir(Q,{recursive:!0});let B=await d9.readdir(A,{withFileTypes:!0});for(let w of B){let $=qH(A,w.name),f=qH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await d9.copyFile($,f)}}}function sxA(A){return new xG1(A)}f5();WA();WA();f5();var SG1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:LI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Ugw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function gG1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function hG1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}f5();E7();f5();WA();var QLQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),BLQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function B5A(A,Q){let B=Q.urlGenerator??K7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>B5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>B5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let y=$[S];if(y)w[y[0]]=f[S]}let I=QLQ.safeParse(A);if(!I.success)return w;let D=I.data,Y=D.entityType,U=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[Y],X=J?J.label:Y.charAt(0).toUpperCase()+Y.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":zI(Y),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),L=Hg(D),V=await wLQ(L,Q),M=Ct(D)??L,O=await $LQ(M,Q);return{...w,...D,url:B.generateUrl(Y,U),typeLabel:X,listUrl:Z,listLabel:N,...V,...O&&{ogImageUrl:O}}}async function wLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await uG1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function $LQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return mG1(B.src,Q.siteUrl);let w=await uG1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return mG1(w.url,Q.siteUrl)}function mG1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function uG1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=BLQ.safeParse(B);if(!w.success)return;return{url:w.data.content,...w.data.metadata.width&&{width:w.data.metadata.width},...w.data.metadata.height&&{height:w.data.metadata.height}}}async function cG1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Hg(I);if(D)B.add(D);let Y=Ct(I);if(Y)B.add(Y)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:T0(w)})}return[...B]}async function lG1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return B5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:K7.getInstance()})}function pG1(A){return{routes:A.routes,siteConfig:{title:A.siteMetadata.title,description:A.siteMetadata.description,...A.siteMetadata.url&&{url:A.siteMetadata.url},...A.siteMetadata.copyright&&{copyright:A.siteMetadata.copyright},...A.siteMetadata.themeMode&&{themeMode:A.siteMetadata.themeMode},...A.siteMetadata.analyticsScript&&{analyticsScript:A.siteMetadata.analyticsScript}},headScripts:A.buildOptions.headScripts,...A.buildOptions.staticAssets&&{staticAssets:A.buildOptions.staticAssets},getContent:async(Q,B)=>{let w=A.parsedOptions.environment==="production";return lG1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return hG1(A.siteMetadata,A.pipelineContext.profileService,A.pipelineContext.routeRegistry)},...A.parsedOptions.themeCSS!==void 0&&{themeCSS:A.parsedOptions.themeCSS},...A.buildOptions.slots&&{slots:A.buildOptions.slots},imageBuildService:A.imageBuildService}}import{join as fLQ}from"path";async function iG1(A){let Q=A.parsedOptions.workingDir??fLQ(A.parsedOptions.outputDir,".preact-work"),B=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await B.clean();return B}async function rG1(A){await new A5A({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay,{visibilityScope:"public",...A.publishedOnly!==void 0&&{publishedOnly:A.publishedOnly}}).generateEntityRoutes()}async function dG1(A){let Q=new e6A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await cG1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function nG1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function oG1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function sG1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function aG1(A){let Q=SG1.parse(A.buildOptions),B=M9.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await rG1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await iG1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=gG1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await dG1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=pG1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await nG1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),oG1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),sG1({outputDir:Q.outputDir,errorMessage:f.message})}}class GD{static instance=null;static defaultStaticSiteBuilderFactory=sxA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){GD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return GD.instance??=new GD(A,GD.defaultStaticSiteBuilderFactory,Q,B,w,$),GD.instance}static resetInstance(){GD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new GD(A,$??GD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,K7.getInstance().configure(f)}async build(A,Q){return aG1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class axA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new GL(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["base"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}f5();function ILQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function w5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?ILQ(w.sections,Q):[]})}function tG1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Ho.parse(w.payload),{routes:f,pluginId:I}=$;return w5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Go.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Ko.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=Fo.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as eG1}from"fs";import{join as AK1}from"path";async function DLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=nxA(w,A.environment);await eG1.writeFile(AK1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=oxA($,w);await eG1.writeFile(AK1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function QK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await DLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();f5();var BK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:LI.optional()});f5();f5();async function ap(A,Q){try{let B=await A({type:$x,payload:void 0});if("success"in B&&B.success&&B.data){let w=LI.safeParse(B.data);if(w.success)return LI.parse({...Q,...w.data})}}catch{}return Q}class txA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:BK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await ap(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:Y},generateEntityUrl:(U,J)=>K7.getInstance().generateUrl(U,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();f5();var YLQ=H.object({slot:H.enum(NL).optional().default("primary"),limit:H.number().optional()});class exA{routeRegistry;logger;id="site:navigation";name="Site Navigation DataSource";description="Provides navigation items for site menus";constructor(A,Q){this.routeRegistry=A;this.logger=Q;this.logger.debug("NavigationDataSource initialized")}async fetch(A,Q,B){let w=YLQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}f5();aA();WA();var ULQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function wK1(A,Q){return[oQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",ULQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();f5();var $K1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:LI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(zL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(NL).optional().describe("Navigation slot (primary or secondary)"),priority:H.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:H.record(H.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var fK1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.121",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class ASA extends UB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",fK1,{...A,layouts:Q},$K1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new Q5A(A.logger),this._slotRegistry=new T6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new exA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=H4.getInstance(A.entityService,A.logger),tG1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)w5A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=GD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new txA(this.logger.child("SiteBuildJobHandler"),A.messaging.send,{siteBuilder:this.siteBuilder,layouts:this.layouts,defaultSiteConfig:this.config.siteInfo,sharedImagesDir:this.config.sharedImagesDir,siteUrl:A.siteUrl,previewUrl:A.previewUrl,themeCSS:this.config.themeCSS,slots:this._slotRegistry,getHeadScripts:()=>this.getRegisteredHeadScripts(),...this.config.staticAssets&&{staticAssets:this.config.staticAssets}})),this.rebuildManager=new axA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(fx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),QK1({context:A,routeRegistry:this._routeRegistry,logger:this.logger})}getRegisteredHeadScripts(){return Array.from(this.headScripts.values())}async getTools(){if(!this.pluginContext||!this.rebuildManager)throw Error("Plugin context not initialized");let A=this.rebuildManager;return wK1(this.id,(Q)=>A.requestBuild(Q))}async getResources(){let A=this.getContext();return[{uri:"brain://site",name:"Site Metadata",description:"Site metadata \u2014 title, description, domain, URLs",mimeType:"application/json",handler:async()=>{let Q=await ap(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await ap(A.messaging.send,this.config.siteInfo);return`## Your Site
5648
+ `+D;await d9.writeFile(I,U,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=qH(process.cwd(),"public");try{await d9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await d9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=qH(A,B.name),$=qH(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await d9.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=qH(this.outputDir,$);await d9.mkdir(ALQ(f),{recursive:!0}),await d9.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await d9.mkdir(Q,{recursive:!0});let B=await d9.readdir(A,{withFileTypes:!0});for(let w of B){let $=qH(A,w.name),f=qH(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await d9.copyFile($,f)}}}function sxA(A){return new xG1(A)}f5();WA();WA();f5();var SG1=H.object({environment:H.enum(["preview","production"]),outputDir:H.string(),workingDir:H.string().optional(),sharedImagesDir:H.string().default("./dist/images"),enableContentGeneration:H.boolean().default(!1),cleanBeforeBuild:H.boolean().default(!0),siteConfig:LI,layouts:H.record(H.any()),themeCSS:H.string().optional()}),Ugw=H.object({success:H.boolean(),outputDir:H.string(),filesGenerated:H.number(),routesBuilt:H.number(),errors:H.array(H.string()).optional(),warnings:H.array(H.string()).optional()});function gG1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function hG1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}f5();E7();f5();WA();var QLQ=H.object({id:H.string(),entityType:H.string(),content:H.string(),metadata:H.object({slug:H.string()}).passthrough()}).passthrough(),BLQ=H.object({content:H.string(),metadata:H.object({width:H.number().optional(),height:H.number().optional()}).passthrough()});async function B5A(A,Q){let B=Q.urlGenerator??K7.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((S)=>B5A(S,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,S])=>B5A(S,{...Q,urlGenerator:B})));for(let S=0;S<$.length;S++){let y=$[S];if(y)w[y[0]]=f[S]}let I=QLQ.safeParse(A);if(!I.success)return w;let D=I.data,Y=D.entityType,U=D.metadata.slug,J=Q.pipelineContext.entityDisplay?.[Y],X=J?J.label:Y.charAt(0).toUpperCase()+Y.slice(1),G=J?J.pluralName??J.label.toLowerCase()+"s":zI(Y),Z=`/${G}`,N=G.charAt(0).toUpperCase()+G.slice(1),L=Hg(D),V=await wLQ(L,Q),M=Ct(D)??L,O=await $LQ(M,Q);return{...w,...D,url:B.generateUrl(Y,U),typeLabel:X,listUrl:Z,listLabel:N,...V,...O&&{ogImageUrl:O}}}async function wLQ(A,Q){let B=A?Q.imageBuildService?.get(A):void 0;if(B)return{coverImageUrl:B.src,coverImageWidth:B.width,coverImageHeight:B.height,...B.srcset&&{coverImageSrcset:B.srcset,coverImageSizes:B.sizes}};let w=await uG1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function $LQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return mG1(B.src,Q.siteUrl);let w=await uG1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return mG1(w.url,Q.siteUrl)}function mG1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function uG1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=BLQ.safeParse(B);if(!w.success)return;return{url:w.data.content,...w.data.metadata.width&&{width:w.data.metadata.width},...w.data.metadata.height&&{height:w.data.metadata.height}}}async function cG1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=Hg(I);if(D)B.add(D);let Y=Ct(I);if(Y)B.add(Y)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:T0(w)})}return[...B]}async function lG1(A,Q,B,w,$){if(!A.template)return A.content??null;let f=A.template,I=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B,visibilityScope:w}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content,visibilityScope:w},D=await $.pipelineContext.services.resolveTemplateContent(f,I);if(!D)return null;return B5A(D,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:K7.getInstance()})}function pG1(A){return{routes:A.routes,siteConfig:{title:A.siteMetadata.title,description:A.siteMetadata.description,...A.siteMetadata.url&&{url:A.siteMetadata.url},...A.siteMetadata.copyright&&{copyright:A.siteMetadata.copyright},...A.siteMetadata.themeMode&&{themeMode:A.siteMetadata.themeMode},...A.siteMetadata.analyticsScript&&{analyticsScript:A.siteMetadata.analyticsScript}},headScripts:A.buildOptions.headScripts,...A.buildOptions.staticAssets&&{staticAssets:A.buildOptions.staticAssets},getContent:async(Q,B)=>{let w=A.parsedOptions.environment==="production";return lG1(B,Q,w,"public",{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService,siteUrl:A.siteMetadata.url})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return hG1(A.siteMetadata,A.pipelineContext.profileService,A.pipelineContext.routeRegistry)},...A.parsedOptions.themeCSS!==void 0&&{themeCSS:A.parsedOptions.themeCSS},...A.buildOptions.slots&&{slots:A.buildOptions.slots},imageBuildService:A.imageBuildService}}import{join as fLQ}from"path";async function iG1(A){let Q=A.parsedOptions.workingDir??fLQ(A.parsedOptions.outputDir,".preact-work"),B=A.staticSiteBuilderFactory({logger:A.logger.child("StaticSiteBuilder"),workingDir:Q,outputDir:A.parsedOptions.outputDir});if(A.parsedOptions.cleanBeforeBuild)await B.clean();return B}async function rG1(A){await new A5A({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay,{visibilityScope:"public",...A.publishedOnly!==void 0&&{publishedOnly:A.publishedOnly}}).generateEntityRoutes()}async function dG1(A){let Q=new e6A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await cG1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function nG1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function oG1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function sG1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function aG1(A){let Q=SG1.parse(A.buildOptions),B=M9.from(A.progress),w=[];try{await B?.report({message:"Starting site build",progress:0,total:100}),await B?.report({message:"Generating dynamic routes",progress:10,total:100}),await rG1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await iG1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=gG1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await dG1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=pG1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await nG1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),oG1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),sG1({outputDir:Q.outputDir,errorMessage:f.message})}}class GD{static instance=null;static defaultStaticSiteBuilderFactory=sxA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){GD.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return GD.instance??=new GD(A,GD.defaultStaticSiteBuilderFactory,Q,B,w,$),GD.instance}static resetInstance(){GD.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new GD(A,$??GD.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,K7.getInstance().configure(f)}async build(A,Q){return aG1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}WA();class axA{config;context;pluginId;logger;debounces=new Map;unsubscribeFunctions=[];constructor(A,Q,B,w){this.config=A;this.context=Q;this.pluginId=B;this.logger=w}requestBuild(A){let Q=A??(this.config.previewOutputDir?"preview":"production"),B=this.debounces.get(Q);if(!B)B=new GL(()=>{this.enqueueBuild(Q)},this.config.rebuildDebounce),this.debounces.set(Q,B);B.trigger()}setupAutoRebuild(){let A=new Set(["base"]),Q=async(w)=>{let{entityType:$}=w.payload;if(!A.has($))this.logger.debug(`Entity type ${$} will trigger rebuild`),this.requestBuild();return{success:!0}},B=["entity:created","entity:updated","entity:deleted"];for(let w of B)this.unsubscribeFunctions.push(this.context.messaging.subscribe(w,Q));this.logger.debug(`Auto-rebuild enabled (${this.config.rebuildDebounce}ms debounce), excluding types: ${[...A].join(", ")}`)}dispose(){for(let A of this.debounces.values())A.dispose();this.debounces.clear();for(let A of this.unsubscribeFunctions)A();this.unsubscribeFunctions=[]}async enqueueBuild(A){let Q=A==="production"?this.config.productionOutputDir:this.config.previewOutputDir;this.logger.debug(`Triggering ${A} site rebuild`);try{await this.context.jobs.enqueue({type:"site-build",data:{environment:A,outputDir:Q,workingDir:this.config.workingDir,enableContentGeneration:!0,metadata:{trigger:"debounced-rebuild",timestamp:new Date().toISOString()}},options:{priority:0,source:this.pluginId,metadata:{operationType:"content_operations"},deduplication:"skip"}}),this.logger.debug("Site rebuild enqueued")}catch(B){this.logger.error("Failed to enqueue site rebuild",{error:B})}}}f5();function ILQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function w5A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?ILQ(w.sections,Q):[]})}function tG1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Ho.parse(w.payload),{routes:f,pluginId:I}=$;return w5A(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Go.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=Ko.parse(w.payload);return{success:!0,data:{routes:Q.list($.pluginId?$:void 0)}}}catch($){return B.error("Failed to list routes",{error:$}),{success:!1,error:"Failed to list routes"}}}),A.messaging.subscribe("plugin:site-builder:route:get",async(w)=>{try{let $=Fo.parse(w.payload);return{success:!0,data:{route:Q.get($.path)}}}catch($){return B.error("Failed to get route",{error:$}),{success:!1,error:"Failed to get route"}}}),A.messaging.subscribe("site-builder:routes:list",async()=>{return{success:!0,data:Q.list()}})}import{promises as eG1}from"fs";import{join as AK1}from"path";async function DLQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=nxA(w,A.environment);await eG1.writeFile(AK1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=oxA($,w);await eG1.writeFile(AK1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function QK1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await DLQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}aA();WA();f5();var BK1=H.object({environment:H.enum(["preview","production"]).optional(),outputDir:H.string(),workingDir:H.string().optional(),enableContentGeneration:H.boolean().optional(),siteConfig:LI.optional()});f5();f5();async function ap(A,Q){try{let B=await A({type:$x,payload:void 0});if("success"in B&&B.success&&B.data){let w=LI.safeParse(B.data);if(w.success)return LI.parse({...Q,...w.data})}}catch{}return Q}class txA extends ZB{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:BK1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await ap(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:Y},generateEntityUrl:(U,J)=>K7.getInstance().generateUrl(U,J)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}WA();f5();var YLQ=H.object({slot:H.enum(NL).optional().default("primary"),limit:H.number().optional()});class exA{routeRegistry;logger;id="site:navigation";name="Site Navigation DataSource";description="Provides navigation items for site menus";constructor(A,Q){this.routeRegistry=A;this.logger=Q;this.logger.debug("NavigationDataSource initialized")}async fetch(A,Q,B){let w=YLQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}f5();aA();WA();var ULQ=H.object({environment:H.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function wK1(A,Q){return[oQ(A,"build-site","Build a static site from registered routes. Call this for every user build/rebuild request, including repeated requests like 'build it again' or 'one more build'.",ULQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}WA();f5();var $K1=H.object({previewOutputDir:H.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:H.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:H.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:H.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:LI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:H.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:H.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:H.any().optional().describe("Template definitions to register"),routes:H.array(zL).optional().describe("Routes to register"),layouts:H.record(H.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:H.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:H.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:H.record(H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:H.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:H.boolean().optional().describe("Enable pagination for list pages"),pageSize:H.number().optional().describe("Items per page (default: 10)"),navigation:H.object({show:H.boolean().optional().describe("Show in navigation"),slot:H.enum(NL).optional().describe("Navigation slot (primary or secondary)"),priority:H.number().min(0).max(100).optional().describe("Navigation priority (0-100)")}).optional().describe("Navigation settings for this entity type")})).optional().describe("Display metadata per entity type \u2014 label, plural name, layout, pagination, navigation slot. Consulted when auto-generating routes for active entity plugins."),staticAssets:H.record(H.string()).optional().describe("Static files to write to the output directory at build time. Keys are output paths (e.g. '/canvases/tree.js'), values are file contents as strings. Typically supplied by a SitePackage via text imports.")});var fK1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.122",description:"Static site generation plugin for Brain system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint .",clean:"rm -rf dist"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*","@tailwindcss/typography":"^0.5.19",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",eslint:"^8.56.0",typescript:"^5.3.3"}};class ASA extends UB{siteBuilder;pluginContext;_routeRegistry;_slotRegistry;profileService;layouts;rebuildManager;headScripts=new Map;get routeRegistry(){if(!this._routeRegistry)throw Error("RouteRegistry not initialized - plugin not registered");return this._routeRegistry}constructor(A={}){let Q=A.layouts??{};super("site-builder",fK1,{...A,layouts:Q},$K1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new Q5A(A.logger),this._slotRegistry=new T6A,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new exA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=H4.getInstance(A.entityService,A.logger),tG1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)w5A(this.config.routes,this.id,this.routeRegistry);let Q={entityService:A.entityService,sendMessage:A.messaging.send,resolveTemplateContent:(B,w)=>A.templates.resolve(B,w),getViewTemplate:(B)=>A.views.get(B),listViewTemplateNames:()=>A.views.list().map((B)=>B.name)};if(this.siteBuilder=GD.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new txA(this.logger.child("SiteBuildJobHandler"),A.messaging.send,{siteBuilder:this.siteBuilder,layouts:this.layouts,defaultSiteConfig:this.config.siteInfo,sharedImagesDir:this.config.sharedImagesDir,siteUrl:A.siteUrl,previewUrl:A.previewUrl,themeCSS:this.config.themeCSS,slots:this._slotRegistry,getHeadScripts:()=>this.getRegisteredHeadScripts(),...this.config.staticAssets&&{staticAssets:this.config.staticAssets}})),this.rebuildManager=new axA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(fx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),QK1({context:A,routeRegistry:this._routeRegistry,logger:this.logger})}getRegisteredHeadScripts(){return Array.from(this.headScripts.values())}async getTools(){if(!this.pluginContext||!this.rebuildManager)throw Error("Plugin context not initialized");let A=this.rebuildManager;return wK1(this.id,(Q)=>A.requestBuild(Q))}async getResources(){let A=this.getContext();return[{uri:"brain://site",name:"Site Metadata",description:"Site metadata \u2014 title, description, domain, URLs",mimeType:"application/json",handler:async()=>{let Q=await ap(A.messaging.send,this.config.siteInfo);return{contents:[{uri:"brain://site",mimeType:"application/json",text:JSON.stringify({...Q,domain:A.domain,siteUrl:A.siteUrl,previewUrl:A.previewUrl},null,2)}]}}},{uri:"site://routes",name:"Site Routes",description:"All registered routes with sections and templates",mimeType:"application/json",handler:async()=>{let Q=this.routeRegistry.list();return{contents:[{uri:"site://routes",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({id:B.id,path:B.path,title:B.title,description:B.description,sections:B.sections.map((w)=>({id:w.id,template:w.template}))})),null,2)}]}}},{uri:"site://templates",name:"View Templates",description:"All registered view templates",mimeType:"application/json",handler:async()=>{let Q=A.views.list();return{contents:[{uri:"site://templates",mimeType:"application/json",text:JSON.stringify(Q.map((B)=>({name:B.name,description:B.description,hasWebRenderer:!!B.renderers.web})),null,2)}]}}}]}getSiteBuilder(){return this.siteBuilder}getSlotRegistry(){return this._slotRegistry}async getInstructions(){let A=this.getContext(),Q="## Site Builder Actions\n- When the user asks to build, rebuild, publish, or build the website/site again, call `site-builder_build-site` immediately.\n- Every repeated build request requires a fresh `site-builder_build-site` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.",B=await ap(A.messaging.send,this.config.siteInfo);return`## Your Site
5649
5649
  ${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
5650
5650
  `)}
5651
5651
 
5652
5652
  ## Site Builder Actions
5653
5653
  - When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
5654
- - Every repeated build request requires a fresh \`site-builder_build-site\` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.`}async onShutdown(){this.logger.debug("Shutting down site-builder plugin"),this.rebuildManager?.dispose(),GD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function sM(A={}){return new ASA(A)}aA();f5();WA();aA();f5();var IK1=H.object({}),tp=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:IK1}),QSA=No,Uv=LI.omit({url:!0,analyticsScript:!0});aA();class LH extends q2{constructor(){super({entityType:"site-info",schema:tp,frontmatterSchema:Uv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Uv.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class VH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return VH.instance??=new VH(A,Q,B),VH.instance}static resetInstance(){VH.instance=null}static createFresh(A,Q,B){return new VH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new LH;let w=VH.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var XLQ=new LH;class $5A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?XLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var DK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.121",description:"Site info entity \u2014 site metadata, title, description, CTA",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var HLQ=new LH;class BSA extends jQ{entityType="site-info";schema=tp;adapter=HLQ;defaultSiteInfo;constructor(A){super("site-info",DK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new $5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=VH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe($x,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(B)=>{if(B.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:fx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aM(A){return new BSA(A)}var GLQ=new LH;async function ep(A){let B=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!B)throw Error("Site info not found \u2014 create a site-info entity");return GLQ.parseSiteInfoBody(B.content)}WA();var KLQ=Uv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var YK1={lexicon:1,id:"ai.rizom.brain.card",defs:{main:{type:"record",description:"Public discovery card for a Rizom brain. The operational A2A Agent Card is conventionally served at /.well-known/agent-card.json under siteUrl.",key:"literal:self",record:{type:"object",required:["siteUrl","brain","anchor","skills","model","version","createdAt"],properties:{siteUrl:{type:"string",format:"uri",description:"Public site URL. Consumers derive the A2A Agent Card URL from this base."},brain:{type:"object",description:"Brain identity described by this discovery card.",required:["did","name","role","purpose","values"],properties:{did:{type:"string",description:"Public DID for the brain identity."},name:{type:"string",maxLength:200,description:"Human-readable brain name."},role:{type:"string",maxLength:500,description:"Brain role or persona."},purpose:{type:"string",maxLength:2000,description:"Short public description of what this brain is for."},values:{type:"array",description:"Public values or principles for this brain.",items:{type:"string",maxLength:200},maxLength:50}}},anchor:{type:"object",description:"Minimal owner/operator snapshot for discovery grouping and display.",required:["did","name","kind"],properties:{did:{type:"string",description:"Public DID for the owner/operator anchor identity."},name:{type:"string",maxLength:200,description:"Human-readable anchor name."},kind:{type:"string",knownValues:["professional","team","collective"],description:"Anchor type."}}},skills:{type:"array",description:"User-facing skills this brain advertises for discovery.",items:{type:"object",required:["id","name","description"],properties:{id:{type:"string",maxLength:200},name:{type:"string",maxLength:200},description:{type:"string",maxLength:2000},tags:{type:"array",items:{type:"string"},maxLength:50},examples:{type:"array",items:{type:"string"},maxLength:20}}},maxLength:100},model:{type:"string",description:"Rizom brain model identifier."},version:{type:"string",description:"Brain runtime/model implementation version."},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var UK1={lexicon:1,id:"ai.rizom.brain.deck",defs:{main:{type:"record",description:"Public presentation deck from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},author:{type:"string"},event:{type:"string"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var JK1={lexicon:1,id:"ai.rizom.brain.link",defs:{main:{type:"record",description:"Public curated link from a Rizom brain.",key:"any",record:{type:"object",required:["title","url","createdAt"],properties:{title:{type:"string",maxLength:500},url:{type:"string",format:"uri"},description:{type:"string",maxLength:2000},summary:{type:"string",maxLength:1e5},domain:{type:"string"},capturedAt:{type:"string",format:"datetime"},source:{type:"object",required:["ref","label"],properties:{ref:{type:"string"},label:{type:"string"}}},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var XK1={lexicon:1,id:"ai.rizom.brain.note",defs:{main:{type:"record",description:"Public knowledge note from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var WK1={lexicon:1,id:"ai.rizom.brain.post",defs:{main:{type:"record",description:"Markdown blog post distributed by a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},summary:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},canonicalUrl:{type:"string",format:"uri"},topics:{type:"array",items:{type:"string"},maxLength:50},coverImage:{type:"object",required:["blob"],properties:{blob:{type:"blob"},alt:{type:"string",maxLength:1000},width:{type:"integer"},height:{type:"integer"}}},series:{type:"string",maxLength:200},seriesIndex:{type:"integer"},sourceEntityType:{type:"string",knownValues:["post"]},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},publishedAt:{type:"string",format:"datetime"}}}}}};var HK1={lexicon:1,id:"ai.rizom.brain.project",defs:{main:{type:"record",description:"Public project or case study from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","year","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},year:{type:"integer"},url:{type:"string",format:"uri"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var GK1={lexicon:1,id:"ai.rizom.brain.series",defs:{main:{type:"record",description:"Public content series from a Rizom brain.",key:"any",record:{type:"object",required:["title","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:1e4},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var KK1={lexicon:1,id:"ai.rizom.brain.socialPost",defs:{main:{type:"record",description:"Semantic local social-post entity from a Rizom brain; not a Bluesky feed post.",key:"any",record:{type:"object",required:["title","platform","body","createdAt"],properties:{title:{type:"string",maxLength:300},platform:{type:"string"},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},status:{type:"string"},publishedAt:{type:"string",format:"datetime"},platformPostId:{type:"string"},sourceLocalEntityType:{type:"string"},sourceLocalEntityId:{type:"string"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var FK1={lexicon:1,id:"ai.rizom.brain.topic",defs:{main:{type:"record",description:"Public topic page from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var CLQ=H.object({type:H.string()}).catchall(H.unknown()),OLQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(CLQ)})})})});function EH(A){return OLQ.parse(A)}var Gw={"ai.rizom.brain.card":EH(YK1),"ai.rizom.brain.deck":EH(UK1),"ai.rizom.brain.link":EH(JK1),"ai.rizom.brain.note":EH(XK1),"ai.rizom.brain.post":EH(WK1),"ai.rizom.brain.project":EH(HK1),"ai.rizom.brain.series":EH(GK1),"ai.rizom.brain.socialPost":EH(KK1),"ai.rizom.brain.topic":EH(FK1)},RLQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function xF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:RLQ}}var bLQ={"ai.rizom.brain.card":xF("@brains/atproto"),"ai.rizom.brain.deck":xF("@brains/decks"),"ai.rizom.brain.link":xF("@brains/link"),"ai.rizom.brain.note":xF("@brains/note"),"ai.rizom.brain.post":xF("@brains/blog"),"ai.rizom.brain.project":xF("@brains/portfolio"),"ai.rizom.brain.series":xF("@brains/series"),"ai.rizom.brain.socialPost":xF("@brains/social-media"),"ai.rizom.brain.topic":xF("@brains/topics")};function tM(){return Object.values(Gw)}function fSA(A){return Gw[A]}function ISA(){return Object.entries(bLQ).map(([A,Q])=>({id:A,...Q}))}function $SA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var PLQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function kLQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>PLQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function ZK1(A){switch(A.type){case"string":return kLQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?ZK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return jLQ(A);case"blob":return H.custom($SA,{message:"expected blob"});default:return H.unknown()}}function NK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=ZK1($);B[w]=Q.has(w)?f:f.optional()}return B}function jLQ(A){return H.object(NK1(A)).passthrough()}function wSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function _LQ(A,Q){if(wSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),$SA(A.brain))wSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if($SA(A.anchor))wSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function MH(A){let Q=H.object({...NK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(_LQ):Q}var vLQ={"ai.rizom.brain.card":MH(Gw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":MH(Gw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":MH(Gw["ai.rizom.brain.link"]),"ai.rizom.brain.note":MH(Gw["ai.rizom.brain.note"]),"ai.rizom.brain.post":MH(Gw["ai.rizom.brain.post"]),"ai.rizom.brain.project":MH(Gw["ai.rizom.brain.project"]),"ai.rizom.brain.series":MH(Gw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":MH(Gw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":MH(Gw["ai.rizom.brain.topic"])};function TLQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function Tz(A,Q){let B=MH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(TLQ(A,Q,w))}var f5A="atproto:brain-card-discovered",zK1="atproto:brain-discovered",qK1="atproto:brain-card-refreshed",LK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:vLQ["ai.rizom.brain.card"]}).strict(),hmw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class d6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new d6,this.instance}static createFresh(){return new d6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}KD();Xv();WA();var DSA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();H6();var SLQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),tmw=qI.extend({title:H.string().optional(),slug:H.string().optional()});class YSA extends z7{constructor(A,Q){super(A,Q,{schema:SLQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:Y,excerpt:U}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");Y=Y??`## Introduction
5654
+ - Every repeated build request requires a fresh \`site-builder_build-site\` call. Do not say a build was started, queued, or requested unless this turn invoked the tool.`}async onShutdown(){this.logger.debug("Shutting down site-builder plugin"),this.rebuildManager?.dispose(),GD.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function sM(A={}){return new ASA(A)}aA();f5();WA();aA();f5();var IK1=H.object({}),tp=A2.extend({id:H.literal("site-info"),entityType:H.literal("site-info"),metadata:IK1}),QSA=No,Uv=LI.omit({url:!0,analyticsScript:!0});aA();class LH extends q2{constructor(){super({entityType:"site-info",schema:tp,frontmatterSchema:Uv,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Uv.parse(A);return this.buildMarkdown("",Q)}parseSiteInfoBody(A){return this.parseFrontmatter(A)}fromMarkdown(A){return{content:A,entityType:"site-info"}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseFrontmatter(A.content);return this.buildMarkdown("",Q)}}class VH{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return VH.instance??=new VH(A,Q,B),VH.instance}static resetInstance(){VH.instance=null}static createFresh(A,Q,B){return new VH(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new LH;let w=VH.getDefaultSiteInfo();this.defaultSiteInfo={...w,...B}}async initialize(){try{if(!await this.entityService.getEntity({entityType:"site-info",id:"site-info"})){if(await this.entityService.getEntity({entityType:"site-info",id:"site-info"}))return;this.logger.info("No site info found, creating default site info");let B=this.adapter.createSiteInfoContent(this.defaultSiteInfo);await this.entityService.createEntity({entity:{id:"site-info",entityType:"site-info",content:B,metadata:{}}}),this.logger.info("Default site info created successfully")}}catch(A){this.logger.error("Failed to initialize site info",{error:A})}}async getSiteInfo(){try{let A=await this.entityService.getEntity({entityType:"site-info",id:"site-info"});if(A)return this.adapter.parseSiteInfoBody(A.content)}catch(A){this.logger.debug("Site info not found, using defaults",{error:A})}return this.defaultSiteInfo}}var XLQ=new LH;class $5A{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?XLQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var DK1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.122",description:"Site info entity \u2014 site metadata, title, description, CTA",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var HLQ=new LH;class BSA extends jQ{entityType="site-info";schema=tp;adapter=HLQ;defaultSiteInfo;constructor(A){super("site-info",DK1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new $5A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=VH.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe($x,async()=>{return{success:!0,data:await Q.getSiteInfo()}}),A.messaging.subscribe("entity:updated",async(B)=>{if(B.payload.entityType==="site-info"){let $=await Q.getSiteInfo();await A.messaging.send({type:fx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function aM(A){return new BSA(A)}var GLQ=new LH;async function ep(A){let B=(await A.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!B)throw Error("Site info not found \u2014 create a site-info entity");return GLQ.parseSiteInfoBody(B.content)}WA();var KLQ=Uv.extend({navigation:H.object({primary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()})),secondary:H.array(H.object({label:H.string(),href:H.string(),priority:H.number()}))}),copyright:H.string(),socialLinks:H.array(H.object({platform:H.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:H.string().describe("Profile or contact URL"),label:H.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});aA();WA();var YK1={lexicon:1,id:"ai.rizom.brain.card",defs:{main:{type:"record",description:"Public discovery card for a Rizom brain. The operational A2A Agent Card is conventionally served at /.well-known/agent-card.json under siteUrl.",key:"literal:self",record:{type:"object",required:["siteUrl","brain","anchor","skills","model","version","createdAt"],properties:{siteUrl:{type:"string",format:"uri",description:"Public site URL. Consumers derive the A2A Agent Card URL from this base."},brain:{type:"object",description:"Brain identity described by this discovery card.",required:["did","name","role","purpose","values"],properties:{did:{type:"string",description:"Public DID for the brain identity."},name:{type:"string",maxLength:200,description:"Human-readable brain name."},role:{type:"string",maxLength:500,description:"Brain role or persona."},purpose:{type:"string",maxLength:2000,description:"Short public description of what this brain is for."},values:{type:"array",description:"Public values or principles for this brain.",items:{type:"string",maxLength:200},maxLength:50}}},anchor:{type:"object",description:"Minimal owner/operator snapshot for discovery grouping and display.",required:["did","name","kind"],properties:{did:{type:"string",description:"Public DID for the owner/operator anchor identity."},name:{type:"string",maxLength:200,description:"Human-readable anchor name."},kind:{type:"string",knownValues:["professional","team","collective"],description:"Anchor type."}}},skills:{type:"array",description:"User-facing skills this brain advertises for discovery.",items:{type:"object",required:["id","name","description"],properties:{id:{type:"string",maxLength:200},name:{type:"string",maxLength:200},description:{type:"string",maxLength:2000},tags:{type:"array",items:{type:"string"},maxLength:50},examples:{type:"array",items:{type:"string"},maxLength:20}}},maxLength:100},model:{type:"string",description:"Rizom brain model identifier."},version:{type:"string",description:"Brain runtime/model implementation version."},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var UK1={lexicon:1,id:"ai.rizom.brain.deck",defs:{main:{type:"record",description:"Public presentation deck from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},author:{type:"string"},event:{type:"string"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var JK1={lexicon:1,id:"ai.rizom.brain.link",defs:{main:{type:"record",description:"Public curated link from a Rizom brain.",key:"any",record:{type:"object",required:["title","url","createdAt"],properties:{title:{type:"string",maxLength:500},url:{type:"string",format:"uri"},description:{type:"string",maxLength:2000},summary:{type:"string",maxLength:1e5},domain:{type:"string"},capturedAt:{type:"string",format:"datetime"},source:{type:"object",required:["ref","label"],properties:{ref:{type:"string"},label:{type:"string"}}},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var XK1={lexicon:1,id:"ai.rizom.brain.note",defs:{main:{type:"record",description:"Public knowledge note from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var WK1={lexicon:1,id:"ai.rizom.brain.post",defs:{main:{type:"record",description:"Markdown blog post distributed by a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},summary:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},canonicalUrl:{type:"string",format:"uri"},topics:{type:"array",items:{type:"string"},maxLength:50},coverImage:{type:"object",required:["blob"],properties:{blob:{type:"blob"},alt:{type:"string",maxLength:1000},width:{type:"integer"},height:{type:"integer"}}},series:{type:"string",maxLength:200},seriesIndex:{type:"integer"},sourceEntityType:{type:"string",knownValues:["post"]},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},publishedAt:{type:"string",format:"datetime"}}}}}};var HK1={lexicon:1,id:"ai.rizom.brain.project",defs:{main:{type:"record",description:"Public project or case study from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","year","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:2000},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},year:{type:"integer"},url:{type:"string",format:"uri"},publishedAt:{type:"string",format:"datetime"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var GK1={lexicon:1,id:"ai.rizom.brain.series",defs:{main:{type:"record",description:"Public content series from a Rizom brain.",key:"any",record:{type:"object",required:["title","createdAt"],properties:{title:{type:"string",maxLength:300},slug:{type:"string"},description:{type:"string",maxLength:1e4},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var KK1={lexicon:1,id:"ai.rizom.brain.socialPost",defs:{main:{type:"record",description:"Semantic local social-post entity from a Rizom brain; not a Bluesky feed post.",key:"any",record:{type:"object",required:["title","platform","body","createdAt"],properties:{title:{type:"string",maxLength:300},platform:{type:"string"},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},status:{type:"string"},publishedAt:{type:"string",format:"datetime"},platformPostId:{type:"string"},sourceLocalEntityType:{type:"string"},sourceLocalEntityId:{type:"string"},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var FK1={lexicon:1,id:"ai.rizom.brain.topic",defs:{main:{type:"record",description:"Public topic page from a Rizom brain.",key:"any",record:{type:"object",required:["title","body","createdAt"],properties:{title:{type:"string",maxLength:300},body:{type:"string",maxLength:1e5},format:{type:"string",knownValues:["text/markdown"]},brainDid:{type:"string"},anchorDid:{type:"string"},sourceEntityType:{type:"string"},sourceEntityId:{type:"string"},createdAt:{type:"string",format:"datetime"},updatedAt:{type:"string",format:"datetime"}}}}}};var CLQ=H.object({type:H.string()}).catchall(H.unknown()),OLQ=H.object({lexicon:H.literal(1),id:H.string(),defs:H.object({main:H.object({type:H.literal("record"),key:H.string().min(1),record:H.object({type:H.literal("object"),required:H.array(H.string()).optional(),properties:H.record(CLQ)})})})});function EH(A){return OLQ.parse(A)}var Gw={"ai.rizom.brain.card":EH(YK1),"ai.rizom.brain.deck":EH(UK1),"ai.rizom.brain.link":EH(JK1),"ai.rizom.brain.note":EH(XK1),"ai.rizom.brain.post":EH(WK1),"ai.rizom.brain.project":EH(HK1),"ai.rizom.brain.series":EH(GK1),"ai.rizom.brain.socialPost":EH(KK1),"ai.rizom.brain.topic":EH(FK1)},RLQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function xF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:RLQ}}var bLQ={"ai.rizom.brain.card":xF("@brains/atproto"),"ai.rizom.brain.deck":xF("@brains/decks"),"ai.rizom.brain.link":xF("@brains/link"),"ai.rizom.brain.note":xF("@brains/note"),"ai.rizom.brain.post":xF("@brains/blog"),"ai.rizom.brain.project":xF("@brains/portfolio"),"ai.rizom.brain.series":xF("@brains/series"),"ai.rizom.brain.socialPost":xF("@brains/social-media"),"ai.rizom.brain.topic":xF("@brains/topics")};function tM(){return Object.values(Gw)}function fSA(A){return Gw[A]}function ISA(){return Object.entries(bLQ).map(([A,Q])=>({id:A,...Q}))}function $SA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var PLQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function kLQ(A){let Q=H.string(),B=A.maxLength!==void 0?Q.max(A.maxLength):Q;if(A.knownValues)B=B.refine((w)=>A.knownValues?.includes(w),{message:`expected one of ${A.knownValues.join(", ")}`});if(A.format==="datetime")B=B.refine((w)=>PLQ.test(w)&&!Number.isNaN(Date.parse(w)),{message:"expected datetime"});if(A.format==="uri")B=B.refine((w)=>{try{return new URL(w),!0}catch{return!1}},{message:"expected uri"});return B}function ZK1(A){switch(A.type){case"string":return kLQ(A);case"integer":return H.number().int();case"boolean":return H.boolean();case"array":{let Q=A.items?ZK1(A.items):H.unknown(),B=H.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return jLQ(A);case"blob":return H.custom($SA,{message:"expected blob"});default:return H.unknown()}}function NK1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let f=ZK1($);B[w]=Q.has(w)?f:f.optional()}return B}function jLQ(A){return H.object(NK1(A)).passthrough()}function wSA(A,Q,B,w=[]){let $=Object.keys(A).filter((f)=>!Q.has(f));if($.length===0)return;B.addIssue({code:H.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function _LQ(A,Q){if(wSA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),$SA(A.brain))wSA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if($SA(A.anchor))wSA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function MH(A){let Q=H.object({...NK1(A.defs.main.record),$type:H.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(_LQ):Q}var vLQ={"ai.rizom.brain.card":MH(Gw["ai.rizom.brain.card"]),"ai.rizom.brain.deck":MH(Gw["ai.rizom.brain.deck"]),"ai.rizom.brain.link":MH(Gw["ai.rizom.brain.link"]),"ai.rizom.brain.note":MH(Gw["ai.rizom.brain.note"]),"ai.rizom.brain.post":MH(Gw["ai.rizom.brain.post"]),"ai.rizom.brain.project":MH(Gw["ai.rizom.brain.project"]),"ai.rizom.brain.series":MH(Gw["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":MH(Gw["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":MH(Gw["ai.rizom.brain.topic"])};function TLQ(A,Q,B){let w=B.path.join(".");if(w==="$type")return`AT Protocol record $type must match lexicon id: ${String(Q.$type)} !== ${A.id}`;if(B.code==="invalid_type"&&B.received==="undefined")return`Missing required AT Protocol record field: ${w}`;if(B.code==="invalid_type")return`Invalid AT Protocol record field ${w}: expected ${B.expected}`;if(B.code==="too_big")return`Invalid AT Protocol record field ${w}: exceeds maxLength ${B.maximum}`;if(B.code==="custom")return`Invalid AT Protocol record field ${w}: ${B.message}`;if(B.code==="unrecognized_keys")return`Unrecognized AT Protocol record field(s): ${B.keys.join(", ")}`;return`Invalid AT Protocol record field ${w}: ${B.message}`}function Tz(A,Q){let B=MH(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(TLQ(A,Q,w))}var f5A="atproto:brain-card-discovered",zK1="atproto:brain-discovered",qK1="atproto:brain-card-refreshed",LK1=H.object({repoDid:H.string().min(1),uri:H.string().min(1),cid:H.string().min(1),record:vLQ["ai.rizom.brain.card"]}).strict(),hmw=H.object({agentId:H.string().min(1),name:H.string().min(1),url:H.string().url(),status:H.enum(["discovered","approved"]),repoDid:H.string().min(1).optional(),brainDid:H.string().min(1).optional(),anchorDid:H.string().min(1).optional(),cardUri:H.string().min(1).optional(),cardCid:H.string().min(1).optional()}).strict();class d6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new d6,this.instance}static createFresh(){return new d6}static resetInstance(){this.instance=void 0}register(A){this.validateProjection(A);let Q=this.projections.get(A.entityType);if(Q){if(!this.isEquivalentProjection(Q,A))throw Error(`AT Protocol projection already registered for entity type ${A.entityType}`);return this.registrationCounts.set(A.entityType,(this.registrationCounts.get(A.entityType)??1)+1),this.createUnregister(A.entityType)}return this.projections.set(A.entityType,A),this.registrationCounts.set(A.entityType,1),this.createUnregister(A.entityType)}get(A){return this.projections.get(A)}has(A){return this.projections.has(A)}list(){return Array.from(this.projections.values())}listLexicons(){return this.list().map((A)=>A.lexicon)}createUnregister(A){let Q=!0;return()=>{if(!Q)return;Q=!1;let B=this.registrationCounts.get(A)??0;if(B<=1){this.registrationCounts.delete(A),this.projections.delete(A);return}this.registrationCounts.set(A,B-1)}}isEquivalentProjection(A,Q){return A.entityType===Q.entityType&&A.collection===Q.collection&&A.lexicon.id===Q.lexicon.id&&A.validate===Q.validate}validateProjection(A){if(A.collection!==A.lexicon.id)throw Error(`AT Protocol projection collection must match lexicon id: ${A.collection} !== ${A.lexicon.id}`);if(!A.lexicon.defs.main.key)throw Error(`AT Protocol projection lexicon must define a record key: ${A.collection}`)}}KD();Xv();WA();var DSA=H.object({defaultPrompt:H.string().default("Write a blog post about my recent work and insights"),paginate:H.boolean().default(!0),pageSize:H.number().default(10)});aA();WA();H6();var SLQ=H.object({prompt:H.string().optional(),title:H.string().optional(),content:H.string().optional(),excerpt:H.string().optional(),coverImageId:H.string().optional(),seriesName:H.string().optional(),seriesIndex:H.number().optional(),skipAi:H.boolean().optional()}),tmw=qI.extend({title:H.string().optional(),slug:H.string().optional()});class YSA extends z7{constructor(A,Q){super(A,Q,{schema:SLQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:Y,excerpt:U}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");Y=Y??`## Introduction
5655
5655
 
5656
5656
  Add your introduction here.
5657
5657
 
@@ -5871,7 +5871,7 @@ ${B.content}`,templateName:"blog:excerpt"})})}aA();Xv();KD();function IVQ(A){let
5871
5871
  letter-spacing: 0.02em;
5872
5872
  }
5873
5873
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
5874
- `}},void 0,!1,void 0,this),n9("header",{className:"printable-hero",children:[n9("div",{className:"printable-masthead",children:Q.brandLabel&&n9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9("div",{children:[n9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&n9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),n9("div",{className:"printable-meta",children:[Q.author&&n9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&n9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&n9("figure",{className:"printable-cover-wrap",children:n9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&n9("footer",{className:"printable-footer",children:[n9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&n9("a",{href:Q.canonicalUrl,children:Q.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var cVQ=26214400,lVQ=60000;class zSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==U5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=pVQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await gVQ(uVQ(mVQ(),"brain-blog-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:mK1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:cVQ,timeoutMs:lVQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${iVQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await hVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function pVQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=z8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function iVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as sVQ,rm as aVQ}from"fs/promises";import{tmpdir as tVQ}from"os";import{join as eVQ}from"path";WA();KD();WA();import{jsxDEV as oVQ}from"preact/jsx-dev-runtime";var Ii="og-image",rVQ="blog:og-image",uK1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),cK1={name:rVQ,pluginId:"blog",schema:uK1,renderers:{image:nVQ}};function dVQ(A){if(!A)return;let Q=new Date(A);if(Number.isNaN(Q.getTime()))return;return Q.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function nVQ(A){let Q=uK1.parse(A);return oVQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:dVQ(Q.publishedAt)},void 0,!1,void 0,this)}var AEQ={width:1200,height:630},QEQ=60000;class qSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??fi}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Ii)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=BEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await sVQ(eVQ(tVQ(),"brain-blog-og-image-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:cK1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),AEQ,{timeoutMs:QEQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${wEQ(Q)}-og.png`}}finally{await f.close()}}finally{await aVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function BEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=z8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function wEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var lK1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.121",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class LSA extends jQ{entityType=gF.entityType;schema=Jv;adapter=gF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",lK1,A,DSA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new YSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return OK1()}getDataSources(){return[new JSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (rK1(),iK1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),RK1(A,this.logger),bK1(A,this.logger),kK1(A,this.logger),jK1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",U5A,new zSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Ii,new qSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=d6.getInstance().register(HSA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:Ii,mediaEntityType:"image",targetEntityField:{location:"frontmatter",field:"ogImageId"},requiredWhen:{status:"published"},autoGenerate:!0,jobType:"image:image-render-source"}}),{success:!0}})}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function VSA(A={}){return new LSA(A)}KD();Xv();aA();WA();WA();o$();aA();var pY=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),dK1=pY.pick({title:!0,slug:!0}),yz=A2.extend({metadata:dK1}),J5A=yz.extend({frontmatter:pY}),X5A=J5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),nK1=H.object({description:H.string().optional()});function QC(A){return new lB(nK1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class ESA extends q2{constructor(){super({entityType:"series",schema:yz,frontmatterSchema:pY,supportsCoverImage:!0,bodyFormatter:QC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,pY).coverImageId,B=QC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=QC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,pY);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,pY);return QC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var xz=new ESA;aA();WA();wY();WA();var IEQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function W5A(A){let Q=IEQ.safeParse(A);return Q.success?Q.data:{}}function BC(A){return W5A(A.metadata).seriesName}function oK1(A){return W5A(A.metadata).seriesIndex}function sK1(A,Q){let B=oK1(A)??Number.MAX_SAFE_INTEGER,w=oK1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class MSA{entityService;logger;constructor(A,Q){this.entityService=A;this.logger=Q}async syncAllSeries(){this.logger.debug("Syncing series from all entity types");let A=await this.collectSeriesNames();this.logger.debug(`Found ${A.size} unique series`);let Q=await this.entityService.listEntities({entityType:"series"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),Y=gB(D);if(I?.contentHash===Y)continue;let U={id:f,entityType:"series",content:D,contentHash:Y,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:U}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=BC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(A);if(!await this.entityService.getEntity({entityType:"series",id:Q}))return;if(!await this.hasSeriesReferences(A))await this.entityService.deleteEntity({entityType:"series",id:Q}),this.logger.debug(`Deleted orphaned series: ${A}`)}async hasSeriesReferences(A){let Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;if((await this.entityService.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}},limit:1}})).length>0)return!0}return!1}async collectSeriesNames(){let A=new Set,Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;let w=await this.entityService.listEntities({entityType:B});for(let $ of w){let f=BC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return b9("",Q)}}aA();WA();var DEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),YEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function UEQ(A){let Q=YEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=DEQ.safeParse(A);if(B.success){let{query:w}=B.data;if(w.id)return{type:"detail",seriesSlug:w.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function aK1(A){let Q=R2(A.content,pY);return J5A.parse({...A,frontmatter:Q.metadata})}class CSA{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,B){let w=UEQ(A),$=B.entityService;if(w.type==="list")return this.fetchSeriesList(Q,$);if(w.seriesName)return this.fetchSeriesDetail(w.seriesName,Q,$);if(w.seriesSlug)return this.fetchSeriesDetailBySlug(w.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let B=await Q.listEntities({entityType:"series"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=aK1(f),D=xz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=aK1(w),f=xz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,B,$)}async countEntitiesPerSeries(A){let Q=new Map,B=A.getEntityTypes();for(let w of B){if(w==="series")continue;let $=await A.listEntities({entityType:w});for(let f of $){let I=BC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(sK1),B}}aA();WA();wY();var JEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),XEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class H5A{logger;context;constructor(A,Q){this.logger=A;this.context=Q}async process(A){let Q=A.seriesId??A.title;if(!Q)return{success:!1,error:"seriesId or title required"};let B=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!B)return{success:!1,error:`Series not found: ${Q}`};let w=await this.gatherMemberSummaries(B.metadata.title);if(w.length===0)return{success:!1,error:`No members found in series: ${B.metadata.title}`};let $=A.prompt??`Series name: ${B.metadata.title}
5874
+ `}},void 0,!1,void 0,this),n9("header",{className:"printable-hero",children:[n9("div",{className:"printable-masthead",children:Q.brandLabel&&n9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9("div",{children:[n9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&n9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),n9("div",{className:"printable-meta",children:[Q.author&&n9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&n9("span",{children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&n9("figure",{className:"printable-cover-wrap",children:n9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),n9(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&n9("footer",{className:"printable-footer",children:[n9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&n9("a",{href:Q.canonicalUrl,children:Q.canonicalUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var cVQ=26214400,lVQ=60000;class zSA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==U5A)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=pVQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await gVQ(uVQ(mVQ(),"brain-blog-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:mK1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:cVQ,timeoutMs:lVQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${iVQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await hVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function pVQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=z8.parse(B);return{title:$.title,body:w,...$.excerpt?{excerpt:$.excerpt}:{},...$.author?{author:$.author}:{},...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.canonicalUrl?{canonicalUrl:$.canonicalUrl}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function iVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}import{mkdtemp as sVQ,rm as aVQ}from"fs/promises";import{tmpdir as tVQ}from"os";import{join as eVQ}from"path";WA();KD();WA();import{jsxDEV as oVQ}from"preact/jsx-dev-runtime";var Ii="og-image",rVQ="blog:og-image",uK1=H.object({title:H.string().min(1),excerpt:H.string().optional(),author:H.string().optional(),publishedAt:H.string().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),cK1={name:rVQ,pluginId:"blog",schema:uK1,renderers:{image:nVQ}};function dVQ(A){if(!A)return;let Q=new Date(A);if(Number.isNaN(Q.getTime()))return;return Q.toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"2-digit"})}function nVQ(A){let Q=uK1.parse(A);return oVQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:dVQ(Q.publishedAt)},void 0,!1,void 0,this)}var AEQ={width:1200,height:630},QEQ=60000;class qSA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??fi}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==Ii)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=BEQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await sVQ(eVQ(tVQ(),"brain-blog-og-image-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:cK1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"image",data:await this.screenshotPng(f.urlFor($.urlPath),AEQ,{timeoutMs:QEQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${wEQ(Q)}-og.png`}}finally{await f.close()}}finally{await aVQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=z8.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function BEQ(A,Q={}){let{frontmatter:B}=jB(A.content),w=z8.parse(B);return{title:w.title,...w.excerpt?{excerpt:w.excerpt}:{},...w.author?{author:w.author}:{},...w.publishedAt?{publishedAt:w.publishedAt}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function wEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var lK1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.122",description:"AI-powered blog post generation from existing brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class LSA extends jQ{entityType=gF.entityType;schema=Jv;adapter=gF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",lK1,A,DSA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new YSA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return OK1()}getDataSources(){return[new JSA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (rK1(),iK1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),RK1(A,this.logger),bK1(A,this.logger),kK1(A,this.logger),jK1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",U5A,new zSA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",Ii,new qSA(A)),this.deferPublishAssetRegistration(A),this.unregisterAtprotoProjection=d6.getInstance().register(HSA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}deferPublishAssetRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish-assets:register",payload:{entityType:"post",attachmentType:Ii,mediaEntityType:"image",targetEntityField:{location:"frontmatter",field:"ogImageId"},requiredWhen:{status:"published"},autoGenerate:!0,jobType:"image:image-render-source"}}),{success:!0}})}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function VSA(A={}){return new LSA(A)}KD();Xv();aA();WA();WA();o$();aA();var pY=H.object({title:H.string(),slug:H.string(),coverImageId:H.string().optional()}),dK1=pY.pick({title:!0,slug:!0}),yz=A2.extend({metadata:dK1}),J5A=yz.extend({frontmatter:pY}),X5A=J5A.extend({description:H.string().optional(),postCount:H.number(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),nK1=H.object({description:H.string().optional()});function QC(A){return new lB(nK1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}aA();class ESA extends q2{constructor(){super({entityType:"series",schema:yz,frontmatterSchema:pY,supportsCoverImage:!0,bodyFormatter:QC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,pY).coverImageId,B=QC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=QC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,pY);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,pY);return QC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var xz=new ESA;aA();WA();wY();WA();var IEQ=H.object({seriesName:H.string().optional(),seriesIndex:H.number().optional()});function W5A(A){let Q=IEQ.safeParse(A);return Q.success?Q.data:{}}function BC(A){return W5A(A.metadata).seriesName}function oK1(A){return W5A(A.metadata).seriesIndex}function sK1(A,Q){let B=oK1(A)??Number.MAX_SAFE_INTEGER,w=oK1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class MSA{entityService;logger;constructor(A,Q){this.entityService=A;this.logger=Q}async syncAllSeries(){this.logger.debug("Syncing series from all entity types");let A=await this.collectSeriesNames();this.logger.debug(`Found ${A.size} unique series`);let Q=await this.entityService.listEntities({entityType:"series"}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=X1($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),Y=gB(D);if(I?.contentHash===Y)continue;let U={id:f,entityType:"series",content:D,contentHash:Y,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:X1($)}};await this.entityService.upsertEntity({entity:U}),this.logger.debug(`Upserted series: ${$}`)}for(let $ of Q)if(!w.has($.id))await this.entityService.deleteEntity({entityType:"series",id:$.id}),this.logger.debug(`Deleted orphaned series: ${$.id}`)}async handleEntityChange(A,Q){let B=BC(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}async ensureSeriesExists(A){let Q=X1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:gB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:X1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=X1(A);if(!await this.entityService.getEntity({entityType:"series",id:Q}))return;if(!await this.hasSeriesReferences(A))await this.entityService.deleteEntity({entityType:"series",id:Q}),this.logger.debug(`Deleted orphaned series: ${A}`)}async hasSeriesReferences(A){let Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;if((await this.entityService.listEntities({entityType:B,options:{filter:{metadata:{seriesName:A}},limit:1}})).length>0)return!0}return!1}async collectSeriesNames(){let A=new Set,Q=this.entityService.getEntityTypes();for(let B of Q){if(B==="series")continue;let w=await this.entityService.listEntities({entityType:B});for(let $ of w){let f=BC($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:X1(A)};return b9("",Q)}}aA();WA();var DEQ=H.object({entityType:H.literal("series"),query:H.object({id:H.string().optional(),limit:H.number().optional(),page:H.number().optional(),pageSize:H.number().optional()}).passthrough()}),YEQ=H.object({type:H.enum(["list","detail"]),seriesName:H.string().optional()});function UEQ(A){let Q=YEQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=DEQ.safeParse(A);if(B.success){let{query:w}=B.data;if(w.id)return{type:"detail",seriesSlug:w.id};return{type:"list"}}throw Error('Invalid series query format. Expected { type: "list"|"detail" } or { entityType: "series", query: { id?: string } }')}function aK1(A){let Q=R2(A.content,pY);return J5A.parse({...A,frontmatter:Q.metadata})}class CSA{logger;id="series:entities";name="Series DataSource";description="Fetches series list and detail data";constructor(A){this.logger=A}async fetch(A,Q,B){let w=UEQ(A),$=B.entityService;if(w.type==="list")return this.fetchSeriesList(Q,$);if(w.seriesName)return this.fetchSeriesDetail(w.seriesName,Q,$);if(w.seriesSlug)return this.fetchSeriesDetailBySlug(w.seriesSlug,Q,$);throw Error("Invalid series query: must specify seriesName or slug for detail")}async fetchSeriesList(A,Q){let B=await Q.listEntities({entityType:"series"}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=aK1(f),D=xz.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=aK1(w),f=xz.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)throw Error(`Series not found with slug: ${A}`);return this.fetchSeriesDetail($.metadata.title,Q,B,$)}async countEntitiesPerSeries(A){let Q=new Map,B=A.getEntityTypes();for(let w of B){if(w==="series")continue;let $=await A.listEntities({entityType:w});for(let f of $){let I=BC(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(sK1),B}}aA();WA();wY();var JEQ=H.object({prompt:H.string().optional(),title:H.string().optional(),seriesId:H.string().optional()}),XEQ=H.object({title:H.string().optional(),excerpt:H.string().optional()});class H5A{logger;context;constructor(A,Q){this.logger=A;this.context=Q}async process(A){let Q=A.seriesId??A.title;if(!Q)return{success:!1,error:"seriesId or title required"};let B=await this.context.entityService.getEntity({entityType:"series",id:Q});if(!B)return{success:!1,error:`Series not found: ${Q}`};let w=await this.gatherMemberSummaries(B.metadata.title);if(w.length===0)return{success:!1,error:`No members found in series: ${B.metadata.title}`};let $=A.prompt??`Series name: ${B.metadata.title}
5875
5875
 
5876
5876
  Content in this series:
5877
5877
  ${w.join(`
@@ -5883,7 +5883,7 @@ Your task is to write a series description (2-3 sentences) that:
5883
5883
  3. Is engaging and makes readers want to explore the content
5884
5884
  4. Works well as a series overview on a website
5885
5885
 
5886
- Be concise and focus on what makes this series unique and valuable.`});async function $F1({entity:A,config:Q}){let B=yz.parse(A),w=xz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function OSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Gw["ai.rizom.brain.series"],validate:!1,buildRecord:$F1}}var fF1={name:"@brains/series",private:!0,version:"0.2.0-alpha.121",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var IF1=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("source"),entityId:H.string(),entityType:H.string(),seriesName:H.string().optional(),previousSeriesName:H.string().optional()})]);class RSA extends jQ{entityType="series";schema=yz;adapter=xz;manager;unregisterAtprotoProjection;constructor(){super("series",fF1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new H5A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...BF1(),description:wF1}}getDataSources(){return[new CSA(this.logger.child("SeriesDataSource"))]}getDerivedEntityProjections(A){return[{id:"series-projection",targetType:"series",job:{type:"series:project",handler:this.createSeriesProjectionHandler(A)},initialSync:{jobData:{mode:"derive",reason:"initial-sync"},jobOptions:this.getSyncProjectionJobOptions("initial-sync")},sourceChange:{sourceTypes:["*"],events:["entity:created","entity:updated","entity:deleted"],requireInitialSync:!0,jobData:(Q)=>{if(Q.entityType==="series")return null;if(!Q.entity)return null;let B=BC(Q.entity),w=W5A(Q.previousMetadata).seriesName;if(!B&&!w)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...B?{seriesName:B}:{},...w&&w!==B?{previousSeriesName:w}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new MSA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=d6.getInstance().register(OSA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=IF1.parse(Q);if(B.mode==="derive")return await this.projectAll(A),{success:!0};let w=await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(w)await this.projectSource(w,B.previousSeriesName);else{let $=this.requireManager();for(let f of[B.seriesName,B.previousSeriesName])if(f)await $.cleanupOrphanedSeries(f)}return{success:!0}},validateAndParse:(Q)=>{let B=IF1.safeParse(Q??{});return B.success?B.data:null}}}requireManager(){if(!this.manager)throw Error("SeriesPlugin not registered");return this.manager}getSyncProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-sync:${A}`,metadata:{operationType:"data_processing",operationTarget:"series"}}}getSourceProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-source:${A.entityType}:${A.id}`,metadata:{operationType:"data_processing",operationTarget:`series:${A.entityType}:${A.id}`}}}async projectSource(A,Q){await this.requireManager().handleEntityChange(A,Q)}async projectAll(A){await this.requireManager().syncAllSeries();let Q=new H5A(this.logger.child("SeriesGenerationHandler"),A),B=await A.entityService.listEntities({entityType:"series"});for(let w of B)try{if(!this.adapter.parseBody(w.content).description)this.logger.info(`Generating description for series: ${w.metadata.title}`),await Q.process({seriesId:w.id})}catch($){this.logger.error(`Failed to generate description for series: ${w.id}`,{error:$})}}}function bSA(){return new RSA}aA();WA();aA();WA();WA();aA();var FEQ=H.enum(["generating","draft","queued","published","failed"]),DF1="publishedAt is required when deck status is published",YF1=(A)=>A.status==="published"&&!A.publishedAt,PSA=(A)=>{if(YF1(A))throw Error(DF1)},iY=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:FEQ,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),ZEQ=iY.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:H.string(),error:H.string().optional()}).superRefine((A,Q)=>{if(!YF1(A))return;Q.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:DF1})}),Hv=A2.extend({entityType:H.literal("deck"),metadata:ZEQ}),G5A=Hv.extend({frontmatter:iY,body:H.string(),ogImageUrl:H.string().optional()}),wC=G5A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});class kSA extends q2{constructor(){super({entityType:"deck",schema:Hv,frontmatterSchema:iY,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);let B=this.parseFrontMatter(A.content,iY);PSA(B);let w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);PSA(Q),this.validateSlideStructure(B);let w=Q.slug??X1(Q.title),$=Q.status;return{entityType:"deck",content:A,metadata:{slug:w,title:Q.title,description:Q.description,status:$,publishedAt:Q.publishedAt,coverImageId:Q.coverImageId}}}generateTitle(A){return A.metadata.title}generateSummary(A){if(A.metadata.description)return A.metadata.description;return`Presentation: ${A.metadata.title}`}generateFrontMatter(A){return this.toMarkdown(A)}buildStub(A){let Q={title:A.title,slug:A.id,status:"generating"};return{content:this.buildMarkdown(`---
5886
+ Be concise and focus on what makes this series unique and valuable.`});async function $F1({entity:A,config:Q}){let B=yz.parse(A),w=xz.parseBody(B.content);return{$type:"ai.rizom.brain.series",title:B.metadata.title,slug:B.metadata.slug,...w.description&&{description:w.description},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"series",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function OSA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:Gw["ai.rizom.brain.series"],validate:!1,buildRecord:$F1}}var fF1={name:"@brains/series",private:!0,version:"0.2.0-alpha.122",description:"Cross-content series \u2014 auto-derived from entities with seriesName metadata",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/entity-service":"workspace:*","@brains/job-queue":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var IF1=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("source"),entityId:H.string(),entityType:H.string(),seriesName:H.string().optional(),previousSeriesName:H.string().optional()})]);class RSA extends jQ{entityType="series";schema=yz;adapter=xz;manager;unregisterAtprotoProjection;constructor(){super("series",fF1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new H5A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...BF1(),description:wF1}}getDataSources(){return[new CSA(this.logger.child("SeriesDataSource"))]}getDerivedEntityProjections(A){return[{id:"series-projection",targetType:"series",job:{type:"series:project",handler:this.createSeriesProjectionHandler(A)},initialSync:{jobData:{mode:"derive",reason:"initial-sync"},jobOptions:this.getSyncProjectionJobOptions("initial-sync")},sourceChange:{sourceTypes:["*"],events:["entity:created","entity:updated","entity:deleted"],requireInitialSync:!0,jobData:(Q)=>{if(Q.entityType==="series")return null;if(!Q.entity)return null;let B=BC(Q.entity),w=W5A(Q.previousMetadata).seriesName;if(!B&&!w)return null;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,...B?{seriesName:B}:{},...w&&w!==B?{previousSeriesName:w}:{}}},jobOptions:(Q)=>{if(!Q.entity)return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new MSA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=d6.getInstance().register(OSA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=IF1.parse(Q);if(B.mode==="derive")return await this.projectAll(A),{success:!0};let w=await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(w)await this.projectSource(w,B.previousSeriesName);else{let $=this.requireManager();for(let f of[B.seriesName,B.previousSeriesName])if(f)await $.cleanupOrphanedSeries(f)}return{success:!0}},validateAndParse:(Q)=>{let B=IF1.safeParse(Q??{});return B.success?B.data:null}}}requireManager(){if(!this.manager)throw Error("SeriesPlugin not registered");return this.manager}getSyncProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-sync:${A}`,metadata:{operationType:"data_processing",operationTarget:"series"}}}getSourceProjectionJobOptions(A){return{source:this.id,deduplication:"coalesce",deduplicationKey:`series-source:${A.entityType}:${A.id}`,metadata:{operationType:"data_processing",operationTarget:`series:${A.entityType}:${A.id}`}}}async projectSource(A,Q){await this.requireManager().handleEntityChange(A,Q)}async projectAll(A){await this.requireManager().syncAllSeries();let Q=new H5A(this.logger.child("SeriesGenerationHandler"),A),B=await A.entityService.listEntities({entityType:"series"});for(let w of B)try{if(!this.adapter.parseBody(w.content).description)this.logger.info(`Generating description for series: ${w.metadata.title}`),await Q.process({seriesId:w.id})}catch($){this.logger.error(`Failed to generate description for series: ${w.id}`,{error:$})}}}function bSA(){return new RSA}aA();WA();aA();WA();WA();aA();var FEQ=H.enum(["generating","draft","queued","published","failed"]),DF1="publishedAt is required when deck status is published",YF1=(A)=>A.status==="published"&&!A.publishedAt,PSA=(A)=>{if(YF1(A))throw Error(DF1)},iY=H.object({title:H.string(),slug:H.string().optional(),description:H.string().optional(),author:H.string().optional(),status:FEQ,publishedAt:H.string().datetime().optional(),event:H.string().optional(),coverImageId:H.string().optional(),ogImageId:H.string().optional()}),ZEQ=iY.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:H.string(),error:H.string().optional()}).superRefine((A,Q)=>{if(!YF1(A))return;Q.addIssue({code:H.ZodIssueCode.custom,path:["publishedAt"],message:DF1})}),Hv=A2.extend({entityType:H.literal("deck"),metadata:ZEQ}),G5A=Hv.extend({frontmatter:iY,body:H.string(),ogImageUrl:H.string().optional()}),wC=G5A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});class kSA extends q2{constructor(){super({entityType:"deck",schema:Hv,frontmatterSchema:iY,supportsCoverImage:!0})}validateSlideStructure(A){if(!/^---$/gm.test(A))throw Error("Invalid deck: markdown must contain slide separators (---) to be a valid presentation")}toMarkdown(A){let Q=this.extractBody(A.content);this.validateSlideStructure(Q);let B=this.parseFrontMatter(A.content,iY);PSA(B);let w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontmatter(A),B=this.extractBody(A);PSA(Q),this.validateSlideStructure(B);let w=Q.slug??X1(Q.title),$=Q.status;return{entityType:"deck",content:A,metadata:{slug:w,title:Q.title,description:Q.description,status:$,publishedAt:Q.publishedAt,coverImageId:Q.coverImageId}}}generateTitle(A){return A.metadata.title}generateSummary(A){if(A.metadata.description)return A.metadata.description;return`Presentation: ${A.metadata.title}`}generateFrontMatter(A){return this.toMarkdown(A)}buildStub(A){let Q={title:A.title,slug:A.id,status:"generating"};return{content:this.buildMarkdown(`---
5887
5887
  `,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var Di=new kSA;WA();Ew();var NEQ=H.object({markdown:H.string().describe("Markdown content with slide separators (---)"),deck:wC.optional()}),jSA=P1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:NEQ,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:ZTA,fullscreen:!0}});Ew();WA();var _SA=H.object({decks:H.array(G5A)}),vSA=H.object({decks:H.array(wC),pageTitle:H.string().optional(),pageLabel:H.string().optional()});import{jsxDEV as TSA}from"preact/jsx-dev-runtime";var zEQ="Presentations",ySA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return TSA("div",{className:"deck-list bg-theme",children:TSA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:TSA(Bp,{label:Q&&Q!=="Decks"?Q:zEQ,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};o$();class K5A extends lB{constructor(){super(_SA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var xSA=P1({name:"deck-list",description:"List view of all presentation decks",schema:vSA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new K5A,layout:{component:ySA}});WA();aA();var qEQ=H.object({title:H.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:H.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:H.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),UF1=P1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:qEQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
5888
5888
 
5889
5889
  Your task is to generate a complete slide deck based on the user's prompt.
@@ -6191,14 +6191,14 @@ ${D}`,templateName:"decks:description"})).description,await this.reportProgress(
6191
6191
  color: var(--carousel-accent);
6192
6192
  font-weight: 600;
6193
6193
  }
6194
- `}},void 0,!1,void 0,this),$.map((U,J)=>m7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[m7("header",{className:"deck-carousel-header",children:m7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[m7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&m7(OEQ,{children:[m7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),m7("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m7("div",{className:"deck-carousel-body",children:m7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:Y(U.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),m7("footer",{className:"deck-carousel-footer",children:[m7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),m7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[m7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",m7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as REQ,rm as bEQ}from"fs/promises";import{tmpdir as PEQ}from"os";import{join as kEQ}from"path";WA();var jEQ=26214400,_EQ=60000,GF1=20;class hSA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=vEQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>GF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${GF1}`);let w=await this.getThemeMode(),$=await REQ(kEQ(PEQ(),"brain-deck-carousel-"));try{let f=await ZD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:HF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ND({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:jEQ,timeoutMs:_EQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${TEQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await bEQ($,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name;return Q.length>0?Q:void 0}}function vEQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function TEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as SEQ}from"preact/jsx-dev-runtime";var F5A="og-image",yEQ="decks:og-image",KF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),FF1={name:yEQ,pluginId:"decks",schema:KF1,renderers:{image:xEQ}};function xEQ(A){let Q=KF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return SEQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class mSA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==F5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=iY.parse(B),f=gEQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),Y={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/deck/${Q.id}`,template:FF1,content:Y,title:Y.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${hEQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function gEQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function hEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function ZF1({entity:A,config:Q}){let B=Hv.parse(A),w=R2(B.content,iY),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function uSA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Gw["ai.rizom.brain.deck"],validate:!1,buildRecord:ZF1}}var NF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.121",description:"Presentation decks plugin for creating and viewing slide presentations",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class cSA extends jQ{deps;entityType=Di.entityType;schema=Di.schema;adapter=Di;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",NF1);this.deps=A}createGenerationHandler(A){return new gSA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":jSA,"deck-list":xSA,generation:UF1,description:JF1}}getDataSources(){return[new SSA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerOgImageAttachmentProvider(A),this.registerEvalHandlers(A),this.unregisterAtprotoProjection=d6.getInstance().register(uSA()),this.logger.info("Decks plugin registered")}async onShutdown(){this.unregisterCarouselAttachmentProvider?.(),this.unregisterCarouselAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}deferPublishRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Deck not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await ep(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",XF1,new hSA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",F5A,new mSA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=H.object({prompt:H.string(),event:H.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
6194
+ `}},void 0,!1,void 0,this),$.map((U,J)=>m7("section",{className:`deck-carousel-slide${J===0?" is-cover":""}`,children:[m7("header",{className:"deck-carousel-header",children:m7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[m7("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&m7(OEQ,{children:[m7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),m7("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m7("div",{className:"deck-carousel-body",children:m7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:Y(U.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),m7("footer",{className:"deck-carousel-footer",children:[m7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),m7("span",{className:"deck-carousel-counter","aria-label":`Slide ${J+1} of ${I}`,children:[m7("span",{className:"deck-carousel-counter-current",children:String(J+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",m7("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},J,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as REQ,rm as bEQ}from"fs/promises";import{tmpdir as PEQ}from"os";import{join as kEQ}from"path";WA();var jEQ=26214400,_EQ=60000,GF1=20;class hSA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X,this.getThemeMode=Q.getThemeMode??(async()=>"dark")}async resolve(A){if(A.sourceEntityType!=="deck")return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let B=vEQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>GF1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${GF1}`);let w=await this.getThemeMode(),$=await REQ(kEQ(PEQ(),"brain-deck-carousel-"));try{let f=await ZD({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:HF1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ND({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:jEQ,timeoutMs:_EQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${TEQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await bEQ($,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name;return Q.length>0?Q:void 0}}function vEQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function TEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();import{jsxDEV as SEQ}from"preact/jsx-dev-runtime";var F5A="og-image",yEQ="decks:og-image",KF1=H.object({title:H.string().min(1),description:H.string().optional(),event:H.string().optional(),brandLabel:H.string().optional(),slideCount:H.number().int().positive().optional(),coverImageUrl:H.string().optional()}),FF1={name:yEQ,pluginId:"decks",schema:KF1,renderers:{image:xEQ}};function xEQ(A){let Q=KF1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return SEQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}WA();class mSA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==F5A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=iY.parse(B),f=gEQ(w),I=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl($.coverImageId),Y={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...f?{slideCount:f}:{},...D?{coverImageUrl:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/deck/${Q.id}`,template:FF1,content:Y,title:Y.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${hEQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function gEQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function hEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}aA();async function ZF1({entity:A,config:Q}){let B=Hv.parse(A),w=R2(B.content,iY),$=w.metadata;return{$type:"ai.rizom.brain.deck",title:$.title,...$.slug&&{slug:$.slug},...$.description&&{description:$.description},body:w.content,format:"text/markdown",...$.author&&{author:$.author},...$.event&&{event:$.event},...$.publishedAt&&{publishedAt:$.publishedAt},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"deck",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function uSA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:Gw["ai.rizom.brain.deck"],validate:!1,buildRecord:ZF1}}var NF1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.122",description:"Presentation decks plugin for creating and viewing slide presentations",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/image":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class cSA extends jQ{deps;entityType=Di.entityType;schema=Di.schema;adapter=Di;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",NF1);this.deps=A}createGenerationHandler(A){return new gSA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":jSA,"deck-list":xSA,generation:UF1,description:JF1}}getDataSources(){return[new SSA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerOgImageAttachmentProvider(A),this.registerEvalHandlers(A),this.unregisterAtprotoProjection=d6.getInstance().register(uSA()),this.logger.info("Decks plugin registered")}async onShutdown(){this.unregisterCarouselAttachmentProvider?.(),this.unregisterCarouselAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}deferPublishRegistration(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})},config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="deck")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"deck",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Deck not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await ep(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",XF1,new hSA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",F5A,new mSA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=H.object({prompt:H.string(),event:H.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
6195
6195
 
6196
6196
  Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=H.object({title:H.string(),content:H.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
6197
6197
 
6198
6198
  Content:
6199
6199
  ${B.content}`,templateName:"decks:description"})})}}function Ui(){return new cSA}aA();WA();WA();U8();var lSA=H.literal("application/pdf"),pSA=H.object({title:H.string().optional(),mimeType:lSA,filename:H.string().min(1),pageCount:H.number().int().min(0).optional(),sourceEntityType:H.string().min(1).optional(),sourceEntityId:H.string().min(1).optional(),attachmentType:H.string().min(1).optional(),dedupKey:H.string().min(1).optional()}),Gv=A2.extend({entityType:H.literal("document"),content:H.string().regex(/^data:application\/pdf;base64,.+$/),metadata:pSA});function Ji(A){let Q=A.match(/^data:(application\/pdf);base64,(.+)$/i);if(!Q?.[1]||!Q[2])throw Error("Invalid PDF document data URL");return{mimeType:"application/pdf",base64:Q[2]}}function Z5A(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function iSA(A){let Q=Buffer.from(A).toString("latin1"),B=0,w=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(w)){let I=parseInt(f[1]??f[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class N5A{entityType="document";schema=Gv;toMarkdown(A){return A.content}fromMarkdown(A){return Ji(A),{entityType:"document",content:A}}extractMetadata(A){return A.metadata}parseFrontMatter(A,Q){return Q.parse({})}generateFrontMatter(A){return""}getBodyTemplate(){return""}createDocumentEntity(A){let{dataUrl:Q,...B}=A,{mimeType:w}=Ji(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var Sz=new N5A;async function PgA(A,Q={}){let B=Q.maxBytes??5000000;if(A.byteLength>B)throw Error(`Uploaded PDF is too large for synchronous markdown extraction (${A.byteLength} bytes; max ${B} bytes)`);let $=await(await Promise.resolve().then(() => (RN1(),ON1))).getDocument({data:new Uint8Array(A),disableFontFace:!1,useSystemFonts:!0,useWorkerFetch:!1}).promise;try{let f=Q.maxPages??50;if($.numPages>f)throw Error(`Uploaded PDF has ${$.numPages} pages; maximum supported for synchronous markdown extraction is ${f}`);let I=[];for(let Y=1;Y<=$.numPages;Y+=1){let X=(await(await $.getPage(Y)).getTextContent()).items.flatMap((G)=>("str"in G)?[G.str]:[]).join(" ").replace(/\s+/g," ").trim();if(X.length>0)I.push(X)}let D=I.join(`
6200
6200
 
6201
- `).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as EMQ}from"crypto";var MMQ=26214400,CMQ=20,OMQ=60000,bN1=80,RMQ=10,f$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),bv=f$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class I$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:bv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??$X}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??CMQ,$=A.maxBytes??MMQ,f=A.timeoutMs??OMQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=xi(A,I),Y=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let U=await this.findDocumentByDedupKey(I,Y?D:void 0);if(U&&(!Y||U.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,U.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:U.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let U=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=U.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=iSA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?U.filename:`${D}.pdf`),N=Sz.createDocumentEntity({dataUrl:Z5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:D}))await this.context.entityService.deleteEntity({entityType:"document",id:D});if(await this.context.entityService.createEntity({entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(U){throw this.logger.error("Document generation failed",{jobId:Q,error:T0(U)}),U}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map((w)=>w.id),preferredDocumentId:Q});return B.find((w)=>w.id===Q)??B[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(PMQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,Y=D.some((U)=>U.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:U4($.content,"documents",Y)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!kMQ(f,B))w.push($)}return w}}function xi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return bMQ($)}function bMQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${PN1(A)}`;if(Q.length<=bN1)return Q;let B=`-${PN1(A)}`;return`${Q.slice(0,bN1-B.length).replace(/-+$/g,"")}${B}`}function PN1(A){return EMQ("sha256").update(A).digest("hex").slice(0,RMQ)}function PMQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function kMQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function kgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',f$A,async(B,w)=>{let $=bv.safeParse(B);if(!$.success)return X$($.error.message);let f=xi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return Y8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var kN1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.121",description:"Document entity type for generated PDFs and publishable document attachments",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};var _MQ=H.object({}),jgA={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function vMQ(A,Q){let B=A.title?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}function TMQ(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function yMQ(A){let Q=encodeURIComponent(A.entityId);return{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${Q}`,downloadUrl:`/api/chat/attachments/document?id=${Q}&download=1`,filename:A.filename,source:{entityType:"document",entityId:A.entityId,attachmentType:"uploaded"}}}class _gA extends UB{entityType=Sz.entityType;schema=Gv;adapter=Sz;pluginContext;constructor(){super("document",kN1,{},_MQ)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.entities.registerCreateInterceptor(this.entityType,(Q)=>this.interceptCreate(Q)),A.jobs.registerHandler("generate",new I$A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===jgA.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(!A.from)return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=bv.parse({sourceEntityType:A.from.sourceEntityType,sourceEntityId:A.from.sourceEntityId,attachmentType:A.from.attachmentType,...A.title&&{title:A.title},...A.replace===!0&&{replace:!0},...A.targetEntityType&&{targetEntityType:A.targetEntityType},...A.targetEntityId&&{targetEntityId:A.targetEntityId}}),w=await this.getDedupKey(B,Q),f=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??xi(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:f}}),D=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:B.attachmentType}}}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==jgA.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w;try{w=await Q.uploads.scoped(jgA).read(B.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(w.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=vMQ(A,w.record.filename),f=X1($);if(!f)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let I=new Date().toISOString(),D=Sz.createDocumentEntity({dataUrl:TMQ(w.record.mediaType,w.content),filename:w.record.filename,title:$,attachmentType:"uploaded",dedupKey:`upload:${B.kind}:${B.id}`}),Y=await Q.entityService.createEntity({entity:{id:f,...D,created:I,updated:I},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:Y.entityId,status:"created",attachment:yMQ({entityId:Y.entityId,filename:w.record.filename})}}}}async getDedupKey(A,Q){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,w=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${B}:${w.contentHash}`:B}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return'For durable raw PDF saves/promotions from uploaded PDFs, call system_create with entityType: "document", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the raw PDF as a document. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Uploaded PDFs are not decks; raw upload promotion preserves the PDF as a document. Do not use entityType: "base" or transform: "extract-markdown" unless the user asks to turn the upload into a note/markdown. For generated/source-derived PDFs, call system_create with entityType: "document" and sourceAttachment. Deck carousel PDFs use sourceAttachment: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use sourceAttachment with attachmentType: "printable" and sourceEntityType "post", "project", or "product". Omit upload and sourceAttachment entirely for ordinary direct document creates that use content, prompt, or url. Include targetEntityType/targetEntityId when the user asks to attach the saved document to another entity. Use replace: true when they ask to regenerate or replace a saved PDF. Only use document_generate for explicit preview/prepare requests where they need an immediate PDF attachment. Do not use generic attachment types like "document".'}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return kgA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function vgA(){return new _gA}aA();WA();WA();aA();var xMQ=H.enum(["generating","failed"]),lF=H.object({title:H.string().optional(),status:xMQ.optional(),error:H.string().optional()}),jN1=lF.pick({title:!0,status:!0,error:!0}).extend({title:H.string()}),lz=A2.extend({entityType:H.literal("base"),metadata:jN1}),SMQ=lz.extend({frontmatter:lF,body:H.string()});aA();WA();class TgA extends q2{constructor(){super({entityType:"base",schema:lz,frontmatterSchema:lF})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,lF);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),B=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:B,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,lF)}catch{return{}}}buildStub(A){let Q={title:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:{title:A.title,status:"generating"}}}createNoteContent(A,Q){try{let B=this.parseFrontMatter(Q,H.record(H.unknown()));if(Object.keys(B).length===0)return Q;let w={...B,title:B.title??A},$=this.extractBody(Q);return this.buildMarkdown($,w)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var pz=new TgA;WA();var ygA=H.object({defaultPrompt:H.string().default("Create a note summarizing key concepts from my knowledge base")});WA();aA();var _N1=H.object({title:H.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:H.string().describe("Note content in markdown format with clear organization and structure")}),xgA=P1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:_N1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
6201
+ `).trim();if(!D)throw Error("Could not extract text from the uploaded PDF");return D}finally{await $.destroy()}}aA();WA();import{createHash as EMQ}from"crypto";var MMQ=26214400,CMQ=20,OMQ=60000,bN1=80,RMQ=10,f$A=H.object({renderUrl:H.string().url().optional(),sourceEntityType:H.string().min(1),sourceEntityId:H.string().min(1),attachmentType:H.string().min(1),documentId:H.string().min(1).optional(),title:H.string().min(1).optional(),filename:H.string().min(1).optional(),dedupKey:H.string().min(1).optional(),replace:H.boolean().optional(),pageCount:H.number().int().min(0).optional(),maxPageCount:H.number().int().positive().optional(),maxBytes:H.number().int().positive().optional(),timeoutMs:H.number().int().positive().optional(),width:H.union([H.string(),H.number()]).optional(),height:H.union([H.string(),H.number()]).optional(),format:H.string().optional(),targetEntityType:H.string().min(1).optional(),targetEntityId:H.string().min(1).optional()}),bv=f$A.refine((A)=>A.targetEntityType===void 0&&A.targetEntityId===void 0||A.targetEntityType!==void 0&&A.targetEntityId!==void 0,{message:"targetEntityType and targetEntityId must be provided together",path:["targetEntityId"]});class I$A extends ZB{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:bv,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??$X}async getDedupKey(A){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let Q=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,B=await this.context.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return B?`${Q}:${B.contentHash}`:Q}async process(A,Q,B){this.logger.debug("Starting document generation job",{jobId:Q,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});let w=A.maxPageCount??CMQ,$=A.maxBytes??MMQ,f=A.timeoutMs??OMQ;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=await this.getDedupKey(A),D=xi(A,I),Y=A.documentId!==void 0||A.filename!==void 0;if(A.replace!==!0){let U=await this.findDocumentByDedupKey(I,Y?D:void 0);if(U&&(!Y||U.id===D)){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,U.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:U.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let U=await this.resolveDocumentAttachment(A,D,{timeoutMs:f,maxBytes:$}),J=U.data;if(J.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${J.byteLength} bytes`);let X=iSA(J);if(X>w)throw Error(`Rendered PDF has ${X} pages, exceeding maxPageCount=${w}`);let G=X>0?X:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let Z=A.filename??(A.renderUrl===void 0?U.filename:`${D}.pdf`),N=Sz.createDocumentEntity({dataUrl:Z5A(J),filename:Z,...A.title&&{title:A.title},...G!==void 0&&{pageCount:G},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:D}))await this.context.entityService.deleteEntity({entityType:"document",id:D});if(await this.context.entityService.createEntity({entity:{...N,id:D}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,D,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:D,reused:!1}}catch(U){throw this.logger.error("Document generation failed",{jobId:Q,error:T0(U)}),U}}async resolveDocumentAttachment(A,Q,B){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:B.timeoutMs,maxBytes:B.maxBytes,printBackground:!0,preferCSSPageSize:!0,...A.width!==void 0&&{width:A.width},...A.height!==void 0&&{height:A.height},...A.format!==void 0&&{format:A.format}}),mimeType:"application/pdf",filename:A.filename??`${Q}.pdf`};let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);if(w.type!=="document")throw Error(`Attachment provider returned ${w.type}; expected document`);return w}async findDocumentByDedupKey(A,Q){let B=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(B.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:B.length,ids:B.map((w)=>w.id),preferredDocumentId:Q});return B.find((w)=>w.id===Q)??B[0]}async attachDocumentToTarget(A,Q,B,w){let $=await this.context.entityService.getEntity({entityType:A,id:Q});if(!$)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:f}=jB($.content),I=Array.isArray(f.documents)?f.documents.filter(PMQ):[],D=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,Y=D.some((U)=>U.id===B)?D:[...D,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:U4($.content,"documents",Y)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let f=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!f||!kMQ(f,B))w.push($)}return w}}function xi(A,Q){let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`,w=A.documentId??A.filename?.replace(/\.pdf$/i,"")??Q??B,$=A.replace===!0&&A.documentId===void 0?`${w}-${Date.now()}`:w;return bMQ($)}function bMQ(A){let Q=X1(A.replace(/[/:]+/g," "))||`document-${PN1(A)}`;if(Q.length<=bN1)return Q;let B=`-${PN1(A)}`;return`${Q.slice(0,bN1-B.length).replace(/-+$/g,"")}${B}`}function PN1(A){return EMQ("sha256").update(A).digest("hex").slice(0,RMQ)}function PMQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function kMQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}aA();function kgA(A,Q){return[oQ(A,"generate",'Preview or prepare a PDF document attachment from a source attachment or render URL. For save/regenerate durable document requests, including deck carousel PDFs and printable post/project/product PDFs, prefer system_create with entityType: "document" and from.',f$A,async(B,w)=>{let $=bv.safeParse(B);if(!$.success)return X$($.error.message);let f=xi($.data),I=await Q({...$.data,documentId:f},w),D=$.data.filename??`${f}.pdf`;return Y8({jobId:I,documentId:f,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var kN1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.122",description:"Document entity type for generated PDFs and publishable document attachments",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};var _MQ=H.object({}),jgA={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};function vMQ(A,Q){let B=A.title?.trim();if(B)return B;return Q.replace(/\.[^.]+$/,"").trim()||Q}function TMQ(A,Q){return`data:${A};base64,${Q.toString("base64")}`}function yMQ(A){let Q=encodeURIComponent(A.entityId);return{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${Q}`,downloadUrl:`/api/chat/attachments/document?id=${Q}&download=1`,filename:A.filename,source:{entityType:"document",entityId:A.entityId,attachmentType:"uploaded"}}}class _gA extends UB{entityType=Sz.entityType;schema=Gv;adapter=Sz;pluginContext;constructor(){super("document",kN1,{},_MQ)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.entities.registerCreateInterceptor(this.entityType,(Q)=>this.interceptCreate(Q)),A.jobs.registerHandler("generate",new I$A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){let Q=this.pluginContext;if(A.from?.kind===jgA.refKind){if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};return this.promoteUpload(A,Q)}if(!A.from)return{kind:"continue",input:A};if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=bv.parse({sourceEntityType:A.from.sourceEntityType,sourceEntityId:A.from.sourceEntityId,attachmentType:A.from.attachmentType,...A.title&&{title:A.title},...A.replace===!0&&{replace:!0},...A.targetEntityType&&{targetEntityType:A.targetEntityType},...A.targetEntityId&&{targetEntityId:A.targetEntityId}}),w=await this.getDedupKey(B,Q),f=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??xi(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:f}}),D=`${f}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:f,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(f)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(f)}&download=1`,filename:D,source:{entityType:"document",entityId:f,attachmentType:B.attachmentType}}}}}}async promoteUpload(A,Q){let B=A.from;if(B?.kind!==jgA.refKind)return{kind:"handled",result:{success:!1,error:"Unsupported upload ref kind"}};let w;try{w=await Q.uploads.scoped(jgA).read(B.id)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}if(w.record.mediaType!=="application/pdf")return{kind:"handled",result:{success:!1,error:"Only PDF uploads can be promoted to document entities"}};let $=vMQ(A,w.record.filename),f=X1($);if(!f)return{kind:"handled",result:{success:!1,error:"Could not derive a document id from the uploaded filename. Provide a title."}};let I=new Date().toISOString(),D=Sz.createDocumentEntity({dataUrl:TMQ(w.record.mediaType,w.content),filename:w.record.filename,title:$,attachmentType:"uploaded",dedupKey:`upload:${B.kind}:${B.id}`}),Y=await Q.entityService.createEntity({entity:{id:f,...D,created:I,updated:I},options:{deduplicateId:!0}});return{kind:"handled",result:{success:!0,data:{entityId:Y.entityId,status:"created",attachment:yMQ({entityId:Y.entityId,filename:w.record.filename})}}}}async getDedupKey(A,Q){if(A.dedupKey!==void 0)return A.dedupKey;if(A.renderUrl!==void 0)return`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl}`;let B=`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:resolved-attachment`,w=await Q.entityService.getEntity({entityType:A.sourceEntityType,id:A.sourceEntityId});return w?`${B}:${w.contentHash}`:B}async findExistingDocument(A,Q){return(await Q.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}}))[0]}async getInstructions(){return'For durable raw PDF saves/promotions from uploaded PDFs, call system_create with entityType: "document", the exact upload object shown in the current turn or conversation "Available upload refs" hint, and no transform. Do this only after the user explicitly asks to save/import/promote the raw PDF as a document. If that hint is absent, omit upload entirely; never invent upload IDs or placeholder upload refs. Uploaded PDFs are not decks; raw upload promotion preserves the PDF as a document. Do not use entityType: "base" or transform: "extract-markdown" unless the user asks to turn the upload into a note/markdown. For generated/source-derived PDFs, call system_create with entityType: "document" and sourceAttachment. Deck carousel PDFs use sourceAttachment: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use sourceAttachment with attachmentType: "printable" and sourceEntityType "post", "project", or "product". Omit upload and sourceAttachment entirely for ordinary direct document creates that use content, prompt, or url. Include targetEntityType/targetEntityId when the user asks to attach the saved document to another entity. Use replace: true when they ask to regenerate or replace a saved PDF. Only use document_generate for explicit preview/prepare requests where they need an immediate PDF attachment. Do not use generic attachment types like "document".'}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return kgA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function vgA(){return new _gA}aA();WA();WA();aA();var xMQ=H.enum(["generating","failed"]),lF=H.object({title:H.string().optional(),status:xMQ.optional(),error:H.string().optional()}),jN1=lF.pick({title:!0,status:!0,error:!0}).extend({title:H.string()}),lz=A2.extend({entityType:H.literal("base"),metadata:jN1}),SMQ=lz.extend({frontmatter:lF,body:H.string()});aA();WA();class TgA extends q2{constructor(){super({entityType:"base",schema:lz,frontmatterSchema:lF})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,lF);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.parseMarkdownFrontmatter(A),B=Q.title??this.extractH1(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:B,...Q.status&&{status:Q.status},...Q.error&&{error:Q.error}}}}parseNoteFrontmatter(A){return this.parseMarkdownFrontmatter(A.content)}parseMarkdownFrontmatter(A){try{return this.parseFrontMatter(A,lF)}catch{return{}}}buildStub(A){let Q={title:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:{title:A.title,status:"generating"}}}createNoteContent(A,Q){try{let B=this.parseFrontMatter(Q,H.record(H.unknown()));if(Object.keys(B).length===0)return Q;let w={...B,title:B.title??A},$=this.extractBody(Q);return this.buildMarkdown($,w)}catch{return Q}}extractH1(A){return A.match(/^#\s+(.+)$/m)?.[1]?.trim()??null}}var pz=new TgA;WA();var ygA=H.object({defaultPrompt:H.string().default("Create a note summarizing key concepts from my knowledge base")});WA();aA();var _N1=H.object({title:H.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:H.string().describe("Note content in markdown format with clear organization and structure")}),xgA=P1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:_N1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
6202
6202
 
6203
6203
  Your task is to generate a well-structured note based on the user's prompt.
6204
6204
 
@@ -6213,7 +6213,7 @@ title: ${JSON.stringify(A)}
6213
6213
  ---
6214
6214
 
6215
6215
  ${Q.trim()}
6216
- `}var cMQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},lMQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class ggA extends ZB{context;constructor(A,Q){super(A,{schema:lMQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(cMQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await xN1({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=pz.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"base",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function SN1({entity:A,config:Q}){let B=lz.parse(A),w=R2(B.content,lF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"base",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function hgA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:Gw["ai.rizom.brain.note"],validate:!1,buildRecord:SN1}}var gN1={name:"@brains/note",private:!0,version:"0.2.0-alpha.121",description:"Personal knowledge capture with markdown-first workflow",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var hN1={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};class mgA extends jQ{entityType=pz.entityType;schema=lz;adapter=pz;unregisterAtprotoProjection;constructor(A={}){super("note",gN1,A,ygA)}async interceptCreate(A,Q,B){if(A.from?.kind!==hN1.refKind)return{kind:"continue",input:A};if(A.transform!=="extract-markdown")return{kind:"handled",result:{success:!1,error:'Importing an upload as a note requires transform: "extract-markdown"'}};let w=A.from.id,$;try{$=await B.uploads.scoped(hN1).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!yN1($.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let f=SgA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}}),I=await B.jobs.enqueue({type:"upload-import",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I}}}}catch(f){return{kind:"handled",result:{success:!1,error:f instanceof Error?f.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new D$A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:xgA}}async onRegister(A){A.jobs.registerHandler("upload-import",new ggA(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let B=H.object({prompt:H.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=d6.getInstance().register(hgA())}async getInstructions(){return'To turn an uploaded text or PDF file into an editable markdown note, call system_create with entityType: "base", the exact upload object from the current turn or conversation upload refs hint, and transform: "extract-markdown". Use this only when the user explicitly asks to import, extract, or turn the upload into a note/markdown. Do not use this note-import pattern for raw file saves/promotions such as saving a PDF as a document or saving an image as an image; those use the raw upload with entityType "document" or "image" and no transform. Omit transform for ordinary direct note creates.'}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function UC(A={}){return new mgA(A)}aA();WA();WA();aA();var mN1=H.object({ref:H.string(),label:H.string()}),uN1=H.enum(["pending","draft","published"]),pF=H.object({status:uN1,title:H.string(),url:H.string().url(),description:H.string().optional(),domain:H.string(),capturedAt:H.string().datetime(),source:mN1}),cN1=pF.pick({title:!0,status:!0}),JC=A2.extend({entityType:H.literal("link"),metadata:cN1}),ugA=H.object({enableSummarization:H.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:H.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});aA();class iz extends q2{constructor(){super({entityType:"link",schema:JC,frontmatterSchema:pF})}createLinkContent(A){let Q={status:A.status,title:A.title,url:A.url,description:A.description,domain:A.domain,capturedAt:A.capturedAt,source:A.source},B=A.summary??"";return this.buildMarkdown(B,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,pF),summary:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseLinkContent(A);return{content:A,entityType:"link",metadata:{title:Q.title,status:Q.status}}}}var Pv=new iz;aA();WA();var iMQ=H.object({success:H.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:H.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:H.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:H.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:H.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),lN1=P1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:iMQ,basePrompt:`You are an expert at extracting key information from webpage content.
6216
+ `}var cMQ={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"},lMQ=H.object({uploadId:H.string().min(1),title:H.string().optional()});class ggA extends ZB{context;constructor(A,Q){super(A,{schema:lMQ,jobTypeName:"upload-import"});this.context=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Reading uploaded file"});let w=await this.context.uploads.scoped(cMQ).read(A.uploadId);await this.reportProgress(B,{progress:35,message:"Extracting markdown from upload"});let $=await xN1({upload:w,...A.title!==void 0?{title:A.title}:{}});await this.reportProgress(B,{progress:80,message:"Saving imported note"});let f=new Date().toISOString(),I=pz.fromMarkdown($.content),D=await this.context.entityService.createEntity({entity:{id:$.id,entityType:"base",content:$.content,metadata:{title:$.title,...I.metadata},created:f,updated:f},options:{deduplicateId:!0}});return await this.reportProgress(B,{progress:100,message:"Upload imported as markdown note"}),{entityId:D.entityId,status:"created"}}summarizeDataForLog(A){return{uploadId:A.uploadId,hasTitle:A.title!==void 0}}}aA();async function SN1({entity:A,config:Q}){let B=lz.parse(A),w=R2(B.content,lF);return{$type:"ai.rizom.brain.note",title:B.metadata.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"base",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function hgA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:Gw["ai.rizom.brain.note"],validate:!1,buildRecord:SN1}}var gN1={name:"@brains/note",private:!0,version:"0.2.0-alpha.122",description:"Personal knowledge capture with markdown-first workflow",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/document":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var hN1={namespace:"upload",refKind:"upload",routePath:"/api/chat/uploads"};class mgA extends jQ{entityType=pz.entityType;schema=lz;adapter=pz;unregisterAtprotoProjection;constructor(A={}){super("note",gN1,A,ygA)}async interceptCreate(A,Q,B){if(A.from?.kind!==hN1.refKind)return{kind:"continue",input:A};if(A.transform!=="extract-markdown")return{kind:"handled",result:{success:!1,error:'Importing an upload as a note requires transform: "extract-markdown"'}};let w=A.from.id,$;try{$=await B.uploads.scoped(hN1).readRecord(w)}catch{return{kind:"handled",result:{success:!1,error:"Upload ref not found"}}}try{if(!yN1($.mediaType))return{kind:"handled",result:{success:!1,error:"Only text, JSON, and PDF uploads can be imported as markdown notes"}};let f=SgA({filename:$.filename,...A.title!==void 0?{title:A.title}:{}}),I=await B.jobs.enqueue({type:"upload-import",data:{uploadId:w,...A.title!==void 0?{title:A.title}:{}}});return{kind:"handled",result:{success:!0,data:{entityId:f.id,status:"generating",jobId:I}}}}catch(f){return{kind:"handled",result:{success:!1,error:f instanceof Error?f.message:"Failed to import upload as markdown"}}}}createGenerationHandler(A){return new D$A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:xgA}}async onRegister(A){A.jobs.registerHandler("upload-import",new ggA(this.logger.child("UploadMarkdownImportJobHandler"),A)),A.eval.registerHandler("generateNote",async(Q)=>{let B=H.object({prompt:H.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=d6.getInstance().register(hgA())}async getInstructions(){return'To turn an uploaded text or PDF file into an editable markdown note, call system_create with entityType: "base", the exact upload object from the current turn or conversation upload refs hint, and transform: "extract-markdown". Use this only when the user explicitly asks to import, extract, or turn the upload into a note/markdown. Do not use this note-import pattern for raw file saves/promotions such as saving a PDF as a document or saving an image as an image; those use the raw upload with entityType "document" or "image" and no transform. Omit transform for ordinary direct note creates.'}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function UC(A={}){return new mgA(A)}aA();WA();WA();aA();var mN1=H.object({ref:H.string(),label:H.string()}),uN1=H.enum(["pending","draft","published"]),pF=H.object({status:uN1,title:H.string(),url:H.string().url(),description:H.string().optional(),domain:H.string(),capturedAt:H.string().datetime(),source:mN1}),cN1=pF.pick({title:!0,status:!0}),JC=A2.extend({entityType:H.literal("link"),metadata:cN1}),ugA=H.object({enableSummarization:H.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:H.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});aA();class iz extends q2{constructor(){super({entityType:"link",schema:JC,frontmatterSchema:pF})}createLinkContent(A){let Q={status:A.status,title:A.title,url:A.url,description:A.description,domain:A.domain,capturedAt:A.capturedAt,source:A.source},B=A.summary??"";return this.buildMarkdown(B,Q)}parseLinkContent(A){return{frontmatter:this.parseFrontMatter(A,pF),summary:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseLinkContent(A);return{content:A,entityType:"link",metadata:{title:Q.title,status:Q.status}}}}var Pv=new iz;aA();WA();var iMQ=H.object({success:H.boolean().describe("Set to true if you can extract meaningful content. Set to false only if the provided content is empty, just an error message, or otherwise unusable."),error:H.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:H.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:H.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:H.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),lN1=P1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:iMQ,basePrompt:`You are an expert at extracting key information from webpage content.
6217
6217
 
6218
6218
  You will receive webpage content in markdown format. Your job is to extract structured information from it.
6219
6219
 
@@ -6235,7 +6235,7 @@ Accuracy rules:
6235
6235
 
6236
6236
  `))return{success:!1,error:I.trim(),errorType:"fetch_failed"};return{success:!0,content:I}}catch(B){return this.handleFetchError(B,A)}}handleHttpError(A,Q){if(A===400)return{success:!1,error:`Invalid or non-existent URL: ${Q}`,errorType:"url_not_found"};if(A===404)return{success:!1,error:`Page not found: ${Q}`,errorType:"url_not_found"};if(A>=500)return{success:!1,error:`Server error while fetching ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`HTTP ${A} error while fetching ${Q}`,errorType:"fetch_failed"}}handleFetchError(A,Q){if(A instanceof Error){if(A.name==="AbortError")return{success:!1,error:`Request timeout while fetching ${Q}`,errorType:"url_unreachable"};if(A.message.includes("ENOTFOUND")||A.message.includes("getaddrinfo"))return{success:!1,error:`Domain not found: ${new URL(Q).hostname}`,errorType:"url_not_found"};if(A.message.includes("ECONNREFUSED")||A.message.includes("ETIMEDOUT"))return{success:!1,error:`Could not connect to ${Q}`,errorType:"url_unreachable"};return{success:!1,error:`Failed to fetch ${Q}: ${A.message}`,errorType:"fetch_failed"}}return{success:!1,error:`Unknown error fetching ${Q}`,errorType:"fetch_failed"}}}import{createHash as oMQ}from"crypto";class XC{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(XC.URL_PATTERN)??[];return[...new Set(Q)]}static normalizeUrl(A){try{let Q=new URL(A),B=Q.pathname.replace(/\/$/,"")||"/";return`${Q.protocol}//${Q.host}${B}`}catch{return A}}static generateEntityId(A){let Q=this.normalizeUrl(A),B=oMQ("sha256").update(Q).digest("hex");try{return`${new URL(Q).hostname.replace(/\./g,"-")}-${B.substring(0,6)}`}catch{return B.substring(0,12)}}static isValidUrl(A){try{let Q=new URL(A);return["http:","https:"].includes(Q.protocol)}catch{return!1}}}aA();WA();H6();var sMQ=H.object({url:H.string().url(),metadata:H.object({interfaceId:H.string().optional(),userId:H.string().optional(),channelId:H.string().optional(),channelName:H.string().optional(),timestamp:H.string().optional()}).optional()}),tow=H.object({success:H.boolean(),entityId:H.string().optional(),title:H.string().optional(),url:H.string().optional(),status:H.enum(["pending","draft","published"]).optional(),error:H.string().optional()});class U$A extends ZB{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:sMQ,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new iz,this.urlFetcher=new kv(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:zQ.START,total:100,message:"Starting link capture"});let f=XC.generateEntityId(w);await B.report({progress:zQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:f});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:f});let{frontmatter:Z}=this.linkAdapter.parseLinkContent(I.content);return{success:!0,entityId:I.id,title:Z.title,url:w,status:I.metadata.status}}await B.report({progress:zQ.FETCH,total:100,message:"Fetching webpage content"});let D=await this.urlFetcher.fetch(w);if(!D.success){if(D.errorType==="url_not_found"||D.errorType==="url_unreachable")return this.logger.warn("Link URL not accessible",{url:w,errorType:D.errorType,error:D.error}),{success:!1,error:`Could not capture link: ${D.error}`}}await B.report({progress:zQ.PROCESS,total:100,message:"Extracting content with AI"});let Y=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
6237
6237
 
6238
- ${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:zQ.EXTRACT,total:100,message:"Processing extraction results"});let U=this.resolveSource($),J=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:zQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:J,source:U}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:zQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:zQ.SAVE,total:100,message:`Saving link: "${Y.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:J,source:U}),G=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:zQ.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:G.entityId,title:Y.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),$5.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function rN1({entity:A,config:Q}){let B=JC.parse(A),{frontmatter:w,summary:$}=Pv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function dgA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Gw["ai.rizom.brain.link"],validate:!1,buildRecord:rN1}}var dN1={name:"@brains/link",private:!0,version:"0.2.0-alpha.121",description:"Web content capture plugin with AI-powered extraction and structured storage",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ngA extends jQ{entityType=Pv.entityType;schema=JC;adapter=Pv;shell;unregisterAtprotoProjection;constructor(A={}){super("link",dN1,A,ugA)}async register(A){this.shell=A;let Q=await super.register(A);if(!this.context)throw Error("LinkPlugin context was not initialized during register()");return A.getJobQueueService().registerHandler("link-capture",new U$A(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,Y=this.extractFirstUrl(A.content);if(I&&D&&Y){let U=X1(Y)||X1(I)||`${A.entityType}-${Date.now()}`,J=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:U,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:J,updated:J}})).entityId,status:"created"}}}}}catch{}let w=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if(w){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:w,metadata:{interfaceId:Q.interfaceType,userId:Q.userId,...Q.channelId?{channelId:Q.channelId}:{},...Q.channelName?{channelName:Q.channelName}:{},timestamp:new Date().toISOString()}},options:{source:this.id,metadata:{operationType:"data_processing",pluginId:this.id,interfaceType:Q.interfaceType,...Q.channelId?{channelId:Q.channelId}:{}}}})}}}}catch($){return{kind:"handled",result:{success:!1,error:$ instanceof Error?$.message:"Failed to queue link capture job"}}}}if(A.content)return{kind:"handled",result:{success:!1,error:"Direct link creation requires full link markdown/frontmatter, or provide a URL to capture."}};if(A.prompt)return{kind:"handled",result:{success:!1,error:"Link creation requires a URL in the prompt, content, or title, or full link markdown content for direct creation."}};return{kind:"continue",input:A}}createGenerationHandler(A){return new U$A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:lN1,"link-list":pN1,"link-detail":iN1}}getDataSources(){return[new rgA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=d6.getInstance().register(dgA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=H.object({url:H.string().url()}).parse(Q),$=await new kv(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(B);if(!$.success)return{success:!1,error:$.error,errorType:$.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
6238
+ ${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:zQ.EXTRACT,total:100,message:"Processing extraction results"});let U=this.resolveSource($),J=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:zQ.SAVE,total:100,message:"Saving link as pending"});let N=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:J,source:U}),L=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:N,metadata:{status:"pending",title:Z}}});return await B.report({progress:zQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:zQ.SAVE,total:100,message:`Saving link: "${Y.title}"`});let X=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:J,source:U}),G=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:X,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:zQ.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:G.entityId,title:Y.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),$5.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}async function rN1({entity:A,config:Q}){let B=JC.parse(A),{frontmatter:w,summary:$}=Pv.parseLinkContent(B.content);return{$type:"ai.rizom.brain.link",title:w.title,url:w.url,...w.description&&{description:w.description},...$&&{summary:$},domain:w.domain,capturedAt:w.capturedAt,source:w.source,...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"link",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function dgA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:Gw["ai.rizom.brain.link"],validate:!1,buildRecord:rN1}}var dN1={name:"@brains/link",private:!0,version:"0.2.0-alpha.122",description:"Web content capture plugin with AI-powered extraction and structured storage",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ngA extends jQ{entityType=Pv.entityType;schema=JC;adapter=Pv;shell;unregisterAtprotoProjection;constructor(A={}){super("link",dN1,A,ugA)}async register(A){this.shell=A;let Q=await super.register(A);if(!this.context)throw Error("LinkPlugin context was not initialized during register()");return A.getJobQueueService().registerHandler("link-capture",new U$A(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,Y=this.extractFirstUrl(A.content);if(I&&D&&Y){let U=X1(Y)||X1(I)||`${A.entityType}-${Date.now()}`,J=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:U,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:J,updated:J}})).entityId,status:"created"}}}}}catch{}let w=A.url??this.extractFirstUrl(A.content,A.prompt,A.title);if(w){if(!this.shell)throw Error("LinkPlugin shell was not initialized during register()");try{return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await this.shell.getJobQueueService().enqueue({type:"link-capture",data:{url:w,metadata:{interfaceId:Q.interfaceType,userId:Q.userId,...Q.channelId?{channelId:Q.channelId}:{},...Q.channelName?{channelName:Q.channelName}:{},timestamp:new Date().toISOString()}},options:{source:this.id,metadata:{operationType:"data_processing",pluginId:this.id,interfaceType:Q.interfaceType,...Q.channelId?{channelId:Q.channelId}:{}}}})}}}}catch($){return{kind:"handled",result:{success:!1,error:$ instanceof Error?$.message:"Failed to queue link capture job"}}}}if(A.content)return{kind:"handled",result:{success:!1,error:"Direct link creation requires full link markdown/frontmatter, or provide a URL to capture."}};if(A.prompt)return{kind:"handled",result:{success:!1,error:"Link creation requires a URL in the prompt, content, or title, or full link markdown content for direct creation."}};return{kind:"continue",input:A}}createGenerationHandler(A){return new U$A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:lN1,"link-list":pN1,"link-detail":iN1}}getDataSources(){return[new rgA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=d6.getInstance().register(dgA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=H.object({url:H.string().url()}).parse(Q),$=await new kv(this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0).fetch(B);if(!$.success)return{success:!1,error:$.error,errorType:$.errorType};return A.ai.generate({templateName:"link:extraction",prompt:`Extract structured information from this webpage content:
6239
6239
 
6240
6240
  ${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=XC.extractUrls(Q);if(B)return B}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function nN1(A={}){return new ngA(A)}var WC=nN1;WA();var Msw=H.object({id:H.string().optional(),metadata:H.object({conversationId:H.string().optional(),interfaceId:H.string().optional(),userId:H.string().optional(),messageId:H.string().optional(),timestamp:H.string().optional()}).optional()});aA();WA();Ew();WA();aA();var oN1=H.enum(["generating","draft","published","failed"]),O$=H.object({title:H.string(),slug:H.string().optional(),status:oN1,publishedAt:H.string().datetime().optional(),description:H.string(),year:H.number(),coverImageId:H.string().optional(),ogImageId:H.string().optional(),url:H.string().url().optional()}),sN1=O$.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:H.string(),error:H.string().optional()}),rz=A2.extend({entityType:H.literal("project"),metadata:sN1}),J$A=H.object({context:H.string(),problem:H.string(),solution:H.string(),outcome:H.string()}),gi=rz.extend({frontmatter:O$,body:H.string(),structuredContent:J$A.optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional()}),jv=gi.extend({url:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()}),tMQ=gi.extend({url:H.string(),typeLabel:H.string(),coverImageUrl:H.string().optional(),ogImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();o$();class ogA extends lB{constructor(){super(J$A,{title:"Project",mappings:[{key:"context",label:"Context",type:"string"},{key:"problem",label:"Problem",type:"string"},{key:"solution",label:"Solution",type:"string"},{key:"outcome",label:"Outcome",type:"string"}]})}}var sgA=new ogA;class agA extends q2{constructor(){super({entityType:"project",schema:rz,frontmatterSchema:O$,supportsCoverImage:!0,bodyFormatter:sgA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,O$),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,O$),B=Q.slug??X1(Q.title);return{content:A,entityType:"project",metadata:{title:Q.title,slug:B,status:Q.status,publishedAt:Q.publishedAt,year:Q.year}}}parseProjectFrontmatter(A){return this.parseFrontMatter(A.content,O$)}parseStructuredContent(A){return sgA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=sgA.format(Q);return this.buildMarkdown(B,A)}buildStub(A){let Q=new Date().getUTCFullYear(),B={title:A.title,slug:A.id,status:"generating",description:"",year:Q};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:A.id,status:"generating",year:Q}}}}var dz=new agA;WA();var tgA=H.object({});import{jsxDEV as MD,Fragment as ACQ}from"preact/jsx-dev-runtime";var eMQ=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return MD(PB,{href:B,children:[w&&MD("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),MD(U9,{children:Q.title},void 0,!1,void 0,this),MD("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},egA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",f=B?.totalItems??A.length,I=`Browse all ${f} ${f===1?"project":"projects"}`;return MD(ACQ,{children:[MD(KQ,{title:$,description:I},void 0,!1,void 0,this),MD("div",{className:"project-list bg-theme",children:MD("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[MD("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),MD("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>MD(eMQ,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&MD("div",{className:"mt-12",children:MD(VF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as fw,Fragment as aN1}from"preact/jsx-dev-runtime";var QCQ=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return fw("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:fw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?fw(PB,{href:A.url,variant:"compact",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),fw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:A.metadata.title},void 0,!1,void 0,this)]},void 0,!0,void 0,this):fw("div",{},void 0,!1,void 0,this),Q&&fw(PB,{href:Q.url,variant:"compact",className:"md:text-right",children:[fw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),fw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Q.metadata.title},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},X$A=({title:A,content:Q})=>{if(!Q)return null;return fw("section",{className:"mb-12",children:[fw("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),fw(V$,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},AhA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A,D=A.ogImageUrl??I;return fw(aN1,{children:[fw(KQ,{title:w.title,description:w.description,...D?{ogImage:D}:{},ogType:"article"},void 0,!1,void 0,this),fw("article",{className:"project-detail",children:fw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:fw("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&fw(qF,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),fw("h1",{className:"text-4xl md:text-5xl font-bold text-heading leading-tight tracking-tight mb-4",children:w.title},void 0,!1,void 0,this),fw("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[fw("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),w.url&&fw(aN1,{children:[fw("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),fw("a",{href:w.url,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:"View Project"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),fw("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&fw("div",{className:"case-study",children:[fw(X$A,{title:"Context",content:$.context},void 0,!1,void 0,this),fw(X$A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),fw(X$A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),fw(X$A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),fw(QCQ,{prevProject:Q,nextProject:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();aA();var BCQ=H.object({title:H.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:H.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:H.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:H.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:H.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:H.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),QhA=P1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:BCQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
6241
6241
 
@@ -6411,7 +6411,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
6411
6411
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
6412
6412
  }
6413
6413
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
6414
- `}},void 0,!1,void 0,this),R$("section",{className:"project-shell",children:[R$("header",{className:"project-hero",children:[R$("div",{className:"project-index",children:[Q.brandLabel&&R$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&R$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$("div",{className:"project-title-panel",children:[R$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),R$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&R$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),R$("div",{className:"printable-meta",children:[Q.year&&R$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&R$("span",{children:Q.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&R$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),R$(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&R$("footer",{className:"printable-footer",children:[R$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?R$("a",{href:Q.canonicalUrl??Q.url,children:Q.canonicalUrl??Q.url},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var XCQ=26214400,WCQ=60000;class $hA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==G$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=HCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await DCQ(JCQ(UCQ(),"brain-project-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:A31,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:XCQ,timeoutMs:WCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${GCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await YCQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=O$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function HCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=O$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function GCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as ZCQ}from"preact/jsx-dev-runtime";var K$A="og-image",KCQ="portfolio:og-image",Q31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),B31={name:KCQ,pluginId:"portfolio",schema:Q31,renderers:{image:FCQ}};function FCQ(A){let Q=Q31.parse(A);return ZCQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class fhA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==K$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=O$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/project/${Q.id}`,template:B31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${NCQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function NCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var w31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.121",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var qCQ=H.object({projects:H.array(jv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()});function LCQ(A,Q){for(let B of[A,Q]){let w=B?.match(/\b(19\d{2}|20\d{2})\b/);if(w?.[1])return Number(w[1])}return null}class IhA extends jQ{entityType=dz.entityType;schema=rz;adapter=dz;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",w31,A,tgA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=LCQ(A.title,A.prompt);if(!w)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await B.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:w},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new W$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:qCQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:egA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:jv,prevProject:jv.nullable(),nextProject:jv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:AhA}}),generation:QhA}}getDataSources(){return[new H$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",G$A,new $hA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",K$A,new fhA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=d6.getInstance().register(whA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:BhA(B),templateName:"portfolio:generation"})})}deferPublishRegistration(A){let Q={name:"internal",publish:async()=>({id:"internal"})};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=R2($.content,O$),I=new Date().toISOString(),D=b9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}}function DhA(A={}){return new IhA(A)}aA();WA();var VCQ=H.enum(["public","shared","restricted"]),$31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:VCQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var ECQ=H.object({}),_v=A2.extend({entityType:H.literal("topic"),metadata:ECQ}),ztw=H.object({content:H.string()}),f31=H.object({title:H.string().describe("Topic title")});var HC="topics",Iw="topic",YhA="topics-projection",I31="topic:project",F$A="topics-plugin",D31="topics:batch-completed",Y31="topics-source-batch";class IX extends q2{constructor(){super({entityType:Iw,schema:_v,frontmatterSchema:f31})}buildFrontmatter(A){return{title:A}}toMarkdown(A){let Q=this.parseTopicBody(A.content);return this.buildMarkdown(Q.content,this.buildFrontmatter(Q.title))}fromMarkdown(A){return{content:A,entityType:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var MCQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),U31=H.array(MCQ);var CCQ=H.object({topics:U31}),J31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:CCQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
6414
+ `}},void 0,!1,void 0,this),R$("section",{className:"project-shell",children:[R$("header",{className:"project-hero",children:[R$("div",{className:"project-index",children:[Q.brandLabel&&R$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&R$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$("div",{className:"project-title-panel",children:[R$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),R$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&R$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),R$("div",{className:"printable-meta",children:[Q.year&&R$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&R$("span",{children:Q.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q.coverImageUrl&&R$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),R$(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&R$("footer",{className:"printable-footer",children:[R$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?R$("a",{href:Q.canonicalUrl??Q.url,children:Q.canonicalUrl??Q.url},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var XCQ=26214400,WCQ=60000;class $hA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==G$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=HCQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await DCQ(JCQ(UCQ(),"brain-project-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:A31,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:XCQ,timeoutMs:WCQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${GCQ(Q)}-printable.pdf`}}finally{await f.close()}}finally{await YCQ(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){let{frontmatter:Q}=jB(A.content),B=O$.parse(Q);if(!B.coverImageId)return;let w=await this.context.entityService.getEntity({entityType:"image",id:B.coverImageId});return w?.content.startsWith("data:image/")?w.content:void 0}}function HCQ(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=O$.parse(B);return{title:$.title,body:w,...$.description?{description:$.description}:{},year:$.year,...$.publishedAt?{publishedAt:$.publishedAt}:{},...$.url?{url:$.url,canonicalUrl:$.url}:{},...Q.coverImageUrl?{coverImageUrl:Q.coverImageUrl}:{},...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function GCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}WA();WA();import{jsxDEV as ZCQ}from"preact/jsx-dev-runtime";var K$A="og-image",KCQ="portfolio:og-image",Q31=H.object({title:H.string().min(1),description:H.string().optional(),year:H.number().optional(),brandLabel:H.string().optional(),coverImageUrl:H.string().optional()}),B31={name:KCQ,pluginId:"portfolio",schema:Q31,renderers:{image:FCQ}};function FCQ(A){let Q=Q31.parse(A);return ZCQ(zF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class fhA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==K$A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=jB(Q.content),w=O$.parse(B),$=this.resolveBrandLabel(),f=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...f?{coverImageUrl:f}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/project/${Q.id}`,template:B31,content:I,title:I.title,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-project-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${NCQ(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}async resolveCoverImageUrl(A){if(!A)return;let Q=await this.context.entityService.getEntity({entityType:"image",id:A});return Q?.content.startsWith("data:image/")?Q.content:void 0}}function NCQ(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.title)}var w31={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.122",description:"Portfolio showcase for projects and case studies",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest",typescript:"^5.3.3"}};var qCQ=H.object({projects:H.array(jv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()});function LCQ(A,Q){for(let B of[A,Q]){let w=B?.match(/\b(19\d{2}|20\d{2})\b/);if(w?.[1])return Number(w[1])}return null}class IhA extends jQ{entityType=dz.entityType;schema=rz;adapter=dz;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",w31,A,tgA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=LCQ(A.title,A.prompt);if(!w)return{kind:"continue",input:A};return{kind:"handled",result:{success:!0,data:{status:"generating",jobId:await B.jobs.enqueue({type:"project:generation",data:{prompt:A.prompt,...A.title?{title:A.title}:{},year:w},toolContext:Q,options:{source:this.id,metadata:{operationType:"content_operations"}}})}}}}createGenerationHandler(A){return new W$A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":P1({name:"project-list",description:"Portfolio project list page template",schema:qCQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:egA}}),"project-detail":P1({name:"project-detail",description:"Individual project case study template",schema:H.object({project:jv,prevProject:jv.nullable(),nextProject:jv.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:AhA}}),generation:QhA}}getDataSources(){return[new H$A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",G$A,new $hA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",K$A,new fhA(A)),this.deferPublishRegistration(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=d6.getInstance().register(whA())}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}registerEvalHandlers(A){A.eval.registerHandler("generateProject",async(Q)=>{let B=H.object({prompt:H.string(),year:H.number()}).parse(Q);return A.ai.generate({prompt:BhA(B),templateName:"portfolio:generation"})})}deferPublishRegistration(A){let Q={name:"internal",publish:async()=>({id:"internal"})};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q,config:{executionMode:"provider"}}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w}=Q.payload;if(B!=="project")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"project",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Project not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=R2($.content,O$),I=new Date().toISOString(),D=b9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:T0($)}})}return{success:!0}})}}function DhA(A={}){return new IhA(A)}aA();WA();var VCQ=H.enum(["public","shared","restricted"]),$31=H.object({includeEntityTypes:H.array(H.string()).default([]),minRelevanceScore:H.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:H.number().min(0).max(1).default(0.85),autoMerge:H.boolean().default(!0),extractableStatuses:H.array(H.string()).default(["published"]),enableAutoExtraction:H.boolean().default(!0),extractionVisibility:VCQ.default("public"),sourceChangeBatchDelayMs:H.number().int().min(0).default(1000)});aA();WA();aA();var ECQ=H.object({}),_v=A2.extend({entityType:H.literal("topic"),metadata:ECQ}),ztw=H.object({content:H.string()}),f31=H.object({title:H.string().describe("Topic title")});var HC="topics",Iw="topic",YhA="topics-projection",I31="topic:project",F$A="topics-plugin",D31="topics:batch-completed",Y31="topics-source-batch";class IX extends q2{constructor(){super({entityType:Iw,schema:_v,frontmatterSchema:f31})}buildFrontmatter(A){return{title:A}}toMarkdown(A){let Q=this.parseTopicBody(A.content);return this.buildMarkdown(Q.content,this.buildFrontmatter(Q.title))}fromMarkdown(A){return{content:A,entityType:Iw}}extractMetadata(A){return{}}generateFrontMatter(A){let Q=this.parseTopicBody(A.content),w=this.buildMarkdown("",this.buildFrontmatter(Q.title)).match(/^---\n[\s\S]*?\n---/);return w?w[0]:""}parseTopicBody(A){if(A.startsWith("---"))try{let Q=this.parseFrontmatter(A);return{content:this.extractBody(A).replace(/\n*## Sources[\s\S]*$/,"").trim(),formatted:A,title:Q.title}}catch{return{content:A,formatted:A,title:"Unknown Topic"}}return{content:A,formatted:A,title:"Unknown Topic"}}createTopicBody(A){return this.buildMarkdown(A.content,this.buildFrontmatter(A.title))}}aA();WA();WA();var MCQ=H.object({title:H.string().max(100),content:H.string(),relevanceScore:H.number().min(0).max(1)}),U31=H.array(MCQ);var CCQ=H.object({topics:U31}),J31=P1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:CCQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
6415
6415
 
6416
6416
  Analyze the provided content and extract meaningful topics discussed.
6417
6417
 
@@ -6514,13 +6514,13 @@ ${A.incomingTopic.content}`})}}function xCQ(A){if(A.length===0)return"";return A
6514
6514
 
6515
6515
  ${Q.content}`}).join(`
6516
6516
 
6517
- `)}async function GC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",Y=L31(A),U=new DX(Q.entityService,B),J=w.topicMergeSynthesizer??new GhA(Q,B),X=await L$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,L=0;for(let M of Y){B.info(`Processing batch of ${M.length} entities`);let O=xCQ(M),E=V$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let y=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((T)=>T.relevanceScore>=$);for(let T of y)try{if(f){let g=await U.findMergeCandidate({incoming:T,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:T}),m=await U.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${T.title}`);G.set(m.id,m),N++;continue}}let _=U.getTopicIdForTitle(T.title,D);if(G.has(_)){L++;continue}let x=await U.createTopicOptimistic({title:T.title,content:T.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else L++}catch(_){B.error("Topic batch item failed",{title:T.title,error:T0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:T0(S)})}}let V={created:Z,merged:N,skipped:L,batches:Y.length};if(Z>0||N>0)await Q.messaging.send({type:D31,payload:V,broadcast:!0});return V}aA();WA();var SCQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class KhA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function R31(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return gCQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=SCQ.safeParse($??{});return f.success?f.data:null}}}async function gCQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(U)=>({ref:U,entity:await A.context.entityService.getEntity({entityType:U.entityType,id:U.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:U,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==U.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!KN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let Y=await GC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...Y,stale:w,missing:$,unpublished:f,hidden:I}}function b31(){return{priority:5,source:F$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:HC}}}async function P31(A){let Q=await j31(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await GC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function k31(A){let Q=await j31(A),B=await FhA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function FhA(A,Q,B,w){let $=new DX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await GC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function j31(A){let Q=hCQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function hCQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var yv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),mCQ=yv.extend({minRelevanceScore:H.number().optional()}),uCQ=H.object({contentA:yv,contentB:yv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),ci=H.object({title:H.string(),content:H.string()}),cCQ=H.object({existingTopics:H.array(ci),incomingTopic:ci,threshold:H.number().optional()}),lCQ=H.object({existingTopics:H.array(ci).default([]),incomingTopic:ci.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),pCQ=H.object({entities:H.array(yv).min(1),minRelevanceScore:H.number().optional()}),iCQ=H.object({existingTopics:H.array(ci).optional(),entities:H.array(yv)}),rCQ=H.object({entities:H.array(yv)});function Tv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function _31(A){return{title:A.title,relevanceScore:A.relevanceScore}}function dCQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function nCQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:dCQ(Q)}]}}async function KC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function oCQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function v31(A){let{context:Q,logger:B,config:w}=A,$=new HhA(Q,B),f=async(I,D,Y="")=>{let U=Tv(I,Y);return $.extractFromEntity(U,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await KC(Q);let D=mCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=Tv(D);return(await $.extractFromEntity(U,Y)).map((X)=>nCQ(X,U))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await KC(Q);let D=uCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,Y,"-a"),f(D.contentB,Y,"-b")]),G=new DX(Q.entityService,B),Z=[];for(let V of J){let M=await G.createTopic(V);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(V)=>{let M=await G.findMergeCandidate({incoming:V,threshold:U,additionalCandidates:Z});if(!M)return null;return{incomingTitle:V.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((V)=>V!==null),L=N.map((V)=>V.candidateTitle);return{topicsA:J.map(_31),topicsB:X.map(_31),matchingTitles:L,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await KC(Q);let D=cCQ.parse(I),Y=D.threshold??w.mergeSimilarityThreshold,U=new DX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await U.createTopic(G);if(Z)J.push(Z)}let X=await U.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:Y,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await KC(Q);let D=lCQ.parse(I),Y=new DX(Q.entityService,B);for(let G of D.existingTopics)await Y.createTopic({title:G.title,content:G.content});await oCQ(Q);let U=Tv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await GC([U],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(XhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await KC(Q);let D=iCQ.parse(I),Y=new DX(Q.entityService,B);for(let G of D.existingTopics??[])await Y.createTopic(G);let U=D.entities.map((G,Z)=>Tv(G,`-rebuild-${Z}`)),J=await FhA(U,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(XhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await KC(Q);let D=pCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=new DX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=Tv(Z,`-sequential-${G}`),L=await $.extractFromEntity(N,Y);for(let V of L)await U.createTopic({title:V.title,content:V.content});J.push({extractedTitles:L.map((V)=>V.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(vv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await KC(Q);let Y=rCQ.parse(I).entities.map((X,G)=>Tv(X,`-batch-${G}`)),U=await GC(Y,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...U,topics:J.map(vv)}})}var sCQ=new IX;async function T31({entity:A,config:Q}){let B=_v.parse(A),w=sCQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function ZhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Gw["ai.rizom.brain.topic"],validate:!1,buildRecord:T31}}var y31={name:"@brains/topics",private:!0,version:"0.2.0-alpha.121",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var tCQ=new IX;class x31 extends jQ{entityType=Iw;schema=_v;adapter=tCQ;unregisterAtprotoProjection;sourceBatch=new KhA;constructor(A={}){super(HC,y31,A,$31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:J31,"merge-synthesis":X31,"topic-list":W31,"topic-detail":H31}}getDataSources(){return[new WhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:YhA,targetType:Iw,job:{type:I31,handler:R31({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await OL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:b31()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!KN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:F$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:Y31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:HC}})}}]}async onRegister(A){A.insights.register("topic-distribution",F31()),Z31({context:A,pluginId:this.id}),v31({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=d6.getInstance().register(ZhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(YhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await P31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await k31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function E$A(A){return new x31(A)}aA();WA();aA();var NhA=H.enum(["linkedin"]),zhA=H.enum(["generating","draft","queued","published","failed"]),S31=H.enum(["post","deck"]),g31=H.object({id:H.string().min(1).describe("Document entity ID")}),oY=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:NhA.describe("Target platform"),status:zhA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(g31).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:S31.optional().describe("Source entity type (post, deck)")}),h31=oY.extend({platform:NhA.optional(),status:zhA.optional()}),m31=oY.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),nz=A2.extend({entityType:H.literal("social-post"),metadata:m31}),M$A=nz.extend({frontmatter:oY,body:H.string()}),C$A=M$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class qhA extends q2{constructor(){super({entityType:"social-post",schema:nz,frontmatterSchema:oY,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,oY),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,h31),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,oY)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var s9=new qhA;aA();aA();WA();var eCQ=QW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),AOQ=BW.extend({query:eCQ.optional()});function u31(A){let Q=R2(A.content,oY);return M$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class O$A extends m5{id="social-media:posts";name="Social Post DataSource";description="Fetches and transforms social post entities for queue management and publishing";config={entityType:"social-post",defaultSort:[{field:"publishedAt",direction:"desc",nullsFirst:!0},{field:"created",direction:"desc"}],defaultLimit:100};constructor(A){super(A);this.logger.debug("SocialPostDataSource initialized")}parseQuery(A){let Q=AOQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return u31(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:U}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(Y,U,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?u31(w):null;return A.parse({post:$})}}WA();var c31=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),LhA=H.object({linkedin:c31.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();H6();EhA();import{jsxDEV as N5,Fragment as wOQ}from"preact/jsx-dev-runtime";function QOQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function BOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var b$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return N5(wOQ,{children:[N5(KQ,{title:$,description:I},void 0,!1,void 0,this),N5("div",{className:"social-post-list bg-theme",children:N5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[N5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?N5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):N5("ul",{className:"space-y-6",children:A.map((D)=>N5("li",{children:N5(PB,{href:D.url,variant:"horizontal",children:N5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&N5("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),N5("div",{className:"flex-1 min-w-0",children:[N5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[N5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),N5("time",{className:"text-sm text-theme-muted shrink-0",children:BOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("div",{className:"flex items-center gap-2 mb-3",children:[N5(gf,{status:D.frontmatter.status},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("p",{className:"text-theme leading-relaxed",children:QOQ(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&N5(VF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as z5,Fragment as $OQ}from"preact/jsx-dev-runtime";function l31(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var P$A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return z5($OQ,{children:[z5(KQ,{title:Q,description:B},void 0,!1,void 0,this),z5("section",{className:"social-post-detail",children:z5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z5("div",{className:"max-w-3xl mx-auto",children:[z5(UH,{items:w},void 0,!1,void 0,this),z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),z5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[z5(gf,{status:A.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted font-mono",children:A.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.coverImageUrl&&A.coverImageWidth&&A.coverImageHeight&&z5(qF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),z5(PB,{className:"p-8 mb-8",children:z5("p",{className:"text-lg text-theme leading-relaxed whitespace-pre-wrap",children:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),z5("div",{className:"space-y-4 text-sm text-theme-muted",children:[z5("div",{children:[z5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",l31(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&z5("div",{children:[z5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",l31(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&z5("div",{children:z5("a",{href:`https://www.linkedin.com/feed/update/${A.frontmatter.platformPostId}`,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:underline",children:"View on LinkedIn \u2192"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};function li(A){return`social-media:${A}`}var fOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),MhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:fOQ.optional().describe("Generic cover image generation request")}),IOQ=qI.extend({slug:H.string().optional()});class FC extends z7{constructor(A,Q){super(A,Q,{schema:MhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let V=await this.context.ai.generate({prompt:D,templateName:li(B)});Y=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let V=await this.context.entityService.getEntity({entityType:f,id:I});if(!V)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(V.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
6517
+ `)}async function GC(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=w.targetVisibility??"public",Y=L31(A),U=new DX(Q.entityService,B),J=w.topicMergeSynthesizer??new GhA(Q,B),X=await L$A(Q.entityService,void 0,D),G=new Map,Z=0,N=0,L=0;for(let M of Y){B.info(`Processing batch of ${M.length} entities`);let O=xCQ(M),E=V$A({entityTitle:`Batch of ${M.length} entities`,entityType:"batch",content:O,existingTopicTitles:X});try{let y=(await Q.ai.generate({prompt:E,templateName:"topics:extraction"})).topics.filter((T)=>T.relevanceScore>=$);for(let T of y)try{if(f){let g=await U.findMergeCandidate({incoming:T,threshold:I,additionalCandidates:Array.from(G.values()),targetVisibility:D});if(g){let n=await J.synthesize({existingTopic:g.topic,incomingTopic:T}),m=await U.applySynthesizedMerge({existingId:g.topic.id,synthesized:{...n,title:g.title},visibility:D});if(!m)throw Error(`Failed to merge topic: ${T.title}`);G.set(m.id,m),N++;continue}}let _=U.getTopicIdForTitle(T.title,D);if(G.has(_)){L++;continue}let x=await U.createTopicOptimistic({title:T.title,content:T.content,visibility:D});if(x.topic)G.set(x.topic.id,x.topic);if(x.created)Z++;else L++}catch(_){B.error("Topic batch item failed",{title:T.title,error:T0(_)})}}catch(S){B.error("Batch topic extraction failed",{batchSize:M.length,promptChars:E.length,error:T0(S)})}}let V={created:Z,merged:N,skipped:L,batches:Y.length};if(Z>0||N>0)await Q.messaging.send({type:D31,payload:V,broadcast:!0});return V}aA();WA();var SCQ=H.discriminatedUnion("mode",[H.object({mode:H.literal("derive"),reason:H.string().optional()}),H.object({mode:H.literal("rebuild"),reason:H.string().optional()}),H.object({mode:H.literal("source-batch"),minRelevanceScore:H.number().min(0).max(1).optional()})]);class KhA{refs=new Map;add(A){this.refs.set(`${A.entityType}:${A.entityId}`,A)}drain(){let A=Array.from(this.refs.values());return this.refs.clear(),A}}function R31(A){let{context:Q,logger:B,config:w}=A;return{process:async($)=>{if($.mode==="derive")return await A.extractAllTopics(),{success:!0};if($.mode==="rebuild")return await A.rebuildAllTopics(),{success:!0};return gCQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=SCQ.safeParse($??{});return f.success?f.data:null}}}async function gCQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(U)=>({ref:U,entity:await A.context.entityService.getEntity({entityType:U.entityType,id:U.entityId})}))),w=0,$=0,f=0,I=0,D=[];for(let{ref:U,entity:J}of B){if(!J){$++;continue}if(J.contentHash!==U.contentHash){w++;continue}if(!A.isEntityPublished(J)){f++;continue}if(!KN(J.visibility,A.config.extractionVisibility)){I++;continue}D.push(J)}if(D.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f,hidden:I};let Y=await GC(D,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});return{success:!0,sources:Q.length,...Y,stale:w,missing:$,unpublished:f,hidden:I}}function b31(){return{priority:5,source:F$A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:HC}}}async function P31(A){let Q=await j31(A);if(Q.length===0){A.logger.info("No entities to extract topics from");return}A.logger.info(`Batch topic extraction: ${Q.length} entities`);let B=await GC(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold,targetVisibility:A.config.extractionVisibility});A.logger.info("Batch topic extraction complete",B)}async function k31(A){let Q=await j31(A),B=await FhA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function FhA(A,Q,B,w){let $=new DX(Q.entityService,B),f=await $.listTopics({visibility:w.extractionVisibility});for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await GC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:f.length,...I}}async function j31(A){let Q=hCQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function hCQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var yv=H.object({entityType:H.string(),content:H.string(),metadata:H.record(H.unknown()).optional()}),mCQ=yv.extend({minRelevanceScore:H.number().optional()}),uCQ=H.object({contentA:yv,contentB:yv,minRelevanceScore:H.number().optional(),threshold:H.number().min(0).max(1).optional()}),ci=H.object({title:H.string(),content:H.string()}),cCQ=H.object({existingTopics:H.array(ci),incomingTopic:ci,threshold:H.number().optional()}),lCQ=H.object({existingTopics:H.array(ci).default([]),incomingTopic:ci.extend({relevanceScore:H.number().min(0).max(1).optional()}),threshold:H.number().optional()}),pCQ=H.object({entities:H.array(yv).min(1),minRelevanceScore:H.number().optional()}),iCQ=H.object({existingTopics:H.array(ci).optional(),entities:H.array(yv)}),rCQ=H.object({entities:H.array(yv)});function Tv(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:gB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function _31(A){return{title:A.title,relevanceScore:A.relevanceScore}}function dCQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function nCQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:dCQ(Q)}]}}async function KC(A){let Q=await A.entityService.listEntities({entityType:Iw});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:Iw,id:B.id})))}async function oCQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function v31(A){let{context:Q,logger:B,config:w}=A,$=new HhA(Q,B),f=async(I,D,Y="")=>{let U=Tv(I,Y);return $.extractFromEntity(U,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await KC(Q);let D=mCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=Tv(D);return(await $.extractFromEntity(U,Y)).map((X)=>nCQ(X,U))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await KC(Q);let D=uCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=D.threshold??w.mergeSimilarityThreshold,[J,X]=await Promise.all([f(D.contentA,Y,"-a"),f(D.contentB,Y,"-b")]),G=new DX(Q.entityService,B),Z=[];for(let V of J){let M=await G.createTopic(V);if(M)Z.push(M)}let N=(await Promise.all(X.map(async(V)=>{let M=await G.findMergeCandidate({incoming:V,threshold:U,additionalCandidates:Z});if(!M)return null;return{incomingTitle:V.title,candidateTitle:M.title,candidateScore:M.score}}))).filter((V)=>V!==null),L=N.map((V)=>V.candidateTitle);return{topicsA:J.map(_31),topicsB:X.map(_31),matchingTitles:L,mergeCandidates:N,wouldMerge:N.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await KC(Q);let D=cCQ.parse(I),Y=D.threshold??w.mergeSimilarityThreshold,U=new DX(Q.entityService,B),J=[];for(let G of D.existingTopics){let Z=await U.createTopic(G);if(Z)J.push(Z)}let X=await U.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:Y,additionalCandidates:J});return{found:X!==null,candidateTitle:X?.title,candidateScore:X?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await KC(Q);let D=lCQ.parse(I),Y=new DX(Q.entityService,B);for(let G of D.existingTopics)await Y.createTopic({title:G.title,content:G.content});await oCQ(Q);let U=Tv({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),J=await GC([U],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(XhA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await KC(Q);let D=iCQ.parse(I),Y=new DX(Q.entityService,B);for(let G of D.existingTopics??[])await Y.createTopic(G);let U=D.entities.map((G,Z)=>Tv(G,`-rebuild-${Z}`)),J=await FhA(U,Q,B,w),X=await Q.entityService.listEntities({entityType:Iw});return{...J,topicCount:X.length,topics:X.map(XhA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await KC(Q);let D=pCQ.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,U=new DX(Q.entityService,B),J=[];for(let[G,Z]of D.entities.entries()){let N=Tv(Z,`-sequential-${G}`),L=await $.extractFromEntity(N,Y);for(let V of L)await U.createTopic({title:V.title,content:V.content});J.push({extractedTitles:L.map((V)=>V.title)})}let X=await Q.entityService.listEntities({entityType:Iw});return{totalTopics:X.length,perEntity:J,topics:X.map(vv)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await KC(Q);let Y=rCQ.parse(I).entities.map((X,G)=>Tv(X,`-batch-${G}`)),U=await GC(Y,Q,B,{minRelevanceScore:w.minRelevanceScore}),J=await Q.entityService.listEntities({entityType:Iw});return{...U,topics:J.map(vv)}})}var sCQ=new IX;async function T31({entity:A,config:Q}){let B=_v.parse(A),w=sCQ.parseTopicBody(B.content);return{$type:"ai.rizom.brain.topic",title:w.title,body:w.content,format:"text/markdown",...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"topic",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function ZhA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:Gw["ai.rizom.brain.topic"],validate:!1,buildRecord:T31}}var y31={name:"@brains/topics",private:!0,version:"0.2.0-alpha.122",description:"Extract and manage topics from conversations",type:"module",main:"./src/index.ts",types:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"}};var tCQ=new IX;class x31 extends jQ{entityType=Iw;schema=_v;adapter=tCQ;unregisterAtprotoProjection;sourceBatch=new KhA;constructor(A={}){super(HC,y31,A,$31)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:J31,"merge-synthesis":X31,"topic-list":W31,"topic-detail":H31}}getDataSources(){return[new WhA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:YhA,targetType:Iw,job:{type:I31,handler:R31({context:A,logger:this.logger,config:this.config,extractAllTopics:()=>this.extractAllTopics(A),rebuildAllTopics:()=>this.rebuildAllTopics(A),sourceBatch:this.sourceBatch,isEntityPublished:(Q)=>this.isEntityPublished(Q)})},initialSync:{shouldEnqueue:async()=>!await OL(A,Iw,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:b31()},sourceChange:{sourceTypes:this.config.includeEntityTypes,requireInitialSync:!0,jobData:(Q)=>{let B=Q.entity;if(!B)return null;if(!this.shouldProcessEntityType(B.entityType,A.entityService))return null;if(!this.isEntityPublished(B))return null;if(!KN(B.visibility,this.config.extractionVisibility))return null;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:F$A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:Y31,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:HC}})}}]}async onRegister(A){A.insights.register("topic-distribution",F31()),Z31({context:A,pluginId:this.id}),v31({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=d6.getInstance().register(ZhA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(YhA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===Iw)return!1;if(!this.config.includeEntityTypes.includes(A))return!1;return Q.getEntityTypeConfig(A).projectionSource!==!1}isEntityPublished(A){let B=A.metadata.status;if(B===void 0||B===null)return!0;if(typeof B!=="string")return!1;return this.config.extractableStatuses.includes(B)}async extractAllTopics(A){await P31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await k31({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function E$A(A){return new x31(A)}aA();WA();aA();var NhA=H.enum(["linkedin"]),zhA=H.enum(["generating","draft","queued","published","failed"]),S31=H.enum(["post","deck"]),g31=H.object({id:H.string().min(1).describe("Document entity ID")}),oY=H.object({title:H.string().describe("Short descriptive title (3-6 words) for file naming"),platform:NhA.describe("Target platform"),status:zhA,coverImageId:H.string().optional().describe("Image entity ID for post image"),documents:H.array(g31).optional().describe("Document attachments for publishing"),publishedAt:H.string().datetime().optional(),platformPostId:H.string().optional().describe("ID from platform after publishing"),sourceEntityId:H.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:S31.optional().describe("Source entity type (post, deck)")}),h31=oY.extend({platform:NhA.optional(),status:zhA.optional()}),m31=oY.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:H.string().describe("URL-friendly identifier: {platform}-{title}"),error:H.string().optional()}),nz=A2.extend({entityType:H.literal("social-post"),metadata:m31}),M$A=nz.extend({frontmatter:oY,body:H.string()}),C$A=M$A.extend({url:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),typeLabel:H.string().optional(),coverImageUrl:H.string().optional(),coverImageWidth:H.number().optional(),coverImageHeight:H.number().optional()});aA();WA();class qhA extends q2{constructor(){super({entityType:"social-post",schema:nz,frontmatterSchema:oY,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,oY),Q=this.extractBody(A.content)}catch{Q=A.content}let w={...B,title:A.metadata.title,platform:A.metadata.platform,status:A.metadata.status,...A.metadata.publishedAt!==void 0&&{publishedAt:A.metadata.publishedAt},...A.metadata.platformPostId!==void 0&&{platformPostId:A.metadata.platformPostId}};return this.buildMarkdown(Q,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,h31),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${X1(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:$,platform:B,status:w,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,oY)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}buildStub(A){let B={title:A.title,platform:"linkedin",status:"generating"};return{content:this.buildMarkdown("",B),metadata:{title:A.title,slug:`linkedin-${X1(A.title)}`,platform:"linkedin",status:"generating"}}}}var s9=new qhA;aA();aA();WA();var eCQ=QW.extend({platform:H.enum(["linkedin"]).optional(),status:H.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:H.boolean().optional(),nextInQueue:H.boolean().optional()}),AOQ=BW.extend({query:eCQ.optional()});function u31(A){let Q=R2(A.content,oY);return M$A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class O$A extends m5{id="social-media:posts";name="Social Post DataSource";description="Fetches and transforms social post entities for queue management and publishing";config={entityType:"social-post",defaultSort:[{field:"publishedAt",direction:"desc",nullsFirst:!0},{field:"created",direction:"desc"}],defaultLimit:100};constructor(A){super(A);this.logger.debug("SocialPostDataSource initialized")}parseQuery(A){let Q=AOQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return u31(A)}buildDetailResult(A,Q){return{post:A}}buildListResult(A,Q,B){return{posts:A,totalCount:Q?.totalItems??A.length,pagination:Q,baseUrl:B.baseUrl}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.nextInQueue)return this.fetchNextInQueue(Q,$);if(w.id){let{item:J}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(J,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:U}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(Y,U,w))}async fetchNextInQueue(A,Q){let w=(await Q.listEntities({entityType:this.config.entityType,options:{filter:{metadata:{status:"queued"}},sortFields:[{field:"queueOrder",direction:"asc"}],limit:1}}))[0],$=w?u31(w):null;return A.parse({post:$})}}WA();var c31=H.object({accessToken:H.string().optional(),refreshToken:H.string().optional(),organizationId:H.string().optional(),apiVersion:H.string().regex(/^\d{6}$/).optional()}),LhA=H.object({linkedin:c31.optional(),publishInterval:H.number().default(3600000),enabled:H.boolean().default(!0),defaultPrompt:H.string().default("Create an engaging social media post that drives engagement"),maxRetries:H.number().default(3),autoGenerateOnBlogPublish:H.boolean().default(!1)});aA();WA();H6();EhA();import{jsxDEV as N5,Fragment as wOQ}from"preact/jsx-dev-runtime";function QOQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function BOQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var b$A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return N5(wOQ,{children:[N5(KQ,{title:$,description:I},void 0,!1,void 0,this),N5("div",{className:"social-post-list bg-theme",children:N5("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[N5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?N5("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):N5("ul",{className:"space-y-6",children:A.map((D)=>N5("li",{children:N5(PB,{href:D.url,variant:"horizontal",children:N5("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&N5("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),N5("div",{className:"flex-1 min-w-0",children:[N5("div",{className:"flex items-start justify-between gap-4 mb-2",children:[N5("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),N5("time",{className:"text-sm text-theme-muted shrink-0",children:BOQ(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("div",{className:"flex items-center gap-2 mb-3",children:[N5(gf,{status:D.frontmatter.status},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),N5("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N5("p",{className:"text-theme leading-relaxed",children:QOQ(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&N5(VF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as z5,Fragment as $OQ}from"preact/jsx-dev-runtime";function l31(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var P$A=({post:A})=>{let Q=`Social Post - ${A.frontmatter.platform}`,B=A.body.slice(0,160),w=[{label:"Home",href:"/"},{label:A.listLabel??"Social Posts",href:A.listUrl??"/social-posts"},{label:A.frontmatter.platform}];return z5($OQ,{children:[z5(KQ,{title:Q,description:B},void 0,!1,void 0,this),z5("section",{className:"social-post-detail",children:z5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:z5("div",{className:"max-w-3xl mx-auto",children:[z5(UH,{items:w},void 0,!1,void 0,this),z5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),z5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[z5(gf,{status:A.frontmatter.status},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),z5("span",{className:"text-sm text-theme-muted font-mono",children:A.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.coverImageUrl&&A.coverImageWidth&&A.coverImageHeight&&z5(qF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),z5(PB,{className:"p-8 mb-8",children:z5("p",{className:"text-lg text-theme leading-relaxed whitespace-pre-wrap",children:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),z5("div",{className:"space-y-4 text-sm text-theme-muted",children:[z5("div",{children:[z5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",l31(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&z5("div",{children:[z5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",l31(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&z5("div",{children:z5("a",{href:`https://www.linkedin.com/feed/update/${A.frontmatter.platformPostId}`,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:underline",children:"View on LinkedIn \u2192"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};function li(A){return`social-media:${A}`}var fOQ=H.union([H.boolean(),H.object({generate:H.boolean().optional(),prompt:H.string().optional()})]),MhA=H.object({prompt:H.string().optional(),platform:H.enum(["linkedin"]).optional(),sourceEntityType:H.enum(["post","deck"]).optional(),sourceEntityId:H.string().optional(),title:H.string().optional().describe("Required when content is provided directly"),content:H.string().optional(),addToQueue:H.boolean().optional(),generateImage:H.boolean().optional().describe("Auto-generate cover image for post"),coverImage:fOQ.optional().describe("Generic cover image generation request")}),IOQ=qI.extend({slug:H.string().optional()});class FC extends z7{constructor(A,Q){super(A,Q,{schema:MhA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let V=await this.context.ai.generate({prompt:D,templateName:li(B)});Y=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let V=await this.context.entityService.getEntity({entityType:f,id:I});if(!V)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let O=H.object({slug:H.string()}).safeParse(V.metadata),E=O.success?O.data.slug:I,S=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
6518
6518
 
6519
6519
  Source: ${f}/${E}
6520
6520
 
6521
6521
  ${V.content}`,templateName:li(B)});Y=S.title,D=S.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let V=await this.context.ai.generate({prompt:$,templateName:li(B)});Y=V.title,D=V.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!Y)this.failEarly("Content or title was not generated");let J={title:Y,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},X=s9.createPostContent(J,D),Z=s9.fromMarkdown(X).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let N=await rG({entityType:"social-post",title:Y,deriveId:(V)=>`${B}-${X1(V)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),L=X;if(N!==Y){Z.title=N,Z.slug=`${B}-${X1(N)}`;let V={...J,title:N};L=s9.createPostContent(V,D)}return{id:Z.slug,content:L,metadata:Z,title:N,resultExtras:{slug:Z.slug},createOptions:{deduplicateId:!0}}}async onGenerationFailure(A,Q){await this.context.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:Q}})}async afterCreate(A,Q,B,w){if(A.generateImage){await this.reportProgress(B,{progress:90,message:"Queueing image generation"});let $=w.title??"Social Post";await this.context.jobs.enqueue({type:"image:image-generate",data:{prompt:`Social media graphic for: ${$}`,title:`${$} Image`,aspectRatio:"16:9",targetEntityType:"social-post",targetEntityId:Q},toolContext:{interfaceType:"job",userId:"system"}})}await this.context.messaging.send({type:"generate:report:success",payload:{entityType:"social-post",entityId:Q}})}summarizeDataForLog(A){return{platform:A.platform??"linkedin",hasPrompt:!!A.prompt,sourceEntityType:A.sourceEntityType,addToQueue:A.addToQueue??!1,generateImage:A.generateImage??!1,coverImage:!!A.coverImage}}}function pi(A){if(A.length<=200)return A;return`${A.slice(0,200)}\u2026 (truncated, ${A.length} bytes)`}function DOQ(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function YOQ(A){if(!ChA(A))return null;let Q=k$A(A,"value");if(!Q)return null;let B=k$A(Q,"uploadMechanism");if(!B)return null;let w=k$A(B,"com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest");if(!w)return null;let $=w.uploadUrl,f=Q.asset;if(typeof $!=="string"||typeof f!=="string")return null;return{uploadUrl:$,assetUrn:f}}function UOQ(A){if(!ChA(A))return null;let Q=k$A(A,"value");if(!Q)return null;let{uploadUrl:B,document:w}=Q;if(typeof B!=="string"||typeof w!=="string")return null;return{uploadUrl:B,documentUrn:w}}function k$A(A,Q){let B=A[Q];return ChA(B)?B:null}function ChA(A){return typeof A==="object"&&A!==null}var JOQ="202604";class OhA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";restApiBaseUrl="https://api.linkedin.com/rest";fetch;cachedUserId=null;constructor(A,Q,B={}){this.config=A;this.logger=Q;this.fetch=B.fetch??globalThis.fetch.bind(globalThis)}async publish(A,Q,B,w){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let $=await this.getAuthor(),f=w?.[0];if(w&&w.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:w.length});let I=null;if(f){let X=await this.uploadDocument($,f);return this.publishDocumentPost($,A,X,f.filename)}else if(B){let X=await this.uploadImage($,B);if(X)I={category:"IMAGE",urn:X}}let D={shareCommentary:{text:A},shareMediaCategory:I?.category??"NONE",...I&&{media:[DOQ(I)]}},Y=await this.fetch(`${this.apiBaseUrl}/ugcPosts`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({author:$,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":D},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!Y.ok){let X=pi(await Y.text());throw this.logger.error("LinkedIn API error",{status:Y.status,error:X}),Error(`LinkedIn API error: ${Y.status} - ${X}`)}let U=Y.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:U,mediaCategory:I?.category??"NONE"});let J={id:U};if(U)J.url=`https://www.linkedin.com/feed/update/${U}`;return J}getRestHeaders(){return{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","Linkedin-Version":this.config.apiVersion??JOQ,"X-Restli-Protocol-Version":"2.0.0"}}async uploadImage(A,Q){try{let B=await this.fetch(`${this.apiBaseUrl}/assets?action=registerUpload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({registerUploadRequest:{recipes:["urn:li:digitalmediaRecipe:feedshare-image"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let D=pi(await B.text());return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=YOQ(await B.json());if(!w)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:f}=w,I=await this.fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!I.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:I.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:f}),f}catch(B){return this.logger.warn("LinkedIn image upload error",{error:B}),null}}async uploadDocument(A,Q){let B=await this.fetch(`${this.restApiBaseUrl}/documents?action=initializeUpload`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({initializeUploadRequest:{owner:A}})});if(!B.ok){let f=pi(await B.text());throw Error(`LinkedIn document upload initialization failed: ${B.status} - ${f}`)}let w=UOQ(await B.json());if(!w)throw Error("LinkedIn document upload initialization was malformed");let $=await this.fetch(w.uploadUrl,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!$.ok)throw Error(`LinkedIn document binary upload failed: ${$.status}`);return this.logger.info("LinkedIn document uploaded",{documentUrn:w.documentUrn,filename:Q.filename}),w.documentUrn}async publishDocumentPost(A,Q,B,w){let $=await this.fetch(`${this.restApiBaseUrl}/posts`,{method:"POST",headers:this.getRestHeaders(),body:JSON.stringify({author:A,commentary:Q,visibility:"PUBLIC",distribution:{feedDistribution:"MAIN_FEED",targetEntities:[],thirdPartyDistributionChannels:[]},content:{media:{id:B,title:w}},lifecycleState:"PUBLISHED",isReshareDisabledByAuthor:!1})});if(!$.ok){let D=pi(await $.text());throw this.logger.error("LinkedIn document post API error",{status:$.status,error:D}),Error(`LinkedIn document post API error: ${$.status} - ${D}`)}let f=$.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:f,documentUrn:B});let I={id:f};if(f)I.url=`https://www.linkedin.com/feed/update/${f}`;return I}async validateCredentials(){if(!this.config.accessToken)return!1;try{if(this.config.organizationId)return(await this.fetch(`${this.apiBaseUrl}/organizations/${this.config.organizationId}`,{headers:{Authorization:`Bearer ${this.config.accessToken}`}})).ok;return await this.getUserId(),!0}catch{return!1}}async getAuthor(){if(this.config.organizationId)return`urn:li:organization:${this.config.organizationId}`;return this.getUserId()}async getUserId(){if(this.cachedUserId)return this.cachedUserId;if(!this.config.accessToken)throw Error("LinkedIn access token not configured");try{let B=await this.fetch("https://api.linkedin.com/v2/userinfo",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(B.ok){let w=await B.json();return this.cachedUserId=`urn:li:person:${w.sub}`,this.cachedUserId}}catch{}let A=await this.fetch("https://api.linkedin.com/v2/me",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(!A.ok){let B=pi(await A.text());throw Error(`Failed to get LinkedIn user ID: ${A.status} - ${B}`)}let Q=await A.json();return this.cachedUserId=`urn:li:person:${Q.id}`,this.cachedUserId}}function RhA(A,Q,B={}){return new OhA(A,Q,B)}aA();WA();Ew();EhA();var XOQ=H.object({posts:H.array(C$A),totalCount:H.number().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional()}),WOQ=H.object({post:C$A});function p31(){return{linkedin:R$A,"social-post-list":P1({name:"social-post-list",description:"Social post list page template",schema:XOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:b$A}}),"social-post-detail":P1({name:"social-post-detail",description:"Individual social post template",schema:WOQ,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:P$A}})}}WA();var HOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),platform:H.enum(["linkedin"]).default("linkedin")}),GOQ=H.object({prompt:H.string().optional(),content:H.string().optional(),title:H.string().optional(),platform:H.enum(["linkedin"]).optional()});function i31(A){A.eval.registerHandler("generation",async(Q)=>{let B=HOQ.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
6522
6522
 
6523
- ${B.content}`:B.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:w,templateName:`social-media:${B.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let B=GOQ.parse(Q),w=[],$=M9.from(async(U)=>{let J={progress:U.progress};if(U.message!==void 0)J.message=U.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new FC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(I.success&&I.entityId){let U=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!U,Y=U?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:Y,progressSteps:w}})}WA();aA();class ii{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=R2($.content,oY),Y;if(D.metadata.coverImageId)Y=await this.fetchImageData(D.metadata.coverImageId);let U=D.metadata.documents??[],J=await this.fetchDocumentData(U);try{if(U.length>0&&J.length===0)throw Error(`Refusing to publish: ${U.length} document(s) referenced but none could be fetched`);let X=U.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,Y,G):await I.publish(D.content,$.metadata,Y),N=new Date().toISOString(),L=Z.id||void 0,V={...D.metadata,status:"published",publishedAt:N,...L&&{platformPostId:L}},M=s9.createPostContent(V,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:L})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=s9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=T0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function r31(A,Q,B){if(Q.size===0){B.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let w=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:w,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function d31(A,Q,B){let w=new ii({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function n31(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=T0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function o31(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=T0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function s31(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=T0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function a31({entity:A,config:Q}){let B=nz.parse(A),w=s9.parsePostFrontmatter(B),$=s9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function bhA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Gw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:a31}}var t31={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.121",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class PhA extends jQ{entityType=s9.entityType;schema=nz;adapter=s9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",t31,A,LhA)}createGenerationHandler(A){return new FC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return p31()}getDataSources(){return[new O$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),r31(A,this.providers,this.logger),d31(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)n31(A,this.logger),o31(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");s31(A,this.logger),i31(A),this.unregisterAtprotoProjection=d6.getInstance().register(bhA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=RhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function ri(A){return new PhA(A)}WA();var FOQ=H.enum(["draft","queued","published","failed"]),e31=H.object({status:FOQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class khA{name="internal";async publish(A,Q){return{id:"internal"}}}var di={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},c4={REGISTER:"publish:register",QUEUE:"publish:queue",DIRECT:"publish:direct",REMOVE:"publish:remove",REORDER:"publish:reorder",LIST:"publish:list",REPORT_SUCCESS:"publish:report:success",REPORT_FAILURE:"publish:report:failure",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},oz={REGISTER:"generate:register",REPORT_SUCCESS:"generate:report:success",REPORT_FAILURE:"generate:report:failure",EXECUTE:"generate:execute",COMPLETED:"generate:completed",FAILED:"generate:failed",SKIPPED:"generate:skipped"},Az1={REGISTER:"publish-assets:register"};WA();var ZOQ=H.enum(["provider"]),Qz1=H.object({executionMode:ZOQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var NOQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),Bz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),NOQ).optional()});class vH{static instance=null;queues=new Map;static getInstance(){return vH.instance??=new vH,vH.instance}static resetInstance(){vH.instance=null}static createFresh(){return new vH}constructor(){}async add(A,Q,B=di){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class TH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new khA;static getInstance(){return TH.instance??=new TH,TH.instance}static resetInstance(){TH.instance=null}static createFresh(){return new TH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function wz1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await zOQ(A,Q)}async function zOQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:c4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}jhA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=T0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function jhA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:c4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function $z1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:c4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function fz1(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:oz.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:oz.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function Iz1(A,Q,B){if(B)B.send({type:oz.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function Dz1(A,Q,B){if(B)B.send({type:oz.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var qOQ=1000;class _hA{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,B)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval(qOQ,()=>this.processUnscheduledTypes())}stop(){if(LOQ(this.publishJobs),this.immediateIntervalJob)this.immediateIntervalJob.stop(),this.immediateIntervalJob=null}async processEntityType(A){if(!this.deps.isRunning())return;try{let Q=await this.deps.config.queueManager.getNext(A);if(Q)await this.processEntry(Q)}catch(Q){this.deps.config.logger.error(`Scheduler error for ${A}:`,Q)}}async processUnscheduledTypes(){if(!this.deps.isRunning())return;try{let A=await this.deps.config.queueManager.getQueuedEntityTypes();for(let Q of A)if(!this.entitySchedules[Q]){let B=await this.deps.config.queueManager.getNext(Q);if(B){await this.processEntry(B);break}}}catch(A){this.deps.config.logger.error("Scheduler error for unscheduled types:",A)}}async processEntry(A){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await wz1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function LOQ(A){for(let Q of A.values())Q.stop();A.clear()}class vhA{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,B)}}stop(){VOQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await fz1(A,this.deps.getGenerationDeps())}catch(Q){this.deps.config.logger.error(`Generation trigger error for ${A}:`,Q)}}get generationSchedules(){return this.deps.config.generationSchedules}}function VOQ(A){for(let Q of A.values())Q.stop();A.clear()}class YX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return YX.instance??=new YX(A),YX.instance}static resetInstance(){if(YX.instance)YX.instance.stop();YX.instance=null}static createFresh(A){return new YX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new _hA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new vhA({config:this.config,getGenerationDeps:()=>this.generationDeps,isRunning:()=>this.running})}async start(){if(this.running)return;this.running=!0,this.publishRunner.start(),this.generationRunner.start()}async stop(){this.running=!1,this.publishRunner.stop(),this.generationRunner.stop()}isRunning(){return this.running}completePublish(A,Q,B){jhA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){$z1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){Iz1(A,Q,this.config.messageBus)}failGeneration(A,Q){Dz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${T0(w)}`)}}}class yH{static instance=null;retries=new Map;static getInstance(){return yH.instance??=new yH,yH.instance}static resetInstance(){yH.instance=null}static createFresh(){return new yH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError}}}function u7(A,Q,B,w,$,f,I,D){return u7.fromTZ(u7.tp(A,Q,B,w,$,f,I),D)}u7.fromTZISO=(A,Q,B)=>u7.fromTZ(EOQ(A,Q),B);u7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=ThA(A.tz,B),$=new Date(B.getTime()-w),f=ThA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=ThA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};u7.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};u7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function ThA(A,Q=new Date){let B=Q.toLocaleString("en-US",{timeZone:A,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],w=Q.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${w} GMT`)-Date.parse(`${w} ${B}`)}function EOQ(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?u7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):u7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}u7.minitz=u7;var yhA=32,oi=31|yhA,Xz1=[1,2,4,8,16],Yz1=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new sY(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,oi),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,Y]=f,U=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(Y,10);if(isNaN(U))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(U>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=U;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=I;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=I;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|yhA;else if(Q===oi)this.dayOfWeek[A]=oi;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Xz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},Uz1=[31,28,31,30,31,30,31,31,30,31,30,31],iF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],sY=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&oi&&Xz1[I-1]&$)return!0;if($&yhA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=u7.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>Uz1[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=u7.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(u7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=Uz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let U=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==I&&(U=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(Y-$-1))%7];if(J&&J&oi)J=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?U=U||J:U=U&&J}if(U)return this[B]=Y-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,iF[w][0],Q,iF[w][2]);if($>1){let f=w+1;for(;f<iF.length;)this[iF[f][0]]=-iF[f][2],f++;if($===3)return this[iF[w][1]]++,this[iF[w][0]]=-iF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=iF.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):u7.fromTZ(u7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function MOQ(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new sY(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new sY(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function ni(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function COQ(A){return ni(A)}function OOQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Jz1=30000,j$A=[],xhA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(ni(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(ni(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=MOQ(w),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:w?w.maxRuns:void 0,paused:w?w.paused:!1,pattern:new Yz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new sY(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Yz1(A,this.options.timezone),this.name){if(j$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");j$A.push(this)}return $!==void 0&&COQ($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof sY||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new sY(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=j$A.indexOf(this);A>=0&&j$A.splice(A,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(A){if(A&&this.fn)throw Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");A&&(this.fn=A);let Q=this.msToNext(),B=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||B===null?this:(Q>Jz1&&(Q=Jz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&OOQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new sY(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){ni(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new sY(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&ni(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new sY(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new sY(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new sY(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new sY(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class _$A{scheduleCron(A,Q){let B=new xhA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new xhA(A).stop()}}WA();var Wz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),v$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:Wz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function ShA(A){return`${A.entityType}:${A.attachmentType}`}class xH{static instance=null;definitions=new Map;static getInstance(){return xH.instance??=new xH,xH.instance}static resetInstance(){xH.instance=null}static createFresh(){return new xH}constructor(){}register(A){let Q=v$A.parse(A),B=ShA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(ShA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(ShA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class T$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return ghA(A.metadata[Q]);if(Q.location==="metadata")return ghA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return ghA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function ghA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var ROQ=H.object({id:H.string().min(1)});async function Gz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=bOQ(Q.content),D=w?await jOQ(A,w):void 0,Y;if($&&$.length>0){let J=await _OQ(A,$);if(J.length>0)Y=J}Y??=await kOQ(A,f,I);let U={bodyContent:B};if(D)U.imageData=D;if(Y&&Y.length>0)U.documentData=Y;return U}function bOQ(A){try{let Q=R2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=POQ(Q.metadata.documents),f=Hz1(Q.metadata.sourceEntityType),I=Hz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function POQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=ROQ.safeParse(Q);return B.success?[B.data]:[]})}function Hz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function kOQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function jOQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=Kz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function _OQ(A,Q){return(await Promise.all(Q.map((w)=>vOQ(A,w)))).filter((w)=>w!==void 0)}async function vOQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=Kz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:TOQ(B,Q.id)}}function Kz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function TOQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var yOQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function hhA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...xOQ(B.id,w.publishResultIdField)},D={...Q,content:Fz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function Fz1(A,Q,B,w,$="publishedAt"){if(!yOQ.test(A))return A;let f=U4(U4(A,"status","published"),$,Q);if(!B||!w)return f;return U4(f,w,B)}function xOQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class xv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await Gz1(this.deps.context,B),Y=await $.publish(f,B.metadata,I,D),U=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await hhA(this.deps.context,B,Y,{...U?{publishResultIdField:U}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:Y}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var mhA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),uhA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),SOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(uhA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),gOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),chA=H.union([SOQ,gOQ]);function y$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",mhA,async($,f)=>{let{action:I,entityType:D,entityId:Y,position:U}=$;switch(I){case"list":return hOQ(B,D);case"add":return mOQ(A,B,D,Y,f);case"remove":return uOQ(A,B,D,Y,f);case"reorder":return cOQ(A,B,D,Y,U,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:chA}}async function hOQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function mOQ(A,Q,B,w,$){let f=lhA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function uOQ(A,Q,B,w,$){let f=lhA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function cOQ(A,Q,B,w,$,f){let I=lhA("reorder",B,w);if(!I.success)return I.error;let D=lOQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function lhA(A,Q,B){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!B)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:B}}function lOQ(A){if(A===void 0)return{success:!1,error:{success:!1,error:"position is required for reorder action"}};if(A<1)return{success:!1,error:{success:!1,error:"position must be a positive number"}};return{success:!0,position:A}}WA();var x$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),pOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),iOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),rOQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),phA=H.union([pOQ,iOQ,rOQ]),dOQ=900000,nOQ=1000;class Nz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=nOQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+dOQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function S$A(A,Q,B,w){let $=w??new xv({context:A,providerRegistry:B}),f=new Nz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:x$A.shape,outputSchema:phA,visibility:"anchor",handler:async(D,Y)=>{let U=x$A.safeParse(D);if(!U.success)return{success:!1,error:`Invalid input: ${U.error.errors.map((V)=>`${V.path.join(".")}: ${V.message}`).join(", ")}`};let J=U.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",Y)}catch(V){return{success:!1,error:V instanceof Error?V.message:String(V)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:L}=N;if(J.confirmed){let V=J.confirmationToken;if(!V||!f.has(V))return Zz1(I,J,L,f);if(f.delete(V),J.contentHash&&J.contentHash!==L.contentHash)return{success:!1,error:`Cannot publish ${X}:${L.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:L.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return Zz1(I,J,L,f)}}}function Zz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=oOQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function oOQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var ihA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),rhA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function g$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",ihA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let Y=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),U=0,J=0,X=0;for(let G of Y){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});U+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:Y.length,checkedAssets:U,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:rhA}}aA();WA();function zz1(A,Q){sOQ(A,Q),aOQ(A,Q),tOQ(A,Q),eOQ(A,Q)}function sOQ(A,Q){A.messaging.subscribe(c4.REGISTER,async(B)=>ARQ(Q,B.payload)),A.messaging.subscribe(c4.QUEUE,async(B)=>$RQ(A,Q,B.payload)),A.messaging.subscribe(c4.DIRECT,async(B)=>fRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REMOVE,async(B)=>IRQ(Q,B.payload)),A.messaging.subscribe(c4.REORDER,async(B)=>DRQ(Q,B.payload)),A.messaging.subscribe(c4.LIST,async(B)=>YRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REPORT_SUCCESS,async(B)=>URQ(Q,B.payload)),A.messaging.subscribe(c4.REPORT_FAILURE,async(B)=>JRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function aOQ(A,Q){A.messaging.subscribe(oz.REPORT_SUCCESS,async(B)=>XRQ(Q,B.payload)),A.messaging.subscribe(oz.REPORT_FAILURE,async(B)=>WRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function tOQ(A,Q){A.messaging.subscribe(Az1.REGISTER,async(B)=>QRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function eOQ(A,Q){let B=async(w)=>BRQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function ARQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?Qz1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function QRQ(A,Q){let B=v$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function BRQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!wRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:T0(w)}),{success:!1}}}function wRQ(A){if(!A)return!1;let Q=e31.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function $RQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??di;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:c4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=T0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function fRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??di;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=T0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function IRQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=T0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function DRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function YRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:c4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=T0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function URQ(A,Q){let{entityType:B,entityId:w,result:$}=Q;return A.scheduler.completePublish(B,w,$),A.logger.info(`Publish reported success: ${w}`,{entityType:B}),{success:!0}}async function JRQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function XRQ(A,Q){let{entityType:B,entityId:w}=Q;return A.scheduler.completeGeneration(B,w),A.logger.info("Generation completed",{entityType:B,entityId:w}),{success:!0}}async function WRQ(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}WA();async function qz1(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:T0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${T0($)}`}}}function Lz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,Y=HRQ(Q);return YX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new _$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,publishExecutor:I,onCheckGenerationConditions:(U,J)=>qz1(Q.entityService,D,U,J)})}function HRQ(A){return{send:async($)=>{return A.messaging.send({type:$.type,payload:$.payload,...$.target!==void 0?{target:$.target}:{},...$.metadata!==void 0?{metadata:$.metadata}:{},...$.broadcast!==void 0?{broadcast:$.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function Vz1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var GRQ=["draft","queued","published","failed"];async function Ez1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>KRQ(A)}})}async function KRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=FRQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:ZRQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function FRQ(A){return GRQ.find((Q)=>Q===A)}function ZRQ(A,Q){return typeof Q==="string"?Q:A}var Mz1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.121",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class dhA extends UB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",Mz1,A??{},Bz1)}async onRegister(A){this.pluginContext=A,this.queueManager=vH.createFresh(),this.providerRegistry=TH.createFresh(),this.retryTracker=yH.createFresh(),this.publishAssetRegistry=xH.createFresh(),this.publishAssetPreflight=new T$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new xv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=Lz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),zz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Vz1(A.entityService,this.queueManager,this.logger),await Ez1(A,this.id),await this.scheduler.start(),this.logger.info("Content pipeline plugin started")}async getTools(){if(!this.pluginContext)throw Error("Plugin context not initialized");return[y$A(this.pluginContext,this.id,this.queueManager),S$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),g$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),vH.resetInstance(),TH.resetInstance(),yH.resetInstance(),xH.resetInstance()}}function nhA(A){return new dhA(A)}aA();WA();var Cz1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),ohA=H.object({cloudflare:Cz1.optional()});aA();WA();var zRQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function qRQ(A){if(A.date&&(A.days||A.startDate||A.endDate))return"Cannot combine 'date' with 'days' or 'startDate'/'endDate'";if(A.days&&(A.startDate||A.endDate))return"Cannot combine 'days' with 'startDate'/'endDate'";if(A.startDate&&!A.endDate||!A.startDate&&A.endDate)return"Both 'startDate' and 'endDate' must be provided for custom range";return null}function Oz1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
6523
+ ${B.content}`:B.prompt??"Write an engaging LinkedIn post";return A.ai.generate({prompt:w,templateName:`social-media:${B.platform}`})}),A.eval.registerHandler("create",async(Q)=>{let B=GOQ.parse(Q),w=[],$=M9.from(async(U)=>{let J={progress:U.progress};if(U.message!==void 0)J.message=U.message;w.push(J)});if(!$)throw Error("Failed to create progress reporter");let I=await new FC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(I.success&&I.entityId){let U=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!U,Y=U?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:Y,progressSteps:w}})}WA();aA();class ii{sendMessage;logger;entityService;providers;permissions;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.permissions=A.permissions,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;this.permissions.assertEntityActionAllowed(Q,"publish",A.authContext??{userPermissionLevel:"anchor"}),this.logger.debug("Handling publish:execute",{entityId:B});try{let w=await this.entityService.getEntity({entityType:"social-post",id:B});if(!w){await this.reportFailure(Q,B,`Post not found: ${B}`);return}let $=w;if($.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let f=$.metadata.platform,I=this.providers.get(f);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${f}`);return}let D=R2($.content,oY),Y;if(D.metadata.coverImageId)Y=await this.fetchImageData(D.metadata.coverImageId);let U=D.metadata.documents??[],J=await this.fetchDocumentData(U);try{if(U.length>0&&J.length===0)throw Error(`Refusing to publish: ${U.length} document(s) referenced but none could be fetched`);let X=U.length===0?await this.resolveSourceAttachment(D.metadata):[],G=J.length>0?J:X,Z=G.length?await I.publish(D.content,$.metadata,Y,G):await I.publish(D.content,$.metadata,Y),N=new Date().toISOString(),L=Z.id||void 0,V={...D.metadata,status:"published",publishedAt:N,...L&&{platformPostId:L}},M=s9.createPostContent(V,D.content);await this.entityService.updateEntity({entity:{...$,content:M,metadata:{...$.metadata,status:"published",publishedAt:N,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:f,platformPostId:L})}catch(X){let G=X instanceof Error?X.message:String(X),Z={...D.metadata,status:"failed"},N=s9.createPostContent(Z,D.content);await this.entityService.updateEntity({entity:{...$,content:N,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,G),this.logger.error(`Post publish failed: ${B}`,{platform:f,error:G})}}catch(w){let $=T0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function r31(A,Q,B){if(Q.size===0){B.debug("No providers configured, skipping publish-pipeline registration");return}A.messaging.subscribe("system:plugins:ready",async()=>{let w=Q.values().next().value;return await A.messaging.send({type:"publish:register",payload:{entityType:"social-post",provider:w,config:{publishResultIdField:"platformPostId"}}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function d31(A,Q,B){let w=new ii({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,permissions:A.permissions,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}WA();function n31(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=T0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function o31(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=T0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function s31(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${s9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=T0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function a31({entity:A,config:Q}){let B=nz.parse(A),w=s9.parsePostFrontmatter(B),$=s9.getPostContent(B);return{$type:"ai.rizom.brain.socialPost",title:w.title,platform:w.platform,body:$,format:"text/markdown",status:w.status,...w.publishedAt&&{publishedAt:w.publishedAt},...w.platformPostId&&{platformPostId:w.platformPostId},...w.sourceEntityType&&{sourceLocalEntityType:w.sourceEntityType},...w.sourceEntityId&&{sourceLocalEntityId:w.sourceEntityId},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},sourceEntityType:"social-post",sourceEntityId:B.id,createdAt:B.created,...B.updated&&{updatedAt:B.updated}}}function bhA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:Gw["ai.rizom.brain.socialPost"],validate:!1,buildRecord:a31}}var t31={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.122",description:"Multi-provider social media posting with queue-based publishing",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class PhA extends jQ{entityType=s9.entityType;schema=nz;adapter=s9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",t31,A,LhA)}createGenerationHandler(A){return new FC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return p31()}getDataSources(){return[new O$A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),r31(A,this.providers,this.logger),d31(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)n31(A,this.logger),o31(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");s31(A,this.logger),i31(A),this.unregisterAtprotoProjection=d6.getInstance().register(bhA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=RhA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function ri(A){return new PhA(A)}WA();var FOQ=H.enum(["draft","queued","published","failed"]),e31=H.object({status:FOQ.default("draft"),queueOrder:H.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:H.string().datetime().optional()});class khA{name="internal";async publish(A,Q){return{id:"internal"}}}var di={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},c4={REGISTER:"publish:register",QUEUE:"publish:queue",DIRECT:"publish:direct",REMOVE:"publish:remove",REORDER:"publish:reorder",LIST:"publish:list",REPORT_SUCCESS:"publish:report:success",REPORT_FAILURE:"publish:report:failure",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},oz={REGISTER:"generate:register",REPORT_SUCCESS:"generate:report:success",REPORT_FAILURE:"generate:report:failure",EXECUTE:"generate:execute",COMPLETED:"generate:completed",FAILED:"generate:failed",SKIPPED:"generate:skipped"},Az1={REGISTER:"publish-assets:register"};WA();var ZOQ=H.enum(["provider"]),Qz1=H.object({executionMode:ZOQ.optional(),publishResultIdField:H.string().min(1).optional(),publishTimestampField:H.string().min(1).optional(),enabled:H.boolean().optional()}).strict();var NOQ=H.object({skipIfDraftExists:H.boolean().optional(),minSourceEntities:H.number().optional(),maxUnpublishedDrafts:H.number().optional(),sourceEntityType:H.string().optional()}),Bz1=H.object({entitySchedules:H.record(H.string(),H.string()).optional(),generationSchedules:H.record(H.string(),H.string()).optional(),generationConditions:H.record(H.string(),NOQ).optional()});class vH{static instance=null;queues=new Map;static getInstance(){return vH.instance??=new vH,vH.instance}static resetInstance(){vH.instance=null}static createFresh(){return new vH}constructor(){}async add(A,Q,B=di){let w=this.getOrCreateQueue(A),$=w.find((D)=>D.entityId===Q);if($)return{position:$.position};let f=w.length+1,I={entityId:Q,entityType:A,position:f,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:f}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class TH{static instance=null;providers=new Map;executionModes=new Map;publishResultIdFields=new Map;publishTimestampFields=new Map;defaultProvider=new khA;static getInstance(){return TH.instance??=new TH,TH.instance}static resetInstance(){TH.instance=null}static createFresh(){return new TH}constructor(){}register(A,Q,B){let w=this.providers.get(A);if(w&&w.name!=="internal"&&Q.name==="internal")return;if(this.providers.set(A,Q),this.executionModes.set(A,B?.executionMode??"provider"),B?.publishResultIdField)this.publishResultIdFields.set(A,B.publishResultIdField);else this.publishResultIdFields.delete(A);if(B?.publishTimestampField)this.publishTimestampFields.set(A,B.publishTimestampField);else this.publishTimestampFields.delete(A)}get(A){return this.providers.get(A)??this.defaultProvider}getExecutionMode(A){return this.executionModes.get(A)??"provider"}getPublishResultIdField(A){return this.publishResultIdFields.get(A)}getPublishTimestampField(A){return this.publishTimestampFields.get(A)}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A),this.executionModes.delete(A),this.publishResultIdFields.delete(A),this.publishTimestampFields.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}WA();WA();async function wz1(A,Q){if(!Q.publishExecutor){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"Publish executor not configured",retryCount:0,willRetry:!1});return}await zOQ(A,Q)}async function zOQ(A,Q){if(!Q.publishExecutor)return;try{let B=await Q.publishExecutor.publish({entityType:A.entityType,id:A.entityId});if("error"in B){let w={entityType:A.entityType,entityId:A.entityId,error:B.error,retryCount:0,willRetry:!1};if(Q.messageBus)await Q.messageBus.send({type:c4.FAILED,payload:w,sender:"publish-service"});Q.onFailed?.(w);return}jhA(A.entityType,A.entityId,B.result,Q)}catch(B){let w=T0(B);Q.retryTracker.recordFailure(A.entityId,w);let $=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:w,retryCount:$?.retryCount??1,willRetry:!1})}}function jhA(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:c4.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function $z1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:!1};if(w.messageBus)w.messageBus.send({type:c4.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function fz1(A,Q){let B=Q.generationConditions[A];if(B&&Q.onCheckGenerationConditions){let $=await Q.onCheckGenerationConditions(A,B);if(!$.shouldGenerate){if(Q.messageBus)Q.messageBus.send({type:oz.SKIPPED,payload:{entityType:A,reason:$.reason??"Conditions not met"},sender:"content-pipeline"});return}}let w={entityType:A};if(Q.messageBus)await Q.messageBus.send({type:oz.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function Iz1(A,Q,B){if(B)B.send({type:oz.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function Dz1(A,Q,B){if(B)B.send({type:oz.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var qOQ=1000;class _hA{deps;publishJobs=new Map;immediateIntervalJob=null;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.entitySchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.processEntityType(A));this.publishJobs.set(A,B)}this.immediateIntervalJob=this.deps.config.backend.scheduleInterval(qOQ,()=>this.processUnscheduledTypes())}stop(){if(LOQ(this.publishJobs),this.immediateIntervalJob)this.immediateIntervalJob.stop(),this.immediateIntervalJob=null}async processEntityType(A){if(!this.deps.isRunning())return;try{let Q=await this.deps.config.queueManager.getNext(A);if(Q)await this.processEntry(Q)}catch(Q){this.deps.config.logger.error(`Scheduler error for ${A}:`,Q)}}async processUnscheduledTypes(){if(!this.deps.isRunning())return;try{let A=await this.deps.config.queueManager.getQueuedEntityTypes();for(let Q of A)if(!this.entitySchedules[Q]){let B=await this.deps.config.queueManager.getNext(Q);if(B){await this.processEntry(B);break}}}catch(A){this.deps.config.logger.error("Scheduler error for unscheduled types:",A)}}async processEntry(A){await this.deps.config.queueManager.remove(A.entityType,A.entityId);let Q=this.deps.getPublishDeps();await wz1(A,Q)}get entitySchedules(){return this.deps.config.entitySchedules}}function LOQ(A){for(let Q of A.values())Q.stop();A.clear()}class vhA{deps;generationJobs=new Map;constructor(A){this.deps=A}start(){for(let[A,Q]of Object.entries(this.generationSchedules)){let B=this.deps.config.backend.scheduleCron(Q,()=>this.handleTriggerGeneration(A));this.generationJobs.set(A,B)}}stop(){VOQ(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await fz1(A,this.deps.getGenerationDeps())}catch(Q){this.deps.config.logger.error(`Generation trigger error for ${A}:`,Q)}}get generationSchedules(){return this.deps.config.generationSchedules}}function VOQ(A){for(let Q of A.values())Q.stop();A.clear()}class YX{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return YX.instance??=new YX(A),YX.instance}static resetInstance(){if(YX.instance)YX.instance.stop();YX.instance=null}static createFresh(A){return new YX(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new _hA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new vhA({config:this.config,getGenerationDeps:()=>this.generationDeps,isRunning:()=>this.running})}async start(){if(this.running)return;this.running=!0,this.publishRunner.start(),this.generationRunner.start()}async stop(){this.running=!1,this.publishRunner.stop(),this.generationRunner.stop()}isRunning(){return this.running}completePublish(A,Q,B){jhA(A,Q,B,this.publishDeps)}failPublish(A,Q,B){$z1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){Iz1(A,Q,this.config.messageBus)}failGeneration(A,Q){Dz1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,publishExecutor:this.config.publishExecutor,onPublish:this.config.onPublish,onFailed:this.config.onFailed}}get generationDeps(){return{logger:this.config.logger,messageBus:this.config.messageBus,generationConditions:this.config.generationConditions,onCheckGenerationConditions:this.config.onCheckGenerationConditions,onGenerate:this.config.onGenerate}}validateCronExpressions(){for(let[A,Q]of Object.entries(this.entitySchedules))this.validateCronExpression(A,Q,"publish");for(let[A,Q]of Object.entries(this.generationSchedules))this.validateCronExpression(A,Q,"generation")}validateCronExpression(A,Q,B){try{this.config.backend.validateCron(Q)}catch(w){throw Error(`Invalid ${B} cron expression for ${A}: "${Q}" - ${T0(w)}`)}}}class yH{static instance=null;retries=new Map;static getInstance(){return yH.instance??=new yH,yH.instance}static resetInstance(){yH.instance=null}static createFresh(){return new yH}constructor(){}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q})}clearRetries(A){this.retries.delete(A)}getRetryInfo(A){let Q=this.retries.get(A);if(!Q)return null;return{entityId:Q.entityId,retryCount:Q.retryCount,lastError:Q.lastError}}}function u7(A,Q,B,w,$,f,I,D){return u7.fromTZ(u7.tp(A,Q,B,w,$,f,I),D)}u7.fromTZISO=(A,Q,B)=>u7.fromTZ(EOQ(A,Q),B);u7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=ThA(A.tz,B),$=new Date(B.getTime()-w),f=ThA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=ThA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};u7.toTZ=function(A,Q){let B=A.toLocaleString("en-US",{timeZone:Q}).replace(/[\u202f]/," "),w=new Date(B);return{y:w.getFullYear(),m:w.getMonth()+1,d:w.getDate(),h:w.getHours(),i:w.getMinutes(),s:w.getSeconds(),tz:Q}};u7.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function ThA(A,Q=new Date){let B=Q.toLocaleString("en-US",{timeZone:A,timeZoneName:"shortOffset"}).split(" ").slice(-1)[0],w=Q.toLocaleString("en-US").replace(/[\u202f]/," ");return Date.parse(`${w} GMT`)-Date.parse(`${w} ${B}`)}function EOQ(A,Q){let B=new Date(Date.parse(A));if(isNaN(B))throw Error("minitz: Invalid ISO8601 passed to parser.");let w=A.substring(9);return A.includes("Z")||w.includes("-")||w.includes("+")?u7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):u7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}u7.minitz=u7;var yhA=32,oi=31|yhA,Xz1=[1,2,4,8,16],Yz1=class{pattern;timezone;second;minute;hour;day;month;dayOfWeek;lastDayOfMonth;starDOM;starDOW;constructor(A,Q){this.pattern=A,this.timezone=Q,this.second=Array(60).fill(0),this.minute=Array(60).fill(0),this.hour=Array(24).fill(0),this.day=Array(31).fill(0),this.month=Array(12).fill(0),this.dayOfWeek=Array(7).fill(0),this.lastDayOfMonth=!1,this.starDOM=!1,this.starDOW=!1,this.parse()}parse(){if(!(typeof this.pattern=="string"||this.pattern instanceof String))throw TypeError("CronPattern: Pattern has to be of type string.");this.pattern.indexOf("@")>=0&&(this.pattern=this.handleNicknames(this.pattern).trim());let A=this.pattern.replace(/\s+/g," ").split(" ");if(A.length<5||A.length>6)throw TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exactly five or six space separated parts are required.");if(A.length===5&&A.unshift("0"),A[3].indexOf("L")>=0&&(A[3]=A[3].replace("L",""),this.lastDayOfMonth=!0),A[3]=="*"&&(this.starDOM=!0),A[4].length>=3&&(A[4]=this.replaceAlphaMonths(A[4])),A[5].length>=3&&(A[5]=this.replaceAlphaDays(A[5])),A[5]=="*"&&(this.starDOW=!0),this.pattern.indexOf("?")>=0){let Q=new sY(new Date,this.timezone).getDate(!0);A[0]=A[0].replace("?",Q.getSeconds().toString()),A[1]=A[1].replace("?",Q.getMinutes().toString()),A[2]=A[2].replace("?",Q.getHours().toString()),this.starDOM||(A[3]=A[3].replace("?",Q.getDate().toString())),A[4]=A[4].replace("?",(Q.getMonth()+1).toString()),this.starDOW||(A[5]=A[5].replace("?",Q.getDay().toString()))}this.throwAtIllegalCharacters(A),this.partToArray("second",A[0],0,1),this.partToArray("minute",A[1],0,1),this.partToArray("hour",A[2],0,1),this.partToArray("day",A[3],-1,1),this.partToArray("month",A[4],-1,1),this.partToArray("dayOfWeek",A[5],0,oi),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,Y]=f,U=parseInt(I,10)+B,J=parseInt(D,10)+B,X=parseInt(Y,10);if(isNaN(U))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(J))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(X))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(X===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(X>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(U>J)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let G=U;G<=J;G+=X)this.setPart(Q,G,$[1]||w)}extractNth(A,Q){let B=A,w;if(B.includes("#")){if(Q!=="dayOfWeek")throw Error("CronPattern: nth (#) only allowed in day-of-week field");w=B.split("#")[1],B=B.split("#")[0]}return[B,w]}handleRange(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=I;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=I;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|yhA;else if(Q===oi)this.dayOfWeek[A]=oi;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|Xz1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},Uz1=[31,28,31,30,31,30,31,31,30,31,30,31],iF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],sY=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&oi&&Xz1[I-1]&$)return!0;if($&yhA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=u7.toTZ(Q,this.tz);this.ms=Q.getMilliseconds(),this.second=B.s,this.minute=B.i,this.hour=B.h,this.day=B.d,this.month=B.m-1,this.year=B.y}else this.ms=Q.getMilliseconds(),this.second=Q.getSeconds(),this.minute=Q.getMinutes(),this.hour=Q.getHours(),this.day=Q.getDate(),this.month=Q.getMonth(),this.year=Q.getFullYear()}fromCronDate(Q){this.tz=Q.tz,this.year=Q.year,this.month=Q.month,this.day=Q.day,this.hour=Q.hour,this.minute=Q.minute,this.second=Q.second,this.ms=Q.ms}apply(){if(this.month>11||this.day>Uz1[this.month]||this.hour>59||this.minute>59||this.second>59||this.hour<0||this.minute<0||this.second<0){let Q=new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms));return this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes(),this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),!0}else return!1}fromString(Q){if(typeof this.tz=="number"){let B=u7.fromTZISO(Q);this.ms=B.getUTCMilliseconds(),this.second=B.getUTCSeconds(),this.minute=B.getUTCMinutes(),this.hour=B.getUTCHours(),this.day=B.getUTCDate(),this.month=B.getUTCMonth(),this.year=B.getUTCFullYear(),this.apply()}else return this.fromDate(u7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=Uz1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let U=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==I&&(U=1),B==="day"&&!w.starDOW){let J=w.dayOfWeek[(D+(Y-$-1))%7];if(J&&J&oi)J=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,J)?1:0;else if(J)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${J}`);Q.legacyMode&&!w.starDOM?U=U||J:U=U&&J}if(U)return this[B]=Y-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,iF[w][0],Q,iF[w][2]);if($>1){let f=w+1;for(;f<iF.length;)this[iF[f][0]]=-iF[f][2],f++;if($===3)return this[iF[w][1]]++,this[iF[w][0]]=-iF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=iF.length?this:this.year>=3000?null:this.recurse(Q,B,w)}increment(Q,B,w){return this.second+=B.interval!==void 0&&B.interval>1&&w?B.interval:1,this.ms=0,this.apply(),this.recurse(Q,B,0)}getDate(Q){return Q||this.tz===void 0?new Date(this.year,this.month,this.day,this.hour,this.minute,this.second,this.ms):typeof this.tz=="number"?new Date(Date.UTC(this.year,this.month,this.day,this.hour,this.minute-this.tz,this.second,this.ms)):u7.fromTZ(u7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function MOQ(A){if(A===void 0&&(A={}),delete A.name,A.legacyMode=A.legacyMode===void 0?!0:A.legacyMode,A.paused=A.paused===void 0?!1:A.paused,A.maxRuns=A.maxRuns===void 0?1/0:A.maxRuns,A.catch=A.catch===void 0?!1:A.catch,A.interval=A.interval===void 0?0:parseInt(A.interval.toString(),10),A.utcOffset=A.utcOffset===void 0?void 0:parseInt(A.utcOffset.toString(),10),A.unref=A.unref===void 0?!1:A.unref,A.startAt&&(A.startAt=new sY(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new sY(A.stopAt,A.timezone)),A.interval!==null){if(isNaN(A.interval))throw Error("CronOptions: Supplied value for interval is not a number");if(A.interval<0)throw Error("CronOptions: Supplied value for interval can not be negative")}if(A.utcOffset!==void 0){if(isNaN(A.utcOffset))throw Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");if(A.utcOffset<-870||A.utcOffset>870)throw Error("CronOptions: utcOffset out of bounds.");if(A.utcOffset!==void 0&&A.timezone)throw Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.")}if(A.unref!==!0&&A.unref!==!1)throw Error("CronOptions: Unref should be either true, false or undefined(false).");return A}function ni(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function COQ(A){return ni(A)}function OOQ(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var Jz1=30000,j$A=[],xhA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(ni(Q))$=Q;else if(typeof Q=="object")w=Q;else if(Q!==void 0)throw Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");if(ni(B))$=B;else if(typeof B=="object")w=B;else if(B!==void 0)throw Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");if(this.name=w?.name,this.options=MOQ(w),this._states={kill:!1,blocking:!1,previousRun:void 0,currentRun:void 0,once:void 0,currentTimeout:void 0,maxRuns:w?w.maxRuns:void 0,paused:w?w.paused:!1,pattern:new Yz1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new sY(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new Yz1(A,this.options.timezone),this.name){if(j$A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");j$A.push(this)}return $!==void 0&&COQ($)&&(this.fn=$,this.schedule()),this}nextRun(A){let Q=this._next(A);return Q?Q.getDate(!1):null}nextRuns(A,Q){this._states.maxRuns!==void 0&&A>this._states.maxRuns&&(A=this._states.maxRuns);let B=[],w=Q||this._states.currentRun||void 0;for(;A--&&(w=this.nextRun(w));)B.push(w);return B}getPattern(){return this._states.pattern?this._states.pattern.pattern:void 0}isRunning(){let A=this.nextRun(this._states.currentRun),Q=!this._states.paused,B=this.fn!==void 0,w=!this._states.kill;return Q&&B&&w&&A!==null}isStopped(){return this._states.kill}isBusy(){return this._states.blocking}currentRun(){return this._states.currentRun?this._states.currentRun.getDate():null}previousRun(){return this._states.previousRun?this._states.previousRun.getDate():null}msToNext(A){let Q=this._next(A);return Q?A instanceof sY||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new sY(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=j$A.indexOf(this);A>=0&&j$A.splice(A,1)}pause(){return this._states.paused=!0,!this._states.kill}resume(){return this._states.paused=!1,!this._states.kill}schedule(A){if(A&&this.fn)throw Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");A&&(this.fn=A);let Q=this.msToNext(),B=this.nextRun(this._states.currentRun);return Q==null||isNaN(Q)||B===null?this:(Q>Jz1&&(Q=Jz1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&OOQ(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new sY(void 0,this.options.timezone||this.options.utcOffset),this.options.catch)try{this.fn!==void 0&&await this.fn(this,this.options.context)}catch(Q){ni(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new sY(A,this.options.timezone||this.options.utcOffset),this._states.blocking=!1}async trigger(){await this._trigger()}runsLeft(){return this._states.maxRuns}_checkTrigger(A){let Q=new Date,B=!this._states.paused&&Q.getTime()>=A.getTime(),w=this._states.blocking&&this.options.protect;B&&!w?(this._states.maxRuns!==void 0&&this._states.maxRuns--,this._trigger()):B&&w&&ni(this.options.protect)&&setTimeout(()=>this.options.protect(this),0),this.schedule()}_next(A){let Q=!!(A||this._states.currentRun),B=!1;!A&&this.options.startAt&&this.options.interval&&([A,Q]=this._calculatePreviousRun(A,Q),B=!A),A=new sY(A,this.options.timezone||this.options.utcOffset),this.options.startAt&&A&&A.getTime()<this.options.startAt.getTime()&&(A=this.options.startAt);let w=this._states.once||new sY(A,this.options.timezone||this.options.utcOffset);return!B&&w!==this._states.once&&(w=w.increment(this._states.pattern,this.options,Q)),this._states.once&&this._states.once.getTime()<=A.getTime()||w===null||this._states.maxRuns!==void 0&&this._states.maxRuns<=0||this._states.kill||this.options.stopAt&&w.getTime()>=this.options.stopAt.getTime()?null:w}_calculatePreviousRun(A,Q){let B=new sY(void 0,this.options.timezone||this.options.utcOffset),w=A;if(this.options.startAt.getTime()<=B.getTime()){w=this.options.startAt;let $=w.getTime()+this.options.interval*1000;for(;$<=B.getTime();)w=new sY(w,this.options.timezone||this.options.utcOffset).increment(this._states.pattern,this.options,!0),$=w.getTime()+this.options.interval*1000;Q=!0}return w===null&&(w=void 0),[w,Q]}};class _$A{scheduleCron(A,Q){let B=new xhA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new xhA(A).stop()}}WA();var Wz1=H.union([H.string().min(1),H.object({location:H.enum(["metadata","frontmatter"]),field:H.string().min(1)})]),v$A=H.object({entityType:H.string().min(1),attachmentType:H.string().min(1),mediaEntityType:H.enum(["image","document"]),targetEntityField:Wz1.optional(),requiredWhen:H.object({status:H.string().min(1).optional(),visibility:H.string().min(1).optional()}).optional(),autoGenerate:H.boolean().optional(),requiredForPublish:H.boolean().optional(),jobType:H.string().min(1).optional()});function ShA(A){return`${A.entityType}:${A.attachmentType}`}class xH{static instance=null;definitions=new Map;static getInstance(){return xH.instance??=new xH,xH.instance}static resetInstance(){xH.instance=null}static createFresh(){return new xH}constructor(){}register(A){let Q=v$A.parse(A),B=ShA(Q);return this.definitions.set(B,Q),()=>this.unregister(Q.entityType,Q.attachmentType)}get(A,Q){return this.definitions.get(ShA({entityType:A,attachmentType:Q}))}list(A){let Q=Array.from(this.definitions.values());return A?Q.filter((B)=>B.entityType===A):Q}has(A,Q){return this.get(A,Q)!==void 0}unregister(A,Q){this.definitions.delete(ShA({entityType:A,attachmentType:Q}))}clear(){this.definitions.clear()}}WA();class T$A{deps;constructor(A){this.deps=A}async ensureForEntity(A,Q={}){let B=this.deps.registry.list(A.entityType).filter(($)=>$.autoGenerate===!0).filter(($)=>!Q.attachmentType||$.attachmentType===Q.attachmentType),w={checked:B.length,enqueued:0,skipped:0};for(let $ of B)if(await this.ensureDefinition(A,$))w.enqueued+=1;else w.skipped+=1;return w}async ensureDefinition(A,Q){if(!this.matchesPolicy(A,Q))return!1;if(this.hasTargetField(A,Q.targetEntityField))return!1;if(!this.deps.context.attachments.hasProvider(A.entityType,Q.attachmentType))return!1;let B=this.resolveJobType(Q);if(!B)return!1;let w=this.getPredictedMediaId(A,Q),$=this.getDeduplicationKey(A,Q);return await this.deps.context.jobs.enqueue({type:B,data:{sourceEntityType:A.entityType,sourceEntityId:A.id,attachmentType:Q.attachmentType,imageId:w,dedupKey:$,targetEntityType:A.entityType,targetEntityId:A.id,...this.getTargetImageFieldData(Q.targetEntityField)},options:{source:"content-pipeline",metadata:{operationType:"content_operations"},deduplication:"skip",deduplicationKey:$}}),this.deps.context.logger.debug("Queued publish asset generation",{entityType:A.entityType,entityId:A.id,attachmentType:Q.attachmentType,jobType:B}),!0}matchesPolicy(A,Q){let{requiredWhen:B}=Q;if(!B)return!0;if(B.status&&A.metadata.status!==B.status)return!1;if(B.visibility&&A.visibility!==B.visibility)return!1;return!0}hasTargetField(A,Q){if(!Q)return!1;if(typeof Q==="string")return ghA(A.metadata[Q]);if(Q.location==="metadata")return ghA(A.metadata[Q.field]);let{frontmatter:B}=jB(A.content);return ghA(B[Q.field])}resolveJobType(A){if(A.jobType)return A.jobType;if(A.mediaEntityType==="image")return"image:image-render-source";return}getPredictedMediaId(A,Q){let B=Q.attachmentType==="og-image"?"og":Q.attachmentType;return X1(`${B}-${A.entityType}-${A.id}`)}getDeduplicationKey(A,Q){return`publish-asset:${Q.attachmentType}:${A.entityType}:${A.id}`}getTargetImageFieldData(A){let Q=typeof A==="string"?A:A?.field;if(Q==="coverImageId"||Q==="ogImageId")return{targetImageField:Q};return{}}}function ghA(A){return typeof A==="string"?A.length>0:A!==void 0}aA();WA();var ROQ=H.object({id:H.string().min(1)});async function Gz1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=bOQ(Q.content),D=w?await jOQ(A,w):void 0,Y;if($&&$.length>0){let J=await _OQ(A,$);if(J.length>0)Y=J}Y??=await kOQ(A,f,I);let U={bodyContent:B};if(D)U.imageData=D;if(Y&&Y.length>0)U.documentData=Y;return U}function bOQ(A){try{let Q=R2(A,H.record(H.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=POQ(Q.metadata.documents),f=Hz1(Q.metadata.sourceEntityType),I=Hz1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function POQ(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=ROQ.safeParse(Q);return B.success?[B.data]:[]})}function Hz1(A){return typeof A==="string"&&A.length>0?A:void 0}async function kOQ(A,Q,B){if(!Q||!B)return;let w=await A.attachments.resolve({sourceEntityType:Q,sourceEntityId:B,attachmentType:"carousel"});return w?[w]:void 0}async function jOQ(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=Kz1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function _OQ(A,Q){return(await Promise.all(Q.map((w)=>vOQ(A,w)))).filter((w)=>w!==void 0)}async function vOQ(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=Kz1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:TOQ(B,Q.id)}}function Kz1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function TOQ(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}WA();var yOQ=/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)/;async function hhA(A,Q,B,w={}){let $=w.publishedAt??new Date().toISOString(),f=w.publishTimestampField??"publishedAt",I={...Q.metadata,status:"published",[f]:$,platformId:B.id,...xOQ(B.id,w.publishResultIdField)},D={...Q,content:Fz1(Q.content,$,B.id,w.publishResultIdField,f),metadata:I};return await A.entityService.updateEntity({entity:D}),D}function Fz1(A,Q,B,w,$="publishedAt"){if(!yOQ.test(A))return A;let f=U4(U4(A,"status","published"),$,Q);if(!B||!w)return f;return U4(f,w,B)}function xOQ(A,Q){if(!Q||Q==="platformId")return{};return{[Q]:A}}class xv{deps;constructor(A){this.deps=A}async resolveCandidate(A){let{entityType:Q,id:B,slug:w}=A;if(!B&&!w)return{error:"Either 'id' or 'slug' must be provided"};let $=await this.findPublishableEntity(Q,B,w);if(!$)return{error:`Entity not found: ${Q}:${B??w}`};if($.visibility!=="public")return{error:`Cannot publish ${Q}:${$.id} to a public provider because visibility is ${$.visibility}`};if($.metadata.status==="published")return{error:"Entity is already published"};if(!this.deps.providerRegistry.has(Q))return{error:`No publish provider registered for ${Q}. Check that the required credentials are configured.`};return{entity:$}}async publish(A){let Q=await this.resolveCandidate(A);if("error"in Q)return Q;let{entity:B}=Q,{entityType:w}=A,$=this.deps.providerRegistry.get(w),{bodyContent:f,imageData:I,documentData:D}=await Gz1(this.deps.context,B),Y=await $.publish(f,B.metadata,I,D),U=this.deps.providerRegistry.getPublishResultIdField(w),J=this.deps.providerRegistry.getPublishTimestampField(w),X=await hhA(this.deps.context,B,Y,{...U?{publishResultIdField:U}:{},...J?{publishTimestampField:J}:{}});return await this.runPublishAssetPreflight(X),{entity:X,result:Y}}async runPublishAssetPreflight(A){if(!this.deps.publishAssetPreflight)return;try{await this.deps.publishAssetPreflight.ensureForEntity(A)}catch(Q){this.deps.context.logger.warn("Publish asset preflight failed",{entityType:A.entityType,entityId:A.id,error:Q instanceof Error?Q.message:String(Q)})}}async findPublishableEntity(A,Q,B){if(Q)return this.deps.context.entityService.getEntity({entityType:A,id:Q});if(!B)return null;return(await this.deps.context.entityService.listEntities({entityType:A,options:{filter:{metadata:{slug:B}},limit:1}}))[0]??null}}aA();WA();var mhA=H.object({action:H.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:H.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:H.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:H.number().optional().describe("New position for reorder action (1-based)")}),uhA=H.object({position:H.number(),entityType:H.string(),entityId:H.string(),queuedAt:H.string()}),SOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({queue:H.array(uhA).optional(),entityType:H.string().optional(),entityId:H.string().optional(),position:H.number().optional()}).optional()}),gOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),chA=H.union([SOQ,gOQ]);function y$A(A,Q,B){return{...oQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",mhA,async($,f)=>{let{action:I,entityType:D,entityId:Y,position:U}=$;switch(I){case"list":return hOQ(B,D);case"add":return mOQ(A,B,D,Y,f);case"remove":return uOQ(A,B,D,Y,f);case"reorder":return cOQ(A,B,D,Y,U,f);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:chA}}async function hOQ(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function mOQ(A,Q,B,w,$){let f=lhA("add",B,w);if(!f.success)return f.error;A.permissions.assertEntityActionAllowed(f.entityType,"publish",$??{});let I=await Q.add(f.entityType,f.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:f.entityType,entityId:f.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function uOQ(A,Q,B,w,$){let f=lhA("remove",B,w);if(!f.success)return f.error;return A.permissions.assertEntityActionAllowed(f.entityType,"update",$??{}),await Q.remove(f.entityType,f.entityId),{success:!0,data:{entityType:f.entityType,entityId:f.entityId},message:"Removed from queue"}}async function cOQ(A,Q,B,w,$,f){let I=lhA("reorder",B,w);if(!I.success)return I.error;let D=lOQ($);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",f??{}),await Q.reorder(I.entityType,I.entityId,D.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:D.position},message:`Moved to position ${D.position}`}}function lhA(A,Q,B){if(!Q)return{success:!1,error:{success:!1,error:`entityType is required for ${A} action`}};if(!B)return{success:!1,error:{success:!1,error:`entityId is required for ${A} action`}};return{success:!0,entityType:Q,entityId:B}}function lOQ(A){if(A===void 0)return{success:!1,error:{success:!1,error:"position is required for reorder action"}};if(A<1)return{success:!1,error:{success:!1,error:"position must be a positive number"}};return{success:!0,position:A}}WA();var x$A=H.object({entityType:H.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:H.string().optional().describe("Entity ID to publish"),slug:H.string().optional().describe("Entity slug to publish"),confirmed:H.boolean().optional(),confirmationToken:H.string().optional(),contentHash:H.string().optional()}),pOQ=H.object({success:H.literal(!0),message:H.string().optional(),data:H.object({entityType:H.string().optional(),entityId:H.string().optional(),platformId:H.string().optional(),url:H.string().optional()}).optional()}),iOQ=H.object({success:H.literal(!1),error:H.string(),code:H.string().optional()}),rOQ=H.object({success:H.literal(!1).optional(),error:H.string().optional(),needsConfirmation:H.literal(!0),toolName:H.string(),summary:H.string(),preview:H.string().optional(),args:H.unknown()}),phA=H.union([pOQ,iOQ,rOQ]),dOQ=900000,nOQ=1000;class Nz1{tokens=new Map;add(A){if(this.prune(),this.tokens.size>=nOQ){let Q=this.tokens.keys().next().value;if(Q!==void 0)this.tokens.delete(Q)}this.tokens.set(A,Date.now()+dOQ)}has(A){let Q=this.tokens.get(A);if(Q===void 0)return!1;if(Q<=Date.now())return this.tokens.delete(A),!1;return!0}delete(A){this.tokens.delete(A)}prune(){let A=Date.now();for(let[Q,B]of this.tokens)if(B<=A)this.tokens.delete(Q)}}function S$A(A,Q,B,w){let $=w??new xv({context:A,providerRegistry:B}),f=new Nz1,I=`${Q}_publish`;return{name:I,description:"Publish an entity directly to its platform. Call this when the user asks to publish; the tool will request confirmation itself. Works with any registered entity type (social-post, post, deck, etc.)",inputSchema:x$A.shape,outputSchema:phA,visibility:"anchor",handler:async(D,Y)=>{let U=x$A.safeParse(D);if(!U.success)return{success:!1,error:`Invalid input: ${U.error.errors.map((V)=>`${V.path.join(".")}: ${V.message}`).join(", ")}`};let J=U.data,{entityType:X,id:G,slug:Z}=J;try{A.permissions.assertEntityActionAllowed(X,"publish",Y)}catch(V){return{success:!1,error:V instanceof Error?V.message:String(V)}}let N=await $.resolveCandidate({entityType:X,id:G,slug:Z});if("error"in N)return{success:!1,error:N.error};let{entity:L}=N;if(J.confirmed){let V=J.confirmationToken;if(!V||!f.has(V))return Zz1(I,J,L,f);if(f.delete(V),J.contentHash&&J.contentHash!==L.contentHash)return{success:!1,error:`Cannot publish ${X}:${L.id} because it changed after confirmation. Review it and try again.`};let M;try{M=await $.publish({entityType:X,id:L.id})}catch(S){return{success:!1,error:S instanceof Error?S.message:String(S)}}if("error"in M)return{success:!1,error:M.error};let{entity:O,result:E}=M;return{success:!0,data:{entityType:X,entityId:O.id,platformId:E.id,url:E.url},message:`Published ${X}:${O.id}`}}return Zz1(I,J,L,f)}}}function Zz1(A,Q,B,w){let $=crypto.randomUUID();w.add($);let f=oOQ(B);return{needsConfirmation:!0,toolName:A,summary:`Publish "${f}"?`,preview:`This will publish ${B.entityType}:${B.id} to its registered public publish provider.`,args:{...Q,id:B.id,slug:void 0,confirmed:!0,confirmationToken:$,contentHash:B.contentHash}}}function oOQ(A){let Q=A.metadata.title;if(typeof Q==="string"&&Q.length>0)return Q;let B=A.metadata.subject;if(typeof B==="string"&&B.length>0)return B;let w=A.metadata.slug;if(typeof w==="string"&&w.length>0)return w;return A.id}aA();WA();var ihA=H.object({entityType:H.string().min(1).describe("Entity type to reconcile"),status:H.string().min(1).optional().describe("Optional metadata status filter, e.g. published"),assetType:H.string().min(1).optional().describe("Optional attachment type filter, e.g. og-image")}),rhA=H.object({success:H.literal(!0),data:H.object({entityType:H.string(),assetType:H.string().optional(),checkedEntities:H.number(),checkedAssets:H.number(),enqueued:H.number(),skipped:H.number()}),message:H.string().optional()});function g$A(A,Q,B,w){return{...oQ(Q,"ensure-assets","Reconcile configured publish assets for existing entities, queueing missing generated assets such as OG images.",ihA,async(f,I)=>{if(A.permissions.assertEntityActionAllowed(f.entityType,"publish",I),B.list(f.entityType).filter((G)=>G.autoGenerate===!0).filter((G)=>!f.assetType||G.attachmentType===f.assetType).length===0)return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:0,checkedAssets:0,enqueued:0,skipped:0},message:`No publish assets configured for ${f.entityType}`};let Y=await A.entityService.listEntities({entityType:f.entityType,options:{...f.status&&{filter:{metadata:{status:f.status}}}}}),U=0,J=0,X=0;for(let G of Y){let Z=await w.ensureForEntity(G,{...f.assetType&&{attachmentType:f.assetType}});U+=Z.checked,J+=Z.enqueued,X+=Z.skipped}return{success:!0,data:{entityType:f.entityType,...f.assetType&&{assetType:f.assetType},checkedEntities:Y.length,checkedAssets:U,enqueued:J,skipped:X},message:`Queued ${J} publish asset job(s)`}}),outputSchema:rhA}}aA();WA();function zz1(A,Q){sOQ(A,Q),aOQ(A,Q),tOQ(A,Q),eOQ(A,Q)}function sOQ(A,Q){A.messaging.subscribe(c4.REGISTER,async(B)=>ARQ(Q,B.payload)),A.messaging.subscribe(c4.QUEUE,async(B)=>$RQ(A,Q,B.payload)),A.messaging.subscribe(c4.DIRECT,async(B)=>fRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REMOVE,async(B)=>IRQ(Q,B.payload)),A.messaging.subscribe(c4.REORDER,async(B)=>DRQ(Q,B.payload)),A.messaging.subscribe(c4.LIST,async(B)=>YRQ(A,Q,B.payload)),A.messaging.subscribe(c4.REPORT_SUCCESS,async(B)=>URQ(Q,B.payload)),A.messaging.subscribe(c4.REPORT_FAILURE,async(B)=>JRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function aOQ(A,Q){A.messaging.subscribe(oz.REPORT_SUCCESS,async(B)=>XRQ(Q,B.payload)),A.messaging.subscribe(oz.REPORT_FAILURE,async(B)=>WRQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}function tOQ(A,Q){A.messaging.subscribe(Az1.REGISTER,async(B)=>QRQ(Q,B.payload)),Q.logger.debug("Subscribed to publish asset messages")}function eOQ(A,Q){let B=async(w)=>BRQ(A,Q,w.payload);A.messaging.subscribe("entity:created",B),A.messaging.subscribe("entity:updated",B),Q.logger.debug("Subscribed to entity change messages for publish assets")}async function ARQ(A,Q){let{entityType:B,provider:w,config:$}=Q;try{let f=$?Qz1.safeParse($):void 0;if(f&&!f.success)return A.logger.warn("Invalid publish provider config",{entityType:B,error:f.error.message}),{success:!1};if(w)A.providerRegistry.register(B,w,f?.data),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name,executionMode:A.providerRegistry.getExecutionMode(B)});return{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to register provider: ${I}`),{success:!1}}}async function QRQ(A,Q){let B=v$A.safeParse(Q);if(!B.success)return A.logger.warn("Invalid publish asset registration",{error:B.error.message}),{success:!1};return A.publishAssetRegistry.register(B.data),A.logger.info("Registered publish asset",{entityType:B.data.entityType,attachmentType:B.data.attachmentType,mediaEntityType:B.data.mediaEntityType}),{success:!0}}async function BRQ(A,Q,B){try{if(Q.publishAssetRegistry.list(B.entityType).length===0)return{success:!0};let w=B.entity??await A.entityService.getEntity({entityType:B.entityType,id:B.entityId});if(!wRQ(w))return{success:!0};return await Q.publishAssetPreflight.ensureForEntity(w),{success:!0}}catch(w){return Q.logger.warn("Failed to run publish asset preflight for entity event",{entityType:B.entityType,entityId:B.entityId,error:T0(w)}),{success:!1}}}function wRQ(A){if(!A)return!1;let Q=e31.safeParse(A.metadata);return Q.success&&Q.data.status==="published"}async function $RQ(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=B.authContext??di;A.permissions.assertEntityActionAllowed(w,"publish",f);let I=await Q.queueManager.add(w,$,f);return await A.messaging.send({type:c4.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(f){let I=T0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function fRQ(A,Q,B){let{entityType:w,entityId:$}=B,f=B.authContext??di;try{if(A.permissions.assertEntityActionAllowed(w,"publish",f),!Q.providerRegistry.has(w))return Q.scheduler.failPublish(w,$,`No publish provider registered for ${w}`),{success:!1};let I=await Q.publishExecutor.publish({entityType:w,id:$});if("error"in I)return Q.scheduler.failPublish(w,$,I.error),{success:!1};return Q.scheduler.completePublish(w,$,I.result),Q.logger.debug(`Direct publish completed: ${$}`,{entityType:w}),{success:!0}}catch(I){let D=T0(I);return Q.logger.error(`Failed direct publish request: ${D}`),{success:!1}}}async function IRQ(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=T0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function DRQ(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=T0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function YRQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:c4.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=T0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function URQ(A,Q){let{entityType:B,entityId:w,result:$}=Q;return A.scheduler.completePublish(B,w,$),A.logger.info(`Publish reported success: ${w}`,{entityType:B}),{success:!0}}async function JRQ(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount}),{success:!0}}async function XRQ(A,Q){let{entityType:B,entityId:w}=Q;return A.scheduler.completeGeneration(B,w),A.logger.info("Generation completed",{entityType:B,entityId:w}),{success:!0}}async function WRQ(A,Q){let{entityType:B,error:w}=Q;return A.scheduler.failGeneration(B,w),A.logger.warn("Generation failed",{entityType:B,error:w}),{success:!0}}WA();async function qz1(A,Q,B,w){try{if(w.skipIfDraftExists!==!1){if((await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:1}})).length>0)return{shouldGenerate:!1,reason:"Draft already exists"}}if(w.maxUnpublishedDrafts!==void 0){let $=await A.listEntities({entityType:B,options:{filter:{metadata:{status:"draft"}},limit:w.maxUnpublishedDrafts+1}});if($.length>=w.maxUnpublishedDrafts)return{shouldGenerate:!1,reason:`Max unpublished drafts reached (${$.length}/${w.maxUnpublishedDrafts})`}}if(w.minSourceEntities!==void 0&&w.sourceEntityType){let $=await A.listEntities({entityType:w.sourceEntityType,options:{publishedOnly:!0,limit:w.minSourceEntities}});if($.length<w.minSourceEntities)return{shouldGenerate:!1,reason:`Not enough source entities (${$.length}/${w.minSourceEntities} ${w.sourceEntityType})`}}return{shouldGenerate:!0}}catch($){return Q.error("Failed to check generation conditions",{entityType:B,error:T0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${T0($)}`}}}function Lz1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,publishExecutor:I,logger:D}=A,Y=HRQ(Q);return YX.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:D,backend:new _$A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,publishExecutor:I,onCheckGenerationConditions:(U,J)=>qz1(Q.entityService,D,U,J)})}function HRQ(A){return{send:async($)=>{return A.messaging.send({type:$.type,payload:$.payload,...$.target!==void 0?{target:$.target}:{},...$.metadata!==void 0?{metadata:$.metadata}:{},...$.broadcast!==void 0?{broadcast:$.broadcast}:{}})},subscribe:()=>()=>{},unsubscribe:()=>{}}}async function Vz1(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var GRQ=["draft","queued","published","failed"];async function Ez1(A,Q){await A.messaging.send({type:"dashboard:register-widget",payload:{id:"publication-pipeline",pluginId:Q,title:"Publication Pipeline",section:"secondary",priority:100,rendererName:"PipelineWidget",visibility:"anchor",dataProvider:()=>KRQ(A)}})}async function KRQ(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=FRQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:ZRQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function FRQ(A){return GRQ.find((Q)=>Q===A)}function ZRQ(A,Q){return typeof Q==="string"?Q:A}var Mz1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.122",description:"Content pipeline plugin for managing entity publishing queues, scheduling, and generation",type:"module",main:"src/index.ts",types:"src/index.ts",scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",croner:"^9.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14",typescript:"^5.3.3"},exports:{".":{types:"./src/index.ts",default:"./src/index.ts"}},files:["src"]};class dhA extends UB{pluginContext;queueManager;providerRegistry;retryTracker;publishExecutor;publishAssetRegistry;publishAssetPreflight;scheduler;constructor(A){super("content-pipeline",Mz1,A??{},Bz1)}async onRegister(A){this.pluginContext=A,this.queueManager=vH.createFresh(),this.providerRegistry=TH.createFresh(),this.retryTracker=yH.createFresh(),this.publishAssetRegistry=xH.createFresh(),this.publishAssetPreflight=new T$A({context:A,registry:this.publishAssetRegistry}),this.publishExecutor=new xv({context:A,providerRegistry:this.providerRegistry,publishAssetPreflight:this.publishAssetPreflight}),this.scheduler=Lz1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,logger:this.logger}),zz1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,publishExecutor:this.publishExecutor,publishAssetRegistry:this.publishAssetRegistry,publishAssetPreflight:this.publishAssetPreflight,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await Vz1(A.entityService,this.queueManager,this.logger),await Ez1(A,this.id),await this.scheduler.start(),this.logger.info("Content pipeline plugin started")}async getTools(){if(!this.pluginContext)throw Error("Plugin context not initialized");return[y$A(this.pluginContext,this.id,this.queueManager),S$A(this.pluginContext,this.id,this.providerRegistry,this.publishExecutor),g$A(this.pluginContext,this.id,this.publishAssetRegistry,this.publishAssetPreflight)]}async getInstructions(){return'## Publishing\n- Use `content-pipeline_queue` to manage the publish queue \u2014 list queued items, add entities to the queue, remove them, or reorder.\n- Use `content-pipeline_publish` to publish an entity directly to its platform (e.g. LinkedIn, Buttondown). This tool has its own confirmation flow; call it without `confirmed` when the user asks to publish instead of asking for plain-text confirmation.\n- Use `content-pipeline_ensure-assets` to reconcile missing publish assets such as generated OG images for already-published content.\n- When users ask about their "publish queue", "publishing queue", or "what\'s queued", use `content-pipeline_queue`.'}getQueueManager(){return this.queueManager}getProviderRegistry(){return this.providerRegistry}getRetryTracker(){return this.retryTracker}getPublishAssetRegistry(){return this.publishAssetRegistry}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),vH.resetInstance(),TH.resetInstance(),yH.resetInstance(),xH.resetInstance()}}function nhA(A){return new dhA(A)}aA();WA();var Cz1=H.object({accountId:H.string().describe("Cloudflare account ID"),apiToken:H.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:H.string().describe("Cloudflare Web Analytics site tag")}),ohA=H.object({cloudflare:Cz1.optional()});aA();WA();var zRQ=H.object({date:H.string().describe("Single date in YYYY-MM-DD format").optional(),days:H.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:H.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:H.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:H.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function qRQ(A){if(A.date&&(A.days||A.startDate||A.endDate))return"Cannot combine 'date' with 'days' or 'startDate'/'endDate'";if(A.days&&(A.startDate||A.endDate))return"Cannot combine 'days' with 'startDate'/'endDate'";if(A.startDate&&!A.endDate||!A.startDate&&A.endDate)return"Both 'startDate' and 'endDate' must be provided for custom range";return null}function Oz1(A,Q,B){let w=[];if(!B)return w;return w.push(oQ(A,"query",`Query website analytics from Cloudflare.
6524
6524
 
6525
6525
  Date range options (use only one):
6526
6526
  - No params: yesterday only
@@ -6658,7 +6658,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,zRQ,
6658
6658
  }
6659
6659
  }
6660
6660
  }
6661
- `,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var ahA=7,LRQ=10;function bz1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=oO(),B=en(ahA),w=AN(B),$=AN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:LRQ})]);return{days:ahA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:ahA}}}}var Pz1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.121",description:"Analytics plugin for collecting website and social media metrics",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class kz1 extends UB{cloudflareClient;constructor(A={}){super("analytics",Pz1,A,ohA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new shA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",bz1(this.cloudflareClient))}async onReady(A){let Q=this.config.cloudflare?.siteTag;if(!Q)return;await A.messaging.send({type:"plugin:site-builder:head-script:register",payload:{pluginId:this.id,script:Rz1(Q)}})}async getTools(){return Oz1(this.id,this.getContext(),this.cloudflareClient)}}function ERQ(A={}){return new kz1(A)}var h$A=ERQ;import{randomBytes as PRQ}from"crypto";aA();WA();U8();var MRQ=new Set(["description","excerpt","summary","tagline","story"]);function CRQ(A){if(A.endsWith("s"))return A;return zI(A)}function thA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return thA(A._def.innerType,!0,B);if(w==="ZodDefault")return thA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function ehA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=thA(Q),f=B._def.typeName,I={name:A,label:lX(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((Y)=>Y.kind==="datetime"))return{...I,widget:"datetime"};if(MRQ.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,Y=ehA("item",D);if(Y.widget==="object"&&Y.fields)return{...I,widget:"list",fields:Y.fields};return{...I,widget:"list",field:{name:A,label:lX(A),widget:Y.widget}}}case"ZodObject":{let D=B.shape,Y=Object.entries(D).map(([U,J])=>ehA(U,J));return{...I,widget:"object",fields:Y}}default:return{...I,widget:"string"}}}function jz1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>ehA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function _z1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],Y=w===As?"Note":lX(w),U=D?.label??Y,J=D?.pluralName??CRQ(U);if(f?.isSingleton){B.push({name:w,label:U,file:`${w}/${w}.md`,fields:jz1($,I)});continue}if(w===As){Q.push({name:w,label:J,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:J,folder:w,create:!0,extension:"md",format:"frontmatter",fields:jz1($,I)})}if(B.length>0)Q.push({name:"settings",label:"Settings",files:B});return{backend:{name:"github",repo:A.repo,branch:A.branch,...A.baseUrl&&{base_url:A.baseUrl},...A.authEndpoint&&{auth_endpoint:A.authEndpoint}},media_folder:"image",public_folder:"/images",collections:Q}}var ORQ=new RegExp("[<>&\\u2028\\u2029]","g");function Sv(A){return JSON.stringify(A).replace(ORQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var vz1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function m$A(A){let Q=`<script src="${vz1}"></script>`;return`<!doctype html>
6661
+ `,variables:B})});if(!w.ok){let I=await w.text();throw Error(`Cloudflare API error: ${w.status} - ${I}`)}let $=await w.json();if($.errors&&$.errors.length>0)throw Error(`Cloudflare GraphQL error: ${$.errors.map((I)=>I.message).join(", ")}`);return($.data.viewer.accounts[0]?.rumPageloadEventsAdaptiveGroups??[]).map((I)=>({country:I.dimensions.countryName,visits:I.sum.visits}))}}WA();var ahA=7,LRQ=10;function bz1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=oO(),B=en(ahA),w=AN(B),$=AN(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:LRQ})]);return{days:ahA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:ahA}}}}var Pz1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.122",description:"Analytics plugin for collecting website and social media metrics",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class kz1 extends UB{cloudflareClient;constructor(A={}){super("analytics",Pz1,A,ohA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new shA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",bz1(this.cloudflareClient))}async onReady(A){let Q=this.config.cloudflare?.siteTag;if(!Q)return;await A.messaging.send({type:"plugin:site-builder:head-script:register",payload:{pluginId:this.id,script:Rz1(Q)}})}async getTools(){return Oz1(this.id,this.getContext(),this.cloudflareClient)}}function ERQ(A={}){return new kz1(A)}var h$A=ERQ;import{randomBytes as PRQ}from"crypto";aA();WA();U8();var MRQ=new Set(["description","excerpt","summary","tagline","story"]);function CRQ(A){if(A.endsWith("s"))return A;return zI(A)}function thA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return thA(A._def.innerType,!0,B);if(w==="ZodDefault")return thA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function ehA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=thA(Q),f=B._def.typeName,I={name:A,label:lX(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((Y)=>Y.kind==="datetime"))return{...I,widget:"datetime"};if(MRQ.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,Y=ehA("item",D);if(Y.widget==="object"&&Y.fields)return{...I,widget:"list",fields:Y.fields};return{...I,widget:"list",field:{name:A,label:lX(A),widget:Y.widget}}}case"ZodObject":{let D=B.shape,Y=Object.entries(D).map(([U,J])=>ehA(U,J));return{...I,widget:"object",fields:Y}}default:return{...I,widget:"string"}}}function jz1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>ehA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function _z1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],Y=w===As?"Note":lX(w),U=D?.label??Y,J=D?.pluralName??CRQ(U);if(f?.isSingleton){B.push({name:w,label:U,file:`${w}/${w}.md`,fields:jz1($,I)});continue}if(w===As){Q.push({name:w,label:J,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:J,folder:w,create:!0,extension:"md",format:"frontmatter",fields:jz1($,I)})}if(B.length>0)Q.push({name:"settings",label:"Settings",files:B});return{backend:{name:"github",repo:A.repo,branch:A.branch,...A.baseUrl&&{base_url:A.baseUrl},...A.authEndpoint&&{auth_endpoint:A.authEndpoint}},media_folder:"image",public_folder:"/images",collections:Q}}var ORQ=new RegExp("[<>&\\u2028\\u2029]","g");function Sv(A){return JSON.stringify(A).replace(ORQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var vz1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function m$A(A){let Q=`<script src="${vz1}"></script>`;return`<!doctype html>
6662
6662
  <html>
6663
6663
  <head>
6664
6664
  <meta charset="utf-8" />
@@ -6697,7 +6697,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,zRQ,
6697
6697
  showError(error instanceof Error ? error.message : String(error));
6698
6698
  }
6699
6699
  })();
6700
- `}WA();var Tz1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.121",description:"CMS plugin for config and browser authoring routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/cms-config":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var QmA="brains_cms_oauth_state",kRQ=600,jRQ="auth",_RQ=H.object({label:H.string().optional(),pluralName:H.string().optional()}).passthrough(),vRQ=H.object({clientId:H.string().optional(),clientSecret:H.string().optional(),scope:H.string().optional()}),TRQ=H.object({contentRepoToken:H.string().optional()}),yRQ=H.object({entityDisplay:H.record(_RQ).optional(),routePath:H.string().default("/cms"),githubOAuth:vRQ.optional(),passkeyLogin:TRQ.optional()}).refine((A)=>{let Q=Boolean(ZC(A.githubOAuth?.clientId)&&ZC(A.githubOAuth?.clientSecret)),B=Boolean(ZC(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function xRQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function ZC(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function SRQ(A){let Q=ZC(A.githubOAuth?.clientId),B=ZC(A.githubOAuth?.clientSecret),w=ZC(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:ZC(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function gRQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function hRQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...gRQ(Q)?{authEndpoint:jRQ}:{}}}async function mRQ(A){let Q=await A.messaging.send({type:"git-sync:get-repo-info",payload:{}});if("noop"in Q||!Q.success||!Q.data)throw Error("CMS config unavailable: git-sync repo info unavailable");let{repo:B,branch:w}=Q.data;if(!B||!w)throw Error("CMS config unavailable: git-sync repo info incomplete");return{repo:B,branch:w}}async function uRQ(A,Q={}){let{repo:B,branch:w}=await mRQ(A);return _z1({repo:B,branch:w,...Q.baseUrl&&{baseUrl:Q.baseUrl},...Q.authEndpoint&&{authEndpoint:Q.authEndpoint},entityTypes:A.entityService.getEntityTypes(),getFrontmatterSchema:($)=>A.entities.getEffectiveFrontmatterSchema($),getAdapter:($)=>A.entities.getAdapter($),...Q.entityDisplay&&{entityDisplay:Q.entityDisplay}})}async function Sz1(A,Q={}){return cX(await uRQ(A,Q))}class BmA extends UB{constructor(A={}){super("cms",Tz1,A,yRQ)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40,visibility:"anchor"}),A.interactions.register({id:"cms",label:"CMS",description:"Edit and manage content through the browser CMS.",href:this.config.routePath,kind:"admin",priority:40,visibility:"anchor"})}getWebRoutes(){let A=xRQ(this.config.routePath),Q=SRQ(this.config),B=[];if(Q.githubOAuth||Q.passkeyLogin)B.push({path:"/auth",method:"GET",public:!0,handler:async(w)=>this.handleAuth(w,Q)});if(Q.githubOAuth){let w=Q.githubOAuth;B.push({path:"/auth/callback",method:"GET",public:!0,handler:async($)=>this.handleGitHubCallback($,w)})}if(Q.passkeyLogin){let w=Q.passkeyLogin;B.push({path:"/auth/cms-token",method:"POST",public:!0,handler:async($)=>this.handleCmsToken($,w)})}return[{path:this.config.routePath,method:"GET",public:!0,handler:async(w)=>{if(Q.passkeyLogin){if(!await xz1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return ai(m$A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return ai(m$A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=hRQ(this.config,Q,this.getContext()),f=await Sz1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:si(this.getContext(),w)}:{}});return new Response(f,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch($){return new Response($ instanceof Error?$.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}},...B]}async handleAuth(A,Q){if(Q.githubOAuth)return this.redirectToGitHub(A,Q.githubOAuth);if(Q.passkeyLogin){let B=await xz1(A)?nRQ:dRQ;return ai(B(si(this.getContext(),A)))}return rRQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=PRQ(32).toString("base64url"),w=`${si(this.getContext(),A)}/auth/callback`,$=new URL("https://github.com/login/oauth/authorize");return $.searchParams.set("client_id",Q.clientId),$.searchParams.set("redirect_uri",w),$.searchParams.set("scope",Q.scope),$.searchParams.set("state",B),new Response(null,{status:302,headers:{Location:$.toString(),"Set-Cookie":pRQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let U=B.searchParams.get("error_description")??w;return u$A(`GitHub OAuth failed: ${U}`)}let $=B.searchParams.get("state"),f=iRQ(A.headers.get("cookie"),QmA);if(!$||!f||$!==f)return u$A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return u$A("GitHub OAuth callback did not include a code");let D=`${si(this.getContext(),A)}/auth/callback`,Y=await cRQ(Q,I,D);if(!Y.success)return u$A(Y.error);return ai(oRQ(Y.token,si(this.getContext(),A)),200,{"Set-Cookie":hz1()})}async handleCmsToken(A,Q){if(!await RY()?.getOperatorSession(A))return yz1({error:"Operator session required"},401);return yz1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function NC(A){return new BmA(A)}async function cRQ(A,Q,B){let w=new URLSearchParams({client_id:A.clientId,client_secret:A.clientSecret,code:Q,redirect_uri:B}),$=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:w}),f;try{f=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:lRQ(f)??"GitHub token exchange failed"};if(AmA(f)&&typeof f.error==="string")return{success:!1,error:typeof f.error_description==="string"?f.error_description:f.error};let I=AmA(f)?f.access_token:void 0;if(typeof I!=="string"||I.length===0)return{success:!1,error:"GitHub token response omitted token"};return{success:!0,token:I}}function lRQ(A){if(!AmA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function AmA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function si(A,Q){let B=new URL(Q.url).origin;if(gz1(B))return B;return A.siteUrl??B}function gz1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function pRQ(A,Q){let B=gz1(new URL(Q.url).origin)?"":"; Secure";return`${QmA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${kRQ}${B}`}function hz1(){return`${QmA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function iRQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function ai(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function rRQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function yz1(A,Q=200,B={}){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store",...B}})}function u$A(A){return ai(`<!doctype html><html><body><h1>CMS login failed</h1><p>${tRQ(A)}</p></body></html>`,400,{"Set-Cookie":hz1()})}async function xz1(A){return Boolean(await RY()?.getOperatorSession(A))}function dRQ(A){return`<!doctype html>
6700
+ `}WA();var Tz1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.122",description:"CMS plugin for config and browser authoring routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/cms-config":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var QmA="brains_cms_oauth_state",kRQ=600,jRQ="auth",_RQ=H.object({label:H.string().optional(),pluralName:H.string().optional()}).passthrough(),vRQ=H.object({clientId:H.string().optional(),clientSecret:H.string().optional(),scope:H.string().optional()}),TRQ=H.object({contentRepoToken:H.string().optional()}),yRQ=H.object({entityDisplay:H.record(_RQ).optional(),routePath:H.string().default("/cms"),githubOAuth:vRQ.optional(),passkeyLogin:TRQ.optional()}).refine((A)=>{let Q=Boolean(ZC(A.githubOAuth?.clientId)&&ZC(A.githubOAuth?.clientSecret)),B=Boolean(ZC(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function xRQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function ZC(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function SRQ(A){let Q=ZC(A.githubOAuth?.clientId),B=ZC(A.githubOAuth?.clientSecret),w=ZC(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:ZC(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function gRQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function hRQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...gRQ(Q)?{authEndpoint:jRQ}:{}}}async function mRQ(A){let Q=await A.messaging.send({type:"git-sync:get-repo-info",payload:{}});if("noop"in Q||!Q.success||!Q.data)throw Error("CMS config unavailable: git-sync repo info unavailable");let{repo:B,branch:w}=Q.data;if(!B||!w)throw Error("CMS config unavailable: git-sync repo info incomplete");return{repo:B,branch:w}}async function uRQ(A,Q={}){let{repo:B,branch:w}=await mRQ(A);return _z1({repo:B,branch:w,...Q.baseUrl&&{baseUrl:Q.baseUrl},...Q.authEndpoint&&{authEndpoint:Q.authEndpoint},entityTypes:A.entityService.getEntityTypes(),getFrontmatterSchema:($)=>A.entities.getEffectiveFrontmatterSchema($),getAdapter:($)=>A.entities.getAdapter($),...Q.entityDisplay&&{entityDisplay:Q.entityDisplay}})}async function Sz1(A,Q={}){return cX(await uRQ(A,Q))}class BmA extends UB{constructor(A={}){super("cms",Tz1,A,yRQ)}async onRegister(A){await super.onRegister(A),A.endpoints.register({label:"CMS",url:this.config.routePath,priority:40,visibility:"anchor"}),A.interactions.register({id:"cms",label:"CMS",description:"Edit and manage content through the browser CMS.",href:this.config.routePath,kind:"admin",priority:40,visibility:"anchor"})}getWebRoutes(){let A=xRQ(this.config.routePath),Q=SRQ(this.config),B=[];if(Q.githubOAuth||Q.passkeyLogin)B.push({path:"/auth",method:"GET",public:!0,handler:async(w)=>this.handleAuth(w,Q)});if(Q.githubOAuth){let w=Q.githubOAuth;B.push({path:"/auth/callback",method:"GET",public:!0,handler:async($)=>this.handleGitHubCallback($,w)})}if(Q.passkeyLogin){let w=Q.passkeyLogin;B.push({path:"/auth/cms-token",method:"POST",public:!0,handler:async($)=>this.handleCmsToken($,w)})}return[{path:this.config.routePath,method:"GET",public:!0,handler:async(w)=>{if(Q.passkeyLogin){if(!await xz1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return ai(m$A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return ai(m$A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=hRQ(this.config,Q,this.getContext()),f=await Sz1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:si(this.getContext(),w)}:{}});return new Response(f,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch($){return new Response($ instanceof Error?$.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}},...B]}async handleAuth(A,Q){if(Q.githubOAuth)return this.redirectToGitHub(A,Q.githubOAuth);if(Q.passkeyLogin){let B=await xz1(A)?nRQ:dRQ;return ai(B(si(this.getContext(),A)))}return rRQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=PRQ(32).toString("base64url"),w=`${si(this.getContext(),A)}/auth/callback`,$=new URL("https://github.com/login/oauth/authorize");return $.searchParams.set("client_id",Q.clientId),$.searchParams.set("redirect_uri",w),$.searchParams.set("scope",Q.scope),$.searchParams.set("state",B),new Response(null,{status:302,headers:{Location:$.toString(),"Set-Cookie":pRQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let U=B.searchParams.get("error_description")??w;return u$A(`GitHub OAuth failed: ${U}`)}let $=B.searchParams.get("state"),f=iRQ(A.headers.get("cookie"),QmA);if(!$||!f||$!==f)return u$A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return u$A("GitHub OAuth callback did not include a code");let D=`${si(this.getContext(),A)}/auth/callback`,Y=await cRQ(Q,I,D);if(!Y.success)return u$A(Y.error);return ai(oRQ(Y.token,si(this.getContext(),A)),200,{"Set-Cookie":hz1()})}async handleCmsToken(A,Q){if(!await RY()?.getOperatorSession(A))return yz1({error:"Operator session required"},401);return yz1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function NC(A){return new BmA(A)}async function cRQ(A,Q,B){let w=new URLSearchParams({client_id:A.clientId,client_secret:A.clientSecret,code:Q,redirect_uri:B}),$=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:w}),f;try{f=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:lRQ(f)??"GitHub token exchange failed"};if(AmA(f)&&typeof f.error==="string")return{success:!1,error:typeof f.error_description==="string"?f.error_description:f.error};let I=AmA(f)?f.access_token:void 0;if(typeof I!=="string"||I.length===0)return{success:!1,error:"GitHub token response omitted token"};return{success:!0,token:I}}function lRQ(A){if(!AmA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function AmA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function si(A,Q){let B=new URL(Q.url).origin;if(gz1(B))return B;return A.siteUrl??B}function gz1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function pRQ(A,Q){let B=gz1(new URL(Q.url).origin)?"":"; Secure";return`${QmA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${kRQ}${B}`}function hz1(){return`${QmA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function iRQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function ai(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function rRQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function yz1(A,Q=200,B={}){return new Response(JSON.stringify(A),{status:Q,headers:{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store",...B}})}function u$A(A){return ai(`<!doctype html><html><body><h1>CMS login failed</h1><p>${tRQ(A)}</p></body></html>`,400,{"Set-Cookie":hz1()})}async function xz1(A){return Boolean(await RY()?.getOperatorSession(A))}function dRQ(A){return`<!doctype html>
6701
6701
  <html lang="en">
6702
6702
  <head>
6703
6703
  <meta charset="utf-8" />
@@ -8102,7 +8102,7 @@ ${uz1}`;import{jsxDEV as UX,Fragment as pz1}from"preact/jsx-dev-runtime";functio
8102
8102
  }
8103
8103
  });
8104
8104
  })();`;function vbQ({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=kbQ(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,f=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,D=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,Y=new Date;return HB("html",{lang:"en","data-theme":"dark",children:[HB("head",{children:[HB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),HB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),HB("title",{children:A.title},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),HB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),HB("link",{href:PbQ,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&HB("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),HB("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:lz1}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("body",{children:[HB("main",{class:"console","data-component":"dashboard:dashboard",children:[HB(iz1,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),HB("section",{class:I,children:[$&&HB("div",{class:"identity-column",children:[HB(dz1,{character:A.character},void 0,!1,void 0,this),HB(ImA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&HB(Aq1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("div",{class:"main-column",children:[HB(rz1,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&HB(Aq1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((U)=>HB(i$A,{widget:U},`${U.widget.pluginId}:${U.widget.id}`,!1,void 0,this)),w.secondary.map((U)=>HB(i$A,{widget:U},`${U.widget.pluginId}:${U.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),HB("div",{class:"sidebar-column",children:[!$&&HB(ImA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((U)=>HB(i$A,{widget:U},`${U.widget.pluginId}:${U.widget.id}`,!1,void 0,this)),HB(nz1,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),HB(tz1,{appInfo:A.appInfo,now:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),HB(ez1,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:jbQ}},void 0,!1,void 0,this),HB("script",{dangerouslySetInnerHTML:{__html:_bQ}},void 0,!1,void 0,this),A.widgetScripts.map((U,J)=>HB("script",{dangerouslySetInnerHTML:{__html:U}},`widget-script:${J}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Qq1(A){return`<!doctype html>
8105
- ${bbQ(HB(vbQ,{input:A},void 0,!1,void 0,this))}`}function Bq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var wq1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.121",description:"Dashboard plugin with extensible widget system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var ybQ=H.object({version:H.string().default("1.0.0"),routePath:H.string().default("/dashboard"),themeCSS:H.string().optional()}),xbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number().default(50),section:H.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:H.string(),visibility:J4.default("public"),component:H.custom().optional(),clientScript:H.string().optional(),dataProvider:H.function().returns(H.promise(H.unknown()))}).superRefine((A,Q)=>{if(!fmA(A.rendererName)&&!A.component)Q.addIssue({code:H.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),SbQ=H.object({pluginId:H.string(),widgetId:H.string().optional()});function gbQ(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider}}class YmA extends UB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",wq1,A??{},ybQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new l$A(this.logger),this.datasource=new p$A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.endpoints.register({label:"Dashboard",url:this.config.routePath,priority:30,visibility:"public"}),A.interactions.register({id:"dashboard",label:"Dashboard",description:"Inspect runtime status, endpoints, and dashboard widgets.",href:this.config.routePath,kind:"admin",priority:30,visibility:"public"}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=xbQ.parse(Q.payload),w=gbQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:c$A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:T0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=SbQ.parse(Q.payload);return this.widgetRegistry?.unregister(B.pluginId,B.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:B.pluginId,widgetId:B.widgetId}),{success:!0}}),this.logger.info("Dashboard plugin registered")}getWebRoutes(){return[{path:this.config.routePath,method:"GET",public:!0,handler:async(A)=>{if(!this.datasource||!this.ctx)return new Response("Dashboard unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}});let Q=this.ctx,B=await RY()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((S)=>O9.hasPermission($,S.visibility)),D=f.length-I.length,[Y,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),J=Q.identity.get(),X=Q.identity.getProfile(),G=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...U,endpoints:U.endpoints.filter((S)=>O9.hasPermission($,S.visibility)),interactions:U.interactions.filter((S)=>O9.hasPermission($,S.visibility))},N=X.name||U.model||"Brain Dashboard",L=new URL(A.url),V=`${L.pathname}${L.search}`,M=encodeURIComponent(V),O=Bq1(Y.widgets,this.widgetRegistry),E={title:N,baseUrl:G,widgets:O.widgets,widgetScripts:O.widgetScripts,character:J,profile:X,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${M}`,logoutUrl:`/logout?return_to=${M}`}};return new Response(Qq1(E),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function az(A){return new YmA(A)}aA();WA();var hbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number(),section:H.enum(["primary","secondary","sidebar"]),rendererName:H.string(),visibility:J4,component:H.custom().optional()}),mbQ=H.object({widget:hbQ,data:H.unknown()}),ubQ=H.object({widgets:H.record(mbQ)});WA();aA();WA();import{h as QPQ}from"preact";WA();wY();aA();var gv=H.enum(["generating","draft","queued","published","failed"]),ei=H.object({subject:H.string(),status:gv,entityIds:H.array(H.string()).optional(),scheduledFor:H.string().datetime().optional(),sentAt:H.string().datetime().optional(),buttondownId:H.string().optional(),sourceEntityType:H.string().optional()}),$q1=ei.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:H.string().optional()}),Ar=A2.extend({entityType:H.literal("newsletter"),metadata:$q1});aA();class fq1 extends q2{constructor(){super({entityType:"newsletter",schema:Ar,frontmatterSchema:ei})}toMarkdown(A){let Q=this.extractBody(A.content);return this.buildMarkdown(Q,A.metadata)}fromMarkdown(A){let Q=this.parseFrontmatter(A);return{entityType:"newsletter",content:A,metadata:Q}}buildStub(A){let Q={subject:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:Q}}}var Iq1=new fq1;aA();aA();WA();var cbQ=QW.extend({status:H.enum(["generating","draft","queued","published","failed"]).optional()}),lbQ=BW.extend({query:cbQ.optional()});function Dq1(A){try{let{content:Q}=R2(A.content,ei);return Q}catch{return A.content}}class UmA extends m5{id="newsletter:entities";name="Newsletter Entity DataSource";description="Fetches and transforms newsletter entities for rendering";config={entityType:"newsletter",defaultSort:[{field:"created",direction:"desc"}],defaultLimit:10,lookupField:"id",enableNavigation:!0};constructor(A){super(A);this.logger.debug("NewsletterDataSource initialized")}parseQuery(A){let Q=lbQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=Dq1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:H7(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:Y}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,Y,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let Y=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(J)=>{let X=await B.getEntity({entityType:Y,id:J});if(X){let G=X.metadata;return{id:J,title:G.title??J,url:`/${Y}s/${G.slug??J}`}}return null}))).filter((J)=>J!==null)}let I=Dq1(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}aA();WA();var pbQ=H.object({prompt:H.string().optional().describe("AI generation prompt"),sourceEntityIds:H.array(H.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:H.enum(["post"]).optional().describe("Type of source entities"),content:H.string().optional().describe("Direct content (skip AI)"),subject:H.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:H.boolean().optional().describe("Create as queued (true) or draft (false)")});class JmA extends z7{constructor(A,Q){super(A,Q,{schema:pbQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let N=(await Promise.all($.map((E)=>this.context.entityService.getEntity({entityType:G,id:E})))).filter((E)=>E!=null);if(N.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${N.length} posts`});let V=`Create an engaging newsletter that highlights these blog posts:
8105
+ ${bbQ(HB(vbQ,{input:A},void 0,!1,void 0,this))}`}function Bq1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var wq1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.122",description:"Dashboard plugin with extensible widget system",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/auth-service":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2","preact-render-to-string":"^6.3.1"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var ybQ=H.object({version:H.string().default("1.0.0"),routePath:H.string().default("/dashboard"),themeCSS:H.string().optional()}),xbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number().default(50),section:H.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:H.string(),visibility:J4.default("public"),component:H.custom().optional(),clientScript:H.string().optional(),dataProvider:H.function().returns(H.promise(H.unknown()))}).superRefine((A,Q)=>{if(!fmA(A.rendererName)&&!A.component)Q.addIssue({code:H.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),SbQ=H.object({pluginId:H.string(),widgetId:H.string().optional()});function gbQ(A){return{id:A.id,pluginId:A.pluginId,title:A.title,...A.description?{description:A.description}:{},priority:A.priority,section:A.section,rendererName:A.rendererName,visibility:A.visibility,...A.component?{component:A.component}:{},...A.clientScript?{clientScript:A.clientScript}:{},dataProvider:A.dataProvider}}class YmA extends UB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",wq1,A??{},ybQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new l$A(this.logger),this.datasource=new p$A(this.widgetRegistry,this.logger),A.entities.registerDataSource(this.datasource),A.endpoints.register({label:"Dashboard",url:this.config.routePath,priority:30,visibility:"public"}),A.interactions.register({id:"dashboard",label:"Dashboard",description:"Inspect runtime status, endpoints, and dashboard widgets.",href:this.config.routePath,kind:"admin",priority:30,visibility:"public"}),A.messaging.subscribe("dashboard:register-widget",async(Q)=>{try{let B=xbQ.parse(Q.payload),w=gbQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:c$A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:T0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=SbQ.parse(Q.payload);return this.widgetRegistry?.unregister(B.pluginId,B.widgetId),this.logger.debug("Widget unregistered via messaging",{pluginId:B.pluginId,widgetId:B.widgetId}),{success:!0}}),this.logger.info("Dashboard plugin registered")}getWebRoutes(){return[{path:this.config.routePath,method:"GET",public:!0,handler:async(A)=>{if(!this.datasource||!this.ctx)return new Response("Dashboard unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}});let Q=this.ctx,B=await RY()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((S)=>O9.hasPermission($,S.visibility)),D=f.length-I.length,[Y,U]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),J=Q.identity.get(),X=Q.identity.getProfile(),G=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...U,endpoints:U.endpoints.filter((S)=>O9.hasPermission($,S.visibility)),interactions:U.interactions.filter((S)=>O9.hasPermission($,S.visibility))},N=X.name||U.model||"Brain Dashboard",L=new URL(A.url),V=`${L.pathname}${L.search}`,M=encodeURIComponent(V),O=Bq1(Y.widgets,this.widgetRegistry),E={title:N,baseUrl:G,widgets:O.widgets,widgetScripts:O.widgetScripts,character:J,profile:X,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${M}`,logoutUrl:`/logout?return_to=${M}`}};return new Response(Qq1(E),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function az(A){return new YmA(A)}aA();WA();var hbQ=H.object({id:H.string(),pluginId:H.string(),title:H.string(),description:H.string().optional(),priority:H.number(),section:H.enum(["primary","secondary","sidebar"]),rendererName:H.string(),visibility:J4,component:H.custom().optional()}),mbQ=H.object({widget:hbQ,data:H.unknown()}),ubQ=H.object({widgets:H.record(mbQ)});WA();aA();WA();import{h as QPQ}from"preact";WA();wY();aA();var gv=H.enum(["generating","draft","queued","published","failed"]),ei=H.object({subject:H.string(),status:gv,entityIds:H.array(H.string()).optional(),scheduledFor:H.string().datetime().optional(),sentAt:H.string().datetime().optional(),buttondownId:H.string().optional(),sourceEntityType:H.string().optional()}),$q1=ei.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:H.string().optional()}),Ar=A2.extend({entityType:H.literal("newsletter"),metadata:$q1});aA();class fq1 extends q2{constructor(){super({entityType:"newsletter",schema:Ar,frontmatterSchema:ei})}toMarkdown(A){let Q=this.extractBody(A.content);return this.buildMarkdown(Q,A.metadata)}fromMarkdown(A){let Q=this.parseFrontmatter(A);return{entityType:"newsletter",content:A,metadata:Q}}buildStub(A){let Q={subject:A.title,status:"generating"};return{content:this.buildMarkdown("",Q),metadata:Q}}}var Iq1=new fq1;aA();aA();WA();var cbQ=QW.extend({status:H.enum(["generating","draft","queued","published","failed"]).optional()}),lbQ=BW.extend({query:cbQ.optional()});function Dq1(A){try{let{content:Q}=R2(A.content,ei);return Q}catch{return A.content}}class UmA extends m5{id="newsletter:entities";name="Newsletter Entity DataSource";description="Fetches and transforms newsletter entities for rendering";config={entityType:"newsletter",defaultSort:[{field:"created",direction:"desc"}],defaultLimit:10,lookupField:"id",enableNavigation:!0};constructor(A){super(A);this.logger.debug("NewsletterDataSource initialized")}parseQuery(A){let Q=lbQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=Dq1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:H7(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:Y}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,Y,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let Y=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(J)=>{let X=await B.getEntity({entityType:Y,id:J});if(X){let G=X.metadata;return{id:J,title:G.title??J,url:`/${Y}s/${G.slug??J}`}}return null}))).filter((J)=>J!==null)}let I=Dq1(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}aA();WA();var pbQ=H.object({prompt:H.string().optional().describe("AI generation prompt"),sourceEntityIds:H.array(H.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:H.enum(["post"]).optional().describe("Type of source entities"),content:H.string().optional().describe("Direct content (skip AI)"),subject:H.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:H.boolean().optional().describe("Create as queued (true) or draft (false)")});class JmA extends z7{constructor(A,Q){super(A,Q,{schema:pbQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let G=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let N=(await Promise.all($.map((E)=>this.context.entityService.getEntity({entityType:G,id:E})))).filter((E)=>E!=null);if(N.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${N.length} posts`});let V=`Create an engaging newsletter that highlights these blog posts:
8106
8106
 
8107
8107
  ${N.map((E)=>`## ${E.metadata.title}
8108
8108
 
@@ -8171,14 +8171,14 @@ Newsletter-specific guidelines:
8171
8171
  - "Reply and let me know..."
8172
8172
  - "Until next time..."
8173
8173
 
8174
- The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as l4,Fragment as obQ}from"preact/jsx-dev-runtime";var rbQ=H.object({id:H.string(),subject:H.string(),status:gv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),dbQ=H.object({newsletters:H.array(rbQ),totalCount:H.number(),pagination:Z7.nullable()}),nbQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return l4(obQ,{children:[l4(KQ,{title:f,description:I},void 0,!1,void 0,this),l4("div",{className:"newsletter-list bg-theme",children:l4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[l4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?l4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):l4("div",{className:"space-y-4",children:A.map((D)=>l4(PB,{href:D.url,children:[l4(U9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),l4(c9,{children:l4("div",{className:"flex items-center gap-3",children:[l4(gf,{status:D.status},void 0,!1,void 0,this),l4("span",{className:"text-sm text-theme-muted",children:i6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&l4("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&l4(VF,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Uq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:dbQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:nbQ}});WA();aA();import{jsxDEV as q8,Fragment as ebQ}from"preact/jsx-dev-runtime";var sbQ=H.object({id:H.string(),title:H.string(),url:H.string()}),Jq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),abQ=H.object({id:H.string(),subject:H.string(),status:gv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(sbQ).optional(),prevNewsletter:Jq1.nullable().optional(),nextNewsletter:Jq1.nullable().optional()}),tbQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:Y})=>{let U=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return q8(ebQ,{children:[q8(KQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),q8("section",{className:"newsletter-detail-section",children:q8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q8("div",{className:"max-w-3xl mx-auto",children:[q8(UH,{items:U},void 0,!1,void 0,this),q8("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),q8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[q8(gf,{status:Q},void 0,!1,void 0,this),q8("span",{children:[X,": ",i6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&q8("span",{children:["Scheduled for: ",i6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&q8(PB,{variant:"compact",className:"mb-8",children:[q8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),q8("ul",{className:"space-y-1",children:I.map((G)=>q8("li",{children:q8("a",{href:G.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:G.title},void 0,!1,void 0,this)},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q8(V$,{markdown:B},void 0,!1,void 0,this),(D??Y)&&q8("nav",{className:"mt-12 pt-8 border-t border-theme",children:q8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?q8(PB,{href:D.url,variant:"compact",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q8("div",{},void 0,!1,void 0,this),Y&&q8(PB,{href:Y.url,variant:"compact",className:"md:text-right",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Xq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:abQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:tbQ}});var Wq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.121",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BPQ=H.object({});class XmA extends jQ{entityType="newsletter";schema=Ar;adapter=Iq1;constructor(A={}){super("newsletter",Wq1,A,BPQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new JmA(this.logger,A)}getTemplates(){return{generation:Yq1,"newsletter-list":Uq1,"newsletter-detail":Xq1}}getDataSources(){return[new UmA(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToGenerateExecute(A),this.registerEvalHandlers(A),A.messaging.subscribe("system:plugins:ready",async()=>{let Q=await A.messaging.send({type:"buttondown:is-configured",payload:{}});if(!("noop"in Q)&&Q.success)await A.messaging.send({type:"plugin:site-builder:slot:register",payload:{pluginId:this.id,slotName:"footer-top",render:()=>QPQ(hTA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(B,w)=>{let $=typeof w.subject==="string"?w.subject:"",f=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:$,content:B}});return{id:!("noop"in f)&&f.data?.emailId?f.data.emailId:"internal"}}};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q,config:{publishResultIdField:"buttondownId",publishTimestampField:"sentAt"}}}),{success:!0}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(B.length===0)return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:"No published posts available for newsletter"}}),{success:!0};return await A.jobs.enqueue({type:"newsletter:generation",data:{sourceEntityIds:B.map((w)=>w.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(B){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:T0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=H.object({prompt:H.string().optional(),content:H.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
8174
+ The goal is to build a relationship with readers through valuable, authentic content.`});WA();aA();import{jsxDEV as l4,Fragment as obQ}from"preact/jsx-dev-runtime";var rbQ=H.object({id:H.string(),subject:H.string(),status:gv,excerpt:H.string(),created:H.string(),sentAt:H.string().optional(),url:H.string()}),dbQ=H.object({newsletters:H.array(rbQ),totalCount:H.number(),pagination:Z7.nullable()}),nbQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return l4(obQ,{children:[l4(KQ,{title:f,description:I},void 0,!1,void 0,this),l4("div",{className:"newsletter-list bg-theme",children:l4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[l4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?l4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):l4("div",{className:"space-y-4",children:A.map((D)=>l4(PB,{href:D.url,children:[l4(U9,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),l4(c9,{children:l4("div",{className:"flex items-center gap-3",children:[l4(gf,{status:D.status},void 0,!1,void 0,this),l4("span",{className:"text-sm text-theme-muted",children:i6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&l4("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&l4(VF,{currentPage:w.currentPage,totalPages:w.totalPages,baseUrl:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Uq1=P1({name:"newsletter-list",description:"Newsletter list page template",schema:dbQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:nbQ}});WA();aA();import{jsxDEV as q8,Fragment as ebQ}from"preact/jsx-dev-runtime";var sbQ=H.object({id:H.string(),title:H.string(),url:H.string()}),Jq1=H.object({id:H.string(),subject:H.string(),url:H.string()}),abQ=H.object({id:H.string(),subject:H.string(),status:gv,content:H.string(),created:H.string(),updated:H.string(),sentAt:H.string().optional(),scheduledFor:H.string().optional(),sourceEntities:H.array(sbQ).optional(),prevNewsletter:Jq1.nullable().optional(),nextNewsletter:Jq1.nullable().optional()}),tbQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:Y})=>{let U=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],J=$??w,X=$?"Sent":"Created";return q8(ebQ,{children:[q8(KQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),q8("section",{className:"newsletter-detail-section",children:q8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:q8("div",{className:"max-w-3xl mx-auto",children:[q8(UH,{items:U},void 0,!1,void 0,this),q8("h1",{className:"text-3xl md:text-4xl font-bold text-heading leading-tight tracking-tight mb-4",children:A},void 0,!1,void 0,this),q8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[q8(gf,{status:Q},void 0,!1,void 0,this),q8("span",{children:[X,": ",i6(J,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&q8("span",{children:["Scheduled for: ",i6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&q8(PB,{variant:"compact",className:"mb-8",children:[q8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),q8("ul",{className:"space-y-1",children:I.map((G)=>q8("li",{children:q8("a",{href:G.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:G.title},void 0,!1,void 0,this)},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q8(V$,{markdown:B},void 0,!1,void 0,this),(D??Y)&&q8("nav",{className:"mt-12 pt-8 border-t border-theme",children:q8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?q8(PB,{href:D.url,variant:"compact",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q8("div",{},void 0,!1,void 0,this),Y&&q8(PB,{href:Y.url,variant:"compact",className:"md:text-right",children:[q8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),q8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Xq1=P1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:abQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:tbQ}});var Wq1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.122",description:"Newsletter entity type with AI generation and publish pipeline",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts,.tsx","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/contracts":"workspace:*","@brains/entity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BPQ=H.object({});class XmA extends jQ{entityType="newsletter";schema=Ar;adapter=Iq1;constructor(A={}){super("newsletter",Wq1,A,BPQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new JmA(this.logger,A)}getTemplates(){return{generation:Yq1,"newsletter-list":Uq1,"newsletter-detail":Xq1}}getDataSources(){return[new UmA(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToGenerateExecute(A),this.registerEvalHandlers(A),A.messaging.subscribe("system:plugins:ready",async()=>{let Q=await A.messaging.send({type:"buttondown:is-configured",payload:{}});if(!("noop"in Q)&&Q.success)await A.messaging.send({type:"plugin:site-builder:slot:register",payload:{pluginId:this.id,slotName:"footer-top",render:()=>QPQ(hTA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}deferPublishRegistration(A){let Q={name:"internal",publish:async(B,w)=>{let $=typeof w.subject==="string"?w.subject:"",f=await A.messaging.send({type:"buttondown:send",payload:{entityId:"",subject:$,content:B}});return{id:!("noop"in f)&&f.data?.emailId?f.data.emailId:"internal"}}};A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"publish:register",payload:{entityType:"newsletter",provider:Q,config:{publishResultIdField:"buttondownId",publishTimestampField:"sentAt"}}}),{success:!0}})}subscribeToGenerateExecute(A){A.messaging.subscribe("generate:execute",async(Q)=>{if(Q.payload.entityType!=="newsletter")return{success:!0};try{let B=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:10}});if(B.length===0)return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:"No published posts available for newsletter"}}),{success:!0};return await A.jobs.enqueue({type:"newsletter:generation",data:{sourceEntityIds:B.map((w)=>w.id),sourceEntityType:"post",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}}),{success:!0}}catch(B){return await A.messaging.send({type:"generate:report:failure",payload:{entityType:"newsletter",error:T0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=H.object({prompt:H.string().optional(),content:H.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
8175
8175
 
8176
- ${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function WmA(A={}){return new XmA(A)}aA();WA();class hv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var wPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),$PQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),fPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function Hq1(A,Q,B){let w=new hv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",wPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return Y8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",$PQ,async($)=>{try{return await w.unsubscribe($.email),Y8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",fPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return Y8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return X$(T0(f))}})]}WA();async function Gq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=T0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Kq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.121",description:"Buttondown newsletter integration \u2014 subscriber management and API routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var DPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class HmA extends UB{constructor(A={}){super("buttondown",Kq1,A,DPQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new hv({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(B)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:B.payload.subject,body:B.payload.content,status:"about_to_send"})).id}}}catch(w){return this.logger.error("Buttondown send failed",{error:T0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await Gq1(B.payload,Q,A.entityService,this.logger),{success:!0}}),this.logger.info("Buttondown auto-send on publish enabled")}}async getTools(){if(!this.config.apiKey)return[];return Hq1(this.id,{apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger)}getApiRoutes(){if(!this.config.apiKey)return[];return[{path:"/subscribe",method:"POST",tool:"subscribe",public:!0,successRedirect:"/subscribe/thanks",errorRedirect:"/subscribe/error"}]}}function GmA(A={}){return new HmA(A)}var YPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function Fq1(A={}){let Q=YPQ.parse(A);return[WmA({}),GmA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}aA();WA();import{existsSync as qPQ,mkdirSync as LPQ,writeFileSync as VPQ}from"fs";import{join as dF}from"path";WA();var KmA=H.object({baseFolder:H.string().default("_obsidian")});WA();function UPQ(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof H.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function JPQ(A){if(A instanceof H.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof H.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof H.ZodString)return{type:"string"};if(A instanceof H.ZodNumber)return{type:"number"};if(A instanceof H.ZodBoolean)return{type:"boolean"};if(A instanceof H.ZodArray)return{type:"array"};if(A instanceof H.ZodDate)return{type:"date"};if(A instanceof H.ZodPipeline){if(A._def.out instanceof H.ZodDate)return{type:"date"}}return{type:"unknown"}}function Zq1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=UPQ($),Y=JPQ(f),U={name:w,type:Y.type,required:I},J=D!==void 0?D:Y.defaultValue;if(J!==void 0)U.defaultValue=J;if(Y.enumValues)U.enumValues=Y.enumValues;B.push(U)}return B}function XPQ(A,Q){if(A.name==="entityType")return String(A.defaultValue??Q);if(A.name==="title")return'"{{title}}"';if(A.type==="date"&&(A.name==="created"||A.name==="updated"))return'"{{date}}"';if(A.defaultValue!==void 0){if(Array.isArray(A.defaultValue))return"[]";if(typeof A.defaultValue==="boolean")return String(A.defaultValue);if(typeof A.defaultValue==="number")return String(A.defaultValue);return String(A.defaultValue)}if(A.type==="enum"&&A.enumValues&&A.enumValues.length>0)return A.enumValues[0]??"";switch(A.type){case"string":return'""';case"number":return"";case"boolean":return"false";case"array":return"[]";case"date":return'""';default:return'""'}}function Nq1(A,Q,B=""){let w=["---"];for(let $ of Q){let f=XPQ($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
8176
+ ${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function WmA(A={}){return new XmA(A)}aA();WA();class hv{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}aA();WA();var wPQ=H.object({email:H.string().email().describe("Email address to subscribe"),name:H.string().optional().describe("Subscriber name (optional)"),tags:H.array(H.string()).optional().describe("Tags to apply to subscriber (optional)")}),$PQ=H.object({email:H.string().email().describe("Email address to unsubscribe")}),fPQ=H.object({type:H.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:H.number().optional().describe("Maximum number of results")});function Hq1(A,Q,B){let w=new hv(Q,B);return[oQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",wPQ,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return Y8({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",$PQ,async($)=>{try{return await w.unsubscribe($.email),Y8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return X$(T0(f))}}),oQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",fPQ,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return Y8({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return X$(T0(f))}})]}WA();async function Gq1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=T0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Kq1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.122",description:"Buttondown newsletter integration \u2014 subscriber management and API routes",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var DPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class HmA extends UB{constructor(A={}){super("buttondown",Kq1,A,DPQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new hv({apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger);if(A.messaging.subscribe("buttondown:send",async(B)=>{try{return{success:!0,data:{emailId:(await Q.createEmail({subject:B.payload.subject,body:B.payload.content,status:"about_to_send"})).id}}}catch(w){return this.logger.error("Buttondown send failed",{error:T0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await Gq1(B.payload,Q,A.entityService,this.logger),{success:!0}}),this.logger.info("Buttondown auto-send on publish enabled")}}async getTools(){if(!this.config.apiKey)return[];return Hq1(this.id,{apiKey:this.config.apiKey,doubleOptIn:this.config.doubleOptIn},this.logger)}getApiRoutes(){if(!this.config.apiKey)return[];return[{path:"/subscribe",method:"POST",tool:"subscribe",public:!0,successRedirect:"/subscribe/thanks",errorRedirect:"/subscribe/error"}]}}function GmA(A={}){return new HmA(A)}var YPQ=H.object({apiKey:H.string().optional().describe("Buttondown API key"),doubleOptIn:H.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:H.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function Fq1(A={}){let Q=YPQ.parse(A);return[WmA({}),GmA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}aA();WA();import{existsSync as qPQ,mkdirSync as LPQ,writeFileSync as VPQ}from"fs";import{join as dF}from"path";WA();var KmA=H.object({baseFolder:H.string().default("_obsidian")});WA();function UPQ(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof H.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof H.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function JPQ(A){if(A instanceof H.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof H.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof H.ZodString)return{type:"string"};if(A instanceof H.ZodNumber)return{type:"number"};if(A instanceof H.ZodBoolean)return{type:"boolean"};if(A instanceof H.ZodArray)return{type:"array"};if(A instanceof H.ZodDate)return{type:"date"};if(A instanceof H.ZodPipeline){if(A._def.out instanceof H.ZodDate)return{type:"date"}}return{type:"unknown"}}function Zq1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=UPQ($),Y=JPQ(f),U={name:w,type:Y.type,required:I},J=D!==void 0?D:Y.defaultValue;if(J!==void 0)U.defaultValue=J;if(Y.enumValues)U.enumValues=Y.enumValues;B.push(U)}return B}function XPQ(A,Q){if(A.name==="entityType")return String(A.defaultValue??Q);if(A.name==="title")return'"{{title}}"';if(A.type==="date"&&(A.name==="created"||A.name==="updated"))return'"{{date}}"';if(A.defaultValue!==void 0){if(Array.isArray(A.defaultValue))return"[]";if(typeof A.defaultValue==="boolean")return String(A.defaultValue);if(typeof A.defaultValue==="number")return String(A.defaultValue);return String(A.defaultValue)}if(A.type==="enum"&&A.enumValues&&A.enumValues.length>0)return A.enumValues[0]??"";switch(A.type){case"string":return'""';case"number":return"";case"boolean":return"false";case"array":return"[]";case"date":return'""';default:return'""'}}function Nq1(A,Q,B=""){let w=["---"];for(let $ of Q){let f=XPQ($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
8177
8177
  `)}WA();var WPQ={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function HPQ(A){let Q={name:A.name,id:A.name,type:WPQ[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function zq1(A,Q){let B={filesPaths:A,fields:Q.map(HPQ)};return`---
8178
8178
  ${cX(B)}---
8179
- `}WA();var GPQ=new Set(["entityType"]),KPQ={base:"Notes"},FPQ=new Set(["base"]);function ZPQ(A){let Q=["file.name"];for(let B of A)if(!GPQ.has(B.name))Q.push(B.name);return Q}function NPQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function qq1(A,Q){let B=KPQ[A]??an(A),w=NPQ(Q),$=ZPQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[FPQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:cX(D),hasStatus:w}}function Lq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return cX(B)}function Vq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return cX(B)}var Eq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.121",description:"Obsidian vault integration \u2014 generates templates from entity schemas",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var EPQ={mkdir:LPQ,writeFile:VPQ,existsFile:qPQ},MPQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class FmA extends UB{deps;constructor(A={},Q={}){super("obsidian-vault",Eq1,A,KmA);this.deps={...EPQ,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",MPQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((V)=>Q.includes(V)):B,$=dF(A.dataDir,this.config.baseFolder),f=dF($,"templates"),I=dF($,"fileClasses"),D=dF($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],U=[],J=[],X=[],G=[],Z=[];for(let V of w){let M=A.entities.getEffectiveFrontmatterSchema(V);if(!M){this.logger.debug(`Skipping ${V}: no frontmatter schema`),U.push(V);continue}let O=Zq1(M),E=A.entities.getAdapter(V),S=E?.isSingleton===!0,y=zq1(V,O);if(this.deps.writeFile(dF(I,`${V}.md`),y),J.push(V),S){G.push(V),this.logger.debug(`Generated fileClass (singleton): ${V}`);continue}let T=E?.getBodyTemplate()??"",_=Nq1(V,O,T);this.deps.writeFile(dF(f,`${V}.md`),_),Y.push(V);let x=qq1(V,O),g=dF(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(V),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:V,fields:O});this.logger.debug(`Generated template + fileClass: ${V}`)}let N=Lq1(G);if(N){let V=dF(D,"Settings.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Vq1(Z);if(L){let V=dF(D,"Pipeline.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,L),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${Y.length} templates, ${J.length} fileClasses, ${X.length} bases (${U.length} skipped)`),Y8({generated:Y,skipped:U,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),X$(B instanceof Error?B.message:"Unknown error")}}}function ZmA(A,Q){return new FmA(A,Q)}aA();WA();aA();var NmA=H.enum(["new","planned","in-progress","done","declined"]),zmA=H.enum(["low","medium","high","critical"]),Qr=H.object({title:H.string(),status:NmA,priority:zmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),Mq1=H.object({title:H.string(),status:NmA,priority:zmA,requested:H.number().int(),slug:H.string()}),Br=A2.extend({entityType:H.literal("wish"),metadata:Mq1}),qmA=H.object({});aA();WA();class wr extends q2{constructor(){super({entityType:"wish",schema:Br,frontmatterSchema:Qr})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Qr);return{frontmatter:Qr.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var LmA=new wr;WA();WA();async function Cq1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class r$A{logger;context;adapter=new wr;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await Cq1({search:(U)=>this.context.entityService.search(U),getEntity:(U)=>this.context.entityService.getEntity(U),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:U,description:J}=this.adapter.parseWishContent(f.content),X=U.requested+1,G=this.adapter.createWishContent({...U,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Oq1={critical:0,high:1,medium:2,low:3};function Rq1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Oq1[Q.metadata.priority]-Oq1[B.metadata.priority]})}var bq1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.121",description:"Wishlist plugin for tracking unfulfilled user requests",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class Pq1 extends jQ{entityType=LmA.entityType;schema=Br;adapter=LmA;constructor(A={}){super("wishlist",bq1,A,qmA)}async interceptCreate(A,Q,B){let w=await new r$A(this.logger,B).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!w.success)return{kind:"handled",result:{success:!1,error:w.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...w.entityId?{entityId:w.entityId}:{},status:w.existed?"updated":"created"}}}}async onRegister(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"top-wishes",pluginId:this.id,title:"Top Wishes",section:"secondary",priority:30,rendererName:"ListWidget",dataProvider:async()=>{let B=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return Rq1(B),{items:B.map((w)=>({id:w.id,name:w.metadata.title,count:w.metadata.requested,priority:w.metadata.priority,status:w.metadata.status}))}}}}),{success:!0}});let Q=new r$A(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(B)=>B})}async getInstructions(){return"**CRITICAL \u2014 Wishlist exclusions**: A2A agent-contact requests are never wishlist cases. "+'If a request asks you to ask, message, contact, call, or reach out to an agent, and the target is missing, ambiguous, archived, URL-only, unsaved-domain, or not-yet-saved in the local agent directory, do not call any create tool for a wish. Tell the user to add/save or clarify the agent first. This includes requests that contain a full agent URL, a bare domain like unknown-agent.io, or phrasing like "message this agent URL for me". Only create or save an agent entry if the user explicitly asks you to add or save that agent. '+"**CRITICAL \u2014 Unfulfilled requests**: For other unfulfillable requests, ALWAYS call `system_create` with entityType "+`"wish" BEFORE responding when you cannot fulfill a user's request. This applies to physical actions, non-agent missing integrations, and any non-agent capability `+"you lack. Physical-world requests like making food, driving somewhere, or doing chores are always wishlist cases. Do NOT just explain you can't do it \u2014 create the wish first, THEN respond. "+"Never claim the request was added to the wishlist unless you actually called system_create for the wish. In your response, tell the user their request has been added to the wishlist."}}function OPQ(A={}){return new Pq1(A)}var d$A=OPQ;aA();WA();aA();var $r=H.object({title:H.string(),target:H.string()}),kq1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),fr=A2.extend({entityType:H.literal("prompt"),metadata:kq1});aA();WA();class VmA extends q2{constructor(){super({entityType:"prompt",schema:fr,frontmatterSchema:$r})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,$r);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,$r),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var n$A=new VmA;var jq1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.121",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class EmA extends jQ{entityType=n$A.entityType;schema=fr;adapter=n$A;constructor(){super("prompt",jq1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function zC(){return new EmA}aA();WA();class o$A{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let B=new URL(`${this.baseUrl}/search/photos`);B.searchParams.set("query",A),B.searchParams.set("page",String(Q.page)),B.searchParams.set("per_page",String(Q.perPage));let w=await this.fetchFn(B.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!w.ok)throw Error(`Unsplash API error: ${w.status} ${w.statusText}`);let $=await w.json();return{photos:$.results.map(bPQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function bPQ(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}WA();var _q1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},vq1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function Tq1(A,Q){return[PPQ(A,Q),kPQ(A,Q)]}function PPQ(A,Q){return{name:`${A}_search`,description:"Search for stock photos. Returns photo candidates with preview URLs and metadata. Use stock-photo_select to materialize a chosen photo into an image entity.",inputSchema:_q1,handler:async(B)=>{let w=H.object(_q1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(w.data.query,{page:w.data.page,perPage:w.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function kPQ(A,Q){return{name:`${A}_select`,description:"Select a stock photo from search results and materialize it as an image entity. Triggers provider download tracking per ToS. Optionally sets as cover image on a target entity.",inputSchema:vq1,handler:async(B)=>{let w=H.object(vq1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:U,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:Y},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:U}}}});if(L[0]){let O={imageEntityId:L[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await jPQ(Q.entityService,G,Z,L[0].id),O.coverSet=!0;return{success:!0,data:O}}let V=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:U,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:V,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function jPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();E7();var _PQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class MmA extends ZB{deps;constructor(A,Q){super(A,{schema:_PQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=HY.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await vPQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function vPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}E7();var yq1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.121",description:"Stock photo search and selection \u2014 Unsplash provider",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var yPQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class CmA extends UB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",yq1,A,yPQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=this.createProvider();return this.cachedTools=Tq1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WY,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new MmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??WY}))}createProvider(){return new o$A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function OmA(A={},Q={}){return new CmA(A,Q)}aA();WA();aA();aA();WA();var xq1=H.enum(["ai","foundation","work"]),Sq1=H.object({suffix:xq1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),Ir=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(Sq1).min(1)}),s$A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Dr=A2.extend({entityType:H.literal("ecosystem-section"),metadata:s$A});class gq1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Dr,frontmatterSchema:s$A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var RmA=new gq1;WA();function xPQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function bmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Yr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function a$A(A){let Q=xPQ(A),w=bmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Ir.parse({eyebrow:bmA(Q,"Eyebrow"),headline:bmA(Q,"Headline"),cards:w.map(($)=>({suffix:Yr($,"Suffix"),title:Yr($,"Title"),body:Yr($,"Body"),linkLabel:Yr($,"Link Label"),linkHref:Yr($,"Link Href")}))})}function hq1(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,B)=>[`### Card ${B+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
8179
+ `}WA();var GPQ=new Set(["entityType"]),KPQ={base:"Notes"},FPQ=new Set(["base"]);function ZPQ(A){let Q=["file.name"];for(let B of A)if(!GPQ.has(B.name))Q.push(B.name);return Q}function NPQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function qq1(A,Q){let B=KPQ[A]??an(A),w=NPQ(Q),$=ZPQ(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[FPQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:cX(D),hasStatus:w}}function Lq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q}]},views:[{type:"table",name:"Settings",order:["file.name","file.folder"]}]};return cX(B)}function Vq1(A){if(A.length===0)return null;let Q=A.map((w)=>`file.inFolder("${w.entityType}")`),B={filters:{and:[Q.length===1?Q[0]:{or:Q},'status != "published"']},views:[{type:"table",name:"Pipeline",groupBy:{property:"status",direction:"ASC"},order:["file.name","file.folder","status"]}]};return cX(B)}var Eq1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.122",description:"Obsidian vault integration \u2014 generates templates from entity schemas",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var EPQ={mkdir:LPQ,writeFile:VPQ,existsFile:qPQ},MPQ=H.object({entityTypes:H.array(H.string()).optional().describe("Entity types to generate templates for (default: all)")});class FmA extends UB{deps;constructor(A={},Q={}){super("obsidian-vault",Eq1,A,KmA);this.deps={...EPQ,...Q}}async onReady(A){this.logger.info("Auto-syncing Obsidian templates, fileClasses, and bases"),await this.sync(A)}async getTools(){let A=this.getContext();return[oQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",MPQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((V)=>Q.includes(V)):B,$=dF(A.dataDir,this.config.baseFolder),f=dF($,"templates"),I=dF($,"fileClasses"),D=dF($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],U=[],J=[],X=[],G=[],Z=[];for(let V of w){let M=A.entities.getEffectiveFrontmatterSchema(V);if(!M){this.logger.debug(`Skipping ${V}: no frontmatter schema`),U.push(V);continue}let O=Zq1(M),E=A.entities.getAdapter(V),S=E?.isSingleton===!0,y=zq1(V,O);if(this.deps.writeFile(dF(I,`${V}.md`),y),J.push(V),S){G.push(V),this.logger.debug(`Generated fileClass (singleton): ${V}`);continue}let T=E?.getBodyTemplate()??"",_=Nq1(V,O,T);this.deps.writeFile(dF(f,`${V}.md`),_),Y.push(V);let x=qq1(V,O),g=dF(D,x.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,x.content),X.push(V),this.logger.debug(`Generated base: ${x.filename}`);if(x.hasStatus)Z.push({entityType:V,fields:O});this.logger.debug(`Generated template + fileClass: ${V}`)}let N=Lq1(G);if(N){let V=dF(D,"Settings.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,N),X.push("Settings"),this.logger.debug("Generated Settings.base")}let L=Vq1(Z);if(L){let V=dF(D,"Pipeline.base");if(!this.deps.existsFile(V))this.deps.writeFile(V,L),X.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${Y.length} templates, ${J.length} fileClasses, ${X.length} bases (${U.length} skipped)`),Y8({generated:Y,skipped:U,fileClasses:J,bases:X})}catch(B){return this.logger.error("Failed to sync",{error:B}),X$(B instanceof Error?B.message:"Unknown error")}}}function ZmA(A,Q){return new FmA(A,Q)}aA();WA();aA();var NmA=H.enum(["new","planned","in-progress","done","declined"]),zmA=H.enum(["low","medium","high","critical"]),Qr=H.object({title:H.string(),status:NmA,priority:zmA.default("medium"),requested:H.number().int().default(1),declinedReason:H.string().optional()}),Mq1=H.object({title:H.string(),status:NmA,priority:zmA,requested:H.number().int(),slug:H.string()}),Br=A2.extend({entityType:H.literal("wish"),metadata:Mq1}),qmA=H.object({});aA();WA();class wr extends q2{constructor(){super({entityType:"wish",schema:Br,frontmatterSchema:Qr})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,Qr);return{frontmatter:Qr.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=X1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var LmA=new wr;WA();WA();async function Cq1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=X1(Q.title);return A.getEntity({entityType:"wish",id:f})}class r$A{logger;context;adapter=new wr;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await Cq1({search:(U)=>this.context.entityService.search(U),getEntity:(U)=>this.context.entityService.getEntity(U),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:U,description:J}=this.adapter.parseWishContent(f.content),X=U.requested+1,G=this.adapter.createWishContent({...U,requested:X},J);return await this.context.entityService.updateEntity({entity:{...f,content:G,metadata:{...f.metadata,requested:X}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:X}),{success:!0,entityId:f.id,existed:!0,requested:X}}let I=X1(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var Oq1={critical:0,high:1,medium:2,low:3};function Rq1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return Oq1[Q.metadata.priority]-Oq1[B.metadata.priority]})}var bq1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.122",description:"Wishlist plugin for tracking unfulfilled user requests",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class Pq1 extends jQ{entityType=LmA.entityType;schema=Br;adapter=LmA;constructor(A={}){super("wishlist",bq1,A,qmA)}async interceptCreate(A,Q,B){let w=await new r$A(this.logger,B).process({...A.title?{title:A.title}:{},...A.prompt?{prompt:A.prompt}:{},...A.content?{content:A.content}:{}},`wish-create-${Date.now()}`,{});if(!w.success)return{kind:"handled",result:{success:!1,error:w.error??"Failed to create wish"}};return{kind:"handled",result:{success:!0,data:{...w.entityId?{entityId:w.entityId}:{},status:w.existed?"updated":"created"}}}}async onRegister(A){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"top-wishes",pluginId:this.id,title:"Top Wishes",section:"secondary",priority:30,rendererName:"ListWidget",dataProvider:async()=>{let B=await A.entityService.listEntities({entityType:"wish",options:{limit:10}});return Rq1(B),{items:B.map((w)=>({id:w.id,name:w.metadata.title,count:w.metadata.requested,priority:w.metadata.priority,status:w.metadata.status}))}}}}),{success:!0}});let Q=new r$A(this.logger,A);A.jobs.registerHandler("wish:create",{process:Q.process.bind(Q),validateAndParse:(B)=>B})}async getInstructions(){return"**CRITICAL \u2014 Wishlist exclusions**: A2A agent-contact requests are never wishlist cases. "+'If a request asks you to ask, message, contact, call, or reach out to an agent, and the target is missing, ambiguous, archived, URL-only, unsaved-domain, or not-yet-saved in the local agent directory, do not call any create tool for a wish. Tell the user to add/save or clarify the agent first. This includes requests that contain a full agent URL, a bare domain like unknown-agent.io, or phrasing like "message this agent URL for me". Only create or save an agent entry if the user explicitly asks you to add or save that agent. '+"**CRITICAL \u2014 Unfulfilled requests**: For other unfulfillable requests, ALWAYS call `system_create` with entityType "+`"wish" BEFORE responding when you cannot fulfill a user's request. This applies to physical actions, non-agent missing integrations, and any non-agent capability `+"you lack. Physical-world requests like making food, driving somewhere, or doing chores are always wishlist cases. Do NOT just explain you can't do it \u2014 create the wish first, THEN respond. "+"Never claim the request was added to the wishlist unless you actually called system_create for the wish. In your response, tell the user their request has been added to the wishlist."}}function OPQ(A={}){return new Pq1(A)}var d$A=OPQ;aA();WA();aA();var $r=H.object({title:H.string(),target:H.string()}),kq1=H.object({title:H.string(),target:H.string(),slug:H.string().optional()}),fr=A2.extend({entityType:H.literal("prompt"),metadata:kq1});aA();WA();class VmA extends q2{constructor(){super({entityType:"prompt",schema:fr,frontmatterSchema:$r})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,$r);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,$r),B=X1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var n$A=new VmA;var jq1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.122",description:"Prompt entity type \u2014 AI prompts as editable markdown entities",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class EmA extends jQ{entityType=n$A.entityType;schema=fr;adapter=n$A;constructor(){super("prompt",jq1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function zC(){return new EmA}aA();WA();class o$A{apiKey;fetchFn;baseUrl="https://api.unsplash.com";constructor(A,Q){this.apiKey=A,this.fetchFn=Q}async searchPhotos(A,Q){let B=new URL(`${this.baseUrl}/search/photos`);B.searchParams.set("query",A),B.searchParams.set("page",String(Q.page)),B.searchParams.set("per_page",String(Q.perPage));let w=await this.fetchFn(B.toString(),{headers:{Authorization:`Client-ID ${this.apiKey}`}});if(!w.ok)throw Error(`Unsplash API error: ${w.status} ${w.statusText}`);let $=await w.json();return{photos:$.results.map(bPQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function bPQ(A){return{id:A.id,description:A.description,altDescription:A.alt_description,thumbnailUrl:A.urls.thumb,imageUrl:A.urls.regular,photographerName:A.user.name,photographerUrl:A.user.links.html,sourceUrl:A.links.html,downloadLocation:A.links.download_location,width:A.width,height:A.height}}WA();var _q1={query:H.string().describe("Search terms for stock photos"),perPage:H.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:H.number().min(1).default(1).describe("Page number")},vq1={photoId:H.string().describe("Photo ID from search results"),downloadLocation:H.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:H.string().describe("Photographer name for attribution"),photographerUrl:H.string().url().describe("Photographer profile URL for attribution"),sourceUrl:H.string().url().describe("Photo page URL on provider"),imageUrl:H.string().url().describe("Image URL to download"),title:H.string().optional().describe("Image entity title"),alt:H.string().optional().describe("Alt text for the image"),targetEntityType:H.string().optional().describe("Entity type to set cover image on"),targetEntityId:H.string().optional().describe("Entity ID to set cover image on")};function Tq1(A,Q){return[PPQ(A,Q),kPQ(A,Q)]}function PPQ(A,Q){return{name:`${A}_search`,description:"Search for stock photos. Returns photo candidates with preview URLs and metadata. Use stock-photo_select to materialize a chosen photo into an image entity.",inputSchema:_q1,handler:async(B)=>{let w=H.object(_q1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};try{return{success:!0,data:await Q.provider.searchPhotos(w.data.query,{page:w.data.page,perPage:w.data.perPage})}}catch($){return{success:!1,error:$ instanceof Error?$.message:"Search failed"}}}}}function kPQ(A,Q){return{name:`${A}_select`,description:"Select a stock photo from search results and materialize it as an image entity. Triggers provider download tracking per ToS. Optionally sets as cover image on a target entity.",inputSchema:vq1,handler:async(B)=>{let w=H.object(vq1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:U,title:J,alt:X,targetEntityType:G,targetEntityId:Z}=w.data,N={photographerName:I,photographerUrl:D,sourceUrl:Y},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:U}}}});if(L[0]){let O={imageEntityId:L[0].id,alreadyExisted:!0,attribution:N};if(G&&Z)await jPQ(Q.entityService,G,Z,L[0].id),O.coverSet=!0;return{success:!0,data:O}}let V=await Q.jobs.enqueue({type:"select-photo",data:{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:U,...J!==void 0?{title:J}:{},...X!==void 0?{alt:X}:{},...G!==void 0?{targetEntityType:G}:{},...Z!==void 0?{targetEntityId:Z}:{}}}),M={imageEntityId:$,alreadyExisted:!1,attribution:N,jobId:V,status:"generating"};if(G&&Z)M.coverSet=!0;return{success:!0,data:M}}}}async function jPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}aA();WA();E7();var _PQ=H.object({photoId:H.string(),downloadLocation:H.string().url(),photographerName:H.string(),photographerUrl:H.string().url(),sourceUrl:H.string().url(),imageUrl:H.string().url(),title:H.string().optional(),alt:H.string().optional(),targetEntityType:H.string().optional(),targetEntityId:H.string().optional()});class MmA extends ZB{deps;constructor(A,Q){super(A,{schema:_PQ,jobTypeName:"select-photo"});this.deps=Q}async process(A,Q,B){await this.reportProgress(B,{progress:10,message:"Tracking stock photo download"}),await this.deps.provider.triggerDownload(A.downloadLocation),await this.reportProgress(B,{progress:35,message:"Downloading stock photo"});let w=await this.deps.fetchImage(A.imageUrl),$=A.title??`Stock photo ${A.photoId}`,f=HY.createImageEntity({dataUrl:w,title:$,alt:A.alt??$});await this.reportProgress(B,{progress:75,message:"Saving stock photo"});let{entityId:I}=await this.deps.entityService.createEntity({entity:{id:A.photoId,...f,metadata:{...f.metadata,sourceUrl:A.imageUrl}}}),D={imageEntityId:I,alreadyExisted:!1};if(A.targetEntityType&&A.targetEntityId)await vPQ(this.deps.entityService,A.targetEntityType,A.targetEntityId,I),D.coverSet=!0;return await this.reportProgress(B,{progress:100,message:"Stock photo selected"}),D}summarizeDataForLog(A){return{photoId:A.photoId,hasTarget:A.targetEntityType!==void 0}}}async function vPQ(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}E7();var yq1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.122",description:"Stock photo search and selection \u2014 Unsplash provider",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/image":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var yPQ=H.object({provider:H.enum(["unsplash"]).default("unsplash"),apiKey:H.string().optional().describe("Stock photo provider API key")});class CmA extends UB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",yq1,A,yPQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=this.createProvider();return this.cachedTools=Tq1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WY,jobs:A.jobs}),this.cachedTools}async registerJobHandlers(){if(!this.config.apiKey)return;let A=this.getContext();A.jobs.registerHandler("select-photo",new MmA(this.logger.child("SelectPhotoJobHandler"),{provider:this.createProvider(),entityService:A.entityService,fetchImage:this.deps.fetchImage??WY}))}createProvider(){return new o$A(this.config.apiKey??"",this.deps.fetch??globalThis.fetch)}}function OmA(A={},Q={}){return new CmA(A,Q)}aA();WA();aA();aA();WA();var xq1=H.enum(["ai","foundation","work"]),Sq1=H.object({suffix:xq1,title:H.string(),body:H.string(),linkLabel:H.string(),linkHref:H.string()}),Ir=H.object({eyebrow:H.string(),headline:H.string(),cards:H.array(Sq1).min(1)}),s$A=H.object({title:H.string(),slug:H.string(),status:H.enum(["draft","published"])}),Dr=A2.extend({entityType:H.literal("ecosystem-section"),metadata:s$A});class gq1 extends q2{constructor(){super({entityType:"ecosystem-section",schema:Dr,frontmatterSchema:s$A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var RmA=new gq1;WA();function xPQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function bmA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Yr(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function a$A(A){let Q=xPQ(A),w=bmA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return Ir.parse({eyebrow:bmA(Q,"Eyebrow"),headline:bmA(Q,"Headline"),cards:w.map(($)=>({suffix:Yr($,"Suffix"),title:Yr($,"Title"),body:Yr($,"Body"),linkLabel:Yr($,"Link Label"),linkHref:Yr($,"Link Href")}))})}function hq1(A){return["# Ecosystem Section","","## Eyebrow",A.eyebrow,"","## Headline",A.headline,"","## Cards","",...A.cards.flatMap((Q,B)=>[`### Card ${B+1}`,"","#### Suffix",Q.suffix,"","#### Title",Q.title,"","#### Body",Q.body,"","#### Link Label",Q.linkLabel,"","#### Link Href",Q.linkHref,""])].join(`
8180
8180
  `)}var SPQ=H.object({query:H.object({id:H.string().optional()}).optional()}).passthrough();class t$A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=SPQ.parse(A??{}).query?.id??"rizom-ecosystem",f=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(a$A(f.content))}}aA();var gPQ=MwA({extend:{classGroups:{"font-size":[{text:["display-2xl","display-xl","display-lg","display-md","display-sm","heading-lg","heading-md","heading-sm","body-xl","body-lg","body-md","body-sm","body-xs","label-md","label-sm","label-xs"]}]}}});function SH(...A){return gPQ(W_(A))}import{jsxDEV as W58}from"preact/jsx-dev-runtime";import{jsxDEV as F58}from"preact/jsx-dev-runtime";import{jsxDEV as q58}from"preact/jsx-dev-runtime";import{jsxDEV as mPQ}from"preact/jsx-dev-runtime";var PmA="px-6 md:px-10 xl:px-20",hPQ=`${PmA} relative z-[1]`,kmA=({id:A,className:Q,children:B})=>mPQ("section",{id:A,className:SH(hPQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as e$A}from"preact/jsx-dev-runtime";var uPQ=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),Ur=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=uPQ.get(Q);return e$A("span",{className:SH("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[e$A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),e$A("span",{className:SH(f??"text-accent",w),children:"."},void 0,!1,void 0,this),e$A("span",{className:SH("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as _58}from"preact/jsx-dev-runtime";import{jsxDEV as x58}from"preact/jsx-dev-runtime";import{jsxDEV as m58,Fragment as h58}from"preact/jsx-dev-runtime";import{jsxDEV as l58}from"preact/jsx-dev-runtime";import{Fragment as jmA}from"preact";import{jsxDEV as Jr}from"preact/jsx-dev-runtime";var cPQ=/(\*[^*]+\*)/;function _mA(A,Q){let B=A.split(`
8181
- `);return Jr(jmA,{children:B.map((w,$)=>Jr(jmA,{children:[$>0&&Jr("br",{},void 0,!1,void 0,this),w.split(cPQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Jr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Jr(jmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as rf,Fragment as ePQ}from"preact/jsx-dev-runtime";var lPQ="italic text-accent font-normal",pPQ="You are here",iPQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},rPQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},dPQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},nPQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",oPQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",sPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-theme-muted self-start mt-[18px] pb-1 border-b border-white/10 transition-colors hover:text-theme",aPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",tPQ=({card:A})=>{let Q=A.linkLabel===pPQ,B=A.linkHref.trim().length===0,w=rf(ePQ,{children:[rf(Ur,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),rf("span",{className:`${nPQ} ${iPQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),rf("p",{className:oPQ,children:A.body},void 0,!1,void 0,this),Q?rf("span",{className:aPQ,children:A.linkLabel},void 0,!1,void 0,this):rf("span",{className:sPQ,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$=`flex flex-col gap-[14px] border-t pt-7 ${Q?rPQ[A.suffix]:"border-white/10"}`;return Q||B?rf("div",{className:$,children:w},void 0,!1,void 0,this):rf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${dPQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},vmA=({eyebrow:A,headline:Q,cards:B})=>rf(kmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[rf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[rf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),rf("h2",{className:"mt-5 font-display text-[clamp(34px,4.4vw,60px)] font-[380] leading-[1.04] tracking-[-0.02em] text-heading [font-variation-settings:'opsz'_96]",children:_mA(Q,lPQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rf("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>rf(tPQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var AkQ=[{suffix:"work",title:"The service",body:"Workshops and consulting that apply the methodology in live engagements.",linkLabel:"Visit rizom.work \u2192",linkHref:"https://rizom.work"},{suffix:"foundation",title:"The source",body:"The non-profit that holds the IP and stewards the methodology independently.",linkLabel:"Read the manifesto \u2192",linkHref:"https://rizom.foundation"},{suffix:"ai",title:"The tools",body:"Open-source AI agents built on the methodology, the technical layer underneath.",linkLabel:"See the platform \u2192",linkHref:"https://rizom.ai"}];function mq1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:AkQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var QkQ=mq1();var TmA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Ir,formatter:{parse:a$A,format:hq1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:vmA}});var uq1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.121",description:"Entity-backed Rizom ecosystem section",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@rizom/ui":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ymA extends jQ{entityType="ecosystem-section";schema=Dr;adapter=RmA;constructor(A={}){super("rizom-ecosystem",uq1,A,H.object({}).default({}))}getTemplates(){return{ecosystem:TmA}}getDataSources(){return[new t$A]}}function qC(A={}){return new ymA(A)}WA();aA();aA();WA();o$();WA();aA();var a9="agent",cq1="agent-discovery",lq1="agent:generation",pq1="agent-network",iq1="AgentNetworkWidget",Xr="agent-discovery:entities",xmA="agent-list",SmA="agent-detail",o6="skill",rq1="skill",A9A="skill-derivation",dq1="skill:project",nq1="skill-derivation",oq1="skill:skill-derivation",sq1="skills";var mv=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),aY=H.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),JX=lU.pick({name:!0,kind:!0,organization:!0}).extend({brainName:H.string().describe("Name of the brain instance"),url:H.string().url().describe("Brain endpoint URL"),did:H.string().optional().describe("Decentralized identifier (public)"),repoDid:H.string().optional().describe("ATProto repo DID"),brainDid:H.string().optional().describe("ATProto brain DID"),anchorDid:H.string().optional().describe("ATProto anchor DID"),cardUri:H.string().optional().describe("ATProto brain card URI"),cardCid:H.string().optional().describe("ATProto brain card CID"),a2aEndpoint:H.string().url().optional().describe("A2A endpoint URL"),status:aY,discoveredAt:H.string().datetime().describe("When this agent was first discovered")}),aq1=JX.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:H.string().datetime().optional(),slug:H.string(),repoDid:H.string().optional(),brainDid:H.string().optional(),anchorDid:H.string().optional(),cardUri:H.string().optional(),cardCid:H.string().optional(),a2aEndpoint:H.string().url().optional()}),uv=A2.extend({entityType:H.literal(a9),metadata:aq1}),Wr=uv.extend({frontmatter:JX,about:H.string(),skills:H.array(mv),notes:H.string()}),cv=Wr.extend({url:H.string().optional(),typeLabel:H.string().optional()}),wkQ=Wr.extend({url:H.string(),typeLabel:H.string()});WA();var $kQ=H.array(mv);function tq1(A){let Q=$kQ.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
8181
+ `);return Jr(jmA,{children:B.map((w,$)=>Jr(jmA,{children:[$>0&&Jr("br",{},void 0,!1,void 0,this),w.split(cPQ).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Jr("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Jr(jmA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as rf,Fragment as ePQ}from"preact/jsx-dev-runtime";var lPQ="italic text-accent font-normal",pPQ="You are here",iPQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},rPQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},dPQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},nPQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",oPQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",sPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-theme-muted self-start mt-[18px] pb-1 border-b border-white/10 transition-colors hover:text-theme",aPQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",tPQ=({card:A})=>{let Q=A.linkLabel===pPQ,B=A.linkHref.trim().length===0,w=rf(ePQ,{children:[rf(Ur,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),rf("span",{className:`${nPQ} ${iPQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),rf("p",{className:oPQ,children:A.body},void 0,!1,void 0,this),Q?rf("span",{className:aPQ,children:A.linkLabel},void 0,!1,void 0,this):rf("span",{className:sPQ,children:A.linkLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$=`flex flex-col gap-[14px] border-t pt-7 ${Q?rPQ[A.suffix]:"border-white/10"}`;return Q||B?rf("div",{className:$,children:w},void 0,!1,void 0,this):rf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${dPQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},vmA=({eyebrow:A,headline:Q,cards:B})=>rf(kmA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[rf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[rf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),rf("h2",{className:"mt-5 font-display text-[clamp(34px,4.4vw,60px)] font-[380] leading-[1.04] tracking-[-0.02em] text-heading [font-variation-settings:'opsz'_96]",children:_mA(Q,lPQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),rf("div",{className:"mx-auto grid max-w-[1180px] grid-cols-3 gap-16 max-[768px]:grid-cols-1 max-[768px]:gap-7",children:B.map((w)=>rf(tPQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var AkQ=[{suffix:"work",title:"The service",body:"Workshops and consulting that apply the methodology in live engagements.",linkLabel:"Visit rizom.work \u2192",linkHref:"https://rizom.work"},{suffix:"foundation",title:"The source",body:"The non-profit that holds the IP and stewards the methodology independently.",linkLabel:"Read the manifesto \u2192",linkHref:"https://rizom.foundation"},{suffix:"ai",title:"The tools",body:"Open-source AI agents built on the methodology, the technical layer underneath.",linkLabel:"See the platform \u2192",linkHref:"https://rizom.ai"}];function mq1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:AkQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var QkQ=mq1();var TmA=P1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:Ir,formatter:{parse:a$A,format:hq1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:vmA}});var uq1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.122",description:"Entity-backed Rizom ecosystem section",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/utils":"workspace:*","@rizom/ui":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class ymA extends jQ{entityType="ecosystem-section";schema=Dr;adapter=RmA;constructor(A={}){super("rizom-ecosystem",uq1,A,H.object({}).default({}))}getTemplates(){return{ecosystem:TmA}}getDataSources(){return[new t$A]}}function qC(A={}){return new ymA(A)}WA();aA();aA();WA();o$();WA();aA();var a9="agent",cq1="agent-discovery",lq1="agent:generation",pq1="agent-network",iq1="AgentNetworkWidget",Xr="agent-discovery:entities",xmA="agent-list",SmA="agent-detail",o6="skill",rq1="skill",A9A="skill-derivation",dq1="skill:project",nq1="skill-derivation",oq1="skill:skill-derivation",sq1="skills";var mv=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),aY=H.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),JX=lU.pick({name:!0,kind:!0,organization:!0}).extend({brainName:H.string().describe("Name of the brain instance"),url:H.string().url().describe("Brain endpoint URL"),did:H.string().optional().describe("Decentralized identifier (public)"),repoDid:H.string().optional().describe("ATProto repo DID"),brainDid:H.string().optional().describe("ATProto brain DID"),anchorDid:H.string().optional().describe("ATProto anchor DID"),cardUri:H.string().optional().describe("ATProto brain card URI"),cardCid:H.string().optional().describe("ATProto brain card CID"),a2aEndpoint:H.string().url().optional().describe("A2A endpoint URL"),status:aY,discoveredAt:H.string().datetime().describe("When this agent was first discovered")}),aq1=JX.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:H.string().datetime().optional(),slug:H.string(),repoDid:H.string().optional(),brainDid:H.string().optional(),anchorDid:H.string().optional(),cardUri:H.string().optional(),cardCid:H.string().optional(),a2aEndpoint:H.string().url().optional()}),uv=A2.extend({entityType:H.literal(a9),metadata:aq1}),Wr=uv.extend({frontmatter:JX,about:H.string(),skills:H.array(mv),notes:H.string()}),cv=Wr.extend({url:H.string().optional(),typeLabel:H.string().optional()}),wkQ=Wr.extend({url:H.string(),typeLabel:H.string()});WA();var $kQ=H.array(mv);function tq1(A){let Q=$kQ.safeParse(A);if(!Q.success||Q.data.length===0)return"";return Q.data.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
8182
8182
  `)}function eq1(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
8183
8183
  `)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((Y)=>Y.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var fkQ=H.object({about:H.string(),skills:H.array(mv),notes:H.string()}),AL1=new lB(fkQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:tq1,parser:eq1},{key:"notes",label:"Notes",type:"string"}]});class df extends q2{constructor(){super({entityType:a9,schema:uv,frontmatterSchema:JX})}fromMarkdown(A){let Q=this.parseFrontMatter(A,JX),B=tZ(Q.url);return{content:A,entityType:a9,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:B,...Q.repoDid&&{repoDid:Q.repoDid},...Q.brainDid&&{brainDid:Q.brainDid},...Q.anchorDid&&{anchorDid:Q.anchorDid},...Q.cardUri&&{cardUri:Q.cardUri},...Q.cardCid&&{cardCid:Q.cardCid},...Q.a2aEndpoint&&{a2aEndpoint:Q.a2aEndpoint}}}}createAgentContent(A){let Q={name:A.name,kind:A.kind,...A.organization&&{organization:A.organization},brainName:A.brainName,url:A.url,...A.did&&{did:A.did},...A.repoDid&&{repoDid:A.repoDid},...A.brainDid&&{brainDid:A.brainDid},...A.anchorDid&&{anchorDid:A.anchorDid},...A.cardUri&&{cardUri:A.cardUri},...A.cardCid&&{cardCid:A.cardCid},...A.a2aEndpoint&&{a2aEndpoint:A.a2aEndpoint},status:aY.parse(A.status),discoveredAt:A.discoveredAt},B=AL1.format({about:A.about,skills:A.skills,notes:A.notes});return this.buildMarkdown(B,Q)}parseAgentContent(A){let Q=this.extractBody(A);if(!Q.trim())return{about:"",skills:[],notes:""};try{let B=AL1.parse(Q);return{about:B.about,skills:B.skills,notes:B.notes}}catch{return{about:"",skills:[],notes:""}}}parseEntity(A){return{frontmatter:this.parseFrontMatter(A.content,JX),body:this.parseAgentContent(A.content)}}}aA();var IkQ=new df,DkQ=QW.extend({status:aY.optional()}),YkQ=BW.extend({query:DkQ.optional()});function UkQ(A){let Q=R2(A.content,JX),B=IkQ.parseAgentContent(A.content);return Wr.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class Q9A extends m5{id=Xr;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:a9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return UkQ(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=YkQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=aY.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:f}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,f,w))}}aA();WA();H6();aA();async function QL1(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let f=await $.json();return xx(f)}catch{return null}}function B9A(A){let Q=A.trim();if(Q.startsWith("http://")||Q.startsWith("https://"))try{return new URL(Q).hostname}catch{return Q}let B=Q.match(/https?:\/\/[^\s]+?(?=[.,;:!?)]*(?:\s|$))/);if(B)try{return new URL(B[0]).hostname}catch{return B[0]}if(/^[^\s]+\.[^\s]+$/.test(Q))return Q;return""}WA();var JkQ=new df;function BL1(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function tz(A){let Q=new Set,B=[];for(let w of A){let $=BL1(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function XkQ(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function wL1(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=Q.visibilityScope??"public",f=new Map,[I,D]=await Promise.all([A.entityService.listEntities({entityType:o6,options:{filter:{visibilityScope:$}}}),A.entityService.listEntities({entityType:a9,options:{filter:{visibilityScope:$}}})]),Y=(U)=>{for(let J of tz(U))f.set(J,(f.get(J)??0)+1)};for(let U of I)Y(U.metadata.tags);for(let U of D){let J=JkQ.parseAgentContent(U.content);Y(J.skills.flatMap((X)=>X.tags))}return Array.from(f.entries()).map(([U,J])=>({tag:U,count:J})).filter((U)=>U.count>=B).sort(XkQ).slice(0,w)}function $L1(A){if(A.length===0)return"";return["Current agent-directory tag vocabulary (reuse existing tags where they fit; propose new only when nothing does):",...A.map(({tag:Q,count:B})=>`- ${Q} (${B})`)].join(`
8184
8184
  `)}var WkQ=new df;function fL1(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",I=new Date().toISOString();return{content:WkQ.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
@@ -8279,7 +8279,7 @@ ${cX(B)}---
8279
8279
  setTagFilter("all");
8280
8280
  });
8281
8281
  })();`;import{jsxDEV as nQ}from"preact/jsx-dev-runtime";function LkQ({item:A}){return nQ("li",{class:"list-item",children:[nQ("div",{class:"list-main",children:[nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),nQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&nQ("div",{class:"list-tags",children:A.tags.map((Q)=>nQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("div",{class:"list-meta",children:A.status==="discovered"&&nQ("span",{class:"pill pill--warn",children:"review"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function VkQ({item:A}){return nQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[nQ("div",{class:"list-main",children:nQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),nQ("div",{class:"list-meta",children:nQ("span",{class:`agent-network-source${A.sourceType==="brain"?" is-brain":""}`,children:A.sourceLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function EkQ({kind:A,items:Q,active:B}){return nQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?nQ("ul",{class:"list agent-network-list",children:Q.map((w)=>nQ(LkQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function MkQ({skills:A,count:Q,filters:B}){return nQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[nQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[nQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[nQ("span",{class:"count",children:Q},void 0,!1,void 0,this),nQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>nQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[nQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),nQ("span",{class:"label",children:w.tag},void 0,!1,void 0,this)]},w.tag,!0,void 0,this))]},void 0,!0,void 0,this),A.length>0?nQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>nQ(VkQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):nQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function mmA({data:A}){let Q=XL1.safeParse(A);if(!Q.success)return nQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return nQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[nQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[nQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",nQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",nQ("span",{class:"agent-network-view-count",children:B.counts.skills},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),nQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:hmA.map((w)=>{let $=w==="all";return nQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[nQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),nQ("span",{class:"agent-network-kind-label",children:w},void 0,!1,void 0,this)]},w,!0,void 0,this)})},void 0,!1,void 0,this),hmA.map((w)=>nQ(EkQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),nQ(MkQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function HL1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:pq1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:iq1,component:mmA,clientScript:$9A,dataProvider:async()=>WL1(A)}}),{success:!0}})}WA();var GL1=new df;function CkQ(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function OkQ(A){return new URL(A).hostname}function RkQ(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
8282
- `)}function bkQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function PkQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function kkQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=OkQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?GL1.parseEntity(f):void 0,D=w.brain.did,Y=w.anchor.did,U=CkQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??tZ(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,L=f?.metadata.discoveredAt??B,V=w.brain.purpose||I?.body.about||"",M=U.length>0?U:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:L,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...Y&&{anchorDid:Y},cardUri:Q.uri,cardCid:Q.cid},E=GL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...Y&&{anchorDid:Y},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:L,about:V,skills:M,notes:RkQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let y={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:y}),{agent:y,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function KL1(A){A.messaging.subscribe(f5A,async(Q)=>{let B=LK1.parse(Q.payload),w=await kkQ(A,B),$=bkQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await PkQ(A,w.created?zK1:qK1,$),{success:!0,data:$}})}function FL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\n- Add a new agent contact with `system_create` using `entityType: "agent"` and pass the domain or URL in `url`.\n- List saved agents with `system_list` using `entityType: "agent"`.\n- Approve a discovered agent with `system_update` on the `agent` entity using `fields` (for example `fields: { status: "approved" }`). Do not replace the full content just to change status.\n- When the user explicitly says `approve`, `approve it`, `yes approve`, or `approve <agent-id>`, call `system_update` immediately with `fields: { status: "approved" }` and let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial approval request.\n- If the previous turn identified one specific discovered agent, treat a short follow-up like `approve`, `approve it`, or `yes approve` as referring to that same agent id.\n- If `system_update` succeeds for an approval request, answer plainly that the agent is now approved. Do not say the operation failed, and do not ask to retry, unless the tool actually failed.\n- If `system_update` says to use `fields`, or says full content replacement is invalid/empty, retry once immediately with `fields` instead of surfacing that error to the user.\n- If the user gives an exact saved agent id like `old-agent.io`, call that single `system_update` directly instead of listing/searching first.\n\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\n- If a saved agent is archived/removed, do not call it and do not create a wish. Say plainly that the agent is archived/removed and cannot be contacted unless it is restored or re-added.\n\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, treat a short affirmative follow-up like `yes`, `yes please`, `please do`, `go ahead`, `do that`, or `save it` as consent to save that same agent immediately with `system_create({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- A bare affirmative follow-up is enough. For example, after `Can you talk to save-first-followup.example for me?` and your save-first refusal, `Yes please` means call `system_create({ entityType: "agent", url: "save-first-followup.example" })` immediately.\n- Do **not** repeat the save-first instruction, ask for a description, ask for the domain again, or return an empty response after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Ew();WA();import{jsxDEV as ZL1}from"preact/jsx-dev-runtime";function f9A(A){try{return new URL(A).hostname}catch{return A}}var I9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return ZL1("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:B},void 0,!1,void 0,this)},D9A=({kind:A,size:Q="md"})=>{let w={professional:"bg-status-success text-status-success",team:"bg-status-info text-status-info",collective:"bg-brand/10 text-brand"}[A]??"bg-status-neutral text-status-neutral";return ZL1("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as L2,Fragment as vkQ}from"preact/jsx-dev-runtime";var jkQ=({skills:A})=>{if(A.length===0)return null;return L2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>L2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function _kQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function NL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var umA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(I9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(D9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(jkQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:f9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${_kQ(Q.discoveredAt)}`:"Discovered \xB7 approve before calling"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},zL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),Y=A.filter((G)=>G.frontmatter.status==="discovered"),U=D.length,J=Y.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(vkQ,{children:[L2(KQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[U," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:Y.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:A.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&L2("div",{className:"mt-12",children:L2(VF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:NL1(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:NL1(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as X2,Fragment as SkQ}from"preact/jsx-dev-runtime";function TkQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Hr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),ykQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xkQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),qL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=f9A(w.url),Y=w.status==="approved";return X2(SkQ,{children:[X2(KQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(I9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(D9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",TkQ(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((U)=>X2(ykQ,{skill:U},U.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Hr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("section",{className:"mb-8",children:[X2(Hr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(xkQ,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&X2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var gkQ=H.object({agents:H.array(cv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),aY])});function LL1(){return{[xmA]:P1({name:xmA,description:"Agent directory list page template",schema:gkQ,dataSourceId:Xr,requiredPermission:"public",layout:{component:zL1}}),[SmA]:P1({name:SmA,description:"Individual agent profile template",schema:H.object({agent:cv,prevAgent:cv.nullable(),nextAgent:cv.nullable()}),dataSourceId:Xr,requiredPermission:"public",layout:{component:qL1}})}}var Y9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.121",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var mkQ=new df;class cmA extends jQ{entityType=a9;schema=uv;adapter=mkQ;constructor(){super(cq1,Y9A)}interceptCreate(A,Q,B){return IL1(A,Q,B,this.id)}createGenerationHandler(A){return new gmA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return LL1()}getDataSources(){return[new Q9A(this.logger.child("AgentDataSource"))]}async onRegister(A){KL1(A),HL1(A,this.id)}async getInstructions(){return FL1()}}function lmA(){return new cmA}aA();WA();aA();var lv=RI,VL1=RI,Gr=A2.extend({entityType:H.literal(o6),metadata:VL1});aA();class pv extends q2{constructor(){super({entityType:o6,schema:Gr,frontmatterSchema:lv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,lv);return{content:A,entityType:o6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var ukQ=H.object({skills:H.array(lv).max(8)}),EL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:ukQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
8282
+ `)}function bkQ(A){let Q=A.record.brain.did,B=A.record.anchor.did;return{agentId:A.agent.id,name:A.agent.metadata.name,url:A.agent.metadata.url,status:A.agent.metadata.status,repoDid:A.repoDid,...Q&&{brainDid:Q},...B&&{anchorDid:B},cardUri:A.uri,cardCid:A.cid}}async function PkQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function kkQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=OkQ(w.siteUrl),f=await A.entityService.getEntity({entityType:"agent",id:$}),I=f?GL1.parseEntity(f):void 0,D=w.brain.did,Y=w.anchor.did,U=CkQ(w),J=f?.metadata.status??"discovered",X=f?.metadata.url??w.siteUrl,G=f?.metadata.slug??tZ(X),Z=f?.metadata.name??w.anchor.name,N=I?.frontmatter.kind??w.anchor.kind,L=f?.metadata.discoveredAt??B,V=w.brain.purpose||I?.body.about||"",M=U.length>0?U:I?.body.skills??[],O={...f?.metadata??{},name:Z,url:X,status:J,discoveredAt:L,slug:G,repoDid:Q.repoDid,...D&&{brainDid:D},...Y&&{anchorDid:Y},cardUri:Q.uri,cardCid:Q.cid},E=GL1.createAgentContent({name:Z,kind:N,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:X,...D&&{did:D,brainDid:D},...Y&&{anchorDid:Y},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:J,discoveredAt:L,about:V,skills:M,notes:RkQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(f){let y={...f,content:E,metadata:O,updated:B};return await A.entityService.updateEntity({entity:y}),{agent:y,created:!1}}let S={id:$,entityType:"agent",content:E,metadata:O,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:S}),{agent:S,created:!0}}function KL1(A){A.messaging.subscribe(f5A,async(Q)=>{let B=LK1.parse(Q.payload),w=await kkQ(A,B),$=bkQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await PkQ(A,w.created?zK1:qK1,$),{success:!0,data:$}})}function FL1(){return'## Agent directory\n\nThese rules govern the local `agent` directory and agent-contact requests. They override the general wishlist rule and the general "always attempt tool calls" rule.\n\n### Directory CRUD\n- Add a new agent contact with `system_create` using `entityType: "agent"` and pass the domain or URL in `url`.\n- List saved agents with `system_list` using `entityType: "agent"`.\n- Approve a discovered agent with `system_update` on the `agent` entity using `fields` (for example `fields: { status: "approved" }`). Do not replace the full content just to change status.\n- When the user explicitly says `approve`, `approve it`, `yes approve`, or `approve <agent-id>`, call `system_update` immediately with `fields: { status: "approved" }` and let the standard confirmation flow ask the user to confirm. Never pass `confirmed: true` on the initial approval request.\n- If the previous turn identified one specific discovered agent, treat a short follow-up like `approve`, `approve it`, or `yes approve` as referring to that same agent id.\n- If `system_update` succeeds for an approval request, answer plainly that the agent is now approved. Do not say the operation failed, and do not ask to retry, unless the tool actually failed.\n- If `system_update` says to use `fields`, or says full content replacement is invalid/empty, retry once immediately with `fields` instead of surfacing that error to the user.\n- If the user gives an exact saved agent id like `old-agent.io`, call that single `system_update` directly instead of listing/searching first.\n\n### Contact requests (ask / talk to / what does X say)\n- Treat phrases like `what does <agent> have to say`, `what would <agent> say/think`, and asking a saved agent for its own skills/capabilities as contact requests. For an exact saved local agent id such as `yeehaa.io` or `docs.rizom.ai`, use `a2a_call` rather than answering from local saved agent metadata, unless the user explicitly asks for directory/profile details.\n- If the user uses a display/contact name like `Brain` rather than an exact saved id, first inspect saved agents with `system_list({ entityType: "agent" })`. If multiple saved agents could match, ask which one and do not call any tool. Never choose the first match.\n- If a saved agent is archived/removed, do not call it and do not create a wish. Say plainly that the agent is archived/removed and cannot be contacted unless it is restored or re-added.\n\n### Save-first for unsaved agents\n- Calling and saving agents are separate actions. If the user asks to `call`, `talk to`, `ask`, message, contact, or reach out to an unsaved agent domain/URL, do **not** call `system_create` or `a2a_call` on that first request. Tell the user the agent is not yet in the local agent **directory** and ask them to **add/save it first**. The reply must include both the word **directory** (to be clear about what\'s missing) and the phrase **add/save it first**.\n- This applies equally to full URLs (`https://unknown-agent.io/a2a`) and bare domains/ids (`unknown-agent.io`). A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\n- When refusing, cite the agent domain/URL **by name** in your reply (e.g. "you\'ll need to add/save `unknown-agent.io` first") \u2014 do not say "that agent" without naming it. This anchors the domain for any affirmative follow-up.\n- The save-first refusal turn must have **no tool calls**. Do not create a wish, note, reminder, task, or backlog item to remember the blocked contact request. Specifically: never call `system_create` with `entityType: "wish"` for an agent-contact request, and never create any other fallback entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add/save/unarchive it.\n\n### Affirmative follow-up after save-first refusal\n- If a recent user message named exactly one unsaved agent domain/URL and you told them to add/save it first, treat a short affirmative follow-up like `yes`, `yes please`, `please do`, `go ahead`, `do that`, or `save it` as consent to save that same agent immediately with `system_create({ entityType: "agent", url: "that-domain" })`. The trigger is the user\'s prior reference to the domain, not whether your refusal echoed it back.\n- A bare affirmative follow-up is enough. For example, after `Can you talk to save-first-followup.example for me?` and your save-first refusal, `Yes please` means call `system_create({ entityType: "agent", url: "save-first-followup.example" })` immediately.\n- Do **not** repeat the save-first instruction, ask for a description, ask for the domain again, or return an empty response after such an affirmative follow-up; just call `system_create`.\n\n### Examples\n- User: "Ask https://unknown-agent.io about X" \u2192 do **not** call `a2a_call` and do **not** call `system_create` for a wish. Tell them to add/save `unknown-agent.io` first.\n- User: "Can you message this agent URL for me: https://unknown-agent.io/a2a?" \u2192 do **not** create a wish. Tell them the agent must be saved first.\n- User: "Ask Brain about X" with both `yeehaa.io` and `brain-labs.io` saved as "Brain" \u2192 ask the user to choose between those two saved ids and do not call `a2a_call`.'}aA();Ew();WA();import{jsxDEV as ZL1}from"preact/jsx-dev-runtime";function f9A(A){try{return new URL(A).hostname}catch{return A}}var I9A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return ZL1("div",{className:`flex items-center justify-center rounded-full text-white font-bold flex-shrink-0 ${Q}`,style:{backgroundColor:`hsl(${$}, 55%, 45%)`},children:B},void 0,!1,void 0,this)},D9A=({kind:A,size:Q="md"})=>{let w={professional:"bg-status-success text-status-success",team:"bg-status-info text-status-info",collective:"bg-brand/10 text-brand"}[A]??"bg-status-neutral text-status-neutral";return ZL1("span",{className:`inline-flex items-center rounded-full font-medium ${Q==="sm"?"px-2 py-0.5 text-xs":"px-2.5 py-0.5 text-[13px]"} ${w}`,children:A},void 0,!1,void 0,this)};import{jsxDEV as L2,Fragment as vkQ}from"preact/jsx-dev-runtime";var jkQ=({skills:A})=>{if(A.length===0)return null;return L2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>L2("span",{className:"text-[11px] px-2 py-0.5 bg-theme-subtle rounded-md text-theme-muted",children:Q.name},Q.name,!1,void 0,this))},void 0,!1,void 0,this)};function _kQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function NL1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var umA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return L2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[L2(I9A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),L2("div",{className:"flex-1 min-w-0",children:[L2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[L2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),L2(D9A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&L2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&L2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&L2(jkQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[L2("span",{className:"text-xs text-theme-muted",children:f9A(Q.url)},void 0,!1,void 0,this),L2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${_kQ(Q.discoveredAt)}`:"Discovered \xB7 approve before calling"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},zL1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((G)=>G.frontmatter.status==="approved"),Y=A.filter((G)=>G.frontmatter.status==="discovered"),U=D.length,J=Y.length,X=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return L2(vkQ,{children:[L2(KQ,{title:f,description:X},void 0,!1,void 0,this),L2("div",{className:"agent-list bg-theme",children:L2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[L2("div",{className:"mb-8 pb-6 border-b border-theme",children:[L2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),L2("p",{className:"text-theme-muted mb-4",children:X},void 0,!1,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[U," approved"]},void 0,!0,void 0,this),L2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[J," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-wrap gap-2 text-sm",children:[L2("a",{href:w,className:`px-3 py-1 rounded-full border transition-colors ${$==="all"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"All"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=approved`,className:`px-3 py-1 rounded-full border transition-colors ${$==="approved"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Approved"},void 0,!1,void 0,this),L2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&L2("section",{className:"mb-10",children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:D.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("div",{children:[L2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),L2("p",{className:"text-sm text-theme-muted",children:"Review and approve these before calling them."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:Y.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&L2("section",{children:[L2("div",{className:"flex items-center justify-between mb-4",children:[L2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L2("div",{className:"flex flex-col gap-4",children:A.map((G)=>L2(umA,{agent:G},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&L2("p",{className:"text-center text-theme-muted py-16",children:"No agents in your directory yet."},void 0,!1,void 0,this),B&&B.totalPages>1&&$==="all"&&L2("div",{className:"mt-12",children:L2(VF,{currentPage:B.currentPage,totalPages:B.totalPages,baseUrl:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),B&&B.totalPages>1&&$!=="all"&&L2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?L2("a",{href:NL1(w,$,B.currentPage-1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"\u2190 Prev"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"\u2190 Prev"},void 0,!1,void 0,this),L2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?L2("a",{href:NL1(w,$,B.currentPage+1),className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted hover:text-heading transition-colors",children:"Next \u2192"},void 0,!1,void 0,this):L2("span",{className:"px-3 py-2 rounded-md border border-theme text-sm text-theme-muted opacity-50",children:"Next \u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as X2,Fragment as SkQ}from"preact/jsx-dev-runtime";function TkQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Hr=({children:A})=>X2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),ykQ=({skill:A})=>X2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[X2("div",{className:"flex-1",children:[X2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),X2("div",{className:"text-[13px] text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.tags.length>0&&X2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>X2("span",{className:"text-[11px] px-2 py-0.5 bg-theme rounded-md text-theme-muted",children:Q},Q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xkQ=({label:A,value:Q,valueClassName:B})=>X2("div",{className:"flex justify-between text-[13px]",children:[X2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),X2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),qL1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=f9A(w.url),Y=w.status==="approved";return X2(SkQ,{children:[X2(KQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),X2("article",{className:"agent-detail",children:X2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[X2("a",{href:"/agents",className:"text-sm text-theme-muted hover:text-brand transition-colors mb-6 inline-block",children:"\u2190 Back to Directory"},void 0,!1,void 0,this),X2("div",{className:"flex items-start gap-6 mb-8",children:[X2(I9A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),X2("div",{children:[X2("div",{className:"flex items-center gap-3 mb-1",children:[X2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),X2(D9A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),X2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&X2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&X2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),X2("span",{className:"text-sm",children:["Discovered ",TkQ(w.discoveredAt)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&X2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[X2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),X2("p",{className:"text-sm text-theme-muted",children:"This brain is discovered but not approved yet, so it cannot be called until you approve it."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2("div",{className:"flex flex-col md:flex-row gap-12",children:[X2("div",{className:"flex-[2] min-w-0",children:[$&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"About"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"Skills"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-2.5",children:f.map((U)=>X2(ykQ,{skill:U},U.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&X2("section",{className:"mb-8",children:[X2(Hr,{children:"Notes"},void 0,!1,void 0,this),X2("p",{className:"text-[15px] text-theme leading-relaxed",children:I},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[X2("section",{className:"mb-8",children:[X2(Hr,{children:"Brain"},void 0,!1,void 0,this),X2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[X2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&X2("div",{className:"text-xs text-theme-muted font-mono",children:w.did},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("section",{className:"mb-8",children:[X2(Hr,{children:"Connection"},void 0,!1,void 0,this),X2("div",{className:"flex flex-col gap-3",children:[X2("div",{children:[X2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),X2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X2(xkQ,{label:"Status",value:w.status==="approved"?"Approved":"Discovered",valueClassName:w.status==="approved"?"text-status-success font-medium":"text-theme-muted"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&X2("nav",{className:"mt-12 pt-6 border-t border-theme flex flex-col gap-3 md:flex-row md:items-center md:justify-between",children:[X2("div",{className:"min-h-[1px]",children:Q&&X2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:Q.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X2("div",{className:"min-h-[1px] md:text-right",children:B&&X2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[X2("span",{children:"Next \u2192"},void 0,!1,void 0,this),X2("span",{className:"text-heading font-medium",children:B.frontmatter.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};var gkQ=H.object({agents:H.array(cv),pageTitle:H.string().optional(),pagination:Z7.nullable(),baseUrl:H.string().optional(),selectedStatus:H.union([H.literal("all"),aY])});function LL1(){return{[xmA]:P1({name:xmA,description:"Agent directory list page template",schema:gkQ,dataSourceId:Xr,requiredPermission:"public",layout:{component:zL1}}),[SmA]:P1({name:SmA,description:"Individual agent profile template",schema:H.object({agent:cv,prevAgent:cv.nullable(),nextAgent:cv.nullable()}),dataSourceId:Xr,requiredPermission:"public",layout:{component:qL1}})}}var Y9A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.122",description:"Agent discovery \u2014 brain+anchor contacts and skills",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var mkQ=new df;class cmA extends jQ{entityType=a9;schema=uv;adapter=mkQ;constructor(){super(cq1,Y9A)}interceptCreate(A,Q,B){return IL1(A,Q,B,this.id)}createGenerationHandler(A){return new gmA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return LL1()}getDataSources(){return[new Q9A(this.logger.child("AgentDataSource"))]}async onRegister(A){KL1(A),HL1(A,this.id)}async getInstructions(){return FL1()}}function lmA(){return new cmA}aA();WA();aA();var lv=RI,VL1=RI,Gr=A2.extend({entityType:H.literal(o6),metadata:VL1});aA();class pv extends q2{constructor(){super({entityType:o6,schema:Gr,frontmatterSchema:lv})}fromMarkdown(A){let Q=this.parseFrontMatter(A,lv);return{content:A,entityType:o6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}aA();WA();var ukQ=H.object({skills:H.array(lv).max(8)}),EL1=P1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:ukQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
8283
8283
 
8284
8284
  Given knowledge domains, CONSOLIDATE related topics into broader skills.
8285
8285
  There should be FEWER skills than topics \u2014 combine related domains.
@@ -8429,9 +8429,9 @@ Context:
8429
8429
  ${JSON.stringify(w,null,2)}
8430
8430
 
8431
8431
  Draft SWOT:
8432
- ${JSON.stringify(B,null,2)}`}function F9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function UjQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class Z9A{logger;context;adapter=new nF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=rmA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await amA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:U}=await this.context.ai.generateObject(await IjQ(this.context,w),dmA),J=dmA.parse(U);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await YjQ(this.context,w,J),H9A);$=H9A.parse(X.object),UjQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:F9A($.strengths),weaknesses:F9A($.weaknesses),opportunities:F9A($.opportunities),threats:F9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as c7}from"preact/jsx-dev-runtime";var N9A=H.object({title:H.string(),detail:H.string().optional()}),JjQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(N9A).default([]),weaknesses:H.array(N9A).default([]),opportunities:H.array(N9A).default([]),threats:H.array(N9A).default([]),derivedAt:H.string()})]);function XjQ({items:A}){if(A.length===0)return c7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return c7("ul",{class:"swot-list",children:A.map((Q)=>c7("li",{class:"swot-item",children:[c7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?c7("span",{children:[" \u2014 ",Q.detail]},void 0,!0,void 0,this):null]},`${Q.title}:${Q.detail??""}`,!0,void 0,this))},void 0,!1,void 0,this)}function z9A({title:A,tone:Q,items:B}){return c7("section",{class:`swot-cell is-${Q}`,children:[c7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),c7(XjQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function AuA({data:A}){let Q=JjQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return c7("div",{"data-swot-widget":!0,children:c7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return c7("div",{"data-swot-widget":!0,children:c7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[c7(z9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),c7(z9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),c7(z9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),c7(z9A,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}WA();var QuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.121",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BuA=new nF;class wuA extends jQ{entityType="swot";schema=iv;adapter=BuA;initialSyncComplete=!1;constructor(){super("swot",QuA)}async onRegister(A){let Q=new Z9A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=M9.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return BuA.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:AuA,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=BuA.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function $uA(){return new wuA}aA();o$();WA();var Uf8=new nF,SL1=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),fuA=H.enum(["discovered","approved"]),HjQ=H.object({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:fuA,discoveredAt:H.string().datetime()}),GjQ=A2.extend({entityType:H.literal("agent"),metadata:H.object({name:H.string(),url:H.string().url(),status:fuA,slug:H.string()})}),KjQ=A2.extend({entityType:H.literal("skill"),metadata:RI}),FjQ=H.object({about:H.string(),skills:H.array(SL1),notes:H.string()});function ZjQ(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
8432
+ ${JSON.stringify(B,null,2)}`}function F9A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function UjQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class Z9A{logger;context;adapter=new nF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=rmA.safeParse(A??{});return Q.success?Q.data:null}async process(A,Q,B){await B.report({progress:0.2,message:"Building SWOT context"});let w=await amA(this.context),$;if(w.summary.brainSkillCount+w.summary.approvedAgentCount+w.summary.discoveredAgentCount===0)$={strengths:[],weaknesses:[],opportunities:[],threats:[]};else{await B.report({progress:0.6,message:"Synthesizing SWOT analysis"});let{object:U}=await this.context.ai.generateObject(await IjQ(this.context,w),dmA),J=dmA.parse(U);await B.report({progress:0.75,message:"Refining SWOT language"});let X=await this.context.ai.generateObject(await YjQ(this.context,w,J),H9A);$=H9A.parse(X.object),UjQ(J,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:F9A($.strengths),weaknesses:F9A($.weaknesses),opportunities:F9A($.opportunities),threats:F9A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}WA();import{jsxDEV as c7}from"preact/jsx-dev-runtime";var N9A=H.object({title:H.string(),detail:H.string().optional()}),JjQ=H.discriminatedUnion("status",[H.object({status:H.literal("generating")}),H.object({status:H.literal("ready"),strengths:H.array(N9A).default([]),weaknesses:H.array(N9A).default([]),opportunities:H.array(N9A).default([]),threats:H.array(N9A).default([]),derivedAt:H.string()})]);function XjQ({items:A}){if(A.length===0)return c7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return c7("ul",{class:"swot-list",children:A.map((Q)=>c7("li",{class:"swot-item",children:[c7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?c7("span",{children:[" \u2014 ",Q.detail]},void 0,!0,void 0,this):null]},`${Q.title}:${Q.detail??""}`,!0,void 0,this))},void 0,!1,void 0,this)}function z9A({title:A,tone:Q,items:B}){return c7("section",{class:`swot-cell is-${Q}`,children:[c7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),c7(XjQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function AuA({data:A}){let Q=JjQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return c7("div",{"data-swot-widget":!0,children:c7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return c7("div",{"data-swot-widget":!0,children:c7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[c7(z9A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),c7(z9A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),c7(z9A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),c7(z9A,{title:"Threats",tone:"t",items:B.threats},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}WA();var QuA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.122",description:"Assessment outputs and capability-profile analysis",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix",eval:"cd evals && bun run brain-eval"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var BuA=new nF;class wuA extends jQ{entityType="swot";schema=iv;adapter=BuA;initialSyncComplete=!1;constructor(){super("swot",QuA)}async onRegister(A){let Q=new Z9A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=M9.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return BuA.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:AuA,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=BuA.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function $uA(){return new wuA}aA();o$();WA();var Uf8=new nF,SL1=H.object({name:H.string(),description:H.string(),tags:H.array(H.string())}),fuA=H.enum(["discovered","approved"]),HjQ=H.object({name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:fuA,discoveredAt:H.string().datetime()}),GjQ=A2.extend({entityType:H.literal("agent"),metadata:H.object({name:H.string(),url:H.string().url(),status:fuA,slug:H.string()})}),KjQ=A2.extend({entityType:H.literal("skill"),metadata:RI}),FjQ=H.object({about:H.string(),skills:H.array(SL1),notes:H.string()});function ZjQ(A){if(!Array.isArray(A)||A.length===0)return"";return A.map((B)=>{let w=B.tags.length>0?` [${B.tags.join(", ")}]`:"";return`- ${B.name}: ${B.description}${w}`}).join(`
8433
8433
  `)}function NjQ(A){if(!A.trim())return[];return A.split(`
8434
- `).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((B)=>B.trim()).filter(Boolean):[]}))}var zjQ=new lB(FjQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:ZjQ,parser:NjQ},{key:"notes",label:"Notes",type:"string"}]});class gL1 extends q2{constructor(){super({entityType:"agent",schema:GjQ,frontmatterSchema:HjQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=zjQ.format({about:A.about,skills:A.skills,notes:A.notes});return this.buildMarkdown(Q,{name:A.name,kind:A.kind,...A.organization?{organization:A.organization}:{},brainName:A.brainName,url:A.url,...A.did?{did:A.did}:{},status:A.status,discoveredAt:A.discoveredAt})}}class hL1 extends q2{constructor(){super({entityType:"skill",schema:KjQ,frontmatterSchema:RI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,RI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Jf8=new gL1,Xf8=new hL1,Wf8=H.object({skills:H.array(RI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:fuA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(SL1),notes:H.string().default("")}))});var qjQ=H.object({}).strict();function q9A(A={}){return qjQ.parse(A),[$uA()]}aA();WA();WA();var IuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function LjQ(A){return A.replace(/\/+$/,"")}var VjQ=(A,Q)=>fetch(A,Q);async function Fr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Zr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=LjQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??VjQ}async createSession(){let A=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.server.createSession`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:this.identifier,password:this.appPassword})}),Q=await Fr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Fr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Fr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Fr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Fr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function VC(A){return A?.startsWith("did:web:")??!1}function L9A(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function uL1(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function cL1(A){return A.replace(/\/+$/,"")}function Nr(A){return`did:web:${encodeURIComponent(A)}`}function V9A(A){return`${Nr(A)}:anchor`}function DuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function lL1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...DuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:cL1(A.pdsEndpoint)}]}}function pL1(A){if(!VC(A.brainDid))return null;return lL1(A,A.brainDid)}function mL1(A,Q){if(!A||!Q)return;let B=L9A(A),w=uL1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function E9A(A){let Q=[],B=mL1(A.brainDid,pL1(A));if(B)Q.push(B);if(VC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=mL1(A.anchorDid,DuA(A.anchorDid));if(w)Q.push(w)}return Q}function YuA(A,Q){let B=[];if(!A.brainDid){let w=Nr(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:lL1(A,w)})}if(!A.anchorDid){let w=V9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:DuA(w)})}return B}function EjQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function MjQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function iL1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function rL1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function CjQ(A){let Q=A.metadata,B=iL1(Q,"name"),w=iL1(Q,"description");if(!B||!w)return;let $=rL1(Q,"tags"),f=rL1(Q,"examples");return{id:MjQ(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function OjQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>CjQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function UuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=EjQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,Y=Q.brainDid??Nr(D),U=Q.anchorDid??V9A(D);if(VC(Y)){if(L9A(Y)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await OjQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:Y,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:U,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var dL1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},RjQ={},nL1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},oL1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},sL1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function aL1(A,Q,B){return[bjQ(A,Q),PjQ(A,Q,B),kjQ(A,Q,B),_jQ(A,Q,B),jjQ(A,Q,B)]}function bjQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:RjQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function PjQ(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:dL1,handler:async(w)=>{let $=H.object(dL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function kjQ(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:nL1,handler:async(w)=>{let $=H.object(nL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function jjQ(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:oL1,handler:async(w)=>{let $=H.object(oL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function _jQ(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:sL1,handler:async(w)=>{let $=H.object(sL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var tL1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.121",description:"AT Protocol integration for identity, publishing, discovery, and feeds",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var eL1=Gw["ai.rizom.brain.card"],TjQ="ai.rizom.brain.card",yjQ="self",AV1=50;class JuA extends UB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",tL1,A,IuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??d6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=E9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...E9A(this.config),...YuA(this.config,f)].filter((Y)=>Y.path===w),D=I.find((Y)=>Y.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await UuA(A,this.config);Tz(eL1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let Y=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:Y.uri,cid:Y.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>AV1)throw Error(`AT Protocol discovery accepts at most ${AV1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let Y=await D.getRecord({repo:I.repoDid,collection:TjQ,rkey:yjQ});Tz(eL1,Y.value);let U=SjQ(Y.uri)??I.repoDid,J=`${U}:${Y.uri}:${Y.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:U,uri:Y.uri,cid:Y.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:f5A,payload:{repoDid:U,uri:Y.uri,cid:Y.cid,record:Y.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:U,uri:Y.uri,cid:Y.cid})}catch(I){$.push({repo:f,status:"skipped",error:T0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:T0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return aL1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return Tz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),Y=await D.createSession(),U=f??Y.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(Tz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:U,collection:B.collection,rkey:xjQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:U,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Zr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(gjQ(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Zr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function xjQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function SjQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function gjQ(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function M9A(A,Q){return new JuA(A,Q)}aA();WA();Ew();f5();WA();aA();var C9A=Ws.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),ez=lU.extend(C9A.shape);aA();nG();WA();var hjQ=new wW;class O9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([gR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),ep(w)]),Y=hjQ.parseProfileBody($,ez),U=f.sort(cy).slice(0,3).map(Bi),J=I.sort(cy).slice(0,3).map(Yi);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:Y,posts:U,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();nG();var mjQ=new wW;class R9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await gR(B.entityService),f={profile:mjQ.parseProfileBody(w,ez)};return Q.parse(f)}}import{jsxDEV as w8,Fragment as ljQ}from"preact/jsx-dev-runtime";var ujQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",cjQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",XuA=({number:A,title:Q,blurb:B,children:w})=>w8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:w8("div",{className:"max-w-6xl mx-auto",children:w8("div",{className:ujQ,children:[w8(TTA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),w8("div",{className:cjQ,"aria-hidden":"true"},void 0,!1,void 0,this),w8("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),WuA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),U=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return w8(ljQ,{children:[w8(KQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),w8("div",{className:"homepage-list bg-theme",children:[w8("header",{className:"hero-bg-pattern relative w-full px-6 md:px-12 pt-28 pb-24 md:pt-28 md:pb-24 overflow-hidden border-b border-rule",children:w8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&w8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[w8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),w8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&w8("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:z8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&w8("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:z8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(XuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:w8(N8A,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),U.length>0&&w8(XuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:w8(N8A,{items:U,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&w8(XuA,{number:"03",title:"About",blurb:I.about?.blurb,children:w8("div",{className:"flex flex-col gap-8",children:[A.description&&w8("p",{className:"font-heading font-light text-[1.25rem] leading-[1.55] text-theme max-w-[55ch] [font-variation-settings:'opsz'_24,'SOFT'_50]",children:A.description},void 0,!1,void 0,this),A.expertise&&A.expertise.length>0&&w8(yTA,{subjects:A.expertise},void 0,!1,void 0,this),w8("a",{href:"/about",className:"mt-6 inline-flex items-center gap-2 font-mono text-[0.7rem] font-medium uppercase tracking-[0.18em] text-accent pb-1 relative before:content-[''] before:absolute before:left-0 before:right-full before:bottom-0 before:h-px before:bg-accent before:transition-[right] before:duration-300 hover:before:right-0",children:["Learn more",w8("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(zTA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Fw,Fragment as pjQ}from"preact/jsx-dev-runtime";var HuA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return Fw(pjQ,{children:[Fw(KQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Fw("div",{className:"about-page bg-theme",children:[Fw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Fw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Fw("h1",{className:"text-5xl md:text-6xl font-semibold mb-6 text-heading",children:["About ",A.name||"Me"]},void 0,!0,void 0,this),A.description&&Fw("p",{className:"text-xl md:text-2xl text-theme-muted leading-relaxed",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Fw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Fw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Fw(V$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Fw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Fw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Fw("li",{className:Qp({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Fw("p",{className:"text-lg text-theme leading-relaxed",children:A.currentFocus},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.availability&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Fw("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(A.email||A.website||A.socialLinks&&A.socialLinks.length>0)&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Fw("div",{className:"space-y-4",children:[A.email&&Fw("p",{className:"text-lg",children:Fw("a",{href:`mailto:${A.email}`,className:"text-brand hover:text-brand-dark transition-colors",children:A.email},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.website&&Fw("p",{className:"text-lg",children:Fw("a",{href:A.website,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:A.website},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.socialLinks&&A.socialLinks.length>0&&Fw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Fw(L$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l7,Fragment as QV1}from"preact/jsx-dev-runtime";var GuA=()=>{return l7(QV1,{children:[l7(KQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),l7("p",{className:"text-lg text-theme-muted mb-8",children:"You'll receive a confirmation email shortly. Check your inbox to confirm your subscription."},void 0,!1,void 0,this),l7(L$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},KuA=()=>{return l7(QV1,{children:[l7(KQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),l7("p",{className:"text-lg text-theme-muted mb-8",children:"We couldn't process your subscription. Please try again or contact us if the problem persists."},void 0,!1,void 0,this),l7(L$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();var BV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),wV1=H.object({entityDisplay:H.object({post:BV1,deck:BV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var $V1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.121",description:"Professional site composition package",type:"module",exports:{".":"./src/index.ts"},files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/identity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class FuA extends UB{dependencies=["blog","decks"];constructor(A){super("professional-site",$V1,A,wV1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",C9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new O9A(w,$);A.entities.registerDataSource(f);let I=new R9A;A.entities.registerDataSource(I);let D=H.object({profile:ez,posts:H.array(SF),decks:H.array(wC),postsListUrl:H.string(),decksListUrl:H.string(),cta:QSA,sections:H.record(H.string(),zo)}),Y=H.object({profile:ez}),U=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:WuA}}),about:P1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:HuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:U,requiredPermission:"public",layout:{component:GuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:U,requiredPermission:"public",layout:{component:KuA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function fV1(A){return new FuA(A??{})}var IV1=[{id:"home",path:"/",title:"Home",description:"Professional site homepage",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"homepage",template:"professional-site:homepage-list",dataQuery:{}}]},{id:"about",path:"/about",title:"About",description:"About page",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:90},sections:[{id:"about",template:"professional-site:about",dataQuery:{}}]},{id:"subscribe-thanks",path:"/subscribe/thanks",title:"Thanks for subscribing",description:"Newsletter subscription confirmation",layout:"default",navigation:{show:!1},sections:[{id:"subscribe-thanks",template:"professional-site:subscribe-thanks",dataQuery:{},content:{}}]},{id:"subscribe-error",path:"/subscribe/error",title:"Subscription failed",description:"Newsletter subscription error",layout:"default",navigation:{show:!1},sections:[{id:"subscribe-error",template:"professional-site:subscribe-error",dataQuery:{},content:{}}]}];import{jsxDEV as b9A}from"preact/jsx-dev-runtime";function DV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return b9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[b9A(ETA,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...w!==void 0?{wordmark:w}:{}},void 0,!1,void 0,this),b9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),b9A(LTA,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:B?.getSlot("footer-top").map(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var rjQ={layouts:{default:DV1},routes:IV1,plugin:fV1,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},zr=rjQ;var YV1=`/*
8434
+ `).map((Q)=>Q.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/)).filter((Q)=>Q!==null).map((Q)=>({name:Q[1]??"",description:Q[2]??"",tags:Q[3]?Q[3].split(",").map((B)=>B.trim()).filter(Boolean):[]}))}var zjQ=new lB(FjQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:ZjQ,parser:NjQ},{key:"notes",label:"Notes",type:"string"}]});class gL1 extends q2{constructor(){super({entityType:"agent",schema:GjQ,frontmatterSchema:HjQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=zjQ.format({about:A.about,skills:A.skills,notes:A.notes});return this.buildMarkdown(Q,{name:A.name,kind:A.kind,...A.organization?{organization:A.organization}:{},brainName:A.brainName,url:A.url,...A.did?{did:A.did}:{},status:A.status,discoveredAt:A.discoveredAt})}}class hL1 extends q2{constructor(){super({entityType:"skill",schema:KjQ,frontmatterSchema:RI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,RI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Jf8=new gL1,Xf8=new hL1,Wf8=H.object({skills:H.array(RI),agents:H.array(H.object({id:H.string().optional(),name:H.string(),kind:H.enum(["professional","team","collective"]),organization:H.string().optional(),brainName:H.string(),url:H.string().url(),did:H.string().optional(),status:fuA,discoveredAt:H.string().datetime().optional(),about:H.string(),skills:H.array(SL1),notes:H.string().default("")}))});var qjQ=H.object({}).strict();function q9A(A={}){return qjQ.parse(A),[$uA()]}aA();WA();WA();var IuA=H.object({enabled:H.boolean().default(!0),pdsEndpoint:H.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:H.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:H.string().optional().describe("DID of the PDS repo that owns records"),appPassword:H.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:H.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:H.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function LjQ(A){return A.replace(/\/+$/,"")}var VjQ=(A,Q)=>fetch(A,Q);async function Fr(A){let Q=await A.json();if(!A.ok){let B=typeof Q==="object"&&Q!==null&&"message"in Q&&typeof Q.message==="string"?Q.message:`AT Protocol request failed with ${A.status}`;throw Error(B)}return Q}class Zr{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=LjQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??VjQ}async createSession(){let A=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.server.createSession`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({identifier:this.identifier,password:this.appPassword})}),Q=await Fr(A);return this.session=Q,Q}async createRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.createRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,...A.rkey&&{rkey:A.rkey},...A.validate!==void 0&&{validate:A.validate}})});return Fr(B)}async putRecord(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.putRecord`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":"application/json"},body:JSON.stringify({repo:A.repo,collection:A.collection,record:A.record,rkey:A.rkey,...A.validate!==void 0&&{validate:A.validate},...A.swapRecord!==void 0&&{swapRecord:A.swapRecord}})});return Fr(B)}async getRecord(A){let Q=new URLSearchParams({repo:A.repo,collection:A.collection,rkey:A.rkey}),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.getRecord?${Q.toString()}`,{method:"GET"});return Fr(B)}async uploadBlob(A){let Q=await this.getSession(),B=await this.fetchFn(`${this.pdsEndpoint}/xrpc/com.atproto.repo.uploadBlob`,{method:"POST",headers:{Authorization:`Bearer ${Q.accessJwt}`,"Content-Type":A.mimeType},body:new Blob([new Uint8Array(A.data)],{type:A.mimeType})});return Fr(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function VC(A){return A?.startsWith("did:web:")??!1}function L9A(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[B]=Q.split(":");if(!B)return;try{return decodeURIComponent(B)}catch{return B}}function uL1(A){if(!VC(A))return;let Q=A.slice(8);if(!Q)return;let[,...B]=Q.split(":");if(B.length===0)return"/.well-known/did.json";return`/${B.map(($)=>{try{return decodeURIComponent($)}catch{return $}}).join("/")}/did.json`}function cL1(A){return A.replace(/\/+$/,"")}function Nr(A){return`did:web:${encodeURIComponent(A)}`}function V9A(A){return`${Nr(A)}:anchor`}function DuA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function lL1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...DuA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:cL1(A.pdsEndpoint)}]}}function pL1(A){if(!VC(A.brainDid))return null;return lL1(A,A.brainDid)}function mL1(A,Q){if(!A||!Q)return;let B=L9A(A),w=uL1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function E9A(A){let Q=[],B=mL1(A.brainDid,pL1(A));if(B)Q.push(B);if(VC(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=mL1(A.anchorDid,DuA(A.anchorDid));if(w)Q.push(w)}return Q}function YuA(A,Q){let B=[];if(!A.brainDid){let w=Nr(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:lL1(A,w)})}if(!A.anchorDid){let w=V9A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:DuA(w)})}return B}function EjQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function MjQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function iL1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function rL1(A,Q){let B=A[Q];if(!Array.isArray(B))return;let w=B.filter(($)=>typeof $==="string"&&$.length>0);return w.length>0?w:void 0}function CjQ(A){let Q=A.metadata,B=iL1(Q,"name"),w=iL1(Q,"description");if(!B||!w)return;let $=rL1(Q,"tags"),f=rL1(Q,"examples");return{id:MjQ(B),name:B,description:w,...$&&{tags:$},...f&&{examples:f}}}async function OjQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>CjQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function UuA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),f=await A.identity.getAppInfo(),I=EjQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let D=new URL(I).hostname,Y=Q.brainDid??Nr(D),U=Q.anchorDid??V9A(D);if(VC(Y)){if(L9A(Y)!==D)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let J=await OjQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:Y,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:U,name:$.name,kind:$.kind},skills:J,model:f.model,version:f.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}WA();var dL1={dryRun:H.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},RjQ={},nL1={entityType:H.string().describe("Local entity type with a registered AT Protocol projection"),entityId:H.string().optional().describe("Local entity ID to publish"),slug:H.string().optional().describe("Local entity slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},oL1={repos:H.array(H.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},sL1={entityId:H.string().optional().describe("Local blog post entity ID to publish"),slug:H.string().optional().describe("Local blog post slug to publish"),dryRun:H.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:H.array(H.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function aL1(A,Q,B){return[bjQ(A,Q),PjQ(A,Q,B),kjQ(A,Q,B),_jQ(A,Q,B),jjQ(A,Q,B)]}function bjQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:RjQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function PjQ(A,Q,B){return{name:`${A}_publish_card`,description:"Publish this brain's AT Protocol discovery card to the configured PDS, or dry-run the record payload.",inputSchema:dL1,handler:async(w)=>{let $=H.object(dL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.publishBrainCard(B,{dryRun:$.data.dryRun})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function kjQ(A,Q,B){return{name:`${A}_publish_entity`,description:"Publish any public local entity with a registered AT Protocol projection, or dry-run the record payload.",inputSchema:nL1,handler:async(w)=>{let $=H.object(nL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishEntity(B,{entityType:$.data.entityType,...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}function jjQ(A,Q,B){return{name:`${A}_discover_brain_cards`,description:"Read public ai.rizom.brain.card/self records from candidate AT Protocol repo DIDs or handles and emit internal discovery events.",inputSchema:oL1,handler:async(w)=>{let $=H.object(oL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{return{success:!0,data:await Q.discoverBrainCards(B,{repos:$.data.repos})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Discovery failed"}}}}}function _jQ(A,Q,B){return{name:`${A}_publish_post`,description:"Publish a local blog post entity as an ai.rizom.brain.post AT Protocol record, or dry-run the record payload.",inputSchema:sL1,handler:async(w)=>{let $=H.object(sL1).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};try{if(!$.data.entityId&&!$.data.slug)return{success:!1,error:"Invalid input: entityId or slug is required"};return{success:!0,data:await Q.publishPost(B,{...$.data.entityId&&{entityId:$.data.entityId},...$.data.slug&&{slug:$.data.slug},dryRun:$.data.dryRun,...$.data.topics&&{topics:$.data.topics}})}}catch(f){return{success:!1,error:f instanceof Error?f.message:"Publish failed"}}}}}var tL1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.122",description:"AT Protocol integration for identity, publishing, discovery, and feeds",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var eL1=Gw["ai.rizom.brain.card"],TjQ="ai.rizom.brain.card",yjQ="self",AV1=50;class JuA extends UB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",tL1,A,IuA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??d6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=E9A(this.config),Q=[...!this.config.brainDid?["/.well-known/did.json"]:[],...!this.config.anchorDid?["/anchor/did.json"]:[]];return[...new Set([...A.map((w)=>w.path),...Q])].map((w)=>({path:w,method:"GET",public:!0,handler:($)=>{let f=new URL($.url).hostname,I=[...E9A(this.config),...YuA(this.config,f)].filter((Y)=>Y.path===w),D=I.find((Y)=>Y.hostname===f)??I[0];if(!D)return new Response("Not found",{status:404});return new Response(JSON.stringify(D.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await UuA(A,this.config);Tz(eL1,B);let w=this.config.repoDid;if(Q.dryRun)return{record:B,dryRun:!0,...w&&{repo:w}};let $=this.resolveAppPassword();if(!this.config.identifier||!$)throw Error("AT Protocol publishing requires identifier and app password configuration");let f=this.createPdsClient($),I=await f.createSession(),D=w??I.did;if(!f.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let Y=await f.putRecord({repo:D,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:D,uri:Y.uri,cid:Y.cid,dryRun:!1}}async publishEntity(A,Q){let B=this.projectionRegistry.get(Q.entityType);if(!B)throw Error(`No AT Protocol projection registered for ${Q.entityType}`);return this.publishProjectedEntity(A,Q,B)}async publishPost(A,Q){let B=this.projectionRegistry.get("post");if(!B)throw Error("No AT Protocol projection registered for post");return this.publishProjectedEntity(A,{entityType:"post",...Q},B)}async discoverBrainCards(A,Q){let B=[...new Set(Q.repos.map((f)=>f.trim()))].filter((f)=>f.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>AV1)throw Error(`AT Protocol discovery accepts at most ${AV1} repos per batch`);let w=new Set,$=[];for(let f of B)try{let I=await this.resolveRepoPdsEndpoint(f),D=this.createPublicPdsClient(I.pdsEndpoint);if(!D.getRecord)throw Error("AT Protocol PDS client does not support record reads");let Y=await D.getRecord({repo:I.repoDid,collection:TjQ,rkey:yjQ});Tz(eL1,Y.value);let U=SjQ(Y.uri)??I.repoDid,J=`${U}:${Y.uri}:${Y.cid}`;if(w.has(J)){$.push({repo:f,status:"skipped",repoDid:U,uri:Y.uri,cid:Y.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(J),await A.messaging.send({type:f5A,payload:{repoDid:U,uri:Y.uri,cid:Y.cid,record:Y.value},broadcast:!0}),$.push({repo:f,status:"discovered",repoDid:U,uri:Y.uri,cid:Y.cid})}catch(I){$.push({repo:f,status:"skipped",error:T0(I)})}return{discovered:$.filter((f)=>f.status==="discovered").length,skipped:$.filter((f)=>f.status==="skipped").length,results:$}}async validatePdsCredentials(){let A=this.resolveAppPassword();if(!this.config.identifier||!A)return!1;try{return await this.createPdsClient(A).createSession(),!0}catch(Q){return this.logger.warn("AT Protocol PDS authentication failed",{error:T0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return aL1(this.id,this,this.getContext())}async getInstructions(){if(!this.config.enabled)return;return"## AT Protocol publishing\n- Use `atproto_validate_credentials` to check PDS credentials before publishing.\n- Use `atproto_publish_card` to publish or dry-run this brain's public discovery card.\n- Use `atproto_publish_entity` to publish any public entity with a registered AT Protocol projection.\n- Use `atproto_publish_post` for the blog-post convenience path by `entityId` or `slug`.\n- Use `atproto_discover_brain_cards` to read public `ai.rizom.brain.card/self` records from candidate repo DIDs or handles and emit internal discovery events.\n- Prefer `dryRun: true` first when publishing new AT Protocol records.\n- Only public posts and public cover images can be published."}async publishProjectedEntity(A,Q,B){let w=await this.findPublishEntity(A,Q),$=Q.entityId??Q.slug;if(!$)throw Error(`${Q.entityType} publish requires entityId or slug`);if(!w)throw Error(`${Q.entityType} not found: ${$}`);if(w.visibility!=="public")throw Error(`Cannot publish non-public ${Q.entityType}: ${$}`);let f=this.config.repoDid;if(Q.dryRun){let G=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return Tz(B.lexicon,G),{record:G,dryRun:!0,...f&&{repo:f}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let D=this.createPdsClient(I),Y=await D.createSession(),U=f??Y.did,J=await B.buildRecord({entity:w,context:A,config:this.config,client:D,...Q.topics&&{topics:Q.topics}});if(Tz(B.lexicon,J),!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:U,collection:B.collection,rkey:xjQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:J});return await B.onPublished?.({entity:w,context:A,record:J,uri:X.uri,cid:X.cid}),{record:J,repo:U,uri:X.uri,cid:X.cid,dryRun:!1}}async findPublishEntity(A,Q){if(Q.entityId)return A.entityService.getEntity({entityType:Q.entityType,id:Q.entityId});if(Q.slug)return(await A.entityService.listEntities({entityType:Q.entityType,options:{filter:{metadata:{slug:Q.slug}}}}))[0]??null;return null}createPublicPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""});return new Zr({pdsEndpoint:A,identifier:this.config.identifier??"",appPassword:this.config.appPassword??""})}async resolveRepoPdsEndpoint(A){let Q=A.startsWith("did:")?A:await this.resolveHandleToDid(A);if(!Q)throw Error(`Could not resolve AT Protocol repo: ${A}`);let B=await this.resolveDidToPdsEndpoint(Q);if(!B)throw Error(`Could not resolve AT Protocol PDS for repo: ${Q}`);return{repoDid:Q,pdsEndpoint:B}}async resolveHandleToDid(A){let Q=new URL("/xrpc/com.atproto.identity.resolveHandle",this.config.pdsEndpoint);Q.searchParams.set("handle",A);let B=await this.fetch(Q.toString());if(!B.ok)return;let w=await B.json();if(typeof w!=="object"||w===null||!("did"in w))return;return typeof w.did==="string"?w.did:void 0}async resolveDidToPdsEndpoint(A){let Q=A.startsWith("did:plc:")?await this.fetchJson(`https://plc.directory/${encodeURIComponent(A)}`):A.startsWith("did:web:")?await this.fetchJson(gjQ(A)):void 0;if(typeof Q!=="object"||Q===null)return;let B=Q.service;if(!Array.isArray(B))return;let w=B.find(($)=>{return typeof $==="object"&&$!==null&&($.id==="#atproto_pds"||$.type==="AtprotoPersonalDataServer")});return typeof w?.serviceEndpoint==="string"?w.serviceEndpoint:void 0}async fetchJson(A){let Q=await this.fetch(A);if(!Q.ok)return;return Q.json()}fetch(A){return(this.deps.fetch??fetch)(A)}createPdsClient(A){if(this.deps.createPdsClient)return this.deps.createPdsClient({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A});return new Zr({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function xjQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function SjQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function gjQ(A){let Q=A.slice(8).split(":").map(decodeURIComponent),[B,...w]=Q;if(!B)throw Error(`Invalid did:web value: ${A}`);if(w.length===0)return`https://${B}/.well-known/did.json`;return`https://${B}/${w.join("/")}/did.json`}function M9A(A,Q){return new JuA(A,Q)}aA();WA();Ew();f5();WA();aA();var C9A=Ws.extend({expertise:H.array(H.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:H.string().optional().describe("What you're currently working on"),availability:H.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),ez=lU.extend(C9A.shape);aA();nG();WA();var hjQ=new wW;class O9A{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([gR(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),ep(w)]),Y=hjQ.parseProfileBody($,ez),U=f.sort(cy).slice(0,3).map(Bi),J=I.sort(cy).slice(0,3).map(Yi);if(!D.cta)throw Error("CTA not configured in site-info");let X={profile:Y,posts:U,decks:J,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(X)}}aA();nG();var mjQ=new wW;class R9A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await gR(B.entityService),f={profile:mjQ.parseProfileBody(w,ez)};return Q.parse(f)}}import{jsxDEV as w8,Fragment as ljQ}from"preact/jsx-dev-runtime";var ujQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",cjQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",XuA=({number:A,title:Q,blurb:B,children:w})=>w8("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:w8("div",{className:"max-w-6xl mx-auto",children:w8("div",{className:ujQ,children:[w8(TTA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),w8("div",{className:cjQ,"aria-hidden":"true"},void 0,!1,void 0,this),w8("div",{className:"mt-6 md:mt-0",children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),WuA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),U=B.map((Z)=>({id:Z.id,url:Z.url,title:Z.frontmatter.title||Z.id,date:Z.frontmatter.publishedAt??Z.created,description:Z.frontmatter.description})),J=A.name||"Home",X=A.intro||A.description||D||"Professional site",G=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return w8(ljQ,{children:[w8(KQ,{title:J,description:X,ogType:"website"},void 0,!1,void 0,this),w8("div",{className:"homepage-list bg-theme",children:[w8("header",{className:"hero-bg-pattern relative w-full px-6 md:px-12 pt-28 pb-24 md:pt-28 md:pb-24 overflow-hidden border-b border-rule",children:w8("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&w8("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[w8("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),w8("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&w8("h1",{className:"font-heading text-[clamp(2.75rem,6.5vw,5.5rem)] font-normal text-heading leading-[1.02] tracking-[-0.025em] max-w-[18ch] [font-variation-settings:'opsz'_144,'SOFT'_30]",children:z8A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&w8("p",{className:"font-heading font-light text-[clamp(1.1rem,1.8vw,1.4rem)] leading-[1.5] text-theme-muted max-w-[42ch] mt-8 [font-variation-settings:'opsz'_24]",children:z8A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(XuA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:w8(N8A,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),U.length>0&&w8(XuA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:w8(N8A,{items:U,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&w8(XuA,{number:"03",title:"About",blurb:I.about?.blurb,children:w8("div",{className:"flex flex-col gap-8",children:[A.description&&w8("p",{className:"font-heading font-light text-[1.25rem] leading-[1.55] text-theme max-w-[55ch] [font-variation-settings:'opsz'_24,'SOFT'_50]",children:A.description},void 0,!1,void 0,this),A.expertise&&A.expertise.length>0&&w8(yTA,{subjects:A.expertise},void 0,!1,void 0,this),w8("a",{href:"/about",className:"mt-6 inline-flex items-center gap-2 font-mono text-[0.7rem] font-medium uppercase tracking-[0.18em] text-accent pb-1 relative before:content-[''] before:absolute before:left-0 before:right-full before:bottom-0 before:h-px before:bg-accent before:transition-[right] before:duration-300 hover:before:right-0",children:["Learn more",w8("span",{"aria-hidden":"true",children:"\u2192"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w8(zTA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Fw,Fragment as pjQ}from"preact/jsx-dev-runtime";var HuA=({profile:A})=>{let Q=`About ${A.name||"Me"}`,B=A.description||A.intro||"About page",w=A.expertise&&A.expertise.length>0||A.currentFocus||A.availability||A.email||A.website||A.socialLinks&&A.socialLinks.length>0;return Fw(pjQ,{children:[Fw(KQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Fw("div",{className:"about-page bg-theme",children:[Fw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Fw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Fw("h1",{className:"text-5xl md:text-6xl font-semibold mb-6 text-heading",children:["About ",A.name||"Me"]},void 0,!0,void 0,this),A.description&&Fw("p",{className:"text-xl md:text-2xl text-theme-muted leading-relaxed",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Fw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Fw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Fw(V$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Fw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Fw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Fw("li",{className:Qp({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Fw("p",{className:"text-lg text-theme leading-relaxed",children:A.currentFocus},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.availability&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Fw("p",{className:"text-lg text-theme leading-relaxed",children:A.availability},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(A.email||A.website||A.socialLinks&&A.socialLinks.length>0)&&Fw("section",{children:[Fw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Fw("div",{className:"space-y-4",children:[A.email&&Fw("p",{className:"text-lg",children:Fw("a",{href:`mailto:${A.email}`,className:"text-brand hover:text-brand-dark transition-colors",children:A.email},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.website&&Fw("p",{className:"text-lg",children:Fw("a",{href:A.website,target:"_blank",rel:"noopener noreferrer",className:"text-brand hover:text-brand-dark transition-colors",children:A.website},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.socialLinks&&A.socialLinks.length>0&&Fw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Fw(L$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l7,Fragment as QV1}from"preact/jsx-dev-runtime";var GuA=()=>{return l7(QV1,{children:[l7(KQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),l7("p",{className:"text-lg text-theme-muted mb-8",children:"You'll receive a confirmation email shortly. Check your inbox to confirm your subscription."},void 0,!1,void 0,this),l7(L$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},KuA=()=>{return l7(QV1,{children:[l7(KQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),l7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:l7("div",{className:"text-center max-w-md",children:[l7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),l7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),l7("p",{className:"text-lg text-theme-muted mb-8",children:"We couldn't process your subscription. Please try again or contact us if the problem persists."},void 0,!1,void 0,this),l7(L$,{href:"/",variant:"primary",children:"Back to Home"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};WA();var BV1=H.object({label:H.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:H.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),wV1=H.object({entityDisplay:H.object({post:BV1,deck:BV1}).describe("Display metadata for post and deck entity types (required for homepage)")});var $V1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.122",description:"Professional site composition package",type:"module",exports:{".":"./src/index.ts"},files:["src"],scripts:{typecheck:"tsc --noEmit",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/blog":"workspace:*","@brains/decks":"workspace:*","@brains/identity-service":"workspace:*","@brains/plugins":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-engine":"workspace:*","@brains/site-info":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class FuA extends UB{dependencies=["blog","decks"];constructor(A){super("professional-site",$V1,A,wV1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",C9A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new O9A(w,$);A.entities.registerDataSource(f);let I=new R9A;A.entities.registerDataSource(I);let D=H.object({profile:ez,posts:H.array(SF),decks:H.array(wC),postsListUrl:H.string(),decksListUrl:H.string(),cta:QSA,sections:H.record(H.string(),zo)}),Y=H.object({profile:ez}),U=H.object({});A.templates.register({"homepage-list":P1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:WuA}}),about:P1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:HuA}}),"subscribe-thanks":P1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:U,requiredPermission:"public",layout:{component:GuA}}),"subscribe-error":P1({name:"subscribe-error",description:"Newsletter subscription error page",schema:U,requiredPermission:"public",layout:{component:KuA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function fV1(A){return new FuA(A??{})}var IV1=[{id:"home",path:"/",title:"Home",description:"Professional site homepage",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"homepage",template:"professional-site:homepage-list",dataQuery:{}}]},{id:"about",path:"/about",title:"About",description:"About page",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:90},sections:[{id:"about",template:"professional-site:about",dataQuery:{}}]},{id:"subscribe-thanks",path:"/subscribe/thanks",title:"Thanks for subscribing",description:"Newsletter subscription confirmation",layout:"default",navigation:{show:!1},sections:[{id:"subscribe-thanks",template:"professional-site:subscribe-thanks",dataQuery:{},content:{}}]},{id:"subscribe-error",path:"/subscribe/error",title:"Subscription failed",description:"Newsletter subscription error",layout:"default",navigation:{show:!1},sections:[{id:"subscribe-error",template:"professional-site:subscribe-error",dataQuery:{},content:{}}]}];import{jsxDEV as b9A}from"preact/jsx-dev-runtime";function DV1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return b9A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[b9A(ETA,{title:Q.title,navigation:Q.navigation.primary,showThemeToggle:!0,...Q.logo!==void 0?{logo:Q.logo}:{},...w!==void 0?{wordmark:w}:{}},void 0,!1,void 0,this),b9A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),b9A(LTA,{primaryNavigation:Q.navigation.primary,secondaryNavigation:Q.navigation.secondary,copyright:Q.copyright,socialLinks:Q.socialLinks,title:Q.title,tagline:Q.description,children:B?.getSlot("footer-top").map(($)=>$.render())},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var rjQ={layouts:{default:DV1},routes:IV1,plugin:fV1,entityDisplay:{post:{label:"Post"},deck:{label:"Deck"},project:{label:"Project"},series:{label:"Series",navigation:{slot:"secondary"}},topic:{label:"Topic",navigation:{slot:"secondary"}},link:{label:"Link",navigation:{slot:"secondary"}},base:{label:"Note",navigation:{show:!1}},"social-post":{label:"Social Post",pluralName:"social-posts",navigation:{slot:"secondary"}},newsletter:{label:"Newsletter",navigation:{slot:"secondary"}}}},zr=rjQ;var YV1=`/*
8435
8435
  * Default theme \u2014 simplified editorial base inspired by the Rizom family.
8436
8436
  *
8437
8437
  * This theme is intentionally less branded than @brains/theme-rizom. It
@@ -8819,8 +8819,8 @@ ${JSON.stringify(B,null,2)}`}function F9A(A){return A.map((Q)=>Q.detail===null?{
8819
8819
 
8820
8820
  .btn-primary:disabled { opacity: 0.5; }
8821
8821
  }
8822
- `;var dv=YV1;import{join as ojQ}from"path";var UV1={name:"@brains/rover",version:"0.2.0-alpha.121",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",eval:"brain-eval",lint:"eslint .","lint:fix":"eslint . --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/atproto":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/document-plugin":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/theme-default":"workspace:*","@brains/topics":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var JV1=["prompt","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],XV1=[...JV1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],sjQ=[...XV1,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo"],ajQ=["Rover is a personal professional knowledge and publishing brain for an independent professional. Prioritize personal knowledge management, professional website content, essays, projects, decks, newsletters, and social distribution workflows.",'Rover entity mappings: "blog post", "post", "essay", "article" \u2192 entityType: post; "case study", "portfolio piece", "project" \u2192 entityType: project; "presentation", "deck", "slides" \u2192 entityType: deck; "newsletter" \u2192 entityType: newsletter; "LinkedIn post", "social post" \u2192 entityType: social-post.',"When a user asks for a publishing/content overview, use the available publishing entity types directly instead of treating the request as generic team memory.","Draft blog posts are only post entities with status draft. If the user asks whether draft blog posts exist, call only system_list for entityType post with status draft; do not also list social-post, newsletter, deck, or other draft entity types."],WV1=hN({name:"rover",version:UV1.version,model:"gpt-5.4-mini",site:zr,theme:dv,presets:{core:JV1,default:XV1,full:sjQ},evalDisable:["discord","webserver","web-chat","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:ajQ,capabilities:[["prompt",zC,void 0],["image",Xh,void 0],["cms",NC,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Bu,void 0],["notifications",p0A,void 0],["email-resend",EwA,void 0],["dashboard",az,void 0],["dashboard-root",az,{routePath:"/"}],["blog",VSA,{}],["series",bSA,void 0],["decks",Ui,void 0],["document",vgA,void 0],["note",UC,{}],["link",WC,{}],["portfolio",DhA,{}],["topics",E$A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",nhA,{generationSchedules:{newsletter:"0 9 * * 1","social-post":"0 10 * * *"},generationConditions:{newsletter:{skipIfDraftExists:!0,minSourceEntities:1,sourceEntityType:"post"},"social-post":{skipIfDraftExists:!0,maxUnpublishedDrafts:5}}}],["social-media",ri,{autoGenerateOnBlogPublish:!0}],["newsletter",Fq1,{doubleOptIn:!0}],["obsidian-vault",ZmA,{autoSync:!0}],["wishlist",d$A,{}],["stock-photo",OmA,{}],["agents",J9A,void 0],["assessment",q9A,void 0],["atproto",M9A,(A)=>({...A.ATPROTO_APP_PASSWORD?{appPassword:A.ATPROTO_APP_PASSWORD}:{}})],["directory-sync",WM,{seedContent:!0,seedContentPath:ojQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h$A,{}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{cms:{}}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})],["a2a",aj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{"*":{create:"anchor",update:"anchor",delete:"anchor",extract:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});cN();aA();WA();var HV1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.121",description:"Canonical Rizom AT Protocol lexicon registry",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var KV1=H.object({enabled:H.boolean().default(!0)}),ZuA="/atproto/lexicons";function GV1(A){return new Response(`${JSON.stringify(A,null,2)}
8823
- `,{headers:{"Content-Type":"application/json"}})}class NuA extends UB{constructor(A={}){super("atproto-registry",HV1,A,KV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${ZuA}/index.json`,method:"GET",public:!0,handler:()=>GV1(this.getIndex())},...tM().map((A)=>({path:`${ZuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>GV1(A)}))]}getIndex(){return{lexicons:ISA().map((A)=>({...A,path:`${ZuA}/${A.id}.json`}))}}getLexicon(A){return fSA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return Tz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:tM().length,nsids:tM().map((A)=>A.id),metadata:ISA()}})}}}function zuA(A={}){return new NuA(A)}aA();WA();WA();aA();var P9A=H.object({routeId:H.string(),sectionId:H.string()}),qr=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:P9A});aA();class FV1 extends q2{constructor(){super({entityType:"site-content",schema:qr,frontmatterSchema:P9A})}toMarkdown(A){let Q=this.extractBody(A.content);return this.buildMarkdown(Q,A.metadata)}fromMarkdown(A){return{content:A,entityType:"site-content",metadata:this.parseFrontmatter(A)}}}var quA=new FV1;WA();var k9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),JY8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class LuA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],U=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};U.push({type:"shell:content-generation",data:N})}if(U.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(U,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)Y.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class VuA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new LuA(A)}async generateContent(A,Q){let B=k9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}o$();WA();function Lr(A,Q){return Q?A.optional():A}function MuA(A){switch(A.type){case"string":return Lr(H.string(),A.optional);case"number":return Lr(H.number(),A.optional);case"enum":{let Q=[...A.options];return Lr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=MuA(w);return Lr(H.object(Q),A.optional)}case"array":{let Q=H.array(ejQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Lr(Q,A.optional)}}}function ejQ(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=MuA($);return H.object(B)}}}function EuA(A,Q){switch(Q.type){case"string":case"enum":return{key:A,label:Q.label,type:"string"};case"number":return{key:A,label:Q.label,type:"number"};case"object":return{key:A,label:Q.label,type:"object",children:Object.entries(Q.fields).map(([B,w])=>EuA(B,w))};case"array":{let B={key:A,label:Q.label,type:"array"};switch(Q.items.type){case"string":case"enum":return B.itemType="string",B;case"number":return B.itemType="number",B;case"object":return B.itemType="object",B.itemMappings=Object.entries(Q.items.fields).map(([w,$])=>EuA(w,$)),B}}}}function A_Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=MuA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>EuA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function CuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,A_Q(Q,B)]))}WA();var ZV1=H.object({namespace:H.string(),sections:H.record(H.any())}),NV1=H.object({definitions:H.union([ZV1,H.array(ZV1)]).optional()});aA();function zV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",k9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var qV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.121",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class OuA extends UB{siteContentService;constructor(A={}){super("site-content",qV1,A,NV1)}async onRegister(A){A.entities.register("site-content",qr,quA);for(let Q of iX(this.config.definitions))A.templates.register(CuA(Q),Q.namespace);this.siteContentService=new VuA(A)}async getTools(){return zV1(()=>this.siteContentService,this.id)}}function Vr(A={}){return new OuA(A)}aA();WA();Ew();WA();aA();var LV1=H.enum(["available","early access","coming soon","planned"]),VV1=H.object({title:H.string(),description:H.string()}),CD=H.object({name:H.string(),availability:LV1,order:H.number(),ogImageId:H.string().optional()}),j9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(VV1).min(1).max(6),story:H.string()}),B_Q=CD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),nv=A2.extend({entityType:H.literal("product"),metadata:B_Q}),_9A=nv.extend({frontmatter:CD,body:j9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),v9A=_9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();o$();class ov extends lB{constructor(){super(j9A,{title:"Product",mappings:[{key:"tagline",label:"Tagline",type:"string"},{key:"promise",label:"Promise",type:"string"},{key:"role",label:"Role",type:"string"},{key:"purpose",label:"Purpose",type:"string"},{key:"audience",label:"Audience",type:"string"},{key:"values",label:"Values",type:"array",itemType:"string"},{key:"features",label:"Capabilities",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"story",label:"Story",type:"string"}]})}}class RuA extends q2{constructor(){super({entityType:"product",schema:nv,frontmatterSchema:CD,bodyFormatter:new ov})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,CD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,CD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var T9A=new RuA;WA();aA();var EV1=H.object({title:H.string(),description:H.string()}),MV1=H.object({title:H.string(),description:H.string()}),w_Q=H.object({title:H.string(),description:H.string()}),CV1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),oF=H.object({headline:H.string(),tagline:H.string()}),$_Q=H.object({title:H.string(),description:H.string()}),y9A=H.object({vision:H.string(),pillars:H.array(EV1).min(1).max(6),approach:H.array($_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(w_Q).min(1).max(6),benefits:H.array(MV1).min(1).max(6),cta:CV1}),OV1=oF.pick({headline:!0}).extend({slug:H.string()}),sv=A2.extend({entityType:H.literal("products-overview"),metadata:OV1}),Er=sv.extend({frontmatter:oF,body:y9A,labels:H.record(H.string(),H.string())});aA();WA();o$();class av extends lB{constructor(){super(y9A,{title:"Products Overview",mappings:[{key:"vision",label:"Vision",type:"string"},{key:"pillars",label:"Core Principles",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"approach",label:"How It Works",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"productsIntro",label:"Products",type:"string"},{key:"technologies",label:"Built With",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"benefits",label:"Why Brains",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"cta",label:"Ready to Build",type:"object",children:[{key:"heading",label:"Heading",type:"string"},{key:"buttonText",label:"Button Text",type:"string"},{key:"link",label:"Link",type:"string"}]}]})}}class buA extends q2{constructor(){super({entityType:"products-overview",schema:sv,frontmatterSchema:oF,bodyFormatter:new av})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,oF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,oF),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var PuA=new buA;aA();WA();var f_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function RV1(A,Q){let B=R2(A.content,CD),w=Q.parse(B.content),$=Q.getLabels();return _9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function bV1(A,Q){let B=R2(A.content,oF),w=Q.parse(B.content),$=Q.getLabels();return Er.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class x9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new av;productFormatter=new ov;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=f_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let U=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!U)throw Error("Products overview entity not found");let J=bV1(U,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let U=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!U)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:RV1(U,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:bV1(D,this.overviewFormatter),products:I.map((Y)=>RV1(Y,this.productFormatter))})}}import{jsxDEV as A1,Fragment as Y_Q}from"preact/jsx-dev-runtime";var PV1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(Y_Q,{children:[A1(KQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
8822
+ `;var dv=YV1;import{join as ojQ}from"path";var UV1={name:"@brains/rover",version:"0.2.0-alpha.122",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",eval:"brain-eval","eval:core":"brain-eval --preset core --tags preset-core","eval:core:coverage":"brain-eval --preset core --tags preset-core --tool-coverage",lint:"eslint .","lint:fix":"eslint . --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/analytics":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/atproto":"workspace:*","@brains/auth-service":"workspace:*","@brains/blog":"workspace:*","@brains/cms":"workspace:*","@brains/content-pipeline":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/document-plugin":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/theme-default":"workspace:*","@brains/topics":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var JV1=["prompt","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],XV1=[...JV1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],sjQ=[...XV1,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo"],ajQ=["Rover is a personal professional knowledge and publishing brain for an independent professional. Prioritize personal knowledge management, professional website content, essays, projects, decks, newsletters, and social distribution workflows.",'Rover entity mappings: "blog post", "post", "essay", "article" \u2192 entityType: post; "case study", "portfolio piece", "project" \u2192 entityType: project; "presentation", "deck", "slides" \u2192 entityType: deck; "newsletter" \u2192 entityType: newsletter; "LinkedIn post", "social post" \u2192 entityType: social-post.',"When a user asks for a publishing/content overview, use the available publishing entity types directly instead of treating the request as generic team memory.","Draft blog posts are only post entities with status draft. If the user asks whether draft blog posts exist, call only system_list for entityType post with status draft; do not also list social-post, newsletter, deck, or other draft entity types."],WV1=hN({name:"rover",version:UV1.version,model:"gpt-5.4-mini",site:zr,theme:dv,presets:{core:JV1,default:XV1,full:sjQ},evalDisable:["discord","webserver","web-chat","mcp","atproto","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:ajQ,capabilities:[["prompt",zC,void 0],["image",Xh,void 0],["cms",NC,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Bu,void 0],["notifications",p0A,void 0],["email-resend",EwA,void 0],["dashboard",az,void 0],["dashboard-root",az,{routePath:"/"}],["blog",VSA,{}],["series",bSA,void 0],["decks",Ui,void 0],["document",vgA,void 0],["note",UC,{}],["link",WC,{}],["portfolio",DhA,{}],["topics",E$A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",nhA,{generationSchedules:{newsletter:"0 9 * * 1","social-post":"0 10 * * *"},generationConditions:{newsletter:{skipIfDraftExists:!0,minSourceEntities:1,sourceEntityType:"post"},"social-post":{skipIfDraftExists:!0,maxUnpublishedDrafts:5}}}],["social-media",ri,{autoGenerateOnBlogPublish:!0}],["newsletter",Fq1,{doubleOptIn:!0}],["obsidian-vault",ZmA,{autoSync:!0}],["wishlist",d$A,{}],["stock-photo",OmA,{}],["agents",J9A,void 0],["assessment",q9A,void 0],["atproto",M9A,(A)=>({...A.ATPROTO_APP_PASSWORD?{appPassword:A.ATPROTO_APP_PASSWORD}:{}})],["directory-sync",WM,{seedContent:!0,seedContentPath:ojQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h$A,{}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{cms:{}}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})],["a2a",aj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{"*":{create:"anchor",update:"anchor",delete:"anchor",extract:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});cN();aA();WA();var HV1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.122",description:"Canonical Rizom AT Protocol lexicon registry",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint src test --ext .ts","lint:fix":"eslint src test --ext .ts --fix"},dependencies:{"@brains/atproto-contracts":"workspace:*","@brains/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var KV1=H.object({enabled:H.boolean().default(!0)}),ZuA="/atproto/lexicons";function GV1(A){return new Response(`${JSON.stringify(A,null,2)}
8823
+ `,{headers:{"Content-Type":"application/json"}})}class NuA extends UB{constructor(A={}){super("atproto-registry",HV1,A,KV1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${ZuA}/index.json`,method:"GET",public:!0,handler:()=>GV1(this.getIndex())},...tM().map((A)=>({path:`${ZuA}/${A.id}.json`,method:"GET",public:!0,handler:()=>GV1(A)}))]}getIndex(){return{lexicons:ISA().map((A)=>({...A,path:`${ZuA}/${A.id}.json`}))}}getLexicon(A){return fSA(A)}async getTools(){return[this.createListLexiconsTool(),this.createValidateLexiconTool(),this.createCheckContractsTool()]}createListLexiconsTool(){return{name:`${this.id}_list_lexicons`,description:"List canonical Rizom AT Protocol lexicons.",inputSchema:{},handler:async()=>({success:!0,data:this.getIndex()})}}createValidateLexiconTool(){return{name:`${this.id}_validate_lexicon`,description:"Validate a record payload against a canonical Rizom AT Protocol lexicon.",inputSchema:{nsid:H.string().describe("Canonical lexicon NSID"),record:H.record(H.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=H.object({nsid:H.string(),record:H.record(H.unknown())}).safeParse(A);if(!Q.success)return{success:!1,error:`Invalid input: ${Q.error.message}`};let B=this.getLexicon(Q.data.nsid);if(!B)return{success:!1,error:`Unknown AT Protocol lexicon: ${Q.data.nsid}`};try{return Tz(B,Q.data.record),{success:!0,data:{valid:!0}}}catch(w){return{success:!0,data:{valid:!1,error:w instanceof Error?w.message:"Invalid record"}}}}}}createCheckContractsTool(){return{name:`${this.id}_check_contracts`,description:"Check that canonical Rizom AT Protocol lexicon contracts are available.",inputSchema:{},handler:async()=>({success:!0,data:{lexiconCount:tM().length,nsids:tM().map((A)=>A.id),metadata:ISA()}})}}}function zuA(A={}){return new NuA(A)}aA();WA();WA();aA();var P9A=H.object({routeId:H.string(),sectionId:H.string()}),qr=A2.extend({entityType:H.literal("site-content"),template:H.string().optional(),content:H.string(),metadata:P9A});aA();class FV1 extends q2{constructor(){super({entityType:"site-content",schema:qr,frontmatterSchema:P9A})}toMarkdown(A){let Q=this.extractBody(A.content);return this.buildMarkdown(Q,A.metadata)}fromMarkdown(A){return{content:A,entityType:"site-content",metadata:this.parseFrontmatter(A)}}}var quA=new FV1;WA();var k9A=H.object({routeId:H.string().optional().describe("Optional: specific route filter"),sectionId:H.string().optional().describe("Optional: specific section filter"),dryRun:H.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:H.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),JY8=H.object({jobs:H.array(H.object({jobId:H.string(),routeId:H.string(),sectionId:H.string()})),totalSections:H.number(),queuedSections:H.number(),skippedSections:H.number().optional(),batchId:H.string().optional()});class LuA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((J)=>J.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let J of f)for(let X of J.sections){if(A.sectionId&&X.id!==A.sectionId)continue;if(X.content){w.debug("Section has static content, skipping",{routeId:J.id,sectionId:X.id});continue}if(X.template){let G=this.context.templates.getCapabilities(X.template);if(!G){w.warn("Template not found, skipping section",{routeId:J.id,sectionId:X.id,templateName:X.template});continue}if(!G.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:J.id,sectionId:X.id,templateName:X.template,capabilities:G});continue}}else{w.debug("Section has no template, skipping",{routeId:J.id,sectionId:X.id});continue}if(!A.force&&!A.dryRun){let G=`${J.id}:${X.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:G})){w.debug("Content already exists, skipping",{routeId:J.id,sectionId:X.id});continue}}I.push({route:J,section:X})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],U=[];for(let{route:J,section:X}of I){let G=`${J.id}:${X.id}`,Z=X.template,N={routeId:J.id,sectionId:X.id,entityId:G,entityType:"site-content",templateName:Z,context:{prompt:typeof X.content==="string"?X.content:void 0,data:{routeId:J.id,sectionId:X.id,routeTitle:J.title??Q?.title??"",routeDescription:J.description??Q?.description??"",sectionContent:X.content},conversationId:"system"},siteConfig:Q};U.push({type:"shell:content-generation",data:N})}if(U.length>0){let J=this.createJobOptions(B,"site:content-generation"),X=await this.context.jobs.enqueueBatch(U,J);for(let G=0;G<I.length;G++){let Z=I[G];if(Z)Y.push({jobId:`${X}-${G}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:X}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class VuA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new LuA(A)}async generateContent(A,Q){let B=k9A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}o$();WA();function Lr(A,Q){return Q?A.optional():A}function MuA(A){switch(A.type){case"string":return Lr(H.string(),A.optional);case"number":return Lr(H.number(),A.optional);case"enum":{let Q=[...A.options];return Lr(H.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=MuA(w);return Lr(H.object(Q),A.optional)}case"array":{let Q=H.array(ejQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Lr(Q,A.optional)}}}function ejQ(A){let{items:Q}=A;switch(Q.type){case"string":return H.string();case"number":return H.number();case"enum":{let B=[...Q.options];return H.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=MuA($);return H.object(B)}}}function EuA(A,Q){switch(Q.type){case"string":case"enum":return{key:A,label:Q.label,type:"string"};case"number":return{key:A,label:Q.label,type:"number"};case"object":return{key:A,label:Q.label,type:"object",children:Object.entries(Q.fields).map(([B,w])=>EuA(B,w))};case"array":{let B={key:A,label:Q.label,type:"array"};switch(Q.items.type){case"string":case"enum":return B.itemType="string",B;case"number":return B.itemType="number",B;case"object":return B.itemType="object",B.itemMappings=Object.entries(Q.items.fields).map(([w,$])=>EuA(w,$)),B}}}}function A_Q(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=MuA(I);let w=H.object(B),$=new lB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>EuA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function CuA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,A_Q(Q,B)]))}WA();var ZV1=H.object({namespace:H.string(),sections:H.record(H.any())}),NV1=H.object({definitions:H.union([ZV1,H.array(ZV1)]).optional()});aA();function zV1(A,Q){return[oQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",k9A,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var qV1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.122",description:"Site content entity and generation orchestration",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/plugins":"workspace:*","@brains/site-info":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};class OuA extends UB{siteContentService;constructor(A={}){super("site-content",qV1,A,NV1)}async onRegister(A){A.entities.register("site-content",qr,quA);for(let Q of iX(this.config.definitions))A.templates.register(CuA(Q),Q.namespace);this.siteContentService=new VuA(A)}async getTools(){return zV1(()=>this.siteContentService,this.id)}}function Vr(A={}){return new OuA(A)}aA();WA();Ew();WA();aA();var LV1=H.enum(["available","early access","coming soon","planned"]),VV1=H.object({title:H.string(),description:H.string()}),CD=H.object({name:H.string(),availability:LV1,order:H.number(),ogImageId:H.string().optional()}),j9A=H.object({tagline:H.string(),promise:H.string(),role:H.string(),purpose:H.string(),audience:H.string(),values:H.array(H.string()).min(1),features:H.array(VV1).min(1).max(6),story:H.string()}),B_Q=CD.pick({name:!0,availability:!0,order:!0}).extend({slug:H.string()}),nv=A2.extend({entityType:H.literal("product"),metadata:B_Q}),_9A=nv.extend({frontmatter:CD,body:j9A,labels:H.record(H.string(),H.string()),ogImageUrl:H.string().optional()}),v9A=_9A.extend({url:H.string().optional(),typeLabel:H.string().optional(),listUrl:H.string().optional(),listLabel:H.string().optional(),ogImageUrl:H.string().optional()});aA();WA();o$();class ov extends lB{constructor(){super(j9A,{title:"Product",mappings:[{key:"tagline",label:"Tagline",type:"string"},{key:"promise",label:"Promise",type:"string"},{key:"role",label:"Role",type:"string"},{key:"purpose",label:"Purpose",type:"string"},{key:"audience",label:"Audience",type:"string"},{key:"values",label:"Values",type:"array",itemType:"string"},{key:"features",label:"Capabilities",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"story",label:"Story",type:"string"}]})}}class RuA extends q2{constructor(){super({entityType:"product",schema:nv,frontmatterSchema:CD,bodyFormatter:new ov})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,CD);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,CD),B=X1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var T9A=new RuA;WA();aA();var EV1=H.object({title:H.string(),description:H.string()}),MV1=H.object({title:H.string(),description:H.string()}),w_Q=H.object({title:H.string(),description:H.string()}),CV1=H.object({heading:H.string(),buttonText:H.string(),link:H.string()}),oF=H.object({headline:H.string(),tagline:H.string()}),$_Q=H.object({title:H.string(),description:H.string()}),y9A=H.object({vision:H.string(),pillars:H.array(EV1).min(1).max(6),approach:H.array($_Q).min(1).max(6),productsIntro:H.string(),technologies:H.array(w_Q).min(1).max(6),benefits:H.array(MV1).min(1).max(6),cta:CV1}),OV1=oF.pick({headline:!0}).extend({slug:H.string()}),sv=A2.extend({entityType:H.literal("products-overview"),metadata:OV1}),Er=sv.extend({frontmatter:oF,body:y9A,labels:H.record(H.string(),H.string())});aA();WA();o$();class av extends lB{constructor(){super(y9A,{title:"Products Overview",mappings:[{key:"vision",label:"Vision",type:"string"},{key:"pillars",label:"Core Principles",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"approach",label:"How It Works",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"productsIntro",label:"Products",type:"string"},{key:"technologies",label:"Built With",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"benefits",label:"Why Brains",type:"array",itemType:"object",itemMappings:[{key:"title",label:"Title",type:"string"},{key:"description",label:"Description",type:"string"}]},{key:"cta",label:"Ready to Build",type:"object",children:[{key:"heading",label:"Heading",type:"string"},{key:"buttonText",label:"Button Text",type:"string"},{key:"link",label:"Link",type:"string"}]}]})}}class buA extends q2{constructor(){super({entityType:"products-overview",schema:sv,frontmatterSchema:oF,bodyFormatter:new av})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,oF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,oF),B=X1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var PuA=new buA;aA();WA();var f_Q=H.object({entityType:H.string(),query:H.object({id:H.string().optional()}).optional()});function RV1(A,Q){let B=R2(A.content,CD),w=Q.parse(B.content),$=Q.getLabels();return _9A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function bV1(A,Q){let B=R2(A.content,oF),w=Q.parse(B.content),$=Q.getLabels();return Er.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class x9A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new av;productFormatter=new ov;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=f_Q.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let U=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!U)throw Error("Products overview entity not found");let J=bV1(U,this.overviewFormatter);return Q.parse(J)}if(w.query?.id){let U=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!U)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:RV1(U,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:bV1(D,this.overviewFormatter),products:I.map((Y)=>RV1(Y,this.productFormatter))})}}import{jsxDEV as A1,Fragment as Y_Q}from"preact/jsx-dev-runtime";var PV1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(Y_Q,{children:[A1(KQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),A1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[A1("style",{children:`
8824
8824
  @keyframes wave-drift {
8825
8825
  from { transform: translateX(0); }
8826
8826
  to { transform: translateX(-50%); }
@@ -9015,7 +9015,7 @@ ${JSON.stringify(B,null,2)}`}function F9A(A){return A.map((Q)=>Q.detail===null?{
9015
9015
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
9016
9016
  }
9017
9017
  `}},void 0,!1,void 0,this),OD("section",{className:"product-shell",children:[OD("header",{className:"product-hero",children:[Q.brandLabel&&OD("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),OD("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&OD("div",{className:"printable-meta",children:OD("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),OD("div",{className:"product-body-wrap",children:[OD("aside",{className:"product-rail","aria-hidden":"true",children:OD("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),OD(V$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&OD("footer",{className:"printable-footer",children:Q.brandLabel},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var F_Q=26214400,Z_Q=60000;class juA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??$X}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==S9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let B=N_Q(Q,{brandLabel:this.resolveBrandLabel()}),w=await W_Q(K_Q(G_Q(),"brain-product-printable-"));try{let $=await ZD({outputDir:w,mediaPath:`/_media/printable/product/${Q.id}`,template:_V1,format:"pdf",content:B,siteConfig:{title:B.name,themeMode:"light"},themeCSS:this.context.themeCSS}),f=await ND({rootDir:w});try{return{type:"document",data:await this.renderPdf(f.urlFor($.urlPath),{maxBytes:F_Q,timeoutMs:Z_Q,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${z_Q(Q)}-printable.pdf`}}finally{await f.close()}}finally{await H_Q(w,{recursive:!0,force:!0})}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}}function N_Q(A,Q={}){let{frontmatter:B,content:w}=jB(A.content),$=CD.parse(B);return{name:$.name,body:w,availability:$.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function z_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}WA();WA();import{jsxDEV as V_Q}from"preact/jsx-dev-runtime";var g9A="og-image",q_Q="products:og-image",vV1=H.object({name:H.string().min(1),tagline:H.string().optional(),availability:H.string().optional(),brandLabel:H.string().optional()}),TV1={name:q_Q,pluginId:"products",schema:vV1,renderers:{image:L_Q}};function L_Q(A){let Q=vV1.parse(A);return V_Q(zF,{cover:!0,brandLabel:Q.brandLabel??Q.name,eyebrow:"Product",title:Q.name,subtitle:Q.tagline,tag:Q.availability},void 0,!1,void 0,this)}class _uA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==g9A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=jB(Q.content),$=CD.parse(B),f=E_Q(w,"Tagline"),I=this.resolveBrandLabel(),D={name:$.name,availability:$.availability,...f?{tagline:f}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await AC({mediaPath:`/_media/og/product/${Q.id}`,template:TV1,content:D,title:D.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${M_Q(Q)}-og.png`}}resolveBrandLabel(){let A=this.context.domain?.trim();if(A&&A.length>0)return A;let Q=this.context.identity.getProfile().name.trim();return Q.length>0?Q:void 0}}function E_Q(A,Q){let B=A.split(/\r?\n/),w=B.findIndex((I)=>I.trim().toLowerCase()===`## ${Q.toLowerCase()}`);if(w===-1)return;let $=[];for(let I of B.slice(w+1)){if(I.trim().startsWith("## "))break;$.push(I)}let f=$.join(`
9018
- `).trim();return f.length>0?f:void 0}function M_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var yV1={name:"@brains/products",private:!0,version:"0.2.0-alpha.121",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var O_Q=H.object({overview:Er,products:H.array(v9A)}),R_Q=H.object({product:v9A});class vuA extends jQ{entityType=T9A.entityType;schema=nv;adapter=T9A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",yV1,A,kuA)}getTemplates(){return{"product-list":P1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:O_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:PV1}}),"product-detail":P1({name:"product-detail",description:"Individual product detail page",schema:R_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:kV1}})}}getDataSources(){return[new x9A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",S9A,new juA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",g9A,new _uA(A)),A.entities.register("products-overview",sv,PuA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function TuA(A={}){return new vuA(A)}import{join as QvQ}from"path";import{jsxDEV as h9A,Fragment as b_Q}from"preact/jsx-dev-runtime";var tv=({children:A})=>h9A(b_Q,{children:[h9A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:h9A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h9A("div",{className:"max-w-[1440px] mx-auto relative overflow-x-clip",children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this);import{jsxDEV as VJ8}from"preact/jsx-dev-runtime";import{jsxDEV as k_Q}from"preact/jsx-dev-runtime";var m9A="px-6 md:px-10 xl:px-20",P_Q=`${m9A} relative z-[1]`,Aq=({id:A,className:Q,children:B})=>k_Q("section",{id:A,className:B2(P_Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as kJ8}from"preact/jsx-dev-runtime";import{jsxDEV as vJ8}from"preact/jsx-dev-runtime";import{jsxDEV as y_Q}from"preact/jsx-dev-runtime";var j_Q="inline-flex items-center justify-center cursor-pointer border border-solid transition-all [gap:var(--rizom-btn-gap)] [border-radius:var(--rizom-btn-radius)] [font-family:var(--rizom-btn-font-family)] [font-style:var(--rizom-btn-font-style)] [letter-spacing:var(--rizom-btn-letter-spacing)] [text-transform:var(--rizom-btn-text-transform)]",__Q={primary:"[font-weight:var(--rizom-btn-primary-font-weight)] [color:var(--rizom-btn-primary-color)] [background:var(--rizom-btn-primary-bg)] [border-color:var(--rizom-btn-primary-border-color)] [border-width:var(--rizom-btn-primary-border-width)] [box-shadow:var(--rizom-btn-primary-shadow)] hover:[color:var(--rizom-btn-primary-hover-color)] hover:[background:var(--rizom-btn-primary-hover-bg)] hover:[border-color:var(--rizom-btn-primary-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-hover-shadow)] hover:[transform:var(--rizom-btn-primary-hover-transform)]","primary-strong":"duration-400 ease-[cubic-bezier(0.2,0.8,0.2,1)] [font-weight:var(--rizom-btn-primary-strong-font-weight)] [color:var(--rizom-btn-primary-strong-color)] [background:var(--rizom-btn-primary-strong-bg)] [border-color:var(--rizom-btn-primary-strong-border-color)] [border-width:var(--rizom-btn-primary-strong-border-width)] [box-shadow:var(--rizom-btn-primary-strong-shadow)] hover:[color:var(--rizom-btn-primary-strong-hover-color)] hover:[background:var(--rizom-btn-primary-strong-hover-bg)] hover:[border-color:var(--rizom-btn-primary-strong-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-strong-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-strong-hover-shadow)] hover:[transform:var(--rizom-btn-primary-strong-hover-transform)]",secondary:"[font-weight:var(--rizom-btn-secondary-font-weight)] [color:var(--rizom-btn-secondary-color)] [background:var(--rizom-btn-secondary-bg)] [border-color:var(--rizom-btn-secondary-border-color)] [border-width:var(--rizom-btn-secondary-border-width)] [box-shadow:var(--rizom-btn-secondary-shadow)] hover:[color:var(--rizom-btn-secondary-hover-color)] hover:[background:var(--rizom-btn-secondary-hover-bg)] hover:[border-color:var(--rizom-btn-secondary-hover-border-color)] hover:[border-width:var(--rizom-btn-secondary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-secondary-hover-shadow)] hover:[transform:var(--rizom-btn-secondary-hover-transform)]"},v_Q={md:"text-base [padding:var(--rizom-btn-md-padding)]",lg:"text-body-md md:text-body-lg [padding:var(--rizom-btn-lg-padding-mobile)] md:[padding:var(--rizom-btn-lg-padding-desktop)]"},T_Q="w-full md:w-auto",EC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>y_Q("a",{href:A,className:B2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",j_Q,__Q[Q],v_Q[B],w&&T_Q,$),children:f},void 0,!1,void 0,this);import{jsxDEV as mJ8}from"preact/jsx-dev-runtime";import{jsxDEV as pJ8}from"preact/jsx-dev-runtime";import{Fragment as dJ8}from"preact";import{jsxDEV as oJ8}from"preact/jsx-dev-runtime";import{jsxDEV as xV1}from"preact/jsx-dev-runtime";var u9A=({sections:A})=>xV1(tv,{children:xV1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);aA();WA();var SV1=`/*
9018
+ `).trim();return f.length>0?f:void 0}function M_Q(A){let Q=A.metadata.slug;return Q.length>0?Q:X1(A.metadata.name)}var yV1={name:"@brains/products",private:!0,version:"0.2.0-alpha.122",description:"Product entity management and overview page for marketing showcase",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/media-page-composer":"workspace:*","@brains/media-renderer":"workspace:*","@brains/plugins":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var O_Q=H.object({overview:Er,products:H.array(v9A)}),R_Q=H.object({product:v9A});class vuA extends jQ{entityType=T9A.entityType;schema=nv;adapter=T9A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",yV1,A,kuA)}getTemplates(){return{"product-list":P1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:O_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:PV1}}),"product-detail":P1({name:"product-detail",description:"Individual product detail page",schema:R_Q,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:kV1}})}}getDataSources(){return[new x9A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",S9A,new juA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",g9A,new _uA(A)),A.entities.register("products-overview",sv,PuA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function TuA(A={}){return new vuA(A)}import{join as QvQ}from"path";import{jsxDEV as h9A,Fragment as b_Q}from"preact/jsx-dev-runtime";var tv=({children:A})=>h9A(b_Q,{children:[h9A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:h9A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h9A("div",{className:"max-w-[1440px] mx-auto relative overflow-x-clip",children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this);import{jsxDEV as VJ8}from"preact/jsx-dev-runtime";import{jsxDEV as k_Q}from"preact/jsx-dev-runtime";var m9A="px-6 md:px-10 xl:px-20",P_Q=`${m9A} relative z-[1]`,Aq=({id:A,className:Q,children:B})=>k_Q("section",{id:A,className:B2(P_Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as kJ8}from"preact/jsx-dev-runtime";import{jsxDEV as vJ8}from"preact/jsx-dev-runtime";import{jsxDEV as y_Q}from"preact/jsx-dev-runtime";var j_Q="inline-flex items-center justify-center cursor-pointer border border-solid transition-all [gap:var(--rizom-btn-gap)] [border-radius:var(--rizom-btn-radius)] [font-family:var(--rizom-btn-font-family)] [font-style:var(--rizom-btn-font-style)] [letter-spacing:var(--rizom-btn-letter-spacing)] [text-transform:var(--rizom-btn-text-transform)]",__Q={primary:"[font-weight:var(--rizom-btn-primary-font-weight)] [color:var(--rizom-btn-primary-color)] [background:var(--rizom-btn-primary-bg)] [border-color:var(--rizom-btn-primary-border-color)] [border-width:var(--rizom-btn-primary-border-width)] [box-shadow:var(--rizom-btn-primary-shadow)] hover:[color:var(--rizom-btn-primary-hover-color)] hover:[background:var(--rizom-btn-primary-hover-bg)] hover:[border-color:var(--rizom-btn-primary-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-hover-shadow)] hover:[transform:var(--rizom-btn-primary-hover-transform)]","primary-strong":"duration-400 ease-[cubic-bezier(0.2,0.8,0.2,1)] [font-weight:var(--rizom-btn-primary-strong-font-weight)] [color:var(--rizom-btn-primary-strong-color)] [background:var(--rizom-btn-primary-strong-bg)] [border-color:var(--rizom-btn-primary-strong-border-color)] [border-width:var(--rizom-btn-primary-strong-border-width)] [box-shadow:var(--rizom-btn-primary-strong-shadow)] hover:[color:var(--rizom-btn-primary-strong-hover-color)] hover:[background:var(--rizom-btn-primary-strong-hover-bg)] hover:[border-color:var(--rizom-btn-primary-strong-hover-border-color)] hover:[border-width:var(--rizom-btn-primary-strong-hover-border-width)] hover:[box-shadow:var(--rizom-btn-primary-strong-hover-shadow)] hover:[transform:var(--rizom-btn-primary-strong-hover-transform)]",secondary:"[font-weight:var(--rizom-btn-secondary-font-weight)] [color:var(--rizom-btn-secondary-color)] [background:var(--rizom-btn-secondary-bg)] [border-color:var(--rizom-btn-secondary-border-color)] [border-width:var(--rizom-btn-secondary-border-width)] [box-shadow:var(--rizom-btn-secondary-shadow)] hover:[color:var(--rizom-btn-secondary-hover-color)] hover:[background:var(--rizom-btn-secondary-hover-bg)] hover:[border-color:var(--rizom-btn-secondary-hover-border-color)] hover:[border-width:var(--rizom-btn-secondary-hover-border-width)] hover:[box-shadow:var(--rizom-btn-secondary-hover-shadow)] hover:[transform:var(--rizom-btn-secondary-hover-transform)]"},v_Q={md:"text-base [padding:var(--rizom-btn-md-padding)]",lg:"text-body-md md:text-body-lg [padding:var(--rizom-btn-lg-padding-mobile)] md:[padding:var(--rizom-btn-lg-padding-desktop)]"},T_Q="w-full md:w-auto",EC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>y_Q("a",{href:A,className:B2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",j_Q,__Q[Q],v_Q[B],w&&T_Q,$),children:f},void 0,!1,void 0,this);import{jsxDEV as mJ8}from"preact/jsx-dev-runtime";import{jsxDEV as pJ8}from"preact/jsx-dev-runtime";import{Fragment as dJ8}from"preact";import{jsxDEV as oJ8}from"preact/jsx-dev-runtime";import{jsxDEV as xV1}from"preact/jsx-dev-runtime";var u9A=({sections:A})=>xV1(tv,{children:xV1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);aA();WA();var SV1=`/*
9019
9019
  * Shared globals + helpers used by tree / constellation / roots canvas
9020
9020
  * scripts. Loaded as a shared static asset by the Rizom runtime package
9021
9021
  * so the variant canvases
@@ -11505,7 +11505,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var H
11505
11505
  `);return this.truncateContent(w||Q||DT(A))}truncateContent(A){if(A.length<=qE1)return A;let Q=A.slice(0,qE1-1),B=Q.search(/\s\S*$/);return`${(B>0?Q.slice(0,B):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===s6}isDecisionEntity(A){return A.entityType===RD}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return XX(Q)}}var gvQ=5,hvQ=3;function puA(A){A.messaging.subscribe(ey,async(Q)=>{let B=YDA.parse(Q.payload);return{success:!0,data:await A7A(A,B)}})}async function A7A(A,Q){let B=d$(Q.userPermissionLevel);if(!Q.channelId)return LE1(A,Q,{visibilityScope:B,reason:"no-channel-context",items:[]}),{items:[]};let w=new YT(A),$=await w.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:gvQ,visibilityScope:B}),f=$.results.length===0?await w.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:hvQ,visibilityScope:B}):void 0,I=$.results.length>0,D=I?$.results:f?.results??[];return LE1(A,Q,{visibilityScope:B,spaceId:$.spaceId??f?.spaceId,reason:D.length>0?"memory-injected":"no-same-space-memory",items:D.map((Y)=>mvQ(Y,I))}),{items:D.map(uvQ)}}function LE1(A,Q,B){A.logger.info("Conversation memory agent context audit",{conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,channelName:Q.channelName,userPermissionLevel:Q.userPermissionLevel,visibilityScope:B.visibilityScope,spaceId:B.spaceId,reason:B.reason,itemCount:B.items.length,items:B.items})}function mvQ(A,Q){return{id:A.id,entityType:A.entityType,conversationId:A.conversationId,spaceId:A.spaceId,visibility:A.visibility,score:A.score,updated:A.updated,eligibilityReason:Q?"same-space-query-match":"recent-same-space-memory"}}function uvQ(A){let Q=A.channelName??A.channelId;return{id:A.id,source:"conversation-memory",title:`${A.entityType} from ${Q}`,content:A.content,provenance:{entityType:A.entityType,entityId:A.id,conversationId:A.conversationId,spaceId:A.spaceId,interfaceType:A.interfaceType,channelId:A.channelId,channelName:A.channelName,updated:A.updated,score:A.score,messageCount:A.messageCount,entryCount:A.entryCount,status:A.status}}}aA();H6();WA();wY();var ruA=H.object({role:SG,content:H.string(),timestamp:H.string().datetime().optional(),actor:PL.optional(),source:kL.optional()}),cvQ=H.object({conversationId:H.string().default("eval-conversation"),messages:H.array(ruA)}),lvQ=H.object({conversationId:H.string()}),pvQ=H.object({conversationId:H.string().default("eval-conversation"),interfaceType:H.string().default("eval"),channelId:H.string().default("eval-channel"),channelName:H.string().optional(),projectionDecision:H.enum(["update","append"]).default("update"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(ruA)}),Q7A=H.object({actorId:H.string(),canonicalId:H.string().optional(),displayName:H.string().optional()}),ivQ=Q7A.extend({roles:H.array(H.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:H.array(H.string()).optional()}),rvQ=H.object({actorId:H.string().optional(),canonicalId:H.string().optional(),displayName:H.string()}),ME1=H.object({id:H.string(),entityType:H.enum(["summary","decision","action-item"]),content:H.string(),excerpt:H.string().optional(),score:H.number().optional(),conversationId:H.string(),interfaceType:H.string(),channelId:H.string(),channelName:H.string().optional(),updated:H.string().datetime().optional(),visibility:R9,status:H.string().optional(),participants:H.array(ivQ).optional(),decidedBy:H.array(Q7A).optional(),mentionedBy:H.array(Q7A).optional(),assignedTo:H.array(rvQ).optional(),requestedBy:H.array(Q7A).optional()}),dvQ=H.object({query:H.string().optional(),conversationId:H.string().optional(),interfaceType:H.string().optional(),channelId:H.string().optional(),limit:H.number().int().min(1).optional(),includeOtherSpaces:H.boolean().optional(),actorId:H.string().optional(),canonicalId:H.string().optional(),visibilityScope:R9.optional(),memory:H.array(ME1).optional()}),nvQ=H.object({conversationId:H.string().default("eval-conversation"),message:H.string(),interfaceType:H.string().default("eval"),channelId:H.string().optional(),channelName:H.string().optional(),userPermissionLevel:H.enum(["anchor","trusted","public"]).default("trusted"),memory:H.array(ME1).optional()}),ovQ=H.object({conversationId:H.string().default("eval-conversation"),existingSummary:H.string().optional(),existingMessageCount:H.number().int().min(0).default(0),messages:H.array(ruA)});function CE1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=cvQ.parse($),I=iuA(f.messages,f.conversationId),Y=await new $T(Q,B,w).extract(I);return Y.entries.map((U)=>{let J=Y.decisions.filter((G)=>G.timeRange.start>=U.timeRange.start).filter((G)=>G.timeRange.end<=U.timeRange.end).map((G)=>G.text),X=Y.actionItems.filter((G)=>G.timeRange.start>=U.timeRange.start).filter((G)=>G.timeRange.end<=U.timeRange.end).map((G)=>G.text);return{...U,decisions:J,actionItems:X,keyPointsText:U.keyPoints.join(`
11506
11506
  `),decisionsText:J.join(`
11507
11507
  `),actionItemsText:X.join(`
11508
- `)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=ovQ.parse($),I=iuA(f.messages,f.conversationId),D=f.existingSummary?VE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Bq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=dvQ.parse($),I=f.memory?EE1(Q,f.memory):Q;return new YT(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=nvQ.parse($),I=f.memory?EE1(Q,f.memory):Q;return A7A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=pvQ.parse($),I=iuA(f.messages,f.conversationId),D=svQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),Y=f.existingSummary?VE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,U=[],J=[],X=avQ({context:Q,conversation:D,messages:I,existing:Y,upserted:U,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Bq(X,B,w).projectConversation(f.conversationId),summaries:U.filter((N)=>N.entityType==="summary"),decisions:U.filter((N)=>N.entityType==="decision"),actionItems:U.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=lvQ.parse($);return new Bq(Q,B,w).projectConversation(f.conversationId)})}function VE1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",visibility:A.visibility,created:"2026-01-01T00:00:00.000Z",updated:"2026-01-01T00:00:00.000Z",metadata:{conversationId:A.conversationId,channelId:"eval-channel",interfaceType:"eval",messageCount:A.messageCount,entryCount:1,sourceHash:"eval-source-hash",projectionVersion:A.projectionVersion}}}function iuA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function svQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function avQ(A){let Q=XX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function EE1(A,Q){let B=Q.map(tvQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??DT($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function tvQ(A){if(A.entityType==="summary")return evQ(A);if(A.entityType==="decision")return ATQ(A);return QTQ(A)}function duA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function evQ(A){return{...duA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function ATQ(A){return{...duA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function QTQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...duA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var OE1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.121",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var wTQ=new eY,$TQ=new QT,fTQ=new BT,ITQ=H.object({conversationId:H.string()});class nuA extends jQ{entityType=s6;schema=Cr;adapter=wTQ;constructor(A={}){super(l9A,OE1,A,guA)}getConfig(){return this.config}getTemplates(){return{"summary-list":tV1,"summary-detail":eV1,"ai-response":AE1}}getDataSources(){return[new luA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:s6,job:{type:iV1,handler:new o9A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await OL(A,s6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:SuA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:l9A}}},sourceChange:{sourceKind:_x,sourceTypes:[_x],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[_R],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:SuA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:l9A}}}}}]}parseConversationMessagePayload(A){return ITQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return OC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(RD,Or,$TQ),A.entities.register(tY,Rr,fTQ),wE1({context:A,pluginId:this.id}),fE1({context:A,pluginId:this.id}),KE1({context:A,pluginId:this.id}),NE1({context:A,pluginId:this.id,config:this.config}),puA(A),CE1({context:A,logger:this.logger,config:this.config})}}function ouA(A){return new nuA(A)}aA();WA();aA();var sF=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),RE1=sF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),UT=A2.extend({entityType:H.literal("doc"),metadata:RE1}),aF=UT.extend({frontmatter:sF,body:H.string()});aA();WA();class suA extends q2{constructor(){super({entityType:"doc",schema:UT,frontmatterSchema:sF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=Q.slug??X1(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var B7A=new suA;aA();function bE1(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function PE1(A){let Q=R2(A.content,sF);return aF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class w7A extends m5{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return PE1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=bE1(f.items),D=I.findIndex((J)=>J.id===$.item.id),Y=D>0?I[D-1]:null,U=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:Y,nextDoc:U})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:bE1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Ew();WA();import{jsxDEV as w$}from"preact/jsx-dev-runtime";var DTQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function kr(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function $7A(A){let Q=new Map;for(let B of kr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function JT(A){return`/docs/${A.metadata.slug}`}function f7A(A){return`section-${A+1}`}function XT(A){return DTQ[A]??String(A+1)}var _E1="text-[var(--docs-text)] font-bold",vE1="text-[var(--docs-accent)] font-bold",TE1="text-[var(--docs-text-muted)]",YTQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",UTQ="docs-font-display text-[var(--docs-heading)]",kE1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",jE1="relative hidden py-1 text-[15px] text-[var(--docs-text-muted)] transition-colors duration-150 after:absolute after:bottom-0 after:left-0 after:h-px after:w-0 after:bg-[var(--docs-accent)] after:transition-[width] after:duration-300 hover:text-[var(--docs-text)] hover:after:w-full min-[861px]:inline-block",auA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",gH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:YTQ,display:UTQ,button:`${kE1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${kE1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},yE1=()=>w$("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[w$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[w$("span",{className:_E1,children:"brains"},void 0,!1,void 0,this),w$("span",{className:vE1,children:"."},void 0,!1,void 0,this),w$("span",{className:TE1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[w$("a",{className:jE1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:jE1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),xE1=()=>w$("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[w$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[w$("span",{className:_E1,children:"rizom"},void 0,!1,void 0,this),w$("span",{className:vE1,children:"."},void 0,!1,void 0,this),w$("span",{className:TE1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[w$("a",{className:auA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:auA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{className:auA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),w$("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),JTQ=`
11508
+ `)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=ovQ.parse($),I=iuA(f.messages,f.conversationId),D=f.existingSummary?VE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new Bq(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=dvQ.parse($),I=f.memory?EE1(Q,f.memory):Q;return new YT(I).retrieve(f)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let f=nvQ.parse($),I=f.memory?EE1(Q,f.memory):Q;return A7A(I,f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=pvQ.parse($),I=iuA(f.messages,f.conversationId),D=svQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),Y=f.existingSummary?VE1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,U=[],J=[],X=avQ({context:Q,conversation:D,messages:I,existing:Y,upserted:U,deleted:J,projectionDecision:f.projectionDecision});return{result:await new Bq(X,B,w).projectConversation(f.conversationId),summaries:U.filter((N)=>N.entityType==="summary"),decisions:U.filter((N)=>N.entityType==="decision"),actionItems:U.filter((N)=>N.entityType==="action-item"),deleted:J}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=lvQ.parse($);return new Bq(Q,B,w).projectConversation(f.conversationId)})}function VE1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",visibility:A.visibility,created:"2026-01-01T00:00:00.000Z",updated:"2026-01-01T00:00:00.000Z",metadata:{conversationId:A.conversationId,channelId:"eval-channel",interfaceType:"eval",messageCount:A.messageCount,entryCount:1,sourceHash:"eval-source-hash",projectionVersion:A.projectionVersion}}}function iuA(A,Q){return A.map((B,w)=>{let $=B.timestamp??new Date(Date.UTC(2026,0,1,0,w)).toISOString();return{id:`eval-message-${w+1}`,conversationId:Q,role:B.role,content:B.content,timestamp:$,metadata:{...B.actor?{actor:B.actor}:{},...B.source?{source:B.source}:{}}}})}function svQ(A){let Q=A.messages[0],B=A.messages[A.messages.length-1],w=Q?.timestamp??"2026-01-01T00:00:00.000Z",$=B?.timestamp??w;return{id:A.conversationId,sessionId:A.conversationId,interfaceType:A.interfaceType,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},startedAt:w,lastActiveAt:$,createdAt:w,updatedAt:$,metadata:{}}}function avQ(A){let Q=XX(A.conversation);return{...A.context,spaces:[Q],conversations:{...A.context.conversations,get:async()=>A.conversation,getMessages:async()=>A.messages},ai:{...A.context.ai,generateObject:async()=>({object:{decision:A.projectionDecision,rationale:"Forced by eval input"}})},entityService:{...A.context.entityService,getEntity:async({entityType:B})=>B==="summary"?A.existing:null,listEntities:async()=>[],deleteEntity:async(B)=>{return A.deleted.push(B),!0},upsertEntity:async({entity:B})=>{return A.upserted.push(B),{entityId:B.id,jobId:"eval-upsert",created:!0,skipped:!1}}}}}function EE1(A,Q){let B=Q.map(tvQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??DT($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function tvQ(A){if(A.entityType==="summary")return evQ(A);if(A.entityType==="decision")return ATQ(A);return QTQ(A)}function duA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:gB(A.content),visibility:A.visibility,created:Q,updated:Q}}function evQ(A){return{...duA(A),entityType:"summary",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,messageCount:3,entryCount:1,sourceHash:`source-${A.id}`,projectionVersion:1,...A.participants?{participants:A.participants}:{}}}}function ATQ(A){return{...duA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:A.status==="superseded"?"superseded":"active",...A.decidedBy?{decidedBy:A.decidedBy}:{},...A.mentionedBy?{mentionedBy:A.mentionedBy}:{}}}}function QTQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...duA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:XX(A),timeRange:{start:"2026-01-01T00:00:00.000Z",end:"2026-01-01T00:01:00.000Z"},sourceSummaryId:A.conversationId,sourceMessageCount:2,projectionVersion:1,status:Q,...A.assignedTo?{assignedTo:A.assignedTo}:{},...A.requestedBy?{requestedBy:A.requestedBy}:{}}}}var OE1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.122",description:"Plugin for deriving durable conversation memory",type:"module",main:"./src/index.ts",exports:{".":"./src/index.ts"},scripts:{test:"bun test",typecheck:"tsc --noEmit",lint:"eslint src test --ext .ts,.tsx",eval:"cd evals && bun run brain-eval","lint:fix":"eslint src test --ext .ts,.tsx --fix"},dependencies:{"@brains/content-formatters":"workspace:*","@brains/contracts":"workspace:*","@brains/conversation-service":"workspace:*","@brains/dashboard":"workspace:*","@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","@types/node":"^20.0.0",eslint:"^8.56.0",typescript:"^5.3.3"}};var wTQ=new eY,$TQ=new QT,fTQ=new BT,ITQ=H.object({conversationId:H.string()});class nuA extends jQ{entityType=s6;schema=Cr;adapter=wTQ;constructor(A={}){super(l9A,OE1,A,guA)}getConfig(){return this.config}getTemplates(){return{"summary-list":tV1,"summary-detail":eV1,"ai-response":AE1}}getDataSources(){return[new luA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:s6,job:{type:iV1,handler:new o9A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await OL(A,s6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:SuA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:l9A}}},sourceChange:{sourceKind:_x,sourceTypes:[_x],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[_R],jobData:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{mode:"conversation",conversationId:B,reason:"message-added"}},jobOptions:(Q)=>{let{conversationId:B}=this.parseConversationMessagePayload(Q);return{priority:5,delayMs:this.config.projectionDelayMs,source:SuA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:l9A}}}}}]}parseConversationMessagePayload(A){return ITQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return OC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(RD,Or,$TQ),A.entities.register(tY,Rr,fTQ),wE1({context:A,pluginId:this.id}),fE1({context:A,pluginId:this.id}),KE1({context:A,pluginId:this.id}),NE1({context:A,pluginId:this.id,config:this.config}),puA(A),CE1({context:A,logger:this.logger,config:this.config})}}function ouA(A){return new nuA(A)}aA();WA();aA();var sF=H.object({title:H.string(),section:H.string(),order:H.number().int(),sourcePath:H.string(),description:H.string().optional(),slug:H.string().optional()}),RE1=sF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:H.string()}),UT=A2.extend({entityType:H.literal("doc"),metadata:RE1}),aF=UT.extend({frontmatter:sF,body:H.string()});aA();WA();class suA extends q2{constructor(){super({entityType:"doc",schema:UT,frontmatterSchema:sF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=Q.slug??X1(Q.title);return{content:A,entityType:"doc",metadata:{title:Q.title,section:Q.section,order:Q.order,slug:B,...Q.description?{description:Q.description}:{}}}}}var B7A=new suA;aA();function bE1(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function PE1(A){let Q=R2(A.content,sF);return aF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class w7A extends m5{id="docs:entities";name="Docs Entity DataSource";description="Fetches and transforms doc entities for rendering";config={entityType:"doc",defaultSort:[{field:"order",direction:"asc"},{field:"section",direction:"asc"},{field:"title",direction:"asc"}],defaultLimit:100,enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return PE1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let J=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(J.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=bE1(f.items),D=I.findIndex((J)=>J.id===$.item.id),Y=D>0?I[D-1]:null,U=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:Y,nextDoc:U})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:bE1(A),pagination:Q,baseUrl:B.baseUrl}}}aA();Ew();WA();import{jsxDEV as w$}from"preact/jsx-dev-runtime";var DTQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function kr(A){return[...A].sort((Q,B)=>{let w=Q.metadata.order-B.metadata.order;if(w!==0)return w;return Q.metadata.title.localeCompare(B.metadata.title)})}function $7A(A){let Q=new Map;for(let B of kr(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function JT(A){return`/docs/${A.metadata.slug}`}function f7A(A){return`section-${A+1}`}function XT(A){return DTQ[A]??String(A+1)}var _E1="text-[var(--docs-text)] font-bold",vE1="text-[var(--docs-accent)] font-bold",TE1="text-[var(--docs-text-muted)]",YTQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",UTQ="docs-font-display text-[var(--docs-heading)]",kE1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",jE1="relative hidden py-1 text-[15px] text-[var(--docs-text-muted)] transition-colors duration-150 after:absolute after:bottom-0 after:left-0 after:h-px after:w-0 after:bg-[var(--docs-accent)] after:transition-[width] after:duration-300 hover:text-[var(--docs-text)] hover:after:w-full min-[861px]:inline-block",auA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",gH={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:YTQ,display:UTQ,button:`${kE1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${kE1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},yE1=()=>w$("nav",{className:"docs-header fixed inset-x-0 top-0 z-[100] flex items-center justify-between px-6 py-4 md:px-10 md:py-5 xl:px-20",children:[w$("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[w$("span",{className:_E1,children:"brains"},void 0,!1,void 0,this),w$("span",{className:vE1,children:"."},void 0,!1,void 0,this),w$("span",{className:TE1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[w$("a",{className:jE1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:jE1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{href:"https://rizom.ai",className:"inline-flex items-center justify-center rounded-lg border border-[var(--docs-text)] px-4 py-2 text-[13px] font-semibold text-[var(--docs-text)] transition-colors duration-150 hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)] md:px-6 md:py-2.5 md:text-[15px]",children:"Get Brains"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),xE1=()=>w$("footer",{className:"flex flex-col items-center justify-between gap-4 border-t border-[var(--docs-border-light)] py-8 text-center md:flex-row md:gap-6 md:py-6 md:text-left",children:[w$("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[w$("span",{className:_E1,children:"rizom"},void 0,!1,void 0,this),w$("span",{className:vE1,children:"."},void 0,!1,void 0,this),w$("span",{className:TE1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w$("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[w$("a",{className:auA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),w$("a",{className:auA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),w$("a",{className:auA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),w$("button",{id:"themeToggle",className:"docs-font-label cursor-pointer rounded-md border border-[var(--docs-text-light)] bg-transparent px-2.5 py-1.5 text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:border-[var(--docs-text)] hover:text-[var(--docs-text)]",type:"button",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),JTQ=`
11509
11509
  .docs-handbook {
11510
11510
  --docs-bg: var(--color-bg, #0d0a1a);
11511
11511
  --docs-bg-card: var(--color-bg-card, #1a0a3e);
@@ -11657,7 +11657,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});WA();var H
11657
11657
  background: transparent;
11658
11658
  }
11659
11659
 
11660
- `,SE1=()=>w$("style",{children:JTQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as XTQ}from"preact/jsx-dev-runtime";var I7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(XTQ,{children:[K2(KQ,{title:A,description:Q},void 0,!1,void 0,this),K2(SE1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(yE1,{},void 0,!1,void 0,this),K2("div",{className:`${gH.wrap} ${f}`.trim(),children:[B,$&&K2(xE1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),gE1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${gH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${gH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),K2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:gH.primaryButton,href:JT(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:gH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),hE1=({groups:A})=>K2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[XT(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${f7A(B)}`,children:Q.section},void 0,!1,void 0,this)]},Q.section,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),mE1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:f7A(Q),children:[K2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[XT(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${gH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:JT(B),children:[K2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&K2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),uE1=({title:A})=>K2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),cE1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${f7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[XT($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:JT(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),lE1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:JT(A),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):K2("span",{},void 0,!1,void 0,this),Q&&K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:JT(Q),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as WT}from"preact/jsx-dev-runtime";var tuA=({docs:A})=>{let Q=kr(A),B=$7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return WT(I7A,{title:"Documentation",description:"Brains documentation",children:[WT(gE1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),WT("section",{className:"grid items-start gap-10 py-12 md:grid-cols-[200px_minmax(0,1fr)] md:gap-20 md:py-20 md:pb-[120px]",id:"sections",children:[WT(hE1,{groups:B},void 0,!1,void 0,this),WT("div",{children:B.map((f,I)=>WT(mE1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bD}from"preact/jsx-dev-runtime";var euA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=$7A(Q.length>0?Q:[A]),f=kr(Q.length>0?Q:[A]),I=f.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((U)=>U.metadata.slug===A.metadata.slug)),0);return bD(I7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[bD(uE1,{title:A.metadata.title},void 0,!1,void 0,this),bD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[bD(cE1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),bD("article",{className:"min-w-0",children:[bD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[bD("p",{className:`${gH.label} m-0 mb-6 flex items-baseline gap-3`,children:[bD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[XT(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),bD("h1",{className:`${gH.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&bD("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),bD("div",{className:"docs-article__body",children:bD(V$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),bD(lE1,{prevDoc:B,nextDoc:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var WTQ=H.object({docs:H.array(aF),pagination:Z7.nullable(),baseUrl:H.string().optional()}),HTQ=H.object({doc:aF,docs:H.array(aF),prevDoc:aF.nullable(),nextDoc:aF.nullable()});function pE1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:WTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:tuA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:HTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:euA}})}}var iE1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.121",description:"Documentation entity type \u2014 markdown docs as first-class brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class AcA extends jQ{entityType=B7A.entityType;schema=UT;adapter=B7A;constructor(){super("docs",iE1,{},void 0)}getTemplates(){return pE1()}getDataSources(){return[new w7A(this.logger.child("DocDataSource"))]}}function QcA(){return new AcA}aA();WA();WA();o$();var rE1=H.object({label:H.string(),href:H.string()}),dE1=H.object({label:H.string(),title:H.string(),detail:H.string()}),KTQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),FTQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),BcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),HT=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:rE1,secondaryCta:rE1,inputs:H.array(dE1).min(1),outputs:H.array(dE1).min(1),core:KTQ,legend:H.array(FTQ).min(1)}),wcA=HT.extend({counts:BcA}),nE1={eyebrow:"A team brain, diagrammed",headline:"Relay sits between the work and the world, and keeps both honest.",intro:"Capture sources flow into a shared brain; the brain organizes, summarizes, and \u2014 selectively \u2014 exposes a public surface. Everything else stays private and operational.",primaryCta:{label:"See it on a real team",href:"#diagram"},secondaryCta:{label:"Read the model",href:"/about"},inputs:[{label:"Source \xB7 chat",title:"Discord",detail:"Shared decisions and field notes captured in flow."},{label:"Source \xB7 agent",title:"MCP / CLI",detail:"Structured captures from tools and assistants."},{label:"Source \xB7 web",title:"Links & docs",detail:"External material indexed with sourceable metadata."}],outputs:[{label:"Surface \xB7 public",title:"Default site",detail:"A small, durable face onto what the team currently knows."},{label:"Surface \xB7 agents",title:"A2A exchange",detail:"Peer brains coordinate over an approved, signed protocol."},{label:"Surface \xB7 query",title:"Team Q&A",detail:"Ask the brain in chat; answers cite the captures behind them."}],core:{eyebrow:"The relay",name:"brain",sub:"capture \u2192 topics \u2192 summaries"},legend:[{tone:"capture",title:"Capture",text:"Anything the team already does that produces a trace \u2014 chat messages, links, deploys, decisions."},{tone:"synthesis",title:"Synthesis",text:"The work the brain does on its own time \u2014 clustering captures into topics, summaries, and durable memory."},{tone:"share",title:"Share",text:"A small, opinionated public surface and an approved agent-to-agent protocol. Most memory stays private."}]},oE1=new lB(HT,{title:"Home diagram",mappings:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"headline",label:"Headline",type:"string"},{key:"intro",label:"Intro",type:"string"},{key:"primaryCta",label:"Primary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"secondaryCta",label:"Secondary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"inputs",label:"Inputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"outputs",label:"Outputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"core",label:"Core",type:"object",children:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"name",label:"Name",type:"string"},{key:"sub",label:"Sub",type:"string"}]},{key:"legend",label:"Legend",type:"array",itemType:"object",itemMappings:[{key:"tone",label:"Tone",type:"string"},{key:"title",label:"Title",type:"string"},{key:"text",label:"Text",type:"string"}]}]});function D7A(A){return oE1.parse(A)}function sE1(A){return oE1.format(A)}WA();var ZTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),NTQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class $cA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=ZTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return nE1;return HT.parse(D7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(NTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return BcA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as Q1}from"preact/jsx-dev-runtime";var aE1=H.object({label:H.string(),href:H.string()}),zTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:aE1,secondaryCta:aE1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),qTQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),LTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),VTQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),ETQ={title:"Relay is a collaborative team-memory brain.",intro:"It exists for teams that need to remember together: capturing what happened, summarizing why it matters, and coordinating with trusted peer brains when work crosses boundaries.",points:["Not a personal blog engine or portfolio shell.","Not a marketing automation stack.","A small public face for a larger private knowledge workflow."]},MTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function tE1({href:A,label:Q}){return Q1("a",{href:A,className:MTQ,children:Q},void 0,!1,void 0,this)}function CTQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(tv,{children:[Q1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(tE1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(tE1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var OTQ=({sections:A,siteInfo:Q})=>Q1(CTQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function RTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Aq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function bTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Aq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function PTQ({title:A,intro:Q,cards:B}){return Q1(Aq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function kTQ({title:A,intro:Q,points:B}){return Q1(Aq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var jTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},_TQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),jr=(A,Q,B=`${Q}s`)=>`${_TQ(A)} ${A===1?Q:B}`;function vTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:Y,counts:U}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:jr(U.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:jr(U.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:jr(U.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:jr(U.summaries,"summary","summaries")}];return Q1(Aq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[jr(U.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:Y.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${jTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var TTQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:wcA,formatter:{parse:(A)=>wcA.parse({...D7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>sE1(HT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:vTQ}}),yTQ=(A)=>RTQ(zTQ.parse(A)),xTQ=(A)=>bTQ(qTQ.parse(A)),STQ=(A)=>PTQ(LTQ.parse(A)),gTQ=(A)=>kTQ(VTQ.parse(A)),eE1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},AM1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:yTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...eE1,label:"Primary CTA"},secondaryCta:{...eE1,label:"Secondary CTA"},signals:{type:"array",label:"Signals",minItems:1,items:{type:"object",label:"Signal",fields:{label:{type:"string",label:"Label"},value:{type:"string",label:"Value"},note:{type:"string",label:"Note"}}}}}},"home-loop":{title:"Home operating loop",description:"Relay capture, synthesis, and sharing loop",layout:xTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},steps:{type:"array",label:"Steps",minItems:1,items:{type:"object",label:"Step",fields:{phase:{type:"string",label:"Phase"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},"home-surface":{title:"Home surface",description:"Relay default template explanation cards",layout:STQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},cards:{type:"array",label:"Cards",minItems:1,items:{type:"object",label:"Card",fields:{label:{type:"string",label:"Label"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},about:{title:"About Relay",description:"Default Relay about page",layout:gTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},hTQ=[{id:"home",path:"/",title:"Relay",description:"Collaborative team memory and synthesis brain",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"diagram",template:"relay-site:home-diagram"}]},{id:"about",path:"/about",title:"About Relay",description:"What Relay is designed to do",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:20},sections:[{id:"about",template:"relay-site:about",content:ETQ}]}],QM1=xuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:OTQ,routes:hTQ,templates:{"home-diagram":TTQ},dataSources:[new $cA]});var BM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.121",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var wM1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],$M1=[...wM1,"image","site-info","site-content","site-builder"],cTQ=[...$M1,"docs","decks"],lTQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: base; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],fM1=hN({name:"relay",version:BM1.version,model:"gpt-5.4-mini",site:QM1,theme:ev,presets:{core:wM1,default:$M1,full:cTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:lTQ,capabilities:[["prompt",zC,void 0],["note",UC,{}],["link",WC,{}],["image",Xh,void 0],["topics",E$A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",ouA,{memoryVisibility:"shared"}],["docs",QcA,void 0],["decks",Ui,void 0],["agents",J9A,void 0],["assessment",q9A,void 0],["auth-service",Bu,void 0],["notifications",p0A,void 0],["email-resend",EwA,void 0],["cms",NC,{}],["dashboard",az,void 0],["directory-sync",WM,{seedContent:!0,seedContentPath:uTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Vr,{definitions:AM1}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({captureUrls:!0})],["a2a",aj,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{base:{create:"trusted",update:"trusted",delete:"anchor"},link:{create:"trusted",update:"trusted",delete:"anchor"},doc:{create:"trusted",update:"trusted",delete:"anchor"},deck:{create:"trusted",update:"trusted",delete:"anchor"},decision:{create:"trusted",update:"trusted",delete:"anchor"},"action-item":{create:"trusted",update:"trusted",delete:"anchor"},image:{create:"trusted",update:"trusted",delete:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as VgQ}from"fs";import{join as EgQ}from"path";import{execSync as MgQ}from"child_process";import{parseArgs as rTQ}from"util";var dTQ={model:{type:"string"},domain:{type:"string"},"content-repo":{type:"string"},backend:{type:"string"},"push-to":{type:"string"},"ai-api-key":{type:"string"},"no-interactive":{type:"boolean"},preview:{type:"boolean"},deploy:{type:"boolean"},regen:{type:"boolean"},all:{type:"boolean"},only:{type:"string"},"dry-run":{type:"boolean"},"startup-check":{type:"boolean"},"storage-dir":{type:"string"},yes:{type:"boolean"},remote:{type:"string"},token:{type:"string"},outputDir:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function WX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function wq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function IM1(A){let{values:Q,positionals:B}=rTQ({args:A,options:dTQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:WX(Q,"model"),domain:WX(Q,"domain"),"content-repo":WX(Q,"content-repo"),backend:WX(Q,"backend"),"push-to":WX(Q,"push-to"),"ai-api-key":WX(Q,"ai-api-key"),"no-interactive":wq(Q,"no-interactive"),preview:wq(Q,"preview"),deploy:wq(Q,"deploy"),regen:wq(Q,"regen"),all:wq(Q,"all"),only:WX(Q,"only"),"dry-run":wq(Q,"dry-run"),"startup-check":wq(Q,"startup-check"),"storage-dir":WX(Q,"storage-dir"),yes:wq(Q,"yes"),remote:WX(Q,"remote"),token:WX(Q,"token"),outputDir:WX(Q,"outputDir")}}}_r();import{mkdirSync as WgQ}from"fs";import{join as HgQ}from"path";import{execSync as GgQ}from"child_process";var U7A={name:"@rizom/brain",version:"0.2.0-alpha.121",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as LM1,writeFileSync as Tr,chmodSync as yr,existsSync as GcA,readFileSync as KcA}from"fs";import{basename as FcA,dirname as ZcA,join as f6,resolve as RyQ}from"path";import{fileURLToPath as byQ}from"url";var DM1=`ARG BUN_VERSION=1.3.10
11660
+ `,SE1=()=>w$("style",{children:JTQ},void 0,!1,void 0,this);import{jsxDEV as K2,Fragment as XTQ}from"preact/jsx-dev-runtime";var I7A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>K2(XTQ,{children:[K2(KQ,{title:A,description:Q},void 0,!1,void 0,this),K2(SE1,{},void 0,!1,void 0,this),K2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[K2(yE1,{},void 0,!1,void 0,this),K2("div",{className:`${gH.wrap} ${f}`.trim(),children:[B,$&&K2(xE1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),gE1=({docsCount:A,sectionsCount:Q,startDoc:B})=>K2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[K2("p",{className:`${gH.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),K2("h1",{className:`${gH.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",K2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("p",{className:"mt-8 max-w-[52ch] text-lg leading-[1.65] text-[var(--docs-text-muted)]",children:"Documentation for composing brain models, managing markdown entities, wiring interfaces, and shipping generated sites."},void 0,!1,void 0,this),K2("dl",{className:"mt-10 flex flex-wrap gap-7 docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] md:mt-14 md:gap-12",children:[K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:A},void 0,!1,void 0,this),"Documents"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:Q},void 0,!1,void 0,this),"Sections"]},void 0,!0,void 0,this),K2("div",{children:[K2("strong",{className:"mb-0.5 block font-medium text-[var(--docs-text)]",children:"April 2026"},void 0,!1,void 0,this),"Updated"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&K2("a",{className:gH.primaryButton,href:JT(B),children:"Start reading"},void 0,!1,void 0,this),K2("a",{className:gH.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),hE1=({groups:A})=>K2("aside",{className:"docs-rail sticky top-8 hidden docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)] min-[861px]:block","aria-label":"Documentation sections",children:[K2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>K2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[K2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[XT(B),"."]},void 0,!0,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${f7A(B)}`,children:Q.section},void 0,!1,void 0,this)]},Q.section,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),mE1=({group:A,index:Q})=>K2("article",{className:"mb-16 last:mb-0",id:f7A(Q),children:[K2("header",{className:"mb-2 grid grid-cols-[36px_auto_1fr] items-baseline gap-x-3 border-b border-[var(--docs-border)] pb-3.5 md:grid-cols-[48px_auto_1fr] md:gap-x-5",children:[K2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[XT(Q),"."]},void 0,!0,void 0,this),K2("h2",{className:`${gH.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),K2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>K2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:K2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:JT(B),children:[K2("p",{className:"m-0 text-[22px] leading-[1.2] tracking-[-0.005em] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:B.metadata.title},void 0,!1,void 0,this),B.metadata.description&&K2("p",{className:"mt-1.5 mb-0 max-w-[70ch] text-sm leading-[1.55] text-[var(--docs-text-muted)]",children:B.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},B.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),uE1=({title:A})=>K2("nav",{className:"mb-8 flex flex-wrap items-baseline gap-2.5 docs-font-label text-[11px] uppercase tracking-[0.06em] text-[var(--docs-text-light)]","aria-label":"Breadcrumb",children:[K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),K2("span",{children:"/"},void 0,!1,void 0,this),K2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),cE1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>K2("aside",{className:"docs-detail-rail sticky top-24 hidden max-h-[calc(100vh-120px)] overflow-auto pr-2 min-[861px]:block","aria-label":"Documentation navigation",children:K2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[K2("p",{className:"m-0 mb-4 border-b border-[var(--docs-text)] pb-3 text-[11px] uppercase tracking-[0.08em] text-[var(--docs-text-light)]",children:"Documentation"},void 0,!1,void 0,this),K2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return K2("li",{className:f?"mb-[22px]":"mb-3.5",children:[K2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${f7A($)}`,children:[K2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[XT($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&K2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return K2("li",{children:K2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:JT(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),lE1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return K2("nav",{className:"mt-12 grid grid-cols-1 gap-5 border-t border-[var(--docs-border)] pt-7 md:grid-cols-2","aria-label":"Previous and next docs",children:[A?K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:JT(A),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Previous"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:["\u2190 ",A.metadata.title]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):K2("span",{},void 0,!1,void 0,this),Q&&K2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] text-left transition-colors duration-150 hover:border-[var(--docs-accent)] md:text-right",href:JT(Q),children:[K2("span",{className:"block docs-font-label text-[10.5px] uppercase tracking-[0.22em] text-[var(--docs-text-light)]",children:"Next"},void 0,!1,void 0,this),K2("span",{className:"mt-2 block docs-font-display text-[22px] leading-[1.2] text-[var(--docs-heading)] transition-colors duration-150 group-hover:text-[var(--docs-accent)]",children:[Q.metadata.title," \u2192"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as WT}from"preact/jsx-dev-runtime";var tuA=({docs:A})=>{let Q=kr(A),B=$7A(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return WT(I7A,{title:"Documentation",description:"Brains documentation",children:[WT(gE1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),WT("section",{className:"grid items-start gap-10 py-12 md:grid-cols-[200px_minmax(0,1fr)] md:gap-20 md:py-20 md:pb-[120px]",id:"sections",children:[WT(hE1,{groups:B},void 0,!1,void 0,this),WT("div",{children:B.map((f,I)=>WT(mE1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as bD}from"preact/jsx-dev-runtime";var euA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=$7A(Q.length>0?Q:[A]),f=kr(Q.length>0?Q:[A]),I=f.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((U)=>U.metadata.slug===A.metadata.slug)),0);return bD(I7A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[bD(uE1,{title:A.metadata.title},void 0,!1,void 0,this),bD("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[bD(cE1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),bD("article",{className:"min-w-0",children:[bD("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[bD("p",{className:`${gH.label} m-0 mb-6 flex items-baseline gap-3`,children:[bD("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[XT(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),bD("h1",{className:`${gH.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&bD("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),bD("div",{className:"docs-article__body",children:bD(V$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),bD(lE1,{prevDoc:B,nextDoc:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};var WTQ=H.object({docs:H.array(aF),pagination:Z7.nullable(),baseUrl:H.string().optional()}),HTQ=H.object({doc:aF,docs:H.array(aF),prevDoc:aF.nullable(),nextDoc:aF.nullable()});function pE1(){return{"doc-list":P1({name:"doc-list",description:"Documentation index template",schema:WTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:tuA}}),"doc-detail":P1({name:"doc-detail",description:"Documentation page template",schema:HTQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:euA}})}}var iE1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.122",description:"Documentation entity type \u2014 markdown docs as first-class brain content",type:"module",exports:{".":"./src/index.ts"},scripts:{typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix"},dependencies:{"@brains/plugins":"workspace:*","@brains/templates":"workspace:*","@brains/ui-library":"workspace:*","@brains/utils":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*","bun-types":"latest",typescript:"^5.3.3"}};class AcA extends jQ{entityType=B7A.entityType;schema=UT;adapter=B7A;constructor(){super("docs",iE1,{},void 0)}getTemplates(){return pE1()}getDataSources(){return[new w7A(this.logger.child("DocDataSource"))]}}function QcA(){return new AcA}aA();WA();WA();o$();var rE1=H.object({label:H.string(),href:H.string()}),dE1=H.object({label:H.string(),title:H.string(),detail:H.string()}),KTQ=H.object({eyebrow:H.string(),name:H.string(),sub:H.string()}),FTQ=H.object({tone:H.enum(["capture","synthesis","share"]),title:H.string(),text:H.string()}),BcA=H.object({captures:H.number(),links:H.number(),topics:H.number(),summaries:H.number(),peers:H.number()}),HT=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:rE1,secondaryCta:rE1,inputs:H.array(dE1).min(1),outputs:H.array(dE1).min(1),core:KTQ,legend:H.array(FTQ).min(1)}),wcA=HT.extend({counts:BcA}),nE1={eyebrow:"A team brain, diagrammed",headline:"Relay sits between the work and the world, and keeps both honest.",intro:"Capture sources flow into a shared brain; the brain organizes, summarizes, and \u2014 selectively \u2014 exposes a public surface. Everything else stays private and operational.",primaryCta:{label:"See it on a real team",href:"#diagram"},secondaryCta:{label:"Read the model",href:"/about"},inputs:[{label:"Source \xB7 chat",title:"Discord",detail:"Shared decisions and field notes captured in flow."},{label:"Source \xB7 agent",title:"MCP / CLI",detail:"Structured captures from tools and assistants."},{label:"Source \xB7 web",title:"Links & docs",detail:"External material indexed with sourceable metadata."}],outputs:[{label:"Surface \xB7 public",title:"Default site",detail:"A small, durable face onto what the team currently knows."},{label:"Surface \xB7 agents",title:"A2A exchange",detail:"Peer brains coordinate over an approved, signed protocol."},{label:"Surface \xB7 query",title:"Team Q&A",detail:"Ask the brain in chat; answers cite the captures behind them."}],core:{eyebrow:"The relay",name:"brain",sub:"capture \u2192 topics \u2192 summaries"},legend:[{tone:"capture",title:"Capture",text:"Anything the team already does that produces a trace \u2014 chat messages, links, deploys, decisions."},{tone:"synthesis",title:"Synthesis",text:"The work the brain does on its own time \u2014 clustering captures into topics, summaries, and durable memory."},{tone:"share",title:"Share",text:"A small, opinionated public surface and an approved agent-to-agent protocol. Most memory stays private."}]},oE1=new lB(HT,{title:"Home diagram",mappings:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"headline",label:"Headline",type:"string"},{key:"intro",label:"Intro",type:"string"},{key:"primaryCta",label:"Primary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"secondaryCta",label:"Secondary CTA",type:"object",children:[{key:"label",label:"Label",type:"string"},{key:"href",label:"Href",type:"string"}]},{key:"inputs",label:"Inputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"outputs",label:"Outputs",type:"array",itemType:"object",itemMappings:[{key:"label",label:"Label",type:"string"},{key:"title",label:"Title",type:"string"},{key:"detail",label:"Detail",type:"string"}]},{key:"core",label:"Core",type:"object",children:[{key:"eyebrow",label:"Eyebrow",type:"string"},{key:"name",label:"Name",type:"string"},{key:"sub",label:"Sub",type:"string"}]},{key:"legend",label:"Legend",type:"array",itemType:"object",itemMappings:[{key:"tone",label:"Tone",type:"string"},{key:"title",label:"Title",type:"string"},{key:"text",label:"Text",type:"string"}]}]});function D7A(A){return oE1.parse(A)}function sE1(A){return oE1.format(A)}WA();var ZTQ=H.object({query:H.object({routeId:H.string().default("home"),sectionId:H.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),NTQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class $cA{id="relay-site:home-counts";name="Relay homepage counts";description="Fetches Relay homepage content and live entity counts for the system diagram";async fetch(A,Q,B){let w=ZTQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return nE1;return HT.parse(D7A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(NTQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return BcA.parse(Object.fromEntries(Q))}async countOrZero(A,Q){if(!A.entityService.hasEntityType(Q))return 0;try{return await A.entityService.countEntities({entityType:Q})}catch{return 0}}}import{jsxDEV as Q1}from"preact/jsx-dev-runtime";var aE1=H.object({label:H.string(),href:H.string()}),zTQ=H.object({eyebrow:H.string(),headline:H.string(),intro:H.string(),primaryCta:aE1,secondaryCta:aE1,signals:H.array(H.object({label:H.string(),value:H.string(),note:H.string()}))}),qTQ=H.object({eyebrow:H.string(),title:H.string(),intro:H.string(),steps:H.array(H.object({phase:H.string(),title:H.string(),text:H.string()}))}),LTQ=H.object({title:H.string(),intro:H.string(),cards:H.array(H.object({label:H.string(),title:H.string(),text:H.string()}))}),VTQ=H.object({title:H.string(),intro:H.string(),points:H.array(H.string())}),ETQ={title:"Relay is a collaborative team-memory brain.",intro:"It exists for teams that need to remember together: capturing what happened, summarizing why it matters, and coordinating with trusted peer brains when work crosses boundaries.",points:["Not a personal blog engine or portfolio shell.","Not a marketing automation stack.","A small public face for a larger private knowledge workflow."]},MTQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function tE1({href:A,label:Q}){return Q1("a",{href:A,className:MTQ,children:Q},void 0,!1,void 0,this)}function CTQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(tv,{children:[Q1("nav",{className:"fixed left-0 right-0 top-0 z-[100] flex items-center justify-between border-b border-theme-light bg-nav-fade px-6 py-4 backdrop-blur-[12px] md:px-10 xl:px-20",children:[Q1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[Q1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),Q1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),Q1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex items-center gap-5 md:gap-8",children:[Q1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>Q1(tE1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),Q1("a",{href:w.buttonLink,className:"rounded-[999px] border border-theme px-4 py-2 font-body text-[13px] font-semibold text-theme transition-colors hover:border-accent hover:text-accent md:px-5",children:w.buttonText},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("main",{children:Q},void 0,!1,void 0,this),Q1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:Q1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),Q1("p",{className:"mt-2 max-w-[560px] font-body text-body-xs text-theme-muted",children:A.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>Q1(tE1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),Q1("button",{id:"themeToggle","aria-label":"Toggle light mode",className:"rounded-md border border-theme-light bg-transparent px-2.5 py-1.5 font-body text-label-md text-theme-light transition-colors hover:border-theme hover:text-theme",children:"\u2600 Light"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var OTQ=({sections:A,siteInfo:Q})=>Q1(CTQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function RTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return Q1(Aq,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:Q1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[Q1("div",{children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"rounded-[32px] border border-card-relay-border bg-card-relay-bg p-5 shadow-[0_24px_90px_var(--color-glow-relay)] backdrop-blur-sm",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),Q1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>Q1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[Q1("div",{className:"flex items-center justify-between gap-4",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),Q1("span",{className:"h-2 w-2 rounded-full bg-accent shadow-[0_0_22px_var(--color-accent)]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-xs text-theme-muted",children:I.note},void 0,!1,void 0,this)]},I.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}function bTQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(Aq,{id:"operating-loop",className:"py-section",children:[Q1("div",{className:"max-w-[840px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),Q1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>Q1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[Q1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),Q1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-body text-body-sm text-theme-muted",children:$.text},void 0,!1,void 0,this)]},$.phase,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function PTQ({title:A,intro:Q,cards:B}){return Q1(Aq,{className:"py-section",children:Q1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:Q1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[Q1("div",{children:[Q1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-5 font-body text-body-md text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"grid gap-4",children:B.map((w)=>Q1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[Q1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),Q1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-body-sm text-theme-muted",children:w.text},void 0,!1,void 0,this)]},w.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function kTQ({title:A,intro:Q,points:B}){return Q1(Aq,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[Q1("div",{className:"max-w-[920px]",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),Q1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),Q1("p",{className:"mt-7 font-body text-body-lg text-theme-muted",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>Q1("div",{className:"rounded-[24px] border border-card-panel-current-border bg-card-panel-current-bg p-6 font-body text-body-md text-theme",children:w},w,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var jTQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},_TQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),jr=(A,Q,B=`${Q}s`)=>`${_TQ(A)} ${A===1?Q:B}`;function vTQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:Y,counts:U}){let J=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:jr(U.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:jr(U.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:jr(U.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:jr(U.summaries,"summary","summaries")}];return Q1(Aq,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[Q1("div",{className:"mx-auto max-w-[1040px] text-center",children:[Q1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),Q1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),Q1("p",{className:"mx-auto mt-7 max-w-[64ch] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),Q1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[Q1(EC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(EC,{href:$.href,size:"lg",variant:"secondary",children:$.label},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mx-auto mt-20 max-w-[1020px] rounded-[32px] border border-theme-light bg-[radial-gradient(circle_at_1px_1px,rgb(255_255_255_/_0.05)_1px,transparent_0),linear-gradient(180deg,rgb(255_255_255_/_0.02),transparent)] bg-[length:24px_24px,100%_100%] px-6 py-14",children:[Q1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[Q1("div",{className:"flex flex-col gap-3.5",children:f.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-l-2 border-l-accent bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this),Q1("div",{className:"relative mx-auto grid aspect-square w-full max-w-[320px] place-items-center rounded-full bg-[radial-gradient(circle_at_center,rgb(232_119_34_/_0.25),transparent_65%)]",children:[Q1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),Q1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),J.map((X)=>Q1("span",{className:`absolute whitespace-nowrap rounded-full border border-theme bg-bg px-2.5 py-1 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light ${X.className}`,children:X.label},X.key,!1,void 0,this)),Q1("div",{className:"relative z-[1] px-6 text-center",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[jr(U.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"flex flex-col gap-3.5",children:I.map((X)=>Q1("div",{className:"rounded-2xl border border-card-panel-border border-r-2 border-r-secondary bg-card-panel-bg px-4 py-4 text-left backdrop-blur-sm",children:[Q1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:X.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:X.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:X.detail},void 0,!1,void 0,this)]},`${X.label}-${X.title}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:Y.map((X)=>Q1("div",{className:"text-left",children:[Q1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[Q1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${jTQ(X.tone)}`},void 0,!1,void 0,this),X.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:X.text},void 0,!1,void 0,this)]},X.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var TTQ=P1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:wcA,formatter:{parse:(A)=>wcA.parse({...D7A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>sE1(HT.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:vTQ}}),yTQ=(A)=>RTQ(zTQ.parse(A)),xTQ=(A)=>bTQ(qTQ.parse(A)),STQ=(A)=>PTQ(LTQ.parse(A)),gTQ=(A)=>kTQ(VTQ.parse(A)),eE1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},AM1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:yTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...eE1,label:"Primary CTA"},secondaryCta:{...eE1,label:"Secondary CTA"},signals:{type:"array",label:"Signals",minItems:1,items:{type:"object",label:"Signal",fields:{label:{type:"string",label:"Label"},value:{type:"string",label:"Value"},note:{type:"string",label:"Note"}}}}}},"home-loop":{title:"Home operating loop",description:"Relay capture, synthesis, and sharing loop",layout:xTQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},steps:{type:"array",label:"Steps",minItems:1,items:{type:"object",label:"Step",fields:{phase:{type:"string",label:"Phase"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},"home-surface":{title:"Home surface",description:"Relay default template explanation cards",layout:STQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},cards:{type:"array",label:"Cards",minItems:1,items:{type:"object",label:"Card",fields:{label:{type:"string",label:"Label"},title:{type:"string",label:"Title"},text:{type:"string",label:"Text"}}}}}},about:{title:"About Relay",description:"Default Relay about page",layout:gTQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},hTQ=[{id:"home",path:"/",title:"Relay",description:"Collaborative team memory and synthesis brain",layout:"default",navigation:{show:!0,label:"Home",slot:"secondary",priority:10},sections:[{id:"diagram",template:"relay-site:home-diagram"}]},{id:"about",path:"/about",title:"About Relay",description:"What Relay is designed to do",layout:"default",navigation:{show:!0,label:"About",slot:"primary",priority:20},sections:[{id:"about",template:"relay-site:about",content:ETQ}]}],QM1=xuA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:OTQ,routes:hTQ,templates:{"home-diagram":TTQ},dataSources:[new $cA]});var BM1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.122",description:"Relay brain model \u2014 collaborative knowledge management",type:"module",files:["src","brain.eval.yaml","env.schema.template"],exports:{".":"./src/index.ts"},scripts:{"build:web-chat":"turbo run build --filter=@brains/web-chat","start:core":"bun run build:web-chat && cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"bun run build:web-chat && cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"bun run build:web-chat && cd test-apps/full && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:docs":"bun run build:web-chat && cd test-apps/docs && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start",typecheck:"tsc --noEmit",test:"bun test",eval:"brain-eval",lint:"eslint . --ext .ts,.tsx","lint:fix":"eslint . --ext .ts,.tsx --fix"},dependencies:{"@brains/a2a":"workspace:*","@brains/agent-discovery":"workspace:*","@brains/app":"workspace:*","@brains/assessment":"workspace:*","@brains/auth-service":"workspace:*","@brains/cms":"workspace:*","@brains/content-formatters":"workspace:*","@brains/conversation-memory":"workspace:*","@brains/dashboard":"workspace:*","@brains/decks":"workspace:*","@brains/directory-sync":"workspace:*","@brains/discord":"workspace:*","@brains/doc":"workspace:*","@brains/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/plugins":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-content":"workspace:*","@brains/site-info":"workspace:*","@brains/site-rizom":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/topics":"workspace:*","@brains/utils":"workspace:*","@brains/web-chat":"workspace:*","@brains/webserver":"workspace:*",preact:"^10.27.2"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/test-utils":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var wM1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],$M1=[...wM1,"image","site-info","site-content","site-builder"],cTQ=[...$M1,"docs","decks"],lTQ=["Relay is a collaborative team-memory and synthesis brain. Optimize for capturing shared context, finding what the team already knows, summarizing cross-source evidence, and coordinating with peer brains.","Relay is not Rover-for-teams: do not default to personal branding, blog publishing, newsletters, social media, portfolio, or marketing workflows unless the installed plugins and user request explicitly support them.",'Relay entity mappings: "memo", "note", "team note", "capture" \u2192 entityType: base; "summary", "sync", "team digest" \u2192 entityType: summary; "decision" \u2192 entityType: decision; "action item", "todo" \u2192 entityType: action-item; "handbook", "doc", "documentation" \u2192 entityType: doc; "deck", "walkthrough", "presentation" \u2192 entityType: deck; "agent", "peer brain", "contact" \u2192 entityType: agent.'],fM1=hN({name:"relay",version:BM1.version,model:"gpt-5.4-mini",site:QM1,theme:ev,presets:{core:wM1,default:$M1,full:cTQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:lTQ,capabilities:[["prompt",zC,void 0],["note",UC,{}],["link",WC,{}],["image",Xh,void 0],["topics",E$A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",ouA,{memoryVisibility:"shared"}],["docs",QcA,void 0],["decks",Ui,void 0],["agents",J9A,void 0],["assessment",q9A,void 0],["auth-service",Bu,void 0],["notifications",p0A,void 0],["email-resend",EwA,void 0],["cms",NC,{}],["dashboard",az,void 0],["directory-sync",WM,{seedContent:!0,seedContentPath:uTQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Vr,{definitions:AM1}],["rizom-ecosystem",qC,void 0],["site-info",aM,void 0],["site-builder",sM,{}]],interfaces:[["mcp",q3,()=>({})],["discord",Qz,()=>({captureUrls:!0})],["a2a",aj,()=>({})],["webserver",Bz,()=>({})],["web-chat",sj,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"},{pattern:"web-chat:*",level:"anchor"}],entityActions:{base:{create:"trusted",update:"trusted",delete:"anchor"},link:{create:"trusted",update:"trusted",delete:"anchor"},doc:{create:"trusted",update:"trusted",delete:"anchor"},deck:{create:"trusted",update:"trusted",delete:"anchor"},decision:{create:"trusted",update:"trusted",delete:"anchor"},"action-item":{create:"trusted",update:"trusted",delete:"anchor"},image:{create:"trusted",update:"trusted",delete:"anchor"}}},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as VgQ}from"fs";import{join as EgQ}from"path";import{execSync as MgQ}from"child_process";import{parseArgs as rTQ}from"util";var dTQ={model:{type:"string"},domain:{type:"string"},"content-repo":{type:"string"},backend:{type:"string"},"push-to":{type:"string"},"ai-api-key":{type:"string"},"no-interactive":{type:"boolean"},preview:{type:"boolean"},deploy:{type:"boolean"},regen:{type:"boolean"},all:{type:"boolean"},only:{type:"string"},"dry-run":{type:"boolean"},"startup-check":{type:"boolean"},"storage-dir":{type:"string"},yes:{type:"boolean"},remote:{type:"string"},token:{type:"string"},outputDir:{type:"string"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function WX(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function wq(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function IM1(A){let{values:Q,positionals:B}=rTQ({args:A,options:dTQ,allowPositionals:!0,strict:!1});if(Q.help)return{command:"help",args:[],flags:{help:!0}};if(Q.version)return{command:"version",args:[],flags:{version:!0}};return{command:B[0]??"help",args:B.slice(1),flags:{model:WX(Q,"model"),domain:WX(Q,"domain"),"content-repo":WX(Q,"content-repo"),backend:WX(Q,"backend"),"push-to":WX(Q,"push-to"),"ai-api-key":WX(Q,"ai-api-key"),"no-interactive":wq(Q,"no-interactive"),preview:wq(Q,"preview"),deploy:wq(Q,"deploy"),regen:wq(Q,"regen"),all:wq(Q,"all"),only:WX(Q,"only"),"dry-run":wq(Q,"dry-run"),"startup-check":wq(Q,"startup-check"),"storage-dir":WX(Q,"storage-dir"),yes:wq(Q,"yes"),remote:WX(Q,"remote"),token:WX(Q,"token"),outputDir:WX(Q,"outputDir")}}}_r();import{mkdirSync as WgQ}from"fs";import{join as HgQ}from"path";import{execSync as GgQ}from"child_process";var U7A={name:"@rizom/brain",version:"0.2.0-alpha.122",description:"Brain runtime + CLI \u2014 scaffold, run, and manage AI brain instances",type:"module",bin:{brain:"./dist/brain.js"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./cli":"./dist/brain.js","./plugins":{types:"./dist/plugins.d.ts",import:"./dist/plugins.js"},"./entities":{types:"./dist/entities.d.ts",import:"./dist/entities.js"},"./services":{types:"./dist/services.d.ts",import:"./dist/services.js"},"./interfaces":{types:"./dist/interfaces.d.ts",import:"./dist/interfaces.js"},"./templates":{types:"./dist/templates.d.ts",import:"./dist/templates.js"},"./site":{types:"./dist/site.d.ts",import:"./dist/site.js"},"./themes":{types:"./dist/themes.d.ts",import:"./dist/themes.js"},"./deploy":{types:"./dist/deploy.d.ts",import:"./dist/deploy.js"},"./tsconfig.instance.json":"./tsconfig.instance.json"},files:["dist","templates","tsconfig.instance.json"],scripts:{build:"bun scripts/build.ts",prepublishOnly:"bun scripts/build.ts","dev:start":"bun scripts/build.ts && bun dist/brain.js start",typecheck:"tsc --noEmit",test:"bun test",lint:"eslint . --ext .ts"},dependencies:{"@clack/prompts":"^0.11.0","@modelcontextprotocol/sdk":"^1.24.0","@tailwindcss/postcss":"^4.1.13","@tailwindcss/typography":"^0.5.19",postcss:"^8.5.6",preact:"^10.27.2","preact-render-to-string":"^6.3.1",tailwindcss:"^4.1.11"},optionalDependencies:{"@bitwarden/sdk-napi":"^1.0.0","@libsql/client":"^0.15.7","@tailwindcss/oxide":"^4.1.4","better-sqlite3":"^11.8.1",lightningcss:"^1.29.2","playwright-core":"^1.56.0","react-devtools-core":"^6.1.1",sharp:"^0.34.5"},devDependencies:{"@brains/app":"workspace:*","@brains/content-formatters":"workspace:*","@brains/deploy-support":"workspace:*","@brains/eslint-config":"workspace:*","@brains/mcp-service":"workspace:*","@brains/plugins":"workspace:*","@brains/ranger":"workspace:*","@brains/relay":"workspace:*","@brains/rover":"workspace:*","@brains/site-composition":"workspace:*","@brains/site-default":"workspace:*","@brains/site-personal":"workspace:*","@brains/site-professional":"workspace:*","@brains/theme-default":"workspace:*","@brains/theme-rizom":"workspace:*","@brains/typescript-config":"workspace:*","@brains/utils":"workspace:*","@types/bun":"latest",rollup:"^4.60.2","rollup-plugin-dts":"^6.4.1",typescript:"^5.3.3"},publishConfig:{access:"public"},repository:{type:"git",url:"https://github.com/rizom-ai/brains.git",directory:"packages/brain-cli"},license:"Apache-2.0",author:"Yeehaa <yeehaa@rizom.ai> (https://rizom.ai)",homepage:"https://github.com/rizom-ai/brains/tree/main/packages/brain-cli#readme",bugs:"https://github.com/rizom-ai/brains/issues",engines:{bun:">=1.3.3"},keywords:["brain","ai","cli","mcp","agent","personal-ai","knowledge-management"]};import{mkdirSync as LM1,writeFileSync as Tr,chmodSync as yr,existsSync as GcA,readFileSync as KcA}from"fs";import{basename as FcA,dirname as ZcA,join as f6,resolve as RyQ}from"path";import{fileURLToPath as byQ}from"url";var DM1=`ARG BUN_VERSION=1.3.10
11661
11661
  FROM oven/bun:\${BUN_VERSION}-slim AS runtime
11662
11662
 
11663
11663
  WORKDIR /app