@rizom/brain 0.2.0-alpha.108 → 0.2.0-alpha.109

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
@@ -498,7 +498,7 @@ Some entity actions are gated by policy beyond simple tool availability. Two cas
498
498
  hash text NOT NULL,
499
499
  created_at numeric
500
500
  )
501
- `;await A.session.run($);let I=(await A.values(TA`SELECT id, hash, created_at FROM ${TA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Y=[];for(let X of B)if(!I||Number(I[2])<X.folderMillis){for(let W of X.sql)Y.push(A.run(TA.raw(W)));Y.push(A.run(TA`INSERT INTO ${TA.identifier(w)} ("hash", "created_at") VALUES(${X.hash}, ${X.folderMillis})`))}await A.session.migrate(Y)}var Es=c(()=>{$Y0();r5()});async function DY0(A,Q){let B=Q?.child("entity-migrate")??UQ.getInstance().child("entity-migrate"),{db:w,client:$,url:D}=dr(A);B.debug("Running entity database migrations...");try{await rr($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),await nr($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var IY0=c(()=>{Es();SDA();HA()});async function YY0(A,Q){let B=Q?.child("job-queue-migrate")??UQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:D}=pr(A);B.debug("Running job queue migrations...");try{await lr($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var XY0=c(()=>{Es();RDA();HA()});async function WY0(A,Q){let B=Q?.child("conversation-migrate")??UQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:D}=wn(A);B.debug("Running conversation database migrations...");try{if(D.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let Y=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var fY0=c(()=>{Es();ZIA();HA()});class lT{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Gv,migrateEntities:DY0,migrateJobQueue:YY0,migrateConversations:WY0}}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 sGA=c(()=>{qs();IY0();XY0();fY0()});function B02(){return process.env[Q02]}function HY0(){return B02()!=="production"}var Q02="NODE_ENV";var Vs;var aGA=c(()=>{HA();Vs=J.object({theme:J.object({primaryColor:J.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:J.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var JY0;var UY0=c(()=>{JY0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.108",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 oQ=y(($02,Ms)=>{(function(){function A(wA,gA){Object.defineProperty(w.prototype,wA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",gA[0],gA[1])}})}function Q(wA){if(wA===null||typeof wA!=="object")return null;return wA=lA&&wA[lA]||wA["@@iterator"],typeof wA==="function"?wA:null}function B(wA,gA){wA=(wA=wA.constructor)&&(wA.displayName||wA.name)||"ReactClass";var RA=wA+"."+gA;KA[RA]||(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.",gA,wA),KA[RA]=!0)}function w(wA,gA,RA){this.props=wA,this.context=gA,this.refs=rA,this.updater=RA||OA}function $(){}function D(wA,gA,RA){this.props=wA,this.context=gA,this.refs=rA,this.updater=RA||OA}function I(){}function Y(wA){return""+wA}function X(wA){try{Y(wA);var gA=!1}catch(J0){gA=!0}if(gA){gA=console;var RA=gA.error,mA=typeof Symbol==="function"&&Symbol.toStringTag&&wA[Symbol.toStringTag]||wA.constructor.name||"Object";return RA.call(gA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",mA),Y(wA)}}function W(wA){if(wA==null)return null;if(typeof wA==="function")return wA.$$typeof===W0?null:wA.displayName||wA.name||null;if(typeof wA==="string")return wA;switch(wA){case AA:return"Fragment";case UA:return"Profiler";case o:return"StrictMode";case G0:return"Suspense";case FA:return"SuspenseList";case zA:return"Activity"}if(typeof wA==="object")switch(typeof wA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),wA.$$typeof){case p:return"Portal";case DA:return wA.displayName||"Context";case LA:return(wA._context.displayName||"Context")+".Consumer";case B0:var gA=wA.render;return wA=wA.displayName,wA||(wA=gA.displayName||gA.name||"",wA=wA!==""?"ForwardRef("+wA+")":"ForwardRef"),wA;case Z0:return gA=wA.displayName||null,gA!==null?gA:W(wA.type)||"Memo";case D0:gA=wA._payload,wA=wA._init;try{return W(wA(gA))}catch(RA){}}return null}function H(wA){if(wA===AA)return"<>";if(typeof wA==="object"&&wA!==null&&wA.$$typeof===D0)return"<...>";try{var gA=W(wA);return gA?"<"+gA+">":"<...>"}catch(RA){return"<...>"}}function F(){var wA=w0.A;return wA===null?null:wA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(wA){if(bA.call(wA,"key")){var gA=Object.getOwnPropertyDescriptor(wA,"key").get;if(gA&&gA.isReactWarning)return!1}return wA.key!==void 0}function q(wA,gA){function RA(){$A||($A=!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)",gA))}RA.isReactWarning=!0,Object.defineProperty(wA,"key",{get:RA,configurable:!0})}function L(){var wA=W(this.type);return e0[wA]||(e0[wA]=!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.")),wA=this.props.ref,wA!==void 0?wA:null}function E(wA,gA,RA,mA,J0,M0){var tA=RA.ref;return wA={$$typeof:r,type:wA,key:gA,props:RA,_owner:mA},(tA!==void 0?tA:null)!==null?Object.defineProperty(wA,"ref",{enumerable:!1,get:L}):Object.defineProperty(wA,"ref",{enumerable:!1,value:null}),wA._store={},Object.defineProperty(wA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(wA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(wA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:J0}),Object.defineProperty(wA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:M0}),Object.freeze&&(Object.freeze(wA.props),Object.freeze(wA)),wA}function R(wA,gA){return gA=E(wA.type,gA,wA.props,wA._owner,wA._debugStack,wA._debugTask),wA._store&&(gA._store.validated=wA._store.validated),gA}function j(wA){C(wA)?wA._store&&(wA._store.validated=1):typeof wA==="object"&&wA!==null&&wA.$$typeof===D0&&(wA._payload.status==="fulfilled"?C(wA._payload.value)&&wA._payload.value._store&&(wA._payload.value._store.validated=1):wA._store&&(wA._store.validated=1))}function C(wA){return typeof wA==="object"&&wA!==null&&wA.$$typeof===r}function m(wA){var gA={"=":"=0",":":"=2"};return"$"+wA.replace(/[=:]/g,function(RA){return gA[RA]})}function i(wA,gA){return typeof wA==="object"&&wA!==null&&wA.key!=null?(X(wA.key),m(""+wA.key)):gA.toString(36)}function g(wA){switch(wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason;default:switch(typeof wA.status==="string"?wA.then(I,I):(wA.status="pending",wA.then(function(gA){wA.status==="pending"&&(wA.status="fulfilled",wA.value=gA)},function(gA){wA.status==="pending"&&(wA.status="rejected",wA.reason=gA)})),wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason}}throw wA}function x(wA,gA,RA,mA,J0){var M0=typeof wA;if(M0==="undefined"||M0==="boolean")wA=null;var tA=!1;if(wA===null)tA=!0;else switch(M0){case"bigint":case"string":case"number":tA=!0;break;case"object":switch(wA.$$typeof){case r:case p:tA=!0;break;case D0:return tA=wA._init,x(tA(wA._payload),gA,RA,mA,J0)}}if(tA){tA=wA,J0=J0(tA);var a0=mA===""?"."+i(tA,0):mA;return j0(J0)?(RA="",a0!=null&&(RA=a0.replace(_A,"$&/")+"/"),x(J0,gA,RA,"",function(h1){return h1})):J0!=null&&(C(J0)&&(J0.key!=null&&(tA&&tA.key===J0.key||X(J0.key)),RA=R(J0,RA+(J0.key==null||tA&&tA.key===J0.key?"":(""+J0.key).replace(_A,"$&/")+"/")+a0),mA!==""&&tA!=null&&C(tA)&&tA.key==null&&tA._store&&!tA._store.validated&&(RA._store.validated=2),J0=RA),gA.push(J0)),1}if(tA=0,a0=mA===""?".":mA+":",j0(wA))for(var S0=0;S0<wA.length;S0++)mA=wA[S0],M0=a0+i(mA,S0),tA+=x(mA,gA,RA,M0,J0);else if(S0=Q(wA),typeof S0==="function")for(S0===wA.entries&&(cA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),cA=!0),wA=S0.call(wA),S0=0;!(mA=wA.next()).done;)mA=mA.value,M0=a0+i(mA,S0++),tA+=x(mA,gA,RA,M0,J0);else if(M0==="object"){if(typeof wA.then==="function")return x(g(wA),gA,RA,mA,J0);throw gA=String(wA),Error("Objects are not valid as a React child (found: "+(gA==="[object Object]"?"object with keys {"+Object.keys(wA).join(", ")+"}":gA)+"). If you meant to render a collection of children, use an array instead.")}return tA}function T(wA,gA,RA){if(wA==null)return wA;var mA=[],J0=0;return x(wA,mA,"","",function(M0){return gA.call(RA,M0,J0++)}),mA}function S(wA){if(wA._status===-1){var gA=wA._ioInfo;gA!=null&&(gA.start=gA.end=performance.now()),gA=wA._result;var RA=gA();if(RA.then(function(J0){if(wA._status===0||wA._status===-1){wA._status=1,wA._result=J0;var M0=wA._ioInfo;M0!=null&&(M0.end=performance.now()),RA.status===void 0&&(RA.status="fulfilled",RA.value=J0)}},function(J0){if(wA._status===0||wA._status===-1){wA._status=2,wA._result=J0;var M0=wA._ioInfo;M0!=null&&(M0.end=performance.now()),RA.status===void 0&&(RA.status="rejected",RA.reason=J0)}}),gA=wA._ioInfo,gA!=null){gA.value=RA;var mA=RA.displayName;typeof mA==="string"&&(gA.name=mA)}wA._status===-1&&(wA._status=0,wA._result=RA)}if(wA._status===1)return gA=wA._result,gA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
501
+ `;await A.session.run($);let I=(await A.values(TA`SELECT id, hash, created_at FROM ${TA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,Y=[];for(let X of B)if(!I||Number(I[2])<X.folderMillis){for(let W of X.sql)Y.push(A.run(TA.raw(W)));Y.push(A.run(TA`INSERT INTO ${TA.identifier(w)} ("hash", "created_at") VALUES(${X.hash}, ${X.folderMillis})`))}await A.session.migrate(Y)}var Es=c(()=>{$Y0();r5()});async function DY0(A,Q){let B=Q?.child("entity-migrate")??UQ.getInstance().child("entity-migrate"),{db:w,client:$,url:D}=dr(A);B.debug("Running entity database migrations...");try{await rr($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),await nr($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var IY0=c(()=>{Es();SDA();HA()});async function YY0(A,Q){let B=Q?.child("job-queue-migrate")??UQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:D}=pr(A);B.debug("Running job queue migrations...");try{await lr($,D);let Y=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var XY0=c(()=>{Es();RDA();HA()});async function WY0(A,Q){let B=Q?.child("conversation-migrate")??UQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:D}=wn(A);B.debug("Running conversation database migrations...");try{if(D.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let Y=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await Rb(w,{migrationsFolder:Y}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var fY0=c(()=>{Es();ZIA();HA()});class lT{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Gv,migrateEntities:DY0,migrateJobQueue:YY0,migrateConversations:WY0}}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 sGA=c(()=>{qs();IY0();XY0();fY0()});function B02(){return process.env[Q02]}function HY0(){return B02()!=="production"}var Q02="NODE_ENV";var Vs;var aGA=c(()=>{HA();Vs=J.object({theme:J.object({primaryColor:J.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:J.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var JY0;var UY0=c(()=>{JY0={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.109",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 oQ=y(($02,Ms)=>{(function(){function A(wA,gA){Object.defineProperty(w.prototype,wA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",gA[0],gA[1])}})}function Q(wA){if(wA===null||typeof wA!=="object")return null;return wA=lA&&wA[lA]||wA["@@iterator"],typeof wA==="function"?wA:null}function B(wA,gA){wA=(wA=wA.constructor)&&(wA.displayName||wA.name)||"ReactClass";var RA=wA+"."+gA;KA[RA]||(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.",gA,wA),KA[RA]=!0)}function w(wA,gA,RA){this.props=wA,this.context=gA,this.refs=rA,this.updater=RA||OA}function $(){}function D(wA,gA,RA){this.props=wA,this.context=gA,this.refs=rA,this.updater=RA||OA}function I(){}function Y(wA){return""+wA}function X(wA){try{Y(wA);var gA=!1}catch(J0){gA=!0}if(gA){gA=console;var RA=gA.error,mA=typeof Symbol==="function"&&Symbol.toStringTag&&wA[Symbol.toStringTag]||wA.constructor.name||"Object";return RA.call(gA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",mA),Y(wA)}}function W(wA){if(wA==null)return null;if(typeof wA==="function")return wA.$$typeof===W0?null:wA.displayName||wA.name||null;if(typeof wA==="string")return wA;switch(wA){case AA:return"Fragment";case UA:return"Profiler";case o:return"StrictMode";case G0:return"Suspense";case FA:return"SuspenseList";case zA:return"Activity"}if(typeof wA==="object")switch(typeof wA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),wA.$$typeof){case p:return"Portal";case DA:return wA.displayName||"Context";case LA:return(wA._context.displayName||"Context")+".Consumer";case B0:var gA=wA.render;return wA=wA.displayName,wA||(wA=gA.displayName||gA.name||"",wA=wA!==""?"ForwardRef("+wA+")":"ForwardRef"),wA;case Z0:return gA=wA.displayName||null,gA!==null?gA:W(wA.type)||"Memo";case D0:gA=wA._payload,wA=wA._init;try{return W(wA(gA))}catch(RA){}}return null}function H(wA){if(wA===AA)return"<>";if(typeof wA==="object"&&wA!==null&&wA.$$typeof===D0)return"<...>";try{var gA=W(wA);return gA?"<"+gA+">":"<...>"}catch(RA){return"<...>"}}function F(){var wA=w0.A;return wA===null?null:wA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(wA){if(bA.call(wA,"key")){var gA=Object.getOwnPropertyDescriptor(wA,"key").get;if(gA&&gA.isReactWarning)return!1}return wA.key!==void 0}function q(wA,gA){function RA(){$A||($A=!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)",gA))}RA.isReactWarning=!0,Object.defineProperty(wA,"key",{get:RA,configurable:!0})}function L(){var wA=W(this.type);return e0[wA]||(e0[wA]=!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.")),wA=this.props.ref,wA!==void 0?wA:null}function E(wA,gA,RA,mA,J0,M0){var tA=RA.ref;return wA={$$typeof:r,type:wA,key:gA,props:RA,_owner:mA},(tA!==void 0?tA:null)!==null?Object.defineProperty(wA,"ref",{enumerable:!1,get:L}):Object.defineProperty(wA,"ref",{enumerable:!1,value:null}),wA._store={},Object.defineProperty(wA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(wA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(wA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:J0}),Object.defineProperty(wA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:M0}),Object.freeze&&(Object.freeze(wA.props),Object.freeze(wA)),wA}function R(wA,gA){return gA=E(wA.type,gA,wA.props,wA._owner,wA._debugStack,wA._debugTask),wA._store&&(gA._store.validated=wA._store.validated),gA}function j(wA){C(wA)?wA._store&&(wA._store.validated=1):typeof wA==="object"&&wA!==null&&wA.$$typeof===D0&&(wA._payload.status==="fulfilled"?C(wA._payload.value)&&wA._payload.value._store&&(wA._payload.value._store.validated=1):wA._store&&(wA._store.validated=1))}function C(wA){return typeof wA==="object"&&wA!==null&&wA.$$typeof===r}function m(wA){var gA={"=":"=0",":":"=2"};return"$"+wA.replace(/[=:]/g,function(RA){return gA[RA]})}function i(wA,gA){return typeof wA==="object"&&wA!==null&&wA.key!=null?(X(wA.key),m(""+wA.key)):gA.toString(36)}function g(wA){switch(wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason;default:switch(typeof wA.status==="string"?wA.then(I,I):(wA.status="pending",wA.then(function(gA){wA.status==="pending"&&(wA.status="fulfilled",wA.value=gA)},function(gA){wA.status==="pending"&&(wA.status="rejected",wA.reason=gA)})),wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason}}throw wA}function x(wA,gA,RA,mA,J0){var M0=typeof wA;if(M0==="undefined"||M0==="boolean")wA=null;var tA=!1;if(wA===null)tA=!0;else switch(M0){case"bigint":case"string":case"number":tA=!0;break;case"object":switch(wA.$$typeof){case r:case p:tA=!0;break;case D0:return tA=wA._init,x(tA(wA._payload),gA,RA,mA,J0)}}if(tA){tA=wA,J0=J0(tA);var a0=mA===""?"."+i(tA,0):mA;return j0(J0)?(RA="",a0!=null&&(RA=a0.replace(_A,"$&/")+"/"),x(J0,gA,RA,"",function(h1){return h1})):J0!=null&&(C(J0)&&(J0.key!=null&&(tA&&tA.key===J0.key||X(J0.key)),RA=R(J0,RA+(J0.key==null||tA&&tA.key===J0.key?"":(""+J0.key).replace(_A,"$&/")+"/")+a0),mA!==""&&tA!=null&&C(tA)&&tA.key==null&&tA._store&&!tA._store.validated&&(RA._store.validated=2),J0=RA),gA.push(J0)),1}if(tA=0,a0=mA===""?".":mA+":",j0(wA))for(var S0=0;S0<wA.length;S0++)mA=wA[S0],M0=a0+i(mA,S0),tA+=x(mA,gA,RA,M0,J0);else if(S0=Q(wA),typeof S0==="function")for(S0===wA.entries&&(cA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),cA=!0),wA=S0.call(wA),S0=0;!(mA=wA.next()).done;)mA=mA.value,M0=a0+i(mA,S0++),tA+=x(mA,gA,RA,M0,J0);else if(M0==="object"){if(typeof wA.then==="function")return x(g(wA),gA,RA,mA,J0);throw gA=String(wA),Error("Objects are not valid as a React child (found: "+(gA==="[object Object]"?"object with keys {"+Object.keys(wA).join(", ")+"}":gA)+"). If you meant to render a collection of children, use an array instead.")}return tA}function T(wA,gA,RA){if(wA==null)return wA;var mA=[],J0=0;return x(wA,mA,"","",function(M0){return gA.call(RA,M0,J0++)}),mA}function S(wA){if(wA._status===-1){var gA=wA._ioInfo;gA!=null&&(gA.start=gA.end=performance.now()),gA=wA._result;var RA=gA();if(RA.then(function(J0){if(wA._status===0||wA._status===-1){wA._status=1,wA._result=J0;var M0=wA._ioInfo;M0!=null&&(M0.end=performance.now()),RA.status===void 0&&(RA.status="fulfilled",RA.value=J0)}},function(J0){if(wA._status===0||wA._status===-1){wA._status=2,wA._result=J0;var M0=wA._ioInfo;M0!=null&&(M0.end=performance.now()),RA.status===void 0&&(RA.status="rejected",RA.reason=J0)}}),gA=wA._ioInfo,gA!=null){gA.value=RA;var mA=RA.displayName;typeof mA==="string"&&(gA.name=mA)}wA._status===-1&&(wA._status=0,wA._result=RA)}if(wA._status===1)return gA=wA._result,gA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
502
502
 
503
503
  Your code should look like:
504
504
  const MyComponent = lazy(() => import('./MyComponent'))
@@ -1738,7 +1738,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
1738
1738
  Title: "${A.entityTitle??Y}"
1739
1739
 
1740
1740
  Content:
1741
- ${W}`,v82);X=`${w.trim()} ${j.imagePrompt}`}catch(j){this.logger.warn("AI prompt distillation failed, using fallback",{error:x0(j)})}}await this.reportProgress(B,{progress:JQ.PROCESS,message:"Generating image"});let H=this.context.identity.get(),F=this.context.identity.getProfile(),Z=gU0(H,F)+X,q;try{q=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(j){return this.logger.error("Image generation failed",{jobId:Q,error:x0(j)}),m6.failure(j)}await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let L=b1(Y),E=CH.createImageEntity({dataUrl:q.dataUrl,title:Y});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:{...E,id:L}}),this.logger.debug("Created image entity",{imageId:L}),D&&I){await this.reportProgress(B,{progress:JQ.SAVE,message:`Updating ${D} with cover image`});let j=await qq(this.context.entityService,D,I,this.logger);if(!j)return m6.failure(Error(`Target entity not found: ${D}/${I}`));let C=$L(j,L);await this.context.entities.update(C),this.logger.debug("Updated target entity with cover image",{targetEntityType:D,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:D,targetEntityId:I}),{success:!0,imageId:L}}catch(X){return this.logger.error("Image generation job failed",{jobId:Q,error:x0(X)}),m6.failure(X)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}sA();HA();e8();d7();var g82=J.object({sourceEntityType:J.string().min(1),sourceEntityId:J.string().min(1),attachmentType:J.string().min(1),imageId:J.string().min(1),dedupKey:J.string().min(1).optional(),replace:J.boolean().optional(),targetEntityType:J.string().min(1).optional(),targetEntityId:J.string().min(1).optional(),targetImageField:J.enum(["coverImageId","ogImageId"]).optional()});class JZA extends Uw{context;constructor(A,Q){super(Q,{schema:g82,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 X=await this.findImageByDedupKey(A.dedupKey);if(X)return await this.updateTarget(A,X.id),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:X.id,reused:!0}}await this.reportProgress(B,{progress:JQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return m6.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return m6.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...CH.createImageEntity({dataUrl:pGA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},Y=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(Y)await this.context.entityService.updateEntity({entity:{...Y,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:JQ.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:x0(w)}),m6.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 qq(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"?pT(B,Q):$L(B,Q);await this.context.entities.update($)}}var SU0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.108",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 h82=J.object({defaultAspectRatio:J.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function CW(A){let Q=A?.trim();if(!Q)return;return Q}function m82(A){let Q=CW(A.prompt);if(Q)return Q;let B=CW(A.content);if(B&&!UZA(B))return B;return}function u82(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return b1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function hU0(A){let Q=CW(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return b1(Q)}async function c82(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 GZA(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}}}class FZA extends MQ{entityType=CH.entityType;schema=uT;adapter=CH;constructor(A={}){super("image",SU0,A,h82)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){let w=m82(A),$=CW(A.targetEntityType),D=CW(A.targetEntityId),I=$===this.entityType?D:void 0,Y=A.from;if(Y)return this.enqueueSourceImageRender({...A,from:Y},B);if(!$||!D||I){if(!w)return{kind:"continue",input:A};let K=CW(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...K&&{title:K}}}),q=hU0({prompt:w,...K&&{title:K}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:Z,attachment:GZA(q)}}}}let X=await EY(B.entityService,$,D,this.logger,"Target entity");if(!X.ok)return{kind:"handled",result:{success:!1,error:X.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:X.entity.id}};let W=pa(X.entity.content),H=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:X.entity.id,entityTitle:typeof X.entity.metadata.title==="string"?X.entity.metadata.title:X.entity.id,...W&&{entityContent:W}}}),F=hU0({prompt:w,...A.title&&{title:A.title},targetEntityId:X.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:F,status:"generating",jobId:H,attachment:GZA(F)}}}}async enqueueSourceImageRender(A,Q){let B=CW(A.from.sourceEntityType),w=CW(A.from.sourceEntityId),$=CW(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let D=await EY(Q.entityService,B,w,this.logger,"Source entity");if(!D.ok)return{kind:"handled",result:{success:!1,error:D.error}};let I=CW(A.targetEntityType),Y=CW(A.targetEntityId),X;if(I&&Y){let Z=await EY(Q.entityService,I,Y,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};X=Z.entity.id}let W={sourceEntityType:B,sourceEntityId:D.entity.id,attachmentType:$},H=await c82(Q,W),F=u82(W),K=await Q.jobs.enqueue({type:"image-render-source",data:{...W,imageId:F,dedupKey:H,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...X&&{targetEntityId:X},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:F,status:"generating",jobId:K,attachment:GZA(F,$)}}}}createGenerationHandler(A){return new la(A,this.logger)}async onRegister(A){let Q=new la(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new JZA(A,this.logger))}}function mg(A){return new FZA(A)}sA();import{StdioServerTransport as p82}from"@modelcontextprotocol/sdk/server/stdio.js";function mU0(){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 KZA(){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 ia(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 KZA()}class bW{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return bW.instance??=new bW(A),bW.instance}static resetInstance(){if(bW.instance)bW.instance.stop(),bW.instance=null}static createFresh(A){return new bW(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?ia(this.config.logger):mU0()}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 p82,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 uU0}from"crypto";import{WebStandardStreamableHTTPServerTransport as l82}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as i82}from"@modelcontextprotocol/sdk/types.js";var d82={"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 r82(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 qG{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?ia(this.config.logger):KZA(),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 qG.instance??=new qG(A),qG.instance}static resetInstance(){qG.instance=null}static createFresh(A){return new qG(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(d82))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:`${r82(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([D,I])=>`${D}="${n82(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??[],D=$.filter((I)=>!w.scope?.includes(I));if(D.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${D.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&&i82(B))w=new l82({sessionIdGenerator:()=>uU0(),onsessioninitialized:(D)=>{this.logger.info(`Session initialized: ${D}`),this.transports[D]=w},onsessionclosed:(D)=>{this.logger.info(`Session closed: ${D}`),delete this.transports[D]}}),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??uU0();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 n82(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as s82}from"crypto";import{mkdir as a82,readFile as t82,writeFile as e82,chmod as A62}from"fs/promises";import{dirname as Q62,join as B62}from"path";function cU0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function pU0(A){try{return new URL(A)}catch{return}}function ZZA(A,Q){if(A===Q)return!0;let B=pU0(A),w=pU0(Q);if(!B||!w)return!1;if(!cU0(B.hostname)||!cU0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&o82(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function o82(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function NZA(A,Q){return A.some((B)=>ZZA(B,Q))}var w62="oauth-auth-codes.json",$62=600;function lU0(){return Math.floor(Date.now()/1000)}function D62(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 I62(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(D62)}}async function Y62(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class da{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=B62(A.storageDir,A.storeFile??w62)}async createCode(A){let Q=lU0(),B={code:`ocd_${s82()}`,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+$62};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=lU0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((Y)=>Y.code===A.code),D=$>=0?w.codes[$]:void 0;if(!D)throw new RW("Authorization code not found");if(D.consumed_at!==void 0)throw new RW("Authorization code already consumed");if(D.expires_at<=Q)throw new RW("Authorization code expired");if(D.client_id!==A.clientId)throw new RW("Authorization code client mismatch");if(!ZZA(D.redirect_uri,A.redirectUri))throw new RW("Authorization code redirect URI mismatch");let I=await Y62(A.codeVerifier);if(D.code_challenge!==I)throw new RW("PKCE verification failed");B={...D,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new RW("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return I62(JSON.parse(await t82(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await a82(Q62(this.storeFile),{recursive:!0,mode:448}),await e82(this.storeFile,`${JSON.stringify(A,null,2)}
1741
+ ${W}`,v82);X=`${w.trim()} ${j.imagePrompt}`}catch(j){this.logger.warn("AI prompt distillation failed, using fallback",{error:x0(j)})}}await this.reportProgress(B,{progress:JQ.PROCESS,message:"Generating image"});let H=this.context.identity.get(),F=this.context.identity.getProfile(),Z=gU0(H,F)+X,q;try{q=await this.context.ai.generateImage(Z,{...$&&{aspectRatio:$}})}catch(j){return this.logger.error("Image generation failed",{jobId:Q,error:x0(j)}),m6.failure(j)}await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let L=b1(Y),E=CH.createImageEntity({dataUrl:q.dataUrl,title:Y});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:{...E,id:L}}),this.logger.debug("Created image entity",{imageId:L}),D&&I){await this.reportProgress(B,{progress:JQ.SAVE,message:`Updating ${D} with cover image`});let j=await qq(this.context.entityService,D,I,this.logger);if(!j)return m6.failure(Error(`Target entity not found: ${D}/${I}`));let C=$L(j,L);await this.context.entities.update(C),this.logger.debug("Updated target entity with cover image",{targetEntityType:D,targetEntityId:I,imageId:L})}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:L,targetEntityType:D,targetEntityId:I}),{success:!0,imageId:L}}catch(X){return this.logger.error("Image generation job failed",{jobId:Q,error:x0(X)}),m6.failure(X)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}sA();HA();e8();d7();var g82=J.object({sourceEntityType:J.string().min(1),sourceEntityId:J.string().min(1),attachmentType:J.string().min(1),imageId:J.string().min(1),dedupKey:J.string().min(1).optional(),replace:J.boolean().optional(),targetEntityType:J.string().min(1).optional(),targetEntityId:J.string().min(1).optional(),targetImageField:J.enum(["coverImageId","ogImageId"]).optional()});class JZA extends Uw{context;constructor(A,Q){super(Q,{schema:g82,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 X=await this.findImageByDedupKey(A.dedupKey);if(X)return await this.updateTarget(A,X.id),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Reusing existing generated image"}),{success:!0,imageId:X.id,reused:!0}}await this.reportProgress(B,{progress:JQ.PROCESS,message:"Rendering source image"});let w=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!w)return m6.failure(Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`));if(w.type!=="image")return m6.failure(Error(`Attachment provider returned ${w.type}; expected image`));await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let $=w.mimeType.split("/")[1]??"png",I={...CH.createImageEntity({dataUrl:pGA(w.data.toString("base64"),$),title:A.imageId,sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,...A.dedupKey&&{dedupKey:A.dedupKey}}),id:A.imageId},Y=await this.context.entityService.getEntity({entityType:"image",id:A.imageId});if(Y)await this.context.entityService.updateEntity({entity:{...Y,...I}});else await this.context.entityService.createEntity({entity:I});return await this.updateTarget(A,A.imageId),await this.reportProgress(B,{progress:JQ.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:x0(w)}),m6.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 qq(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"?pT(B,Q):$L(B,Q);await this.context.entities.update($)}}var SU0={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.109",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 h82=J.object({defaultAspectRatio:J.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});function CW(A){let Q=A?.trim();if(!Q)return;return Q}function m82(A){let Q=CW(A.prompt);if(Q)return Q;let B=CW(A.content);if(B&&!UZA(B))return B;return}function u82(A){let Q=A.attachmentType==="og-image"?"og":A.attachmentType;return b1(`${Q}-${A.sourceEntityType}-${A.sourceEntityId}`)}function hU0(A){let Q=CW(A.title)??(A.targetEntityId?`cover-${A.targetEntityId}`:A.prompt.slice(0,60).trim());return b1(Q)}async function c82(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 GZA(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}}}class FZA extends MQ{entityType=CH.entityType;schema=uT;adapter=CH;constructor(A={}){super("image",SU0,A,h82)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){let w=m82(A),$=CW(A.targetEntityType),D=CW(A.targetEntityId),I=$===this.entityType?D:void 0,Y=A.from;if(Y)return this.enqueueSourceImageRender({...A,from:Y},B);if(!$||!D||I){if(!w)return{kind:"continue",input:A};let K=CW(A.title)??I,Z=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...K&&{title:K}}}),q=hU0({prompt:w,...K&&{title:K}});return{kind:"handled",result:{success:!0,data:{entityId:q,status:"generating",jobId:Z,attachment:GZA(q)}}}}let X=await EY(B.entityService,$,D,this.logger,"Target entity");if(!X.ok)return{kind:"handled",result:{success:!1,error:X.error}};if(!w)return{kind:"continue",input:{...A,targetEntityId:X.entity.id}};let W=pa(X.entity.content),H=await B.jobs.enqueue({type:"image-generate",data:{prompt:w,...A.title&&{title:A.title},targetEntityType:$,targetEntityId:X.entity.id,entityTitle:typeof X.entity.metadata.title==="string"?X.entity.metadata.title:X.entity.id,...W&&{entityContent:W}}}),F=hU0({prompt:w,...A.title&&{title:A.title},targetEntityId:X.entity.id});return{kind:"handled",result:{success:!0,data:{entityId:F,status:"generating",jobId:H,attachment:GZA(F)}}}}async enqueueSourceImageRender(A,Q){let B=CW(A.from.sourceEntityType),w=CW(A.from.sourceEntityId),$=CW(A.from.attachmentType);if(!B||!w||!$)return{kind:"handled",result:{success:!1,error:"Image source requires sourceEntityType, sourceEntityId, and attachmentType"}};let D=await EY(Q.entityService,B,w,this.logger,"Source entity");if(!D.ok)return{kind:"handled",result:{success:!1,error:D.error}};let I=CW(A.targetEntityType),Y=CW(A.targetEntityId),X;if(I&&Y){let Z=await EY(Q.entityService,I,Y,this.logger,"Target entity");if(!Z.ok)return{kind:"handled",result:{success:!1,error:Z.error}};X=Z.entity.id}let W={sourceEntityType:B,sourceEntityId:D.entity.id,attachmentType:$},H=await c82(Q,W),F=u82(W),K=await Q.jobs.enqueue({type:"image-render-source",data:{...W,imageId:F,dedupKey:H,...A.replace===!0&&{replace:!0},...I&&{targetEntityType:I},...X&&{targetEntityId:X},...$==="og-image"&&{targetImageField:"ogImageId"}}});return{kind:"handled",result:{success:!0,data:{entityId:F,status:"generating",jobId:K,attachment:GZA(F,$)}}}}createGenerationHandler(A){return new la(A,this.logger)}async onRegister(A){let Q=new la(A,this.logger);A.jobs.registerHandler("image-generate",Q),A.jobs.registerHandler("image-render-source",new JZA(A,this.logger))}}function mg(A){return new FZA(A)}sA();import{StdioServerTransport as p82}from"@modelcontextprotocol/sdk/server/stdio.js";function mU0(){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 KZA(){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 ia(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 KZA()}class bW{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return bW.instance??=new bW(A),bW.instance}static resetInstance(){if(bW.instance)bW.instance.stop(),bW.instance=null}static createFresh(A){return new bW(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?ia(this.config.logger):mU0()}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 p82,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 uU0}from"crypto";import{WebStandardStreamableHTTPServerTransport as l82}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as i82}from"@modelcontextprotocol/sdk/types.js";var d82={"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 r82(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 qG{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?ia(this.config.logger):KZA(),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 qG.instance??=new qG(A),qG.instance}static resetInstance(){qG.instance=null}static createFresh(A){return new qG(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(d82))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:`${r82(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([D,I])=>`${D}="${n82(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??[],D=$.filter((I)=>!w.scope?.includes(I));if(D.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${D.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&&i82(B))w=new l82({sessionIdGenerator:()=>uU0(),onsessioninitialized:(D)=>{this.logger.info(`Session initialized: ${D}`),this.transports[D]=w},onsessionclosed:(D)=>{this.logger.info(`Session closed: ${D}`),delete this.transports[D]}}),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??uU0();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 n82(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as s82}from"crypto";import{mkdir as a82,readFile as t82,writeFile as e82,chmod as A62}from"fs/promises";import{dirname as Q62,join as B62}from"path";function cU0(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function pU0(A){try{return new URL(A)}catch{return}}function ZZA(A,Q){if(A===Q)return!0;let B=pU0(A),w=pU0(Q);if(!B||!w)return!1;if(!cU0(B.hostname)||!cU0(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&o82(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function o82(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function NZA(A,Q){return A.some((B)=>ZZA(B,Q))}var w62="oauth-auth-codes.json",$62=600;function lU0(){return Math.floor(Date.now()/1000)}function D62(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 I62(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(D62)}}async function Y62(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class da{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=B62(A.storageDir,A.storeFile??w62)}async createCode(A){let Q=lU0(),B={code:`ocd_${s82()}`,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+$62};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=lU0(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((Y)=>Y.code===A.code),D=$>=0?w.codes[$]:void 0;if(!D)throw new RW("Authorization code not found");if(D.consumed_at!==void 0)throw new RW("Authorization code already consumed");if(D.expires_at<=Q)throw new RW("Authorization code expired");if(D.client_id!==A.clientId)throw new RW("Authorization code client mismatch");if(!ZZA(D.redirect_uri,A.redirectUri))throw new RW("Authorization code redirect URI mismatch");let I=await Y62(A.codeVerifier);if(D.code_challenge!==I)throw new RW("PKCE verification failed");B={...D,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new RW("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return I62(JSON.parse(await t82(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await a82(Q62(this.storeFile),{recursive:!0,mode:448}),await e82(this.storeFile,`${JSON.stringify(A,null,2)}
1742
1742
  `,{mode:384}),await A62(this.storeFile,384)}}class RW extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as c30}from"crypto";HA();import{randomUUID as iU0}from"crypto";import{mkdir as X62,readFile as W62,writeFile as f62,chmod as H62}from"fs/promises";import{dirname as U62,join as J62}from"path";var G62="oauth-clients.json",F62=J.enum(["none","client_secret_basic","client_secret_post"]),K62=J.object({redirect_uris:J.array(J.string().url()).min(1),token_endpoint_auth_method:F62.default("none"),grant_types:J.array(J.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:J.array(J.literal("code")).default(["code"]),scope:J.string().optional(),client_name:J.string().optional(),client_uri:J.string().url().optional(),logo_uri:J.string().url().optional(),contacts:J.array(J.string()).optional()});function Z62(){return Math.floor(Date.now()/1000)}function N62(){return`ocs_${iU0().replaceAll("-","")}`}function z62(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(q62)}}function q62(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 ra{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=J62(A.storageDir,A.storeFile??G62)}async registerClient(A){let Q=K62.safeParse(A);if(!Q.success)throw new ug(Q.error.message);let B=Q.data,w=Z62(),$=`oc_${iU0()}`,D=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}:{},...!D?{client_secret:N62(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let Y=await this.readStore();Y.clients.push(I),await this.writeStore(Y)}),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 z62(JSON.parse(await W62(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await X62(U62(this.storeFile),{recursive:!0,mode:448}),await f62(this.storeFile,`${JSON.stringify(A,null,2)}
1743
1743
  `,{mode:384}),await H62(this.storeFile,384)}}class ug extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}function dU0(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function L62(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,D=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 Y=B+2,X=Q.slice(Y,Y+I);return new Uint8Array([...rU0(D),...rU0(X)])}function rU0(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 zZA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${dU0(B)}.${dU0(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),D=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(L62(D)).toString("base64url")}`}import{createHash as E62}from"crypto";import{mkdir as V62,readFile as M62,writeFile as O62,chmod as C62}from"fs/promises";import{dirname as b62,join as R62}from"path";var P62="oauth-signing-key.jwk";function nU0(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 oU0(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return E62("sha256").update(Q).digest("base64url")}function k62(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function j62(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!nU0(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=oU0(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class na{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=R62(A.storageDir,A.keyFile??P62)}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 j62();return await V62(b62(this.keyFile),{recursive:!0,mode:448}),await O62(this.keyFile,`${JSON.stringify(Q,null,2)}
1744
1744
  `,{mode:384}),await C62(this.keyFile,384),Q}async getPublicJwk(){return k62(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await M62(this.keyFile,"utf8"));if(!nU0(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:oU0(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var r2={};_B(r2,{trimPadding:()=>aU0,toUTF8String:()=>m62,toBuffer:()=>T62,toBase64:()=>S62,isBase64URL:()=>c62,isBase64:()=>u62,fromUTF8String:()=>h62,fromBuffer:()=>g62});var sU0=(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},_62=sU0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),y62=sU0("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),x62=/^[-A-Za-z0-9\-_]*$/,v62=/^[-A-Za-z0-9+/]*={0,3}$/,vH={};vH.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,D=0,I,Y,X,W;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let H=new ArrayBuffer(w),F=new Uint8Array(H),K=Q?y62:_62;for($=0;$<B;$+=4)I=K[A.charCodeAt($)],Y=K[A.charCodeAt($+1)],X=K[A.charCodeAt($+2)],W=K[A.charCodeAt($+3)],F[D++]=I<<2|Y>>4,F[D++]=(Y&15)<<4|X>>2,F[D++]=(X&3)<<6|W&63;return H};vH.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",D=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<D;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 Y=D%3;if(Y===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(Y===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};vH.toString=(A,Q)=>{return new TextDecoder().decode(vH.toArrayBuffer(A,Q))};vH.fromString=(A,Q)=>{return vH.fromArrayBuffer(new TextEncoder().encode(A),Q)};vH.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?x62.test(A):v62.test(A)}catch(B){return!1}};vH.base64=vH;var LG=vH;function T62(A,Q="base64url"){let B=LG.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function g62(A,Q="base64url"){let B=new Uint8Array(A);return LG.fromArrayBuffer(B.buffer,Q==="base64url")}function S62(A){let Q=LG.toArrayBuffer(A,!0);return LG.fromArrayBuffer(Q)}function h62(A){return LG.fromString(A,!0)}function m62(A){return LG.toString(A,!0)}function u62(A){return LG.validate(A,!1)}function c62(A){return A=aU0(A),LG.validate(A,!0)}function aU0(A){return A.replace(/=/g,"")}var o7={};_B(o7,{encode:()=>W52,decodeFirst:()=>X52});function YR(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),D,I=0;switch(Q){case 24:{if(w>0)D=$.getUint8(0),I=2;break}case 25:{if(w>1)D=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)D=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let Y=$.getBigUint64(0,!1);if(Y>=24n&&Y<=Number.MAX_SAFE_INTEGER)return[Number(Y),9]}break}}if(D&&D>=24)return[D,I];throw Error("Length not supported or not well formed")}var oa=0,cg=1,qZA=2,LZA=3,EZA=4,VZA=5,MZA=6,tU0=7;function TH(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==cg){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 aa{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 eU0(A,Q,B){return YR(A,Q,B)}function p62(A,Q,B){let[w,$]=eU0(A,Q,B);return[-w-1,$]}function AJ0(A,Q,B){let[w,$]=YR(A,Q,B),D=B+$;return[new Uint8Array(A.buffer.slice(D,D+w)),$+w]}var l62=new TextDecoder;function i62(A,Q,B){let[w,$]=AJ0(A,Q,B);return[l62.decode(w),$]}function d62(A,Q,B){if(Q===0)return[[],1];let[w,$]=YR(A,Q,B),D=$,I=[];for(let Y=0;Y<w;Y++){if(A.byteLength-B-D<=0)throw Error("array is not supported or well formed");let[W,H]=EL(A,B+D);I.push(W),D+=H}return[I,D]}var sa="Map is not supported or well formed";function r62(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=YR(A,Q,B),D=$,I=new Map;for(let Y=0;Y<w;Y++){let X=A.byteLength-B-D;if(X<=0)throw Error(sa);let[W,H]=EL(A,B+D);if(D+=H,X-=H,X<=0)throw Error(sa);if(typeof W!=="string"&&typeof W!=="number")throw Error(sa);if(I.has(W))throw Error(sa);let[F,K]=EL(A,B+D);D+=K,I.set(W,F)}return[I,D]}function n62(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 o62(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 s62(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 a62(A,Q,B){let[w,$]=YR(A,Q,B),[D,I]=EL(A,B+$);return[new aa(w,D),$+I]}function EL(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 oa:return eU0(A,$,Q);case cg:return p62(A,$,Q);case qZA:return AJ0(A,$,Q);case LZA:return i62(A,$,Q);case EZA:return d62(A,$,Q);case VZA:return r62(A,$,Q);case MZA:return a62(A,$,Q);case tU0: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 n62(A,Q);case 26:return o62(A,Q);case 27:return s62(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function t62(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function e62(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 A52(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return TH(cg,Math.abs(A));else return TH(oa,A);return[e62(A)]}else if(A<0n)return TH(cg,A*-1n);else return TH(oa,A)}var Q52=new TextEncoder;function B52(A,Q){Q.push(...TH(LZA,A.length)),Q.push(Q52.encode(A))}function w52(A,Q){Q.push(...TH(qZA,A.length)),Q.push(A)}function $52(A,Q){Q.push(...TH(EZA,A.length));for(let B of A)pg(B,Q)}function D52(A,Q){Q.push(new Uint8Array(TH(VZA,A.size)));for(let[B,w]of A.entries())pg(B,Q),pg(w,Q)}function I52(A,Q){Q.push(...TH(MZA,A.tag)),pg(A.value,Q)}function pg(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(t62(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...A52(A));return}if(typeof A=="string"){B52(A,Q);return}if(A instanceof Uint8Array){w52(A,Q);return}if(Array.isArray(A)){$52(A,Q);return}if(A instanceof Map){D52(A,Q);return}if(A instanceof aa){I52(A,Q);return}throw Error("Not implemented")}function OZA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return EL(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return EL(new DataView(A),Q);return EL(A,Q)}function CZA(A){let Q=[];pg(A,Q);let B=0;for(let D of Q)if(typeof D=="number")B+=1;else B+=D.length;let w=new Uint8Array(B),$=0;for(let D of Q)if(typeof D=="number")w[$]=D,$+=1;else w.set(D,$),$+=D.length;return w}function X52(A){let Q=new Uint8Array(A),B=OZA(Q,0),[w]=B;return w}function W52(A){return CZA(A)}var SH={};_B(SH,{verify:()=>vZ0,getRandomValues:()=>DJ0,digest:()=>$J0});function QJ0(A){let Q=A.get(l2.kty);return bZA(Q)&&Q===XI.OKP}function iZ(A){let Q=A.get(l2.kty);return bZA(Q)&&Q===XI.EC2}function XR(A){let Q=A.get(l2.kty);return bZA(Q)&&Q===XI.RSA}var l2;(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"})(l2||(l2={}));var XI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(XI||(XI={}));function bZA(A){return Object.values(XI).indexOf(A)>=0}var t9;(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"})(t9||(t9={}));function BJ0(A){return Object.values(t9).indexOf(A)>=0}var KQ;(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"})(KQ||(KQ={}));function gH(A){return Object.values(KQ).indexOf(A)>=0}function dZ(A){if([KQ.RS1].indexOf(A)>=0)return"SHA-1";else if([KQ.ES256,KQ.PS256,KQ.RS256].indexOf(A)>=0)return"SHA-256";else if([KQ.ES384,KQ.PS384,KQ.RS384].indexOf(A)>=0)return"SHA-384";else if([KQ.ES512,KQ.PS512,KQ.RS512,KQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var lg=void 0;function p4(){return new Promise((Q,B)=>{if(lg)return Q(lg);let w=H52.stubThisGlobalThisCrypto();if(w)return lg=w,Q(lg);return B(new wJ0)})}class wJ0 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var H52={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{lg=A}};async function $J0(A,Q){let B=await p4(),w=dZ(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function DJ0(A){return(await p4()).getRandomValues(A),A}async function WR(A){let Q=await p4(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function ta(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,D=await p4(),I=Q.get(l2.alg),Y=Q.get(l2.crv),X=Q.get(l2.x),W=Q.get(l2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!Y)throw Error("Public key was missing crv (EC2)");if(!X)throw Error("Public key was missing x (EC2)");if(!W)throw Error("Public key was missing y (EC2)");let H;if(Y===t9.P256)H="P-256";else if(Y===t9.P384)H="P-384";else if(Y===t9.P521)H="P-521";else throw Error(`Unexpected COSE crv value of ${Y} (EC2)`);let F={kty:"EC",crv:H,x:r2.fromBuffer(X),y:r2.fromBuffer(W),ext:!1},Z=await WR({keyData:F,algorithm:{name:"ECDSA",namedCurve:H}}),q=dZ(I);if($)q=dZ($);let L={name:"ECDSA",hash:{name:q}};return D.subtle.verify(L,Z,B,w)}function RZA(A){if([KQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([KQ.ES256,KQ.ES384,KQ.ES512,KQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([KQ.RS256,KQ.RS384,KQ.RS512,KQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([KQ.PS256,KQ.PS384,KQ.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 ea(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,D=await p4(),I=Q.get(l2.alg),Y=Q.get(l2.n),X=Q.get(l2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!gH(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!Y)throw Error("Public key was missing n (RSA)");if(!X)throw Error("Public key was missing e (RSA)");let W={kty:"RSA",alg:"",n:r2.fromBuffer(Y),e:r2.fromBuffer(X),ext:!1},H={name:RZA(I),hash:{name:dZ(I)}},F={name:RZA(I)};if($)H.hash.name=dZ($);if(H.name==="RSASSA-PKCS1-v1_5"){if(H.hash.name==="SHA-256")W.alg="RS256";else if(H.hash.name==="SHA-384")W.alg="RS384";else if(H.hash.name==="SHA-512")W.alg="RS512";else if(H.hash.name==="SHA-1")W.alg="RS1"}else if(H.name==="RSA-PSS"){let Z=0;if(H.hash.name==="SHA-256")W.alg="PS256",Z=32;else if(H.hash.name==="SHA-384")W.alg="PS384",Z=48;else if(H.hash.name==="SHA-512")W.alg="PS512",Z=64;F.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${H.name})`);let K=await WR({keyData:W,algorithm:H});return D.subtle.verify(F,K,B,w)}function At(A){let Q=U2.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 O5(A){let Q;if(typeof A==="string")if(r2.isBase64URL(A))Q=r2.toBase64(A);else if(r2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=r2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
@@ -2317,8 +2317,8 @@ ${R}`)}if(w!==void 0&&D?.algorithms!==void 0){let E=D.algorithms.map((R)=>R.alg)
2317
2317
  </form>
2318
2318
  </main>
2319
2319
  </body>
2320
- </html>`}function SzA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hzA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(o30(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function ye(A){let Q=Oh(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function eH(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}HA();var ve="email:send",a30=J.object({to:J.string().email(),subject:J.string().min(1),text:J.string().min(1),html:J.string().min(1).optional(),sensitivity:J.enum(["normal","secret"]).default("normal")}).strict();sA();HA();var t30={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.108",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 uzA="notifications:send",s72=J.object({}),a72=J.discriminatedUnion("type",[J.object({type:J.literal("email"),address:J.string().email()}).strict()]),t72=J.object({recipient:a72,title:J.string().min(1),body:J.string().min(1),html:J.string().min(1).optional(),sensitivity:J.enum(["normal","secret"]).default("normal")}).strict(),e30=J.discriminatedUnion("status",[J.object({status:J.literal("sent"),deliveryId:J.string().optional()}).strict(),J.object({status:J.literal("failed")}).strict()]);class AN0 extends QB{constructor(A={}){super("notifications",t30,A,s72)}async onRegister(A){A.messaging.subscribe(uzA,async(Q)=>{let B=t72.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:ve,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let D=$.data;if(D.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:D.id?{status:"sent",deliveryId:D.id}:{status:"sent"}}})}}function Te(A={}){return new AN0(A)}sA();HA();var QN0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.108",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 A42=J.union([J.string().email(),J.object({to:J.string().email(),subject:J.string().min(1),body:J.string().min(1)}).strict()]),Q42=J.object({issuer:J.string().optional(),trustedIssuers:J.array(J.string()).default([]),allowLocalhostIssuers:J.boolean().optional(),storageDir:J.string().default("./data/auth"),setupEmail:A42.optional()}),B42=J.object({}),ge;function pY(){return ge}class czA extends QB{service;constructor(A={}){super("auth-service",QN0,A,Q42)}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 xe({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},logger:A.logger}),await this.service.initialize(),ge=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(ge===this.service)ge=void 0;this.service=void 0}async getTools(){return[uQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",B42,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return K8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return K8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return K8({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=w42(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:uzA,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 D=e30.safeParse($.data);if(!D.success||D.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,D.data.deliveryId?{deliveryId:D.data.deliveryId}:{})}}function w42(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(`
2321
- `)}}return{to:A.to,subject:BN0(A.subject,Q),body:BN0(A.body,Q)}}function BN0(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 Ph(A){return new czA(A)}HA();var pzA=J.object({transport:J.enum(["stdio","http"]).default("http"),httpPort:J.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:J.string().describe("Bearer token for HTTP transport authentication").optional()});function wN0(A,Q){return[]}sA();function lzA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=XC.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,D=$.type,I=$.status,Y=$.id;if(Q.debug(`${D} ${Y} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${Y}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${Y}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var $N0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.108",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 L3 extends JH{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",$N0,Q,pzA)}async getTools(){return wN0(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"});lzA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=pY();return this.httpServer=qG.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||pY()))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=bW.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(){bW.resetInstance(),qG.resetInstance()}}sA();HA();var EI=X1(nn0(),1);HA();sA();var OCA=J.object({botToken:J.string().min(1).describe("Discord bot token"),allowedChannels:J.array(J.string()).default([]),requireMention:J.boolean().default(!0),allowDMs:J.boolean().default(!0),showTypingIndicator:J.boolean().default(!0),statusMessage:J.string().default("Mention me to chat"),useThreads:J.boolean().default(!0),threadAutoArchive:J.union([J.literal(60),J.literal(1440),J.literal(4320),J.literal(10080)]).default(1440),...fv.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var on0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.108",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 m1A=2000,zh2=8000,qh2=100;function u1A(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class BN extends oJ{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",on0,A,OCA);this.fetchText=Q.fetchText??td}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(!u1A(B))return;let w=Fx(Q,m1A);for(let $ of w)B.send($).catch((D)=>this.logger.error("Failed to send message",{error:D}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),D=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,D)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!u1A(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=Fx(Q,m1A),$;for(let D of w)$=(await B.send(D)).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(!u1A(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,m1A)),!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,D=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(D),Y={channelId:D,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,D))return;let X=Q||$||!this.config.requireMention||w;if(I&&(!X||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,D).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:D}));if(!X){if(this.config.captureUrls){let F=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(F.length>0){await A.react(this.config.captureUrlEmoji).catch((K)=>this.logger.debug("React failed",{error:K}));for(let K of F)await this.captureUrlViaAgent(K,A.channel.id,A.author.id,"discord",Y).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let W=this.stripMention(A.content);if(A.attachments.size>0){let F=this.context.permissions.getUserLevel("discord",A.author.id,Y);if(F==="anchor"||F==="trusted")for(let Z of A.attachments.values()){let q=Z.name,L=Z.contentType??void 0,E=Z.size;if(!this.isUploadableTextFile(q,L))continue;if(!this.isFileSizeAllowed(E))continue;try{let R=await this.fetchText(Z.url);W+=`
2320
+ </html>`}function SzA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function hzA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(o30(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function ye(A){let Q=Oh(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function eH(A){return A.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}HA();var ve="email:send",a30=J.object({to:J.string().email(),subject:J.string().min(1),text:J.string().min(1),html:J.string().min(1).optional(),sensitivity:J.enum(["normal","secret"]).default("normal")}).strict();sA();HA();var t30={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.109",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 uzA="notifications:send",s72=J.object({}),a72=J.discriminatedUnion("type",[J.object({type:J.literal("email"),address:J.string().email()}).strict()]),t72=J.object({recipient:a72,title:J.string().min(1),body:J.string().min(1),html:J.string().min(1).optional(),sensitivity:J.enum(["normal","secret"]).default("normal")}).strict(),e30=J.discriminatedUnion("status",[J.object({status:J.literal("sent"),deliveryId:J.string().optional()}).strict(),J.object({status:J.literal("failed")}).strict()]);class AN0 extends QB{constructor(A={}){super("notifications",t30,A,s72)}async onRegister(A){A.messaging.subscribe(uzA,async(Q)=>{let B=t72.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:ve,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let D=$.data;if(D.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:D.id?{status:"sent",deliveryId:D.id}:{status:"sent"}}})}}function Te(A={}){return new AN0(A)}sA();HA();var QN0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.109",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 A42=J.union([J.string().email(),J.object({to:J.string().email(),subject:J.string().min(1),body:J.string().min(1)}).strict()]),Q42=J.object({issuer:J.string().optional(),trustedIssuers:J.array(J.string()).default([]),allowLocalhostIssuers:J.boolean().optional(),storageDir:J.string().default("./data/auth"),setupEmail:A42.optional()}),B42=J.object({}),ge;function pY(){return ge}class czA extends QB{service;constructor(A={}){super("auth-service",QN0,A,Q42)}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 xe({storageDir:this.config.storageDir,...Q?{issuer:Q}:{},trustedIssuers:this.config.trustedIssuers,...this.config.allowLocalhostIssuers!==void 0?{allowLocalhostIssuers:this.config.allowLocalhostIssuers}:{},logger:A.logger}),await this.service.initialize(),ge=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(ge===this.service)ge=void 0;this.service=void 0}async getTools(){return[uQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",B42,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return K8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return K8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return K8({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=w42(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:uzA,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 D=e30.safeParse($.data);if(!D.success||D.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,D.data.deliveryId?{deliveryId:D.data.deliveryId}:{})}}function w42(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(`
2321
+ `)}}return{to:A.to,subject:BN0(A.subject,Q),body:BN0(A.body,Q)}}function BN0(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 Ph(A){return new czA(A)}HA();var pzA=J.object({transport:J.enum(["stdio","http"]).default("http"),httpPort:J.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:J.string().describe("Bearer token for HTTP transport authentication").optional()});function wN0(A,Q){return[]}sA();function lzA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=XC.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,D=$.type,I=$.status,Y=$.id;if(Q.debug(`${D} ${Y} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${Y}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${Y}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var $N0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.109",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 L3 extends JH{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",$N0,Q,pzA)}async getTools(){return wN0(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"});lzA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=pY();return this.httpServer=qG.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||pY()))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=bW.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(){bW.resetInstance(),qG.resetInstance()}}sA();HA();var EI=X1(nn0(),1);HA();sA();var OCA=J.object({botToken:J.string().min(1).describe("Discord bot token"),allowedChannels:J.array(J.string()).default([]),requireMention:J.boolean().default(!0),allowDMs:J.boolean().default(!0),showTypingIndicator:J.boolean().default(!0),statusMessage:J.string().default("Mention me to chat"),useThreads:J.boolean().default(!0),threadAutoArchive:J.union([J.literal(60),J.literal(1440),J.literal(4320),J.literal(10080)]).default(1440),...fv.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var on0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.109",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 m1A=2000,zh2=8000,qh2=100;function u1A(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class BN extends oJ{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",on0,A,OCA);this.fetchText=Q.fetchText??td}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(!u1A(B))return;let w=Fx(Q,m1A);for(let $ of w)B.send($).catch((D)=>this.logger.error("Failed to send message",{error:D}))}async sendMessageWithId({channelId:A,message:Q,approvalCard:B,approvalCards:w}){let $=w??(B?[B]:[]),D=$.length>0?this.buildApprovalMessagePayload(Q,$):Q;return this.sendPayloadWithId(A,D)}async sendPayloadWithId(A,Q){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!u1A(B))return;if(typeof Q!=="string")return(await B.send(Q)).id;let w=Fx(Q,m1A),$;for(let D of w)$=(await B.send(D)).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(!u1A(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,m1A)),!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,D=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(D),Y={channelId:D,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,D))return;let X=Q||$||!this.config.requireMention||w;if(I&&(!X||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,D).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:D}));if(!X){if(this.config.captureUrls){let F=this.extractCaptureableUrls(A.content,this.config.blockedUrlDomains);if(F.length>0){await A.react(this.config.captureUrlEmoji).catch((K)=>this.logger.debug("React failed",{error:K}));for(let K of F)await this.captureUrlViaAgent(K,A.channel.id,A.author.id,"discord",Y).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let W=this.stripMention(A.content);if(A.attachments.size>0){let F=this.context.permissions.getUserLevel("discord",A.author.id,Y);if(F==="anchor"||F==="trusted")for(let Z of A.attachments.values()){let q=Z.name,L=Z.contentType??void 0,E=Z.size;if(!this.isUploadableTextFile(q,L))continue;if(!this.isFileSizeAllowed(E))continue;try{let R=await this.fetchText(Z.url);W+=`
2322
2322
 
2323
2323
  `+this.formatFileUploadMessage(q,R)}catch(R){this.logger.error("Failed to download attachment",{error:R,filename:q})}}}if(W=W.trim(),!W)return;let H=A.channel.id;await this.routeToAgent(W,H,A,Y)}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((D)=>this.logger.debug("Failed to reply to stale approval button",{error:D}));return}await A.deferUpdate().catch((D)=>this.logger.debug("Failed to defer approval button",{error:D})),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,D=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{D=(await B.startThread({name:u9(A,qh2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(W){this.logger.error("Failed to create thread",{error:W})}let I=`discord-${D}`,Y=this.context.permissions.getUserLevel("discord",B.author.id,w),X=this.getChannelName(B);this.startProcessingInput(D);try{let W=this.client?.channels.cache.get(D);if(u1A(W))this.startTypingIndicator(W);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,D);return}let H=await $.chat(A,I,{userPermissionLevel:Y,interfaceType:"discord",channelId:D,channelName:X,...this.buildUserMessageMetadata(B,Q,X,{threadId:D!==Q||B.channel.isThread()?D:void 0})}),F=this.getPendingApprovalCards(H.cards);if(F.length>0)this.pendingConfirmations.set(I,new Set(F.map((Z)=>Z.id)));else if(H.pendingConfirmations)this.pendingConfirmations.set(I,new Set(H.pendingConfirmations.map((Z)=>Z.id)));let K=await this.sendMessageWithId({channelId:D,message:this.formatAgentResponseText(H.text,F),approvalCards:F});if(K&&H.toolResults){for(let Z of H.toolResults)if(Z.jobId)this.trackAgentResponseForJob(Z.jobId,K,D)}}catch(W){this.logger.error("Error handling message",{error:W,channelId:D}),this.sendMessageToChannel({channelId:D,message:`**Error:** ${W instanceof Error?W.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(D)}}buildApprovalMessagePayload(A,Q){let B=Q.length>1;return{content:u9(A.trim().length>0?`${A}
2324
2324
 
@@ -2389,7 +2389,7 @@ Use the buttons below${B?" for the matching action":", or reply **yes** / **no**
2389
2389
  <p>Once built, this page will be replaced with your actual website.</p>
2390
2390
  </div>
2391
2391
  </body>
2392
- </html>`;var Ro0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.108",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 wN extends JH{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Ro0,A,mCA)}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 e1A({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&&!Po0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(ko0(this.config.previewDistDir,"index.html"),uCA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!Po0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(ko0(this.config.productionDistDir,"index.html"),uCA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}sA();HA();var Ds0="vercel.ai.error",Wm2=Symbol.for(Ds0),jo0,_o0,zB=class A extends(_o0=Error,jo0=Wm2,_o0){constructor({name:Q,message:B,cause:w}){super(B);this[jo0]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,Ds0)}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}},Is0="AI_APICallError",Ys0=`vercel.ai.error.${Is0}`,fm2=Symbol.for(Ys0),yo0,xo0,sIw=class extends(xo0=zB,yo0=fm2,xo0){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:D,cause:I,isRetryable:Y=w!=null&&(w===408||w===409||w===429||w>=500),data:X}){super({name:Is0,message:A,cause:I});this[yo0]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=D,this.isRetryable=Y,this.data=X}static isInstance(A){return zB.hasMarker(A,Ys0)}},Xs0="AI_EmptyResponseBodyError",Ws0=`vercel.ai.error.${Xs0}`,Hm2=Symbol.for(Ws0),vo0,To0,aIw=class extends(To0=zB,vo0=Hm2,To0){constructor({message:A="Empty response body"}={}){super({name:Xs0,message:A});this[vo0]=!0}static isInstance(A){return zB.hasMarker(A,Ws0)}};function fs0(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 Hs0="AI_InvalidArgumentError",Us0=`vercel.ai.error.${Hs0}`,Um2=Symbol.for(Us0),go0,So0,Js0=class extends(So0=zB,go0=Um2,So0){constructor({message:A,cause:Q,argument:B}){super({name:Hs0,message:A,cause:Q});this[go0]=!0,this.argument=B}static isInstance(A){return zB.hasMarker(A,Us0)}},Gs0="AI_InvalidPromptError",Fs0=`vercel.ai.error.${Gs0}`,Jm2=Symbol.for(Fs0),ho0,mo0,tIw=class extends(mo0=zB,ho0=Jm2,mo0){constructor({prompt:A,message:Q,cause:B}){super({name:Gs0,message:`Invalid prompt: ${Q}`,cause:B});this[ho0]=!0,this.prompt=A}static isInstance(A){return zB.hasMarker(A,Fs0)}},Ks0="AI_InvalidResponseDataError",Zs0=`vercel.ai.error.${Ks0}`,Gm2=Symbol.for(Zs0),uo0,co0,eIw=class extends(co0=zB,uo0=Gm2,co0){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:Ks0,message:Q});this[uo0]=!0,this.data=A}static isInstance(A){return zB.hasMarker(A,Zs0)}},Ns0="AI_JSONParseError",zs0=`vercel.ai.error.${Ns0}`,Fm2=Symbol.for(zs0),po0,lo0,cCA=class extends(lo0=zB,po0=Fm2,lo0){constructor({text:A,cause:Q}){super({name:Ns0,message:`JSON parsing failed: Text: ${A}.
2392
+ </html>`;var Ro0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.109",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 wN extends JH{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Ro0,A,mCA)}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 e1A({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&&!Po0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(ko0(this.config.previewDistDir,"index.html"),uCA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!Po0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(ko0(this.config.productionDistDir,"index.html"),uCA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}sA();HA();var Ds0="vercel.ai.error",Wm2=Symbol.for(Ds0),jo0,_o0,zB=class A extends(_o0=Error,jo0=Wm2,_o0){constructor({name:Q,message:B,cause:w}){super(B);this[jo0]=!0,this.name=Q,this.cause=w}static isInstance(Q){return A.hasMarker(Q,Ds0)}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}},Is0="AI_APICallError",Ys0=`vercel.ai.error.${Is0}`,fm2=Symbol.for(Ys0),yo0,xo0,sIw=class extends(xo0=zB,yo0=fm2,xo0){constructor({message:A,url:Q,requestBodyValues:B,statusCode:w,responseHeaders:$,responseBody:D,cause:I,isRetryable:Y=w!=null&&(w===408||w===409||w===429||w>=500),data:X}){super({name:Is0,message:A,cause:I});this[yo0]=!0,this.url=Q,this.requestBodyValues=B,this.statusCode=w,this.responseHeaders=$,this.responseBody=D,this.isRetryable=Y,this.data=X}static isInstance(A){return zB.hasMarker(A,Ys0)}},Xs0="AI_EmptyResponseBodyError",Ws0=`vercel.ai.error.${Xs0}`,Hm2=Symbol.for(Ws0),vo0,To0,aIw=class extends(To0=zB,vo0=Hm2,To0){constructor({message:A="Empty response body"}={}){super({name:Xs0,message:A});this[vo0]=!0}static isInstance(A){return zB.hasMarker(A,Ws0)}};function fs0(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 Hs0="AI_InvalidArgumentError",Us0=`vercel.ai.error.${Hs0}`,Um2=Symbol.for(Us0),go0,So0,Js0=class extends(So0=zB,go0=Um2,So0){constructor({message:A,cause:Q,argument:B}){super({name:Hs0,message:A,cause:Q});this[go0]=!0,this.argument=B}static isInstance(A){return zB.hasMarker(A,Us0)}},Gs0="AI_InvalidPromptError",Fs0=`vercel.ai.error.${Gs0}`,Jm2=Symbol.for(Fs0),ho0,mo0,tIw=class extends(mo0=zB,ho0=Jm2,mo0){constructor({prompt:A,message:Q,cause:B}){super({name:Gs0,message:`Invalid prompt: ${Q}`,cause:B});this[ho0]=!0,this.prompt=A}static isInstance(A){return zB.hasMarker(A,Fs0)}},Ks0="AI_InvalidResponseDataError",Zs0=`vercel.ai.error.${Ks0}`,Gm2=Symbol.for(Zs0),uo0,co0,eIw=class extends(co0=zB,uo0=Gm2,co0){constructor({data:A,message:Q=`Invalid response data: ${JSON.stringify(A)}.`}){super({name:Ks0,message:Q});this[uo0]=!0,this.data=A}static isInstance(A){return zB.hasMarker(A,Zs0)}},Ns0="AI_JSONParseError",zs0=`vercel.ai.error.${Ns0}`,Fm2=Symbol.for(zs0),po0,lo0,cCA=class extends(lo0=zB,po0=Fm2,lo0){constructor({text:A,cause:Q}){super({name:Ns0,message:`JSON parsing failed: Text: ${A}.
2393
2393
  Error message: ${fs0(Q)}`,cause:Q});this[po0]=!0,this.text=A}static isInstance(A){return zB.hasMarker(A,zs0)}},qs0="AI_LoadAPIKeyError",Ls0=`vercel.ai.error.${qs0}`,Km2=Symbol.for(Ls0),io0,do0,AYw=class extends(do0=zB,io0=Km2,do0){constructor({message:A}){super({name:qs0,message:A});this[io0]=!0}static isInstance(A){return zB.hasMarker(A,Ls0)}},Es0="AI_LoadSettingError",Vs0=`vercel.ai.error.${Es0}`,Zm2=Symbol.for(Vs0),ro0,no0,QYw=class extends(no0=zB,ro0=Zm2,no0){constructor({message:A}){super({name:Es0,message:A});this[ro0]=!0}static isInstance(A){return zB.hasMarker(A,Vs0)}},Ms0="AI_NoContentGeneratedError",Os0=`vercel.ai.error.${Ms0}`,Nm2=Symbol.for(Os0),oo0,so0,BYw=class extends(so0=zB,oo0=Nm2,so0){constructor({message:A="No content generated."}={}){super({name:Ms0,message:A});this[oo0]=!0}static isInstance(A){return zB.hasMarker(A,Os0)}},Cs0="AI_NoSuchModelError",bs0=`vercel.ai.error.${Cs0}`,zm2=Symbol.for(bs0),ao0,to0,wYw=class extends(to0=zB,ao0=zm2,to0){constructor({errorName:A=Cs0,modelId:Q,modelType:B,message:w=`No such ${B}: ${Q}`}){super({name:A,message:w});this[ao0]=!0,this.modelId=Q,this.modelType=B}static isInstance(A){return zB.hasMarker(A,bs0)}},Rs0="AI_TooManyEmbeddingValuesForCallError",Ps0=`vercel.ai.error.${Rs0}`,qm2=Symbol.for(Ps0),eo0,As0,$Yw=class extends(As0=zB,eo0=qm2,As0){constructor(A){super({name:Rs0,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[eo0]=!0,this.provider=A.provider,this.modelId=A.modelId,this.maxEmbeddingsPerCall=A.maxEmbeddingsPerCall,this.values=A.values}static isInstance(A){return zB.hasMarker(A,Ps0)}},ks0="AI_TypeValidationError",js0=`vercel.ai.error.${ks0}`,Lm2=Symbol.for(js0),Qs0,Bs0,GU=class A extends(Bs0=zB,Qs0=Lm2,Bs0){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 D=[];if(w.entityName)D.push(w.entityName);if(w.entityId)D.push(`id: "${w.entityId}"`);$+=D.join(", "),$+=")"}super({name:ks0,message:`${$}: Value: ${JSON.stringify(Q)}.
2394
2394
  Error message: ${fs0(B)}`,cause:B});this[Qs0]=!0,this.value=Q,this.context=w}static isInstance(Q){return zB.hasMarker(Q,js0)}static wrap({value:Q,cause:B,context:w}){var $,D,I;if(A.isInstance(B)&&B.value===Q&&(($=B.context)==null?void 0:$.field)===(w==null?void 0:w.field)&&((D=B.context)==null?void 0:D.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})}},_s0="AI_UnsupportedFunctionalityError",ys0=`vercel.ai.error.${_s0}`,Em2=Symbol.for(ys0),ws0,$s0,DYw=class extends($s0=zB,ws0=Em2,$s0){constructor({functionality:A,message:Q=`'${A}' functionality not supported.`}){super({name:_s0,message:Q});this[ws0]=!0,this.functionality=A}static isInstance(A){return zB.hasMarker(A,ys0)}};U1();NH();NH();NH();var hs0="AI_DownloadError",ms0=`vercel.ai.error.${hs0}`,Vm2=Symbol.for(ms0),xs0,vs0,eY=class extends(vs0=zB,xs0=Vm2,vs0){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:hs0,message:$,cause:w});this[xs0]=!0,this.url=A,this.statusCode=Q,this.statusText=B}static isInstance(A){return zB.hasMarker(A,ms0)}},nCA=2147483648;async function us0({response:A,url:Q,maxBytes:B=nCA}){let w=A.headers.get("content-length");if(w!=null){let H=parseInt(w,10);if(!isNaN(H)&&H>B)throw new eY({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes (Content-Length: ${H}).`})}let $=A.body;if($==null)return new Uint8Array(0);let D=$.getReader(),I=[],Y=0;try{while(!0){let{done:H,value:F}=await D.read();if(H)break;if(Y+=F.length,Y>B)throw new eY({url:Q,message:`Download of ${Q} exceeded maximum size of ${B} bytes.`});I.push(F)}}finally{try{await D.cancel()}finally{D.releaseLock()}}let X=new Uint8Array(Y),W=0;for(let H of I)X.set(H,W),W+=H.length;return X}function oCA(A){let Q;try{Q=new URL(A)}catch(w){throw new eY({url:A,message:`Invalid URL: ${A}`})}if(Q.protocol==="data:")return;if(Q.protocol!=="http:"&&Q.protocol!=="https:")throw new eY({url:A,message:`URL scheme must be http, https, or data, got ${Q.protocol}`});let B=Q.hostname;if(!B)throw new eY({url:A,message:"URL must have a hostname"});if(B==="localhost"||B.endsWith(".local")||B.endsWith(".localhost"))throw new eY({url:A,message:`URL with hostname ${B} is not allowed`});if(B.startsWith("[")&&B.endsWith("]")){let w=B.slice(1,-1);if(Mm2(w))throw new eY({url:A,message:`URL with IPv6 address ${B} is not allowed`});return}if(cs0(B)){if(iCA(B))throw new eY({url:A,message:`URL with IP address ${B} is not allowed`});return}}function cs0(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 iCA(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 Mm2(A){let Q=A.toLowerCase();if(Q==="::1")return!0;if(Q==="::")return!0;if(Q.startsWith("::ffff:")){let B=Q.slice(7);if(cs0(B))return iCA(B);let w=B.split(":");if(w.length===2){let $=parseInt(w[0],16),D=parseInt(w[1],16);if(!isNaN($)&&!isNaN(D)){let I=$>>8&255,Y=$&255,X=D>>8&255,W=D&255;return iCA(`${I}.${Y}.${X}.${W}`)}}}if(Q.startsWith("fc")||Q.startsWith("fd"))return!0;if(Q.startsWith("fe80"))return!0;return!1}var WF=({prefix:A,size:Q=16,alphabet:B="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",separator:w="-"}={})=>{let $=()=>{let D=B.length,I=Array(Q);for(let Y=0;Y<Q;Y++)I[Y]=B[Math.random()*D|0];return I.join("")};if(A==null)return $;if(B.includes(w))throw new Js0({argument:"separator",message:`The separator "${w}" must not be part of the alphabet "${B}".`});return()=>`${A}${w}${$()}`},ps0=WF();function sCA(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 ls0(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 Om2(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 A2A(A,...Q){let B=new Headers(Om2(A)),w=B.get("user-agent")||"";return B.set("user-agent",[w,...Q].filter(Boolean).join(" ")),Object.fromEntries(B.entries())}var Cm2=/"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/,bm2=/"(?: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 Ts0(A){let Q=JSON.parse(A);if(Q===null||typeof Q!=="object")return Q;if(Cm2.test(A)===!1&&bm2.test(A)===!1)return Q;return Rm2(Q)}function Rm2(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 D=w[$];if(D&&typeof D==="object")Q.push(D)}}}return A}function Pm2(A){let{stackTraceLimit:Q}=Error;try{Error.stackTraceLimit=0}catch(B){return Ts0(A)}try{return Ts0(A)}finally{Error.stackTraceLimit=Q}}function aCA(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]=tE(B[w])}if(A.items!=null)A.items=Array.isArray(A.items)?A.items.map(tE):tE(A.items);if(A.anyOf!=null)A.anyOf=A.anyOf.map(tE);if(A.allOf!=null)A.allOf=A.allOf.map(tE);if(A.oneOf!=null)A.oneOf=A.oneOf.map(tE);let{definitions:Q}=A;if(Q!=null)for(let B of Object.keys(Q))Q[B]=tE(Q[B]);return A}function tE(A){if(typeof A==="boolean")return A;return aCA(A)}var km2=Symbol("Let zodToJsonSchema decide on which parser to use"),gs0={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"},jm2=(A)=>typeof A==="string"?{...gs0,name:A}:{...gs0,...A};function VI(){return{}}function _m2(A,Q){var B,w,$;let D={type:"array"};if(((B=A.type)==null?void 0:B._def)&&(($=(w=A.type)==null?void 0:w._def)==null?void 0:$.typeName)!==X0.ZodAny)D.items=zw(A.type._def,{...Q,currentPath:[...Q.currentPath,"items"]});if(A.minLength)D.minItems=A.minLength.value;if(A.maxLength)D.maxItems=A.maxLength.value;if(A.exactLength)D.minItems=A.exactLength.value,D.maxItems=A.exactLength.value;return D}function ym2(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 xm2(){return{type:"boolean"}}function is0(A,Q){return zw(A.type._def,Q)}var vm2=(A,Q)=>{return zw(A.innerType._def,Q)};function ds0(A,Q,B){let w=B!=null?B:Q.dateStrategy;if(Array.isArray(w))return{anyOf:w.map(($,D)=>ds0(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 Tm2(A)}}var Tm2=(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 gm2(A,Q){return{...zw(A.innerType._def,Q),default:A.defaultValue()}}function Sm2(A,Q){return Q.effectStrategy==="input"?zw(A.schema._def,Q):VI()}function hm2(A){return{type:"string",enum:Array.from(A.values)}}var mm2=(A)=>{if("type"in A&&A.type==="string")return!1;return"allOf"in A};function um2(A,Q){let B=[zw(A.left._def,{...Q,currentPath:[...Q.currentPath,"allOf","0"]}),zw(A.right._def,{...Q,currentPath:[...Q.currentPath,"allOf","1"]})].filter(($)=>!!$),w=[];return B.forEach(($)=>{if(mm2($))w.push(...$.allOf);else{let D=$;if("additionalProperties"in $&&$.additionalProperties===!1){let{additionalProperties:I,...Y}=$;D=Y}w.push(D)}}),w.length?{allOf:w}:void 0}function cm2(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 pCA=void 0,tW={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(pCA===void 0)pCA=RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u");return pCA},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 rs0(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":eW(B,"email",w.message,Q);break;case"format:idn-email":eW(B,"idn-email",w.message,Q);break;case"pattern:zod":H4(B,tW.email,w.message,Q);break}break;case"url":eW(B,"uri",w.message,Q);break;case"uuid":eW(B,"uuid",w.message,Q);break;case"regex":H4(B,w.regex,w.message,Q);break;case"cuid":H4(B,tW.cuid,w.message,Q);break;case"cuid2":H4(B,tW.cuid2,w.message,Q);break;case"startsWith":H4(B,RegExp(`^${lCA(w.value,Q)}`),w.message,Q);break;case"endsWith":H4(B,RegExp(`${lCA(w.value,Q)}$`),w.message,Q);break;case"datetime":eW(B,"date-time",w.message,Q);break;case"date":eW(B,"date",w.message,Q);break;case"time":eW(B,"time",w.message,Q);break;case"duration":eW(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":{H4(B,RegExp(lCA(w.value,Q)),w.message,Q);break}case"ip":{if(w.version!=="v6")eW(B,"ipv4",w.message,Q);if(w.version!=="v4")eW(B,"ipv6",w.message,Q);break}case"base64url":H4(B,tW.base64url,w.message,Q);break;case"jwt":H4(B,tW.jwt,w.message,Q);break;case"cidr":{if(w.version!=="v6")H4(B,tW.ipv4Cidr,w.message,Q);if(w.version!=="v4")H4(B,tW.ipv6Cidr,w.message,Q);break}case"emoji":H4(B,tW.emoji(),w.message,Q);break;case"ulid":{H4(B,tW.ulid,w.message,Q);break}case"base64":{switch(Q.base64Strategy){case"format:binary":{eW(B,"binary",w.message,Q);break}case"contentEncoding:base64":{B.contentEncoding="base64";break}case"pattern:zod":{H4(B,tW.base64,w.message,Q);break}}break}case"nanoid":H4(B,tW.nanoid,w.message,Q);case"toLowerCase":case"toUpperCase":case"trim":break;default:}return B}function lCA(A,Q){return Q.patternStrategy==="escape"?lm2(A):A}var pm2=new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");function lm2(A){let Q="";for(let B=0;B<A.length;B++){if(!pm2.has(A[B]))Q+="\\";Q+=A[B]}return Q}function eW(A,Q,B,w){var $;if(A.format||(($=A.anyOf)==null?void 0:$.some((D)=>D.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 H4(A,Q,B,w){var $;if(A.pattern||(($=A.allOf)==null?void 0:$.some((D)=>D.pattern))){if(!A.allOf)A.allOf=[];if(A.pattern)A.allOf.push({pattern:A.pattern}),delete A.pattern;A.allOf.push({pattern:Ss0(Q,w),...B&&w.errorMessages&&{errorMessage:{pattern:B}}})}else A.pattern=Ss0(Q,w)}function Ss0(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,D="",I=!1,Y=!1,X=!1;for(let W=0;W<$.length;W++){if(I){D+=$[W],I=!1;continue}if(w.i){if(Y){if($[W].match(/[a-z]/)){if(X)D+=$[W],D+=`${$[W-2]}-${$[W]}`.toUpperCase(),X=!1;else if($[W+1]==="-"&&((B=$[W+2])==null?void 0:B.match(/[a-z]/)))D+=$[W],X=!0;else D+=`${$[W]}${$[W].toUpperCase()}`;continue}}else if($[W].match(/[a-z]/)){D+=`[${$[W]}${$[W].toUpperCase()}]`;continue}}if(w.m){if($[W]==="^"){D+=`(^|(?<=[\r
2395
2395
  ]))`;continue}else if($[W]==="$"){D+=`($|(?=[\r
@@ -2399,7 +2399,7 @@ Error message: ${fs0(B)}`,cause:B});this[Qs0]=!0,this.value=Q,this.context=w}sta
2399
2399
 
2400
2400
  `)},flush(A){A.enqueue(`data: [DONE]
2401
2401
 
2402
- `)}})}},Yp2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function Xa0({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let D=w.pipeThrough(new Ip2);if($){let[I,Y]=D.tee();D=I,$({stream:Y})}return new Response(D.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Dp2(B,Yp2)})}var zu=U.record(U.string(),eE.optional()),nYw=Q2A(()=>Nu(U.union([U.strictObject({type:U.literal("text-start"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("text-delta"),id:U.string(),delta:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("text-end"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("error"),errorText:U.string()}),U.strictObject({type:U.literal("tool-input-start"),toolCallId:U.string(),toolName:U.string(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-input-delta"),toolCallId:U.string(),inputTextDelta:U.string()}),U.strictObject({type:U.literal("tool-input-available"),toolCallId:U.string(),toolName:U.string(),input:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-input-error"),toolCallId:U.string(),toolName:U.string(),input:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),errorText:U.string(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-approval-request"),approvalId:U.string(),toolCallId:U.string()}),U.strictObject({type:U.literal("tool-output-available"),toolCallId:U.string(),output:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),preliminary:U.boolean().optional()}),U.strictObject({type:U.literal("tool-output-error"),toolCallId:U.string(),errorText:U.string(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional()}),U.strictObject({type:U.literal("tool-output-denied"),toolCallId:U.string()}),U.strictObject({type:U.literal("reasoning-start"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("reasoning-delta"),id:U.string(),delta:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("reasoning-end"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("source-url"),sourceId:U.string(),url:U.string(),title:U.string().optional(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("source-document"),sourceId:U.string(),mediaType:U.string(),title:U.string(),filename:U.string().optional(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("file"),url:U.string(),mediaType:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:U.string().optional(),data:U.unknown(),transient:U.boolean().optional()}),U.strictObject({type:U.literal("start-step")}),U.strictObject({type:U.literal("finish-step")}),U.strictObject({type:U.literal("start"),messageId:U.string().optional(),messageMetadata:U.unknown().optional()}),U.strictObject({type:U.literal("finish"),finishReason:U.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:U.unknown().optional()}),U.strictObject({type:U.literal("abort"),reason:U.string().optional()}),U.strictObject({type:U.literal("message-metadata"),messageMetadata:U.unknown()})])));function Xp2(A){return A.type.startsWith("data-")}function eCA(A){return A.type.startsWith("tool-")}function Wp2(A){return A.type==="dynamic-tool"}function os0(A){return eCA(A)||Wp2(A)}function ss0(A){return A.type.split("-").slice(1).join("-")}function fp2({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 Hp2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:D,onData:I}){return A.pipeThrough(new TransformStream({async transform(Y,X){await w(async({state:W,write:H})=>{var F,K,Z,q;function L(C){let i=W.message.parts.filter(os0).find((g)=>g.toolCallId===C);if(i==null)throw new xk({chunkType:"tool-invocation",chunkId:C,message:`No tool invocation found for tool call ID "${C}".`});return i}function E(C){var m;let i=W.message.parts.find((T)=>eCA(T)&&T.toolCallId===C.toolCallId),g=C,x=i;if(i!=null){if(i.state=C.state,x.input=g.input,x.output=g.output,x.errorText=g.errorText,x.rawInput=g.rawInput,x.preliminary=g.preliminary,C.title!==void 0)x.title=C.title;if(C.toolMetadata!==void 0)x.toolMetadata=C.toolMetadata;x.providerExecuted=(m=g.providerExecuted)!=null?m:i.providerExecuted;let T=g.providerMetadata;if(T!=null)if(C.state==="output-available"||C.state==="output-error"){let S=i;S.resultProviderMetadata=T}else i.callProviderMetadata=T}else W.message.parts.push({type:`tool-${C.toolName}`,toolCallId:C.toolCallId,state:C.state,title:C.title,...C.toolMetadata!==void 0?{toolMetadata:C.toolMetadata}:{},input:g.input,output:g.output,rawInput:g.rawInput,errorText:g.errorText,providerExecuted:g.providerExecuted,preliminary:g.preliminary,...g.providerMetadata!=null&&(C.state==="output-available"||C.state==="output-error")?{resultProviderMetadata:g.providerMetadata}:{},...g.providerMetadata!=null&&!(C.state==="output-available"||C.state==="output-error")?{callProviderMetadata:g.providerMetadata}:{}})}function R(C){var m,i;let g=W.message.parts.find((S)=>S.type==="dynamic-tool"&&S.toolCallId===C.toolCallId),x=C,T=g;if(g!=null){if(g.state=C.state,T.toolName=C.toolName,T.input=x.input,T.output=x.output,T.errorText=x.errorText,T.rawInput=(m=x.rawInput)!=null?m:T.rawInput,T.preliminary=x.preliminary,C.title!==void 0)T.title=C.title;if(C.toolMetadata!==void 0)T.toolMetadata=C.toolMetadata;T.providerExecuted=(i=x.providerExecuted)!=null?i:g.providerExecuted;let S=x.providerMetadata;if(S!=null)if(C.state==="output-available"||C.state==="output-error"){let e=g;e.resultProviderMetadata=S}else g.callProviderMetadata=S}else W.message.parts.push({type:"dynamic-tool",toolName:C.toolName,toolCallId:C.toolCallId,state:C.state,input:x.input,output:x.output,errorText:x.errorText,preliminary:x.preliminary,providerExecuted:x.providerExecuted,title:C.title,...C.toolMetadata!==void 0?{toolMetadata:C.toolMetadata}:{},...x.providerMetadata!=null&&(C.state==="output-available"||C.state==="output-error")?{resultProviderMetadata:x.providerMetadata}:{},...x.providerMetadata!=null&&!(C.state==="output-available"||C.state==="output-error")?{callProviderMetadata:x.providerMetadata}:{}})}async function j(C){if(C!=null){let m=W.message.metadata!=null?Ya0(W.message.metadata,C):C;if(Q!=null)await $2A({value:m,schema:Q,context:{field:"message.metadata",entityId:W.message.id}});W.message.metadata=m}}switch(Y.type){case"text-start":{let C={type:"text",text:"",providerMetadata:Y.providerMetadata,state:"streaming"};W.activeTextParts[Y.id]=C,W.message.parts.push(C),H();break}case"text-delta":{let C=W.activeTextParts[Y.id];if(C==null)throw new xk({chunkType:"text-delta",chunkId:Y.id,message:`Received text-delta for missing text part with ID "${Y.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});C.text+=Y.delta,C.providerMetadata=(F=Y.providerMetadata)!=null?F:C.providerMetadata,H();break}case"text-end":{let C=W.activeTextParts[Y.id];if(C==null)throw new xk({chunkType:"text-end",chunkId:Y.id,message:`Received text-end for missing text part with ID "${Y.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});C.state="done",C.providerMetadata=(K=Y.providerMetadata)!=null?K:C.providerMetadata,delete W.activeTextParts[Y.id],H();break}case"reasoning-start":{let C={type:"reasoning",text:"",providerMetadata:Y.providerMetadata,state:"streaming"};W.activeReasoningParts[Y.id]=C,W.message.parts.push(C),H();break}case"reasoning-delta":{let C=W.activeReasoningParts[Y.id];if(C==null)throw new xk({chunkType:"reasoning-delta",chunkId:Y.id,message:`Received reasoning-delta for missing reasoning part with ID "${Y.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});C.text+=Y.delta,C.providerMetadata=(Z=Y.providerMetadata)!=null?Z:C.providerMetadata,H();break}case"reasoning-end":{let C=W.activeReasoningParts[Y.id];if(C==null)throw new xk({chunkType:"reasoning-end",chunkId:Y.id,message:`Received reasoning-end for missing reasoning part with ID "${Y.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});C.providerMetadata=(q=Y.providerMetadata)!=null?q:C.providerMetadata,C.state="done",delete W.activeReasoningParts[Y.id],H();break}case"file":{W.message.parts.push({type:"file",mediaType:Y.mediaType,url:Y.url,...Y.providerMetadata!=null?{providerMetadata:Y.providerMetadata}:{}}),H();break}case"source-url":{W.message.parts.push({type:"source-url",sourceId:Y.sourceId,url:Y.url,title:Y.title,providerMetadata:Y.providerMetadata}),H();break}case"source-document":{W.message.parts.push({type:"source-document",sourceId:Y.sourceId,mediaType:Y.mediaType,title:Y.title,filename:Y.filename,providerMetadata:Y.providerMetadata}),H();break}case"tool-input-start":{let C=W.message.parts.filter(eCA);if(W.partialToolCalls[Y.toolCallId]={text:"",toolName:Y.toolName,index:C.length,dynamic:Y.dynamic,title:Y.title,toolMetadata:Y.toolMetadata},Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-streaming",input:void 0,providerExecuted:Y.providerExecuted,title:Y.title,toolMetadata:Y.toolMetadata,providerMetadata:Y.providerMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-streaming",input:void 0,providerExecuted:Y.providerExecuted,title:Y.title,toolMetadata:Y.toolMetadata,providerMetadata:Y.providerMetadata});H();break}case"tool-input-delta":{let C=W.partialToolCalls[Y.toolCallId];if(C==null)throw new xk({chunkType:"tool-input-delta",chunkId:Y.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${Y.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});C.text+=Y.inputTextDelta;let{value:m}=await qu(C.text);if(C.dynamic)R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"input-streaming",input:m,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:C.toolName,state:"input-streaming",input:m,title:C.title,toolMetadata:C.toolMetadata});H();break}case"tool-input-available":{if(Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-available",input:Y.input,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:Y.title,toolMetadata:Y.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-available",input:Y.input,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:Y.title,toolMetadata:Y.toolMetadata});if(H(),D&&!Y.providerExecuted)await D({toolCall:Y});break}case"tool-input-error":{let C=W.message.parts.filter(os0).find((i)=>i.toolCallId===Y.toolCallId);if(C!=null?C.type==="dynamic-tool":!!Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"output-error",input:Y.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,toolMetadata:Y.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"output-error",input:void 0,rawInput:Y.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,toolMetadata:Y.toolMetadata});H();break}case"tool-approval-request":{let C=L(Y.toolCallId);C.state="approval-requested",C.approval={id:Y.approvalId},H();break}case"tool-output-denied":{let C=L(Y.toolCallId);C.state="output-denied",H();break}case"tool-output-available":{let C=L(Y.toolCallId);if(C.type==="dynamic-tool")R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"output-available",input:C.input,output:Y.output,preliminary:Y.preliminary,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:ss0(C),state:"output-available",input:C.input,output:Y.output,providerExecuted:Y.providerExecuted,preliminary:Y.preliminary,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});H();break}case"tool-output-error":{let C=L(Y.toolCallId);if(C.type==="dynamic-tool")R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"output-error",input:C.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:ss0(C),state:"output-error",input:C.input,rawInput:C.rawInput,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});H();break}case"start-step":{W.message.parts.push({type:"step-start"});break}case"finish-step":{W.activeTextParts={},W.activeReasoningParts={};break}case"start":{if(Y.messageId!=null)W.message.id=Y.messageId;if(await j(Y.messageMetadata),Y.messageId!=null||Y.messageMetadata!=null)H();break}case"finish":{if(Y.finishReason!=null)W.finishReason=Y.finishReason;if(await j(Y.messageMetadata),Y.messageMetadata!=null)H();break}case"message-metadata":{if(await j(Y.messageMetadata),Y.messageMetadata!=null)H();break}case"error":{$==null||$(Error(Y.errorText));break}default:if(Xp2(Y)){if((B==null?void 0:B[Y.type])!=null){let i=W.message.parts.findIndex((x)=>("id"in x)&&("data"in x)&&x.id===Y.id&&x.type===Y.type),g=i>=0?i:W.message.parts.length;await $2A({value:Y.data,schema:B[Y.type],context:{field:`message.parts[${g}].data`,entityName:Y.type,entityId:Y.id}})}let C=Y;if(C.transient){I==null||I(C);break}let m=C.id!=null?W.message.parts.find((i)=>C.type===i.type&&C.id===i.id):void 0;if(m!=null)m.data=C.data;else W.message.parts.push(C);I==null||I(C),H()}}X.enqueue(Y)})}}))}function Up2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:D}){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 Y=!1,X=D.pipeThrough(new TransformStream({transform(q,L){if(q.type==="start"){let E=q;if(E.messageId==null&&A!=null)E.messageId=A}if(q.type==="abort")Y=!0;L.enqueue(q)}}));if(w==null&&B==null)return X;let W=fp2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),H=async(q)=>{await q({state:W,write:()=>{}})},F=!1,K=async()=>{if(F||!w)return;F=!0;let q=W.message.id===(I==null?void 0:I.id);await w({isAborted:Y,isContinuation:q,responseMessage:W.message,messages:[...q?Q.slice(0,-1):Q,W.message],finishReason:W.finishReason})},Z=async()=>{if(!B)return;let q=W.message.id===(I==null?void 0:I.id);try{await B({isContinuation:q,responseMessage:structuredClone(W.message),messages:[...q?Q.slice(0,-1):Q,structuredClone(W.message)]})}catch(L){$(L)}};return Hp2({stream:X,runUpdateMessageJob:H,onError:$}).pipeThrough(new TransformStream({async transform(q,L){if(q.type==="finish-step")await Z();L.enqueue(q)},async cancel(){await K()},async flush(){await K()}}))}var oYw=WF({prefix:"aitxt",size:24});function Wa0({execute:A,onError:Q=sCA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:D=ps0}){let I,Y=[],X=new ReadableStream({start(F){I=F}});function W(F){try{I.enqueue(F)}catch(K){}}try{let F=A({writer:{write(K){W(K)},merge(K){Y.push((async()=>{let Z=K.getReader();while(!0){let{done:q,value:L}=await Z.read();if(q)break;W(L)}})().catch((Z)=>{W({type:"error",errorText:Q(Z)})}))},onError:Q}});if(F)Y.push(F.catch((K)=>{W({type:"error",errorText:Q(K)})}))}catch(F){W({type:"error",errorText:Q(F)})}return new Promise(async(F)=>{while(Y.length>0)await Y.shift();F()}).finally(()=>{try{I.close()}catch(F){}}),Up2({stream:X,messageId:D(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var DD=U.record(U.string(),eE.optional()),eYw=Q2A(()=>Nu(U.array(U.object({id:U.string(),role:U.enum(["system","user","assistant"]),metadata:U.unknown().optional(),parts:U.array(U.union([U.object({type:U.literal("text"),text:U.string(),state:U.enum(["streaming","done"]).optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("reasoning"),text:U.string(),state:U.enum(["streaming","done"]).optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("source-url"),sourceId:U.string(),url:U.string(),title:U.string().optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("source-document"),sourceId:U.string(),mediaType:U.string(),title:U.string(),filename:U.string().optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("file"),mediaType:U.string(),filename:U.string().optional(),url:U.string(),providerMetadata:K2.optional()}),U.object({type:U.literal("step-start")}),U.object({type:U.string().startsWith("data-"),id:U.string().optional(),data:U.unknown()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-streaming"),input:U.unknown().optional(),providerExecuted:U.boolean().optional(),callProviderMetadata:K2.optional(),output:U.never().optional(),errorText:U.never().optional(),approval:U.never().optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-available"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.never().optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-requested"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.never().optional(),reason:U.never().optional()})}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-responded"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.boolean(),reason:U.string().optional()})}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-available"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.unknown(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),preliminary:U.boolean().optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-error"),input:U.unknown().optional(),rawInput:U.unknown().optional(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.string(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-denied"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!1),reason:U.string().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-streaming"),providerExecuted:U.boolean().optional(),callProviderMetadata:K2.optional(),input:U.unknown().optional(),output:U.never().optional(),errorText:U.never().optional(),approval:U.never().optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-available"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.never().optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-requested"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.never().optional(),reason:U.never().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-responded"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.boolean(),reason:U.string().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-available"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.unknown(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),preliminary:U.boolean().optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-error"),providerExecuted:U.boolean().optional(),input:U.unknown().optional(),rawInput:U.unknown().optional(),output:U.never().optional(),errorText:U.string(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-denied"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!1),reason:U.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var QXw=WF({prefix:"aiobj",size:24});function fa0(A){return({url:Q,abortSignal:B})=>uc2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var wXw=WF({prefix:"aiobj",size:24});var $Xw=fa0();var Jp2="AI_NoSuchProviderError",Gp2=`vercel.ai.error.${Jp2}`,Fp2=Symbol.for(Gp2),Kp2;Kp2=Fp2;var DXw=fa0();import{basename as gp2,dirname as Sp2,join as Oa0}from"path";var Ha0={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.108",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"}};HA();var AbA=J.object({routePath:J.string().default("/chat"),apiPath:J.string().default("/api/chat")});var Np2=/\n{0,2}\[Entities affected this turn: [\s\S]*? Reference these IDs directly in follow-ups instead of searching for them\.\]\s*$/;function Ua0(A){return A.replace(Np2,"").trimEnd()}HA();import{mkdir as zp2,readdir as qp2,readFile as Ja0,rm as Lp2,stat as Ep2,writeFile as Ga0}from"fs/promises";import{join as IN}from"path";var vk="web-chat-upload",Tk=/^upload-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Vp2=86400000,Mp2=200;class YN extends Error{code;constructor(A,Q){super(Q);this.code=A;this.name="WebChatUploadStoreError"}}var Op2=J.object({kind:J.literal(vk),id:J.string().regex(Tk)}),Cp2=J.object({id:J.string().regex(Tk),ref:Op2,filename:J.string().min(1),mediaType:J.string().min(1),sizeBytes:J.number().nonnegative(),createdAt:J.string().datetime()});class QbA{options;retentionMs;maxCount;createUploadId;getNow;constructor(A){this.options=A;this.retentionMs=A.retentionMs??Vp2,this.maxCount=A.maxCount??Mp2,this.createUploadId=A.createId??(()=>`upload-${crypto.randomUUID()}`),this.getNow=A.now??(()=>new Date)}async save(A){let Q=this.createUploadId();this.assertValidUploadId(Q);let B={id:Q,ref:{kind:vk,id:Q},filename:A.filename,mediaType:A.mediaType,sizeBytes:A.content.byteLength,createdAt:this.getNow().toISOString()},w=this.getUploadDir(Q);return await zp2(w,{recursive:!0}),await Ga0(IN(w,"content"),A.content),await Ga0(IN(w,"metadata.json"),`${JSON.stringify(B,null,2)}
2402
+ `)}})}},Yp2={"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-vercel-ai-ui-message-stream":"v1","x-accel-buffering":"no"};function Xa0({status:A,statusText:Q,headers:B,stream:w,consumeSseStream:$}){let D=w.pipeThrough(new Ip2);if($){let[I,Y]=D.tee();D=I,$({stream:Y})}return new Response(D.pipeThrough(new TextEncoderStream),{status:A,statusText:Q,headers:Dp2(B,Yp2)})}var zu=U.record(U.string(),eE.optional()),nYw=Q2A(()=>Nu(U.union([U.strictObject({type:U.literal("text-start"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("text-delta"),id:U.string(),delta:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("text-end"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("error"),errorText:U.string()}),U.strictObject({type:U.literal("tool-input-start"),toolCallId:U.string(),toolName:U.string(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-input-delta"),toolCallId:U.string(),inputTextDelta:U.string()}),U.strictObject({type:U.literal("tool-input-available"),toolCallId:U.string(),toolName:U.string(),input:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-input-error"),toolCallId:U.string(),toolName:U.string(),input:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),errorText:U.string(),title:U.string().optional()}),U.strictObject({type:U.literal("tool-approval-request"),approvalId:U.string(),toolCallId:U.string()}),U.strictObject({type:U.literal("tool-output-available"),toolCallId:U.string(),output:U.unknown(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional(),preliminary:U.boolean().optional()}),U.strictObject({type:U.literal("tool-output-error"),toolCallId:U.string(),errorText:U.string(),providerExecuted:U.boolean().optional(),providerMetadata:K2.optional(),toolMetadata:zu.optional(),dynamic:U.boolean().optional()}),U.strictObject({type:U.literal("tool-output-denied"),toolCallId:U.string()}),U.strictObject({type:U.literal("reasoning-start"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("reasoning-delta"),id:U.string(),delta:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("reasoning-end"),id:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("source-url"),sourceId:U.string(),url:U.string(),title:U.string().optional(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("source-document"),sourceId:U.string(),mediaType:U.string(),title:U.string(),filename:U.string().optional(),providerMetadata:K2.optional()}),U.strictObject({type:U.literal("file"),url:U.string(),mediaType:U.string(),providerMetadata:K2.optional()}),U.strictObject({type:U.custom((A)=>typeof A==="string"&&A.startsWith("data-"),{message:'Type must start with "data-"'}),id:U.string().optional(),data:U.unknown(),transient:U.boolean().optional()}),U.strictObject({type:U.literal("start-step")}),U.strictObject({type:U.literal("finish-step")}),U.strictObject({type:U.literal("start"),messageId:U.string().optional(),messageMetadata:U.unknown().optional()}),U.strictObject({type:U.literal("finish"),finishReason:U.enum(["stop","length","content-filter","tool-calls","error","other"]).optional(),messageMetadata:U.unknown().optional()}),U.strictObject({type:U.literal("abort"),reason:U.string().optional()}),U.strictObject({type:U.literal("message-metadata"),messageMetadata:U.unknown()})])));function Xp2(A){return A.type.startsWith("data-")}function eCA(A){return A.type.startsWith("tool-")}function Wp2(A){return A.type==="dynamic-tool"}function os0(A){return eCA(A)||Wp2(A)}function ss0(A){return A.type.split("-").slice(1).join("-")}function fp2({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 Hp2({stream:A,messageMetadataSchema:Q,dataPartSchemas:B,runUpdateMessageJob:w,onError:$,onToolCall:D,onData:I}){return A.pipeThrough(new TransformStream({async transform(Y,X){await w(async({state:W,write:H})=>{var F,K,Z,q;function L(C){let i=W.message.parts.filter(os0).find((g)=>g.toolCallId===C);if(i==null)throw new xk({chunkType:"tool-invocation",chunkId:C,message:`No tool invocation found for tool call ID "${C}".`});return i}function E(C){var m;let i=W.message.parts.find((T)=>eCA(T)&&T.toolCallId===C.toolCallId),g=C,x=i;if(i!=null){if(i.state=C.state,x.input=g.input,x.output=g.output,x.errorText=g.errorText,x.rawInput=g.rawInput,x.preliminary=g.preliminary,C.title!==void 0)x.title=C.title;if(C.toolMetadata!==void 0)x.toolMetadata=C.toolMetadata;x.providerExecuted=(m=g.providerExecuted)!=null?m:i.providerExecuted;let T=g.providerMetadata;if(T!=null)if(C.state==="output-available"||C.state==="output-error"){let S=i;S.resultProviderMetadata=T}else i.callProviderMetadata=T}else W.message.parts.push({type:`tool-${C.toolName}`,toolCallId:C.toolCallId,state:C.state,title:C.title,...C.toolMetadata!==void 0?{toolMetadata:C.toolMetadata}:{},input:g.input,output:g.output,rawInput:g.rawInput,errorText:g.errorText,providerExecuted:g.providerExecuted,preliminary:g.preliminary,...g.providerMetadata!=null&&(C.state==="output-available"||C.state==="output-error")?{resultProviderMetadata:g.providerMetadata}:{},...g.providerMetadata!=null&&!(C.state==="output-available"||C.state==="output-error")?{callProviderMetadata:g.providerMetadata}:{}})}function R(C){var m,i;let g=W.message.parts.find((S)=>S.type==="dynamic-tool"&&S.toolCallId===C.toolCallId),x=C,T=g;if(g!=null){if(g.state=C.state,T.toolName=C.toolName,T.input=x.input,T.output=x.output,T.errorText=x.errorText,T.rawInput=(m=x.rawInput)!=null?m:T.rawInput,T.preliminary=x.preliminary,C.title!==void 0)T.title=C.title;if(C.toolMetadata!==void 0)T.toolMetadata=C.toolMetadata;T.providerExecuted=(i=x.providerExecuted)!=null?i:g.providerExecuted;let S=x.providerMetadata;if(S!=null)if(C.state==="output-available"||C.state==="output-error"){let e=g;e.resultProviderMetadata=S}else g.callProviderMetadata=S}else W.message.parts.push({type:"dynamic-tool",toolName:C.toolName,toolCallId:C.toolCallId,state:C.state,input:x.input,output:x.output,errorText:x.errorText,preliminary:x.preliminary,providerExecuted:x.providerExecuted,title:C.title,...C.toolMetadata!==void 0?{toolMetadata:C.toolMetadata}:{},...x.providerMetadata!=null&&(C.state==="output-available"||C.state==="output-error")?{resultProviderMetadata:x.providerMetadata}:{},...x.providerMetadata!=null&&!(C.state==="output-available"||C.state==="output-error")?{callProviderMetadata:x.providerMetadata}:{}})}async function j(C){if(C!=null){let m=W.message.metadata!=null?Ya0(W.message.metadata,C):C;if(Q!=null)await $2A({value:m,schema:Q,context:{field:"message.metadata",entityId:W.message.id}});W.message.metadata=m}}switch(Y.type){case"text-start":{let C={type:"text",text:"",providerMetadata:Y.providerMetadata,state:"streaming"};W.activeTextParts[Y.id]=C,W.message.parts.push(C),H();break}case"text-delta":{let C=W.activeTextParts[Y.id];if(C==null)throw new xk({chunkType:"text-delta",chunkId:Y.id,message:`Received text-delta for missing text part with ID "${Y.id}". Ensure a "text-start" chunk is sent before any "text-delta" chunks.`});C.text+=Y.delta,C.providerMetadata=(F=Y.providerMetadata)!=null?F:C.providerMetadata,H();break}case"text-end":{let C=W.activeTextParts[Y.id];if(C==null)throw new xk({chunkType:"text-end",chunkId:Y.id,message:`Received text-end for missing text part with ID "${Y.id}". Ensure a "text-start" chunk is sent before any "text-end" chunks.`});C.state="done",C.providerMetadata=(K=Y.providerMetadata)!=null?K:C.providerMetadata,delete W.activeTextParts[Y.id],H();break}case"reasoning-start":{let C={type:"reasoning",text:"",providerMetadata:Y.providerMetadata,state:"streaming"};W.activeReasoningParts[Y.id]=C,W.message.parts.push(C),H();break}case"reasoning-delta":{let C=W.activeReasoningParts[Y.id];if(C==null)throw new xk({chunkType:"reasoning-delta",chunkId:Y.id,message:`Received reasoning-delta for missing reasoning part with ID "${Y.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-delta" chunks.`});C.text+=Y.delta,C.providerMetadata=(Z=Y.providerMetadata)!=null?Z:C.providerMetadata,H();break}case"reasoning-end":{let C=W.activeReasoningParts[Y.id];if(C==null)throw new xk({chunkType:"reasoning-end",chunkId:Y.id,message:`Received reasoning-end for missing reasoning part with ID "${Y.id}". Ensure a "reasoning-start" chunk is sent before any "reasoning-end" chunks.`});C.providerMetadata=(q=Y.providerMetadata)!=null?q:C.providerMetadata,C.state="done",delete W.activeReasoningParts[Y.id],H();break}case"file":{W.message.parts.push({type:"file",mediaType:Y.mediaType,url:Y.url,...Y.providerMetadata!=null?{providerMetadata:Y.providerMetadata}:{}}),H();break}case"source-url":{W.message.parts.push({type:"source-url",sourceId:Y.sourceId,url:Y.url,title:Y.title,providerMetadata:Y.providerMetadata}),H();break}case"source-document":{W.message.parts.push({type:"source-document",sourceId:Y.sourceId,mediaType:Y.mediaType,title:Y.title,filename:Y.filename,providerMetadata:Y.providerMetadata}),H();break}case"tool-input-start":{let C=W.message.parts.filter(eCA);if(W.partialToolCalls[Y.toolCallId]={text:"",toolName:Y.toolName,index:C.length,dynamic:Y.dynamic,title:Y.title,toolMetadata:Y.toolMetadata},Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-streaming",input:void 0,providerExecuted:Y.providerExecuted,title:Y.title,toolMetadata:Y.toolMetadata,providerMetadata:Y.providerMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-streaming",input:void 0,providerExecuted:Y.providerExecuted,title:Y.title,toolMetadata:Y.toolMetadata,providerMetadata:Y.providerMetadata});H();break}case"tool-input-delta":{let C=W.partialToolCalls[Y.toolCallId];if(C==null)throw new xk({chunkType:"tool-input-delta",chunkId:Y.toolCallId,message:`Received tool-input-delta for missing tool call with ID "${Y.toolCallId}". Ensure a "tool-input-start" chunk is sent before any "tool-input-delta" chunks.`});C.text+=Y.inputTextDelta;let{value:m}=await qu(C.text);if(C.dynamic)R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"input-streaming",input:m,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:C.toolName,state:"input-streaming",input:m,title:C.title,toolMetadata:C.toolMetadata});H();break}case"tool-input-available":{if(Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-available",input:Y.input,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:Y.title,toolMetadata:Y.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"input-available",input:Y.input,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:Y.title,toolMetadata:Y.toolMetadata});if(H(),D&&!Y.providerExecuted)await D({toolCall:Y});break}case"tool-input-error":{let C=W.message.parts.filter(os0).find((i)=>i.toolCallId===Y.toolCallId);if(C!=null?C.type==="dynamic-tool":!!Y.dynamic)R({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"output-error",input:Y.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,toolMetadata:Y.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:Y.toolName,state:"output-error",input:void 0,rawInput:Y.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,toolMetadata:Y.toolMetadata});H();break}case"tool-approval-request":{let C=L(Y.toolCallId);C.state="approval-requested",C.approval={id:Y.approvalId},H();break}case"tool-output-denied":{let C=L(Y.toolCallId);C.state="output-denied",H();break}case"tool-output-available":{let C=L(Y.toolCallId);if(C.type==="dynamic-tool")R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"output-available",input:C.input,output:Y.output,preliminary:Y.preliminary,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:ss0(C),state:"output-available",input:C.input,output:Y.output,providerExecuted:Y.providerExecuted,preliminary:Y.preliminary,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});H();break}case"tool-output-error":{let C=L(Y.toolCallId);if(C.type==="dynamic-tool")R({toolCallId:Y.toolCallId,toolName:C.toolName,state:"output-error",input:C.input,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});else E({toolCallId:Y.toolCallId,toolName:ss0(C),state:"output-error",input:C.input,rawInput:C.rawInput,errorText:Y.errorText,providerExecuted:Y.providerExecuted,providerMetadata:Y.providerMetadata,title:C.title,toolMetadata:C.toolMetadata});H();break}case"start-step":{W.message.parts.push({type:"step-start"});break}case"finish-step":{W.activeTextParts={},W.activeReasoningParts={};break}case"start":{if(Y.messageId!=null)W.message.id=Y.messageId;if(await j(Y.messageMetadata),Y.messageId!=null||Y.messageMetadata!=null)H();break}case"finish":{if(Y.finishReason!=null)W.finishReason=Y.finishReason;if(await j(Y.messageMetadata),Y.messageMetadata!=null)H();break}case"message-metadata":{if(await j(Y.messageMetadata),Y.messageMetadata!=null)H();break}case"error":{$==null||$(Error(Y.errorText));break}default:if(Xp2(Y)){if((B==null?void 0:B[Y.type])!=null){let i=W.message.parts.findIndex((x)=>("id"in x)&&("data"in x)&&x.id===Y.id&&x.type===Y.type),g=i>=0?i:W.message.parts.length;await $2A({value:Y.data,schema:B[Y.type],context:{field:`message.parts[${g}].data`,entityName:Y.type,entityId:Y.id}})}let C=Y;if(C.transient){I==null||I(C);break}let m=C.id!=null?W.message.parts.find((i)=>C.type===i.type&&C.id===i.id):void 0;if(m!=null)m.data=C.data;else W.message.parts.push(C);I==null||I(C),H()}}X.enqueue(Y)})}}))}function Up2({messageId:A,originalMessages:Q=[],onStepFinish:B,onFinish:w,onError:$,stream:D}){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 Y=!1,X=D.pipeThrough(new TransformStream({transform(q,L){if(q.type==="start"){let E=q;if(E.messageId==null&&A!=null)E.messageId=A}if(q.type==="abort")Y=!0;L.enqueue(q)}}));if(w==null&&B==null)return X;let W=fp2({lastMessage:I?structuredClone(I):void 0,messageId:A!=null?A:""}),H=async(q)=>{await q({state:W,write:()=>{}})},F=!1,K=async()=>{if(F||!w)return;F=!0;let q=W.message.id===(I==null?void 0:I.id);await w({isAborted:Y,isContinuation:q,responseMessage:W.message,messages:[...q?Q.slice(0,-1):Q,W.message],finishReason:W.finishReason})},Z=async()=>{if(!B)return;let q=W.message.id===(I==null?void 0:I.id);try{await B({isContinuation:q,responseMessage:structuredClone(W.message),messages:[...q?Q.slice(0,-1):Q,structuredClone(W.message)]})}catch(L){$(L)}};return Hp2({stream:X,runUpdateMessageJob:H,onError:$}).pipeThrough(new TransformStream({async transform(q,L){if(q.type==="finish-step")await Z();L.enqueue(q)},async cancel(){await K()},async flush(){await K()}}))}var oYw=WF({prefix:"aitxt",size:24});function Wa0({execute:A,onError:Q=sCA,originalMessages:B,onStepFinish:w,onFinish:$,generateId:D=ps0}){let I,Y=[],X=new ReadableStream({start(F){I=F}});function W(F){try{I.enqueue(F)}catch(K){}}try{let F=A({writer:{write(K){W(K)},merge(K){Y.push((async()=>{let Z=K.getReader();while(!0){let{done:q,value:L}=await Z.read();if(q)break;W(L)}})().catch((Z)=>{W({type:"error",errorText:Q(Z)})}))},onError:Q}});if(F)Y.push(F.catch((K)=>{W({type:"error",errorText:Q(K)})}))}catch(F){W({type:"error",errorText:Q(F)})}return new Promise(async(F)=>{while(Y.length>0)await Y.shift();F()}).finally(()=>{try{I.close()}catch(F){}}),Up2({stream:X,messageId:D(),originalMessages:B,onStepFinish:w,onFinish:$,onError:Q})}var DD=U.record(U.string(),eE.optional()),eYw=Q2A(()=>Nu(U.array(U.object({id:U.string(),role:U.enum(["system","user","assistant"]),metadata:U.unknown().optional(),parts:U.array(U.union([U.object({type:U.literal("text"),text:U.string(),state:U.enum(["streaming","done"]).optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("reasoning"),text:U.string(),state:U.enum(["streaming","done"]).optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("source-url"),sourceId:U.string(),url:U.string(),title:U.string().optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("source-document"),sourceId:U.string(),mediaType:U.string(),title:U.string(),filename:U.string().optional(),providerMetadata:K2.optional()}),U.object({type:U.literal("file"),mediaType:U.string(),filename:U.string().optional(),url:U.string(),providerMetadata:K2.optional()}),U.object({type:U.literal("step-start")}),U.object({type:U.string().startsWith("data-"),id:U.string().optional(),data:U.unknown()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-streaming"),input:U.unknown().optional(),providerExecuted:U.boolean().optional(),callProviderMetadata:K2.optional(),output:U.never().optional(),errorText:U.never().optional(),approval:U.never().optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-available"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.never().optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-requested"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.never().optional(),reason:U.never().optional()})}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-responded"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.boolean(),reason:U.string().optional()})}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-available"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.unknown(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),preliminary:U.boolean().optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-error"),input:U.unknown().optional(),rawInput:U.unknown().optional(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.string(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.literal("dynamic-tool"),toolName:U.string(),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-denied"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!1),reason:U.string().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-streaming"),providerExecuted:U.boolean().optional(),callProviderMetadata:K2.optional(),input:U.unknown().optional(),output:U.never().optional(),errorText:U.never().optional(),approval:U.never().optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("input-available"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.never().optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-requested"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.never().optional(),reason:U.never().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("approval-responded"),input:U.unknown(),providerExecuted:U.boolean().optional(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.boolean(),reason:U.string().optional()})}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-available"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.unknown(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),preliminary:U.boolean().optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-error"),providerExecuted:U.boolean().optional(),input:U.unknown().optional(),rawInput:U.unknown().optional(),output:U.never().optional(),errorText:U.string(),callProviderMetadata:K2.optional(),resultProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!0),reason:U.string().optional()}).optional()}),U.object({type:U.string().startsWith("tool-"),toolCallId:U.string(),toolMetadata:DD.optional(),state:U.literal("output-denied"),providerExecuted:U.boolean().optional(),input:U.unknown(),output:U.never().optional(),errorText:U.never().optional(),callProviderMetadata:K2.optional(),approval:U.object({id:U.string(),approved:U.literal(!1),reason:U.string().optional()})})])).nonempty("Message must contain at least one part")})).nonempty("Messages array must not be empty")));var QXw=WF({prefix:"aiobj",size:24});function fa0(A){return({url:Q,abortSignal:B})=>uc2({url:Q,maxBytes:A==null?void 0:A.maxBytes,abortSignal:B})}var wXw=WF({prefix:"aiobj",size:24});var $Xw=fa0();var Jp2="AI_NoSuchProviderError",Gp2=`vercel.ai.error.${Jp2}`,Fp2=Symbol.for(Gp2),Kp2;Kp2=Fp2;var DXw=fa0();import{basename as gp2,dirname as Sp2,join as Oa0}from"path";var Ha0={name:"@brains/web-chat",private:!0,version:"0.2.0-alpha.109",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"}};HA();var AbA=J.object({routePath:J.string().default("/chat"),apiPath:J.string().default("/api/chat")});var Np2=/\n{0,2}\[Entities affected this turn: [\s\S]*? Reference these IDs directly in follow-ups instead of searching for them\.\]\s*$/;function Ua0(A){return A.replace(Np2,"").trimEnd()}HA();import{mkdir as zp2,readdir as qp2,readFile as Ja0,rm as Lp2,stat as Ep2,writeFile as Ga0}from"fs/promises";import{join as IN}from"path";var vk="web-chat-upload",Tk=/^upload-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Vp2=86400000,Mp2=200;class YN extends Error{code;constructor(A,Q){super(Q);this.code=A;this.name="WebChatUploadStoreError"}}var Op2=J.object({kind:J.literal(vk),id:J.string().regex(Tk)}),Cp2=J.object({id:J.string().regex(Tk),ref:Op2,filename:J.string().min(1),mediaType:J.string().min(1),sizeBytes:J.number().nonnegative(),createdAt:J.string().datetime()});class QbA{options;retentionMs;maxCount;createUploadId;getNow;constructor(A){this.options=A;this.retentionMs=A.retentionMs??Vp2,this.maxCount=A.maxCount??Mp2,this.createUploadId=A.createId??(()=>`upload-${crypto.randomUUID()}`),this.getNow=A.now??(()=>new Date)}async save(A){let Q=this.createUploadId();this.assertValidUploadId(Q);let B={id:Q,ref:{kind:vk,id:Q},filename:A.filename,mediaType:A.mediaType,sizeBytes:A.content.byteLength,createdAt:this.getNow().toISOString()},w=this.getUploadDir(Q);return await zp2(w,{recursive:!0}),await Ga0(IN(w,"content"),A.content),await Ga0(IN(w,"metadata.json"),`${JSON.stringify(B,null,2)}
2403
2403
  `,"utf8"),await this.prune(),B}async read(A){let Q=await this.readRecord(A);try{let B=await Ja0(IN(this.getUploadDir(A),"content"));return{record:Q,content:B}}catch{throw new YN("not_found","Upload not found")}}async readRecord(A){this.assertValidUploadId(A);try{let Q=await Ja0(IN(this.getUploadDir(A),"metadata.json"),"utf8"),B=Cp2.safeParse(JSON.parse(Q));if(!B.success||B.data.id!==A)throw new YN("invalid_metadata","Invalid upload metadata");return B.data}catch(Q){if(Q instanceof YN)throw Q;throw new YN("not_found","Upload not found")}}toResponseBody(A){return{...A,url:this.getUploadUrl(A.id),downloadUrl:this.getUploadUrl(A.id,!0)}}async prune(){let A=this.getUploadsRoot();try{let Q=await qp2(A),w=(await Promise.all(Q.map(async(I)=>{try{let Y=await Ep2(IN(A,I));return Y.isDirectory()?{entry:I,mtimeMs:Y.mtimeMs}:null}catch{return null}}))).filter((I)=>I!==null).sort((I,Y)=>Y.mtimeMs-I.mtimeMs),$=this.getNow().getTime()-this.retentionMs,D=w.filter((I,Y)=>Y>=this.maxCount||I.mtimeMs<$);await Promise.all(D.map((I)=>Lp2(IN(A,I.entry),{recursive:!0,force:!0})))}catch{}}getUploadDir(A){return this.assertValidUploadId(A),IN(this.getUploadsRoot(),A)}getUploadsRoot(){return IN(this.options.dataDir,"web-chat","uploads")}getUploadUrl(A,Q=!1){return this.assertValidUploadId(A),`/api/chat/uploads?id=${encodeURIComponent(A)}${Q?"&download=1":""}`}assertValidUploadId(A){if(!Tk.test(A))throw new YN("invalid_ref","Invalid upload ref")}}var Ka0="upload.txt";var Za0=5000000,bp2=[".md",".txt",".markdown"],Rp2=["text/plain","text/markdown","text/x-markdown"],BbA=new Map([[".png","image/png"],[".jpg","image/jpeg"],[".jpeg","image/jpeg"],[".webp","image/webp"],[".gif","image/gif"],[".pdf","application/pdf"]]),Pp2=new Set(BbA.values());function I2A(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 Na0(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 za0(A,Q){let B=Q?.trim()??"",w=B.split(";",1)[0]?.toLowerCase()??B;if(w.length>0&&w!=="application/octet-stream")return w;let $=Na0(A,void 0);if($!=="application/octet-stream")return $;let D=A.toLowerCase();for(let[I,Y]of BbA)if(D.endsWith(I))return Y;return"application/octet-stream"}function qa0(A,Q){if(Q&&Rp2.some((B)=>Q.toLowerCase().startsWith(B)))return!0;return bp2.some((B)=>A.toLowerCase().endsWith(B))}function kp2(A){return A<=1e5}function jp2(A){return A<=5000000}function _p2(A,Q){let B=za0(A,Q);if(Pp2.has(B))return!0;return BbA.has(vp2(A))}function yp2(A){if(A.includes(0))return!1;try{return new TextDecoder("utf-8",{fatal:!0}).decode(A),!0}catch{return!1}}function xp2(A){let Q=I2A(A.filename),B=Na0(Q,A.mediaType);if(!qa0(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!kp2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!yp2(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 Y2A(A){let Q=I2A(A.filename),B=za0(Q,A.mediaType);if(qa0(Q,B)){let w=xp2({filename:Q,mediaType:B,content:A.content});return w.ok?{...w,kind:"text"}:w}if(!_p2(Q,B))return{ok:!1,code:"unsupported_type",message:`Unsupported file upload type: ${Q}`};if(!jp2(A.content.byteLength))return{ok:!1,code:"file_too_large",message:`File upload too large: ${Q}`};if(!Tp2(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 vp2(A){let Q=A.lastIndexOf(".");return Q>=0?A.slice(Q).toLowerCase():""}function Tp2(A,Q){switch(Q){case"image/png":return Fa0(A,[137,80,78,71]);case"image/jpeg":return Fa0(A,[255,216,255]);case"image/gif":return D2A(A,"GIF87a")||D2A(A,"GIF89a");case"image/webp":return D2A(A,"RIFF")&&La0(A,"WEBP",8);case"application/pdf":return D2A(A,"%PDF-");default:return!1}}function Fa0(A,Q){return Q.every((B,w)=>A[w]===B)}function D2A(A,Q){return La0(A,Q,0)}function La0(A,Q,B){return Array.from(Q).every((w,$)=>A[B+$]===w.charCodeAt(0))}var hp2=J.object({type:J.literal("text"),text:J.string()}),mp2=J.object({type:J.literal("file"),mediaType:J.string().optional(),filename:J.string().optional(),url:J.string()}),up2=J.object({state:J.literal("approval-responded"),approval:J.object({id:J.string(),approved:J.boolean()})}).passthrough(),cp2=J.object({role:J.string(),parts:J.array(J.unknown()).optional(),content:J.string().optional()}),pp2=J.object({id:J.string().optional(),messages:J.array(cp2).min(1),trigger:J.string().optional()}),gk="web-chat",lp2=25,ip2=6,wbA=48,dp2="file",rp2=16384,np2=J.object({kind:J.literal(vk),id:J.string().regex(Tk)}),Ea0=J.object({type:J.literal("data-upload"),data:J.object({ref:np2})}),op2=J.object({title:J.string().trim().min(1).max(wbA)}),sp2=J.object({kind:J.literal("text"),filename:J.string().min(1),mediaType:J.string().min(1),sizeBytes:J.number().nonnegative().optional(),source:J.object({kind:J.string().min(1),id:J.string().min(1)}).optional()}),ap2=J.array(sp2),tp2=J.object({kind:J.literal("attachment"),id:J.string().min(1),jobId:J.string().min(1).optional(),title:J.string().min(1),description:J.string().optional(),attachment:J.object({mediaType:J.string().min(1),url:J.string().min(1),downloadUrl:J.string().min(1).optional(),previewUrl:J.string().min(1).optional(),filename:J.string().min(1).optional(),sizeBytes:J.number().nonnegative().optional(),source:J.object({entityType:J.string().optional(),entityId:J.string().optional(),attachmentType:J.string().optional()}).optional()})}),ep2=J.array(tp2),Va0="/chat/assets/app.js",Al2=Oa0(import.meta.dir,"..","dist","ui","app.js"),Ql2=`
2404
2404
  /* \u2500\u2500\u2500 Chat tokens \u2014 alias chain pattern matching plugins/dashboard.
2405
2405
  Each --chat-* falls back through:
@@ -4379,7 +4379,7 @@ ${B.preview}`:B.summary}),B.state){case"approval-requested":A.write({type:"tool-
4379
4379
 
4380
4380
  `);$=I.pop()??"";for(let Y of I){let X=Y.split(`
4381
4381
  `).find((E)=>E.startsWith("data: "));if(!X)continue;let W;try{W=JSON.parse(X.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let H=W.result;if(!H)continue;if(H.final!==!0)continue;B.cancel().catch(()=>{});let K=H.status,Z=K?.state??"unknown",L=(K?.message?.parts??[]).filter((E)=>E.kind==="text"&&typeof E.text==="string").map((E)=>E.text).join(`
4382
- `)||"No response text";return{success:!0,data:{state:Z,response:L}}}D=await Ta0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class Lu extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class Eu extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function Ll2(A,Q,B,w){let $=new AbortController,D;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,Y)=>{D=setTimeout(()=>{$.abort(),Y(new Lu(w))},w)})])}catch(I){if(I instanceof Lu)throw I;if($.signal.aborted)throw new Lu(w);throw I}finally{if(D)clearTimeout(D)}}async function Ta0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new Eu(Q)),Q)})])}catch(w){if(w instanceof Eu)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function El2(A){if(A instanceof Lu||A instanceof Eu)return!0;return A instanceof Error}function Vl2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof Eu)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Sa0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??Gl2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Fl2,maxNetworkAttempts:A.maxNetworkAttempts??Kl2};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. 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:va0,visibility:"anchor",handler:async(w)=>{let $=J.object(va0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:D,message:I}=$.data,Y=Zl2(D);if(!Y)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 X=await A.entityService.getEntity({entityType:"agent",id:Y,visibilityScope:C$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!X)return{success:!1,error:`Agent ${Y} is not in your directory. Add it first.`};if(X.metadata.status!=="approved")return{success:!1,error:`Agent ${Y} is discovered but not approved yet. Approve it first.`};let W=`https://${Y}`,H=await Nl2(W,Q);if(!H)return{success:!1,error:`Could not fetch Agent Card from ${W}`};let F=H.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return zl2(F,I,Q,K,B)}}}var YbA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.108",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 Ol2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class hk extends JH{agentCard;taskManager=new DbA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",YbA,A,ba0)}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,D;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)D=I.map((Y)=>aD.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=Ra0({character:Q,profile:B,version:YbA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:D,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(Ol2))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 kk;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=ja0.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=ya0.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:Y}=xa0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(Y,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let D=await _a0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(D))}),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[Sa0({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`). Never pass a full URL or a display name like `Brain`.\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- 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` for the fresh call.\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")}}}}sA();class XbA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(D)=>{let I=await B({type:"directory-import",data:{paths:[D]}});this.logger.debug("Queued import job for file change",{jobId:I,path:D})},this.handleDelete=async(D)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:D});return}try{let{entityType:I,id:Y}=this.fileOperations.parseEntityFromPath(D),X=await B({type:"directory-delete",data:{entityId:Y,entityType:I,filePath:D}});this.logger.info("Queued delete job for removed file",{jobId:X,path:D,entityId:Y,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:D,error:I})}};else this.handleImport=async(D)=>{await Q([D])},this.handleDelete=async(D)=>{this.logger.warn("File deleted but no job queue available",{path:D})}}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 BA1=X1(ee0(),1);import{extname as Vo2}from"path";var b2A=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function wV(A){let Q=Vo2(A).toLowerCase();return b2A.includes(Q)}function AA1(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 YRA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Mo2,relative as Oo2,sep as QA1,join as Co2}from"path";function AX(A,Q){return Mo2(Q)?Q:Co2(A,Q)}function dk(A,Q){let B=AX(A,Q),w=Oo2(A,B);return QA1==="/"?w:w.split(QA1).join("/")}function bo2(A,Q){if(!dk(Q,A).startsWith("image/"))return!1;return wV(A)}function Ro2(A,Q){if(dk(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return bo2(A,Q)}class XRA{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=BA1.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(!Ro2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=dk(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=AX(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 wA1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Po2(Q)}function $A1(A){if(A)A.stop();return}function DA1(A,Q){if(A)A.setCallback(Q)}async function Po2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:D,fileOperations:I,deleteOnFileRemoval:Y}=A,X=new XbA(Q,$,D,I,Y),W=new XRA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(H,F)=>{await X.handleFileChange(H,F)}});return await W.start(),W}async function IA1(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:$}}sA();class WRA{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??l5(),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 fRA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new WRA({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 HRA{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 vo2,dirname as To2,extname as go2}from"path";import{extname as ko2}from"path";var R2A=[".pdf"],YA1=".meta.json";function $V(A){let Q=ko2(A).toLowerCase();return R2A.includes(Q)}function XA1(A){return A.toLowerCase().endsWith(YA1)}function URA(A){return`${A}${YA1}`}function WA1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as jo2,join as P2A}from"path";function k2A(A,Q){let w=dk(A,Q).split("/"),$,D;if(w.length===1)$="base",D=w;else if(w.length>1&&w[0])$=w[0],D=w.slice(1);else $="base",D=w;let I;if(D.length>1){let Y=D[D.length-1];if(Y)D[D.length-1]=fA1(Y);I=D.join(":")}else I=fA1(D[0]??"");return{entityType:$,id:I}}function HA1(A,Q,B,w=".md"){let $=Q.split(":").filter((W)=>W.length>0),D=B==="base";if($.length===1)return D?P2A(A,`${$[0]}${w}`):P2A(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let Y=I[I.length-1],X=I.slice(0,-1);if(D)return P2A(A,...X,`${Y}${w}`);return P2A(A,B,...X,`${Y}${w}`)}function UA1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return YRA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?YRA(B[1]):".md"}function fA1(A){let Q=jo2(A).toLowerCase();return Q===".md"||b2A.includes(Q)||R2A.includes(Q)?A.slice(0,-Q.length):A}LY();import{mkdir as So2,readFile as rk,writeFile as GRA,stat as ho2,utimes as mo2}from"fs/promises";import{join as j2A}from"path";import{mkdir as JA1,readdir as yo2,stat as xo2}from"fs/promises";import{access as _o2}from"fs/promises";async function n6(A){try{return await _o2(A),!0}catch{return!1}}async function JRA(A,Q){return ZA1(A,Q,{includeDocuments:!1,includeImages:!1})}async function GA1(A,Q){return ZA1(A,Q,{includeDocuments:!0,includeImages:!0})}async function FA1(A,Q){if(!await n6(A))await JA1(A,{recursive:!0});for(let B of Q)if(B!=="base")await JA1(j2A(A,B),{recursive:!0})}async function KA1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await n6(A))return{files:B,stats:w};let $=await JRA(A,Q);for(let D of $)try{let I=j2A(A,D),Y=await xo2(I),{entityType:X}=k2A(A,D);B.push({path:D,entityType:X,modified:Y.mtime}),w.totalFiles++,w.byEntityType[X]=(w.byEntityType[X]??0)+1}catch{continue}return{files:B,stats:w}}async function ZA1(A,Q,B){let w=[];if(!await n6(A))return w;let $=async(D,I="",Y=!1,X=!1)=>{let W=await yo2(D,{withFileTypes:!0});for(let H of W){let F=I?j2A(I,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")&&!XA1(H.name)){if(H.name.endsWith(".md"))w.push(F);else if(B.includeImages&&Y&&wV(H.name))w.push(F);else if(B.includeDocuments&&X&&$V(H.name))w.push(F)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(I===""&&!Q.hasEntityType(H.name))continue;let K=j2A(D,H.name),Z=H.name==="image"&&I==="",q=H.name==="document"&&I==="";await $(K,F,Y||Z,X||q)}}};return await $(A),w}function uo2(A){return typeof A==="object"&&A!==null}class FRA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return k2A(this.syncPath,A)}async readEntity(A){let Q=AX(this.syncPath,A),B=await ho2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),D=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,Y,X;if(wV(A)||$V(A)){let F=(await rk(Q)).toString("base64"),K=go2(A);if(Y=`data:${$V(A)?WA1(K):AA1(K)};base64,${F}`,$V(A))X=await this.readDocumentSidecar(Q,A)}else Y=await rk(Q,"utf-8");let W={entityType:w,id:$,content:Y,created:D,updated:I};if(X)W.metadata=X;return W}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:vo2(Q)},w=URA(A);if(!await n6(w))return B;try{let $=await rk(w,"utf-8"),D=JSON.parse($),I=uo2(D)?D:{};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 D=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(D),Y=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),X=!1;if(await n6(Q)){let W=await rk(Q),H=bB(W.toString("base64")),F=bB(Y.toString("base64"));if(H===F)X=!0}if(!X)await this.ensureEntityDirectory(A,Q),await GRA(Q,Y);if(w)await this.writeDocumentSidecar(A,Q);if(X)return}else{let D=this.entityService.serializeEntity(A);if(await n6(Q)){let I=await rk(Q,"utf-8"),Y=bB(I),X=bB(D);if(Y===X)return}await this.ensureEntityDirectory(A,Q),await GRA(Q,D,"utf-8")}let $=new Date(A.updated);await mo2(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await So2(To2(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,Y]of Object.entries(B)){if(I==="mimeType")continue;if(Y===void 0)continue;w[I]=Y}let $=URA(Q),D=`${JSON.stringify(w,null,2)}
4382
+ `)||"No response text";return{success:!0,data:{state:Z,response:L}}}D=await Ta0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class Lu extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class Eu extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function Ll2(A,Q,B,w){let $=new AbortController,D;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,Y)=>{D=setTimeout(()=>{$.abort(),Y(new Lu(w))},w)})])}catch(I){if(I instanceof Lu)throw I;if($.signal.aborted)throw new Lu(w);throw I}finally{if(D)clearTimeout(D)}}async function Ta0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new Eu(Q)),Q)})])}catch(w){if(w instanceof Eu)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function El2(A){if(A instanceof Lu||A instanceof Eu)return!0;return A instanceof Error}function Vl2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof Eu)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Sa0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??Gl2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Fl2,maxNetworkAttempts:A.maxNetworkAttempts??Kl2};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. 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:va0,visibility:"anchor",handler:async(w)=>{let $=J.object(va0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:D,message:I}=$.data,Y=Zl2(D);if(!Y)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 X=await A.entityService.getEntity({entityType:"agent",id:Y,visibilityScope:C$("a2a_call tool is anchor-only and resolves saved remote agents at any visibility")});if(!X)return{success:!1,error:`Agent ${Y} is not in your directory. Add it first.`};if(X.metadata.status!=="approved")return{success:!1,error:`Agent ${Y} is discovered but not approved yet. Approve it first.`};let W=`https://${Y}`,H=await Nl2(W,Q);if(!H)return{success:!1,error:`Could not fetch Agent Card from ${W}`};let F=H.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return zl2(F,I,Q,K,B)}}}var YbA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.109",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 Ol2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class hk extends JH{agentCard;taskManager=new DbA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",YbA,A,ba0)}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,D;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}});if(I.length>0)D=I.map((Y)=>aD.safeParse(Y.metadata)).filter((Y)=>Y.success).map((Y)=>Y.data)}catch{}this.agentCard=Ra0({character:Q,profile:B,version:YbA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:D,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(Ol2))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 kk;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=ja0.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=ya0.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:Y}=xa0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(Y,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let D=await _a0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(D))}),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[Sa0({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`). Never pass a full URL or a display name like `Brain`.\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- 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` for the fresh call.\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")}}}}sA();class XbA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(D)=>{let I=await B({type:"directory-import",data:{paths:[D]}});this.logger.debug("Queued import job for file change",{jobId:I,path:D})},this.handleDelete=async(D)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:D});return}try{let{entityType:I,id:Y}=this.fileOperations.parseEntityFromPath(D),X=await B({type:"directory-delete",data:{entityId:Y,entityType:I,filePath:D}});this.logger.info("Queued delete job for removed file",{jobId:X,path:D,entityId:Y,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:D,error:I})}};else this.handleImport=async(D)=>{await Q([D])},this.handleDelete=async(D)=>{this.logger.warn("File deleted but no job queue available",{path:D})}}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 BA1=X1(ee0(),1);import{extname as Vo2}from"path";var b2A=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function wV(A){let Q=Vo2(A).toLowerCase();return b2A.includes(Q)}function AA1(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 YRA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Mo2,relative as Oo2,sep as QA1,join as Co2}from"path";function AX(A,Q){return Mo2(Q)?Q:Co2(A,Q)}function dk(A,Q){let B=AX(A,Q),w=Oo2(A,B);return QA1==="/"?w:w.split(QA1).join("/")}function bo2(A,Q){if(!dk(Q,A).startsWith("image/"))return!1;return wV(A)}function Ro2(A,Q){if(dk(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return bo2(A,Q)}class XRA{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=BA1.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(!Ro2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=dk(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=AX(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 wA1(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Po2(Q)}function $A1(A){if(A)A.stop();return}function DA1(A,Q){if(A)A.setCallback(Q)}async function Po2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:D,fileOperations:I,deleteOnFileRemoval:Y}=A,X=new XbA(Q,$,D,I,Y),W=new XRA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(H,F)=>{await X.handleFileChange(H,F)}});return await W.start(),W}async function IA1(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:$}}sA();class WRA{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??l5(),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 fRA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new WRA({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 HRA{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 vo2,dirname as To2,extname as go2}from"path";import{extname as ko2}from"path";var R2A=[".pdf"],YA1=".meta.json";function $V(A){let Q=ko2(A).toLowerCase();return R2A.includes(Q)}function XA1(A){return A.toLowerCase().endsWith(YA1)}function URA(A){return`${A}${YA1}`}function WA1(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as jo2,join as P2A}from"path";function k2A(A,Q){let w=dk(A,Q).split("/"),$,D;if(w.length===1)$="base",D=w;else if(w.length>1&&w[0])$=w[0],D=w.slice(1);else $="base",D=w;let I;if(D.length>1){let Y=D[D.length-1];if(Y)D[D.length-1]=fA1(Y);I=D.join(":")}else I=fA1(D[0]??"");return{entityType:$,id:I}}function HA1(A,Q,B,w=".md"){let $=Q.split(":").filter((W)=>W.length>0),D=B==="base";if($.length===1)return D?P2A(A,`${$[0]}${w}`):P2A(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let Y=I[I.length-1],X=I.slice(0,-1);if(D)return P2A(A,...X,`${Y}${w}`);return P2A(A,B,...X,`${Y}${w}`)}function UA1(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return YRA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?YRA(B[1]):".md"}function fA1(A){let Q=jo2(A).toLowerCase();return Q===".md"||b2A.includes(Q)||R2A.includes(Q)?A.slice(0,-Q.length):A}LY();import{mkdir as So2,readFile as rk,writeFile as GRA,stat as ho2,utimes as mo2}from"fs/promises";import{join as j2A}from"path";import{mkdir as JA1,readdir as yo2,stat as xo2}from"fs/promises";import{access as _o2}from"fs/promises";async function n6(A){try{return await _o2(A),!0}catch{return!1}}async function JRA(A,Q){return ZA1(A,Q,{includeDocuments:!1,includeImages:!1})}async function GA1(A,Q){return ZA1(A,Q,{includeDocuments:!0,includeImages:!0})}async function FA1(A,Q){if(!await n6(A))await JA1(A,{recursive:!0});for(let B of Q)if(B!=="base")await JA1(j2A(A,B),{recursive:!0})}async function KA1(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await n6(A))return{files:B,stats:w};let $=await JRA(A,Q);for(let D of $)try{let I=j2A(A,D),Y=await xo2(I),{entityType:X}=k2A(A,D);B.push({path:D,entityType:X,modified:Y.mtime}),w.totalFiles++,w.byEntityType[X]=(w.byEntityType[X]??0)+1}catch{continue}return{files:B,stats:w}}async function ZA1(A,Q,B){let w=[];if(!await n6(A))return w;let $=async(D,I="",Y=!1,X=!1)=>{let W=await yo2(D,{withFileTypes:!0});for(let H of W){let F=I?j2A(I,H.name):H.name;if(H.isFile()&&!H.name.endsWith(".invalid")&&!XA1(H.name)){if(H.name.endsWith(".md"))w.push(F);else if(B.includeImages&&Y&&wV(H.name))w.push(F);else if(B.includeDocuments&&X&&$V(H.name))w.push(F)}else if(H.isDirectory()&&!H.name.startsWith(".")){if(I===""&&!Q.hasEntityType(H.name))continue;let K=j2A(D,H.name),Z=H.name==="image"&&I==="",q=H.name==="document"&&I==="";await $(K,F,Y||Z,X||q)}}};return await $(A),w}function uo2(A){return typeof A==="object"&&A!==null}class FRA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return k2A(this.syncPath,A)}async readEntity(A){let Q=AX(this.syncPath,A),B=await ho2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),D=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,Y,X;if(wV(A)||$V(A)){let F=(await rk(Q)).toString("base64"),K=go2(A);if(Y=`data:${$V(A)?WA1(K):AA1(K)};base64,${F}`,$V(A))X=await this.readDocumentSidecar(Q,A)}else Y=await rk(Q,"utf-8");let W={entityType:w,id:$,content:Y,created:D,updated:I};if(X)W.metadata=X;return W}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:vo2(Q)},w=URA(A);if(!await n6(w))return B;try{let $=await rk(w,"utf-8"),D=JSON.parse($),I=uo2(D)?D:{};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 D=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(D),Y=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),X=!1;if(await n6(Q)){let W=await rk(Q),H=bB(W.toString("base64")),F=bB(Y.toString("base64"));if(H===F)X=!0}if(!X)await this.ensureEntityDirectory(A,Q),await GRA(Q,Y);if(w)await this.writeDocumentSidecar(A,Q);if(X)return}else{let D=this.entityService.serializeEntity(A);if(await n6(Q)){let I=await rk(Q,"utf-8"),Y=bB(I),X=bB(D);if(Y===X)return}await this.ensureEntityDirectory(A,Q),await GRA(Q,D,"utf-8")}let $=new Date(A.updated);await mo2(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await So2(To2(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,Y]of Object.entries(B)){if(I==="mimeType")continue;if(Y===void 0)continue;w[I]=Y}let $=URA(Q),D=`${JSON.stringify(w,null,2)}
4383
4383
  `;if(await n6($)){if(await rk($,"utf-8")===D)return}await this.ensureEntityDirectory(A,$),await GRA($,D,"utf-8")}getFilePath(A,Q,B=".md"){return HA1(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,UA1(A))}async getAllMarkdownFiles(){return JRA(this.syncPath,this.entityService)}async getAllSyncFiles(){return GA1(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await FA1(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=bB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return KA1(this.syncPath,this.entityService)}async syncDirectoryExists(){return n6(this.syncPath)}async fileExists(A){return n6(A)}}d7();HA();d7();async function _2A(A,Q,B,w){let{sourceUrl:$}=A,D=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(D[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:D[0].id}),D[0].id;let I=await B($),{base64:Y}=PZ(I),X=wL(Y),W=kZ(Y);if(!X||!W)throw Error("Could not detect image format or dimensions");let H=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:X,width:W.width,height:W.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:H.entityId}),H.entityId}var NA1=J.object({title:J.string(),slug:J.string().optional(),coverImageUrl:J.string().url(),coverImageId:J.string().optional(),coverImageAlt:J.string().optional()});class KRA{entityService;fetcher;logger;constructor(A,Q,B=zW){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=yB(A)}catch{return null}let{frontmatter:B}=Q,w=NA1.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!gJ(I))return null;return{sourceUrl:I,postTitle:$,postSlug:D??b1($),customAlt:Y}}async convert(A){let Q;try{Q=yB(A)}catch(W){return this.logger.debug("Parse failed",{error:W}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=NA1.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:D,coverImageUrl:I,coverImageAlt:Y}=w.data;if(!gJ(I))return{content:A,converted:!1};let X={postTitle:$,postSlug:D??b1($),sourceUrl:I,customAlt:Y};try{let W=await this.createImageEntity(X),H={...B};return delete H.coverImageUrl,delete H.coverImageAlt,H.coverImageId=W,{content:xJ(H,Q.content),converted:!0,imageId:W}}catch(W){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:x0(W)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,D=`Cover image for ${Q}`;return _2A({id:`${B}-cover`,title:D,alt:$??D,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}d7();HA();class Tu{entityService;fetcher;logger;constructor(A,Q,B=zW){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=rGA(A);for(let $ of w){if(!gJ($.url))continue;if($.url.startsWith("entity://"))continue;let D=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:D,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,D=0;for(let I of B)try{let Y=await this.createImageEntity(I,D++),X=`![${I.alt}](entity://image/${Y})`;w=w.replace(I.originalMarkdown,X),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:Y})}catch(Y){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:x0(Y)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return _2A({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class ZRA{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:[]},D=A??await this.fileOperations.getAllSyncFiles(),I=D.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let Y=0;Y<I;Y+=B){let X=D.slice(Y,Y+B),W=await w(X);$.imported+=W.imported,$.skipped+=W.skipped,$.failed+=W.failed,$.quarantined+=W.quarantined,$.errors.push(...W.errors),$.quarantinedFiles.push(...W.quarantinedFiles),$.jobIds.push(...W.jobIds);let H=Math.min(Y+B,I),F=Math.round(H/I*40);await Q.report({progress:F,message:`Imported ${H}/${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 D=await w(A);return await Q.report({progress:100,message:`Exported ${D.exported} entities`}),this.logger.debug("Export completed",D),D}}HA();import{rename as co2,appendFile as po2,readFile as lo2,writeFile as io2,access as do2}from"fs/promises";import{join as zA1}from"path";class NRA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof J.ZodError)return!0;let Q=x0(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),D=`${$}.invalid`;try{await co2($,D),B.quarantined++,B.quarantinedFiles.push(A);let I=zA1(this.syncPath,".import-errors.log"),Y=new Date().toISOString(),X=x0(Q),W=`${Y} - ${A}: ${X}
4384
4384
  \u2192 ${A}.invalid
4385
4385
 
@@ -4407,7 +4407,7 @@ ${B.preview}`:B.summary}),B.state){case"approval-requested":A.write({type:"tool-
4407
4407
  *...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
4408
4408
  ## Getting Started
4409
4409
  `),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(`
4410
- `)}}sA();class DQA extends Uw{directorySync;constructor(A,Q,B){super(A,{schema:ZPA,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}}}sA();class IQA extends Uw{directorySync;constructor(A,Q,B){super(A,{schema:KPA,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}}}sA();class YQA extends Uw{directorySync;context;constructor(A,Q,B){super(A,{schema:FPA,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 D={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"}),D=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(D.jobIds,B),await B.report({progress:100,message:`Import complete: ${D.imported} imported`});else await B.report({progress:50,message:`Imported ${D.imported} entities`}),await this.waitForImportJobs(D.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let X=$==="export"?10:60;await B.report({progress:X,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: ${D.imported} imported, ${I.exported} exported`})}let Y=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Y,imported:D.imported,exported:I.exported}),{import:D,export:I,duration:Y}}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,D=Date.now(),I=async()=>{let X=(await Promise.all(A.map((H)=>B.getAsyncJobStatus(H)))).filter((H)=>H&&(H.status==="completed"||H.status==="failed")).length;if(X===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-D>w){this.logger.warn(`Timeout waiting for import jobs (${X}/${A.length} completed)`);return}let W=Math.round(X/A.length*100);return await Q.report({progress:50+Math.round(W*0.05),message:`Processing ${X}/${A.length} entities`}),await new Promise((H)=>setTimeout(H,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}sA();class XQA extends Uw{context;constructor(A,Q,B){super(A,{schema:wQA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=wQA.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}}}sA();HA();var ue2=J.object({});class WQA extends Uw{directorySync;constructor(A,Q){super(A,{schema:ue2,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}}sA();d7();HA();e8();d7();import{readFile as ce2,writeFile as pe2}from"fs/promises";var le2=NPA;class fQA extends Uw{context;fetcher;constructor(A,Q,B=zW){super(Q,{schema:le2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:D,postSlug:I,customAlt:Y}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:JQ.INIT,message:`Reading file: ${w}`});let X;try{X=await ce2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:x0(L)}),m6.failure(L)}let W;try{W=yB(X)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:x0(L)}),m6.failure(L)}let H=W.frontmatter;if(H.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:JQ.FETCH,message:"Checking for existing image"});let F=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),K;if(F[0])K=F[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:K}),await this.reportProgress(B,{progress:JQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:JQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(i){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:x0(i)}),m6.failure(i)}await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let{base64:E}=PZ(L),R=wL(E),j=kZ(E);if(!R||!j)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),m6.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let C=`Cover image for ${D}`,m=Y??C;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:C,alt:m,format:R,width:j.width,height:j.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:JQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:JQ.SAVE,message:"Updating file"});let Z={...H};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=xJ(Z,W.content);try{await pe2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:x0(L)}),m6.failure(L)}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(X){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:x0(X)}),m6.failure(X)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}sA();d7();HA();e8();import{readFile as ie2,writeFile as de2}from"fs/promises";class HQA extends Uw{converter;constructor(A,Q,B=zW){super(Q,{schema:zPA,jobTypeName:"inline-image-convert"});this.converter=new Tu(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:JQ.INIT,message:`Reading file: ${w}`});let D;try{D=await ie2(w,"utf-8")}catch(X){let W=x0(X);return this.logger.error("Failed to read file",{filePath:w,error:W}),{success:!1,error:W}}await this.reportProgress(B,{progress:JQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(D,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:JQ.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:JQ.PROCESS,message:`Converting ${I.length} images`});let Y=await this.converter.convert(D,$);if(!Y.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:JQ.SAVE,message:"Writing updated file"});try{await de2(w,Y.content,"utf-8")}catch(X){let W=x0(X);return this.logger.error("Failed to write file",{filePath:w,error:W}),{success:!1,error:W}}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:Y.convertedCount}),{success:!0,convertedCount:Y.convertedCount}}catch(D){let I=x0(D);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 s21(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new YQA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new DQA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new IQA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new XQA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new WQA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new fQA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new HQA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}sA();import{unlink as re2,access as ne2}from"fs/promises";function a21(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:D}=A;$("entity:created",async(I)=>{let{entity:Y}=I.payload;try{await Q.fileOps.writeEntity(Y),B.debug("Auto-exported created entity",{id:Y.id,entityType:Y.entityType})}catch(X){B.error("Auto-export FAILED for created entity",{id:Y.id,entityType:Y.entityType,error:X instanceof Error?X.message:String(X),stack:X instanceof Error?X.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:Y,entityId:X}=I.payload;try{let W=await D.getEntity({entityType:Y,id:X});if(!W)return B.debug("Entity not found in DB, skipping export",{entityType:Y,entityId:X}),{success:!1};await Q.fileOps.writeEntity(W),B.debug("Auto-exported updated entity",{id:W.id,entityType:W.entityType})}catch(W){B.error("Auto-export FAILED for updated entity",{entityType:Y,entityId:X,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:Y,entityType:X}=I.payload,W=Q.fileOps.getFilePath(Y,X);if(await ne2(W).then(()=>!0,()=>!1))await re2(W),B.debug("Auto-deleted entity file",{id:Y,entityType:X,path:W});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function t21(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:l5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}HA();sA();import{readdir as QQ1,mkdir as se2,copyFile as ae2}from"fs/promises";import{join as AQ1,resolve as qPA}from"path";import{join as oe2}from"path";async function e21(A){if(!await n6(oe2(A,".git")))return!1;try{return await JF(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function te2(A,Q){if(!await n6(A))return!0;if((await QQ1(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await e21(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function BQ1(A,Q){let B=await QQ1(A,{withFileTypes:!0});for(let w of B){let $=AQ1(A,w.name),D=AQ1(Q,w.name);if(w.isDirectory()){if(!await n6(D))await se2(D,{recursive:!0});await BQ1($,D)}else await ae2($,D)}}async function wQ1(A,Q,B){let w=qPA(process.cwd(),A);B=B?qPA(B):qPA(process.cwd(),"seed-content");let $=await te2(w,Q);if($&&await n6(B))Q.debug("Copying seed content to brain-data directory"),await BQ1(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 $Q1(A,Q,B,w,$){let D=!1,I=async()=>{if(D)return;D=!0;let Y=Q();if(B.seedContent){let X=B.syncPath??A.dataDir;await wQ1(X,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let W=await $.pull();if(W.files.length>0)w.info("Pulled changes from remote",{filesChanged:W.files.length})}w.debug("Starting initial sync");let X=await Y.sync();w.debug("Initial sync completed",{imported:X.import.imported,failed:X.import.failed,duration:X.duration}),await A.messaging.send({type:Cq.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(X){w.error("Initial sync failed",X),await A.messaging.send({type:Cq.initialSyncCompleted,payload:{success:!1,error:x0(X)},...{broadcast:!0}})}};A.messaging.subscribe(Cq.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}HA();function DQ1(A,Q,B,w){let $=new Wq(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Y){w.error("Git auto-commit failed",{error:Y})}})},B),D=["entity:created","entity:updated","entity:deleted"],I=[];for(let Y of D){let X=A.subscribe(Y,async()=>{return $.trigger(),{success:!0}});I.push(X)}return()=>{$.dispose();for(let Y of I)Y()}}function IQ1(A,Q,B,w,$){if(w<=0)return()=>{};let D=w*60*1000,I=!1,Y=async()=>{if(I)return;I=!0;try{let{files:W,result:H}=await A.withLock(async()=>{let F=await A.pull();if(F.files.length===0)return{files:[],result:null};let K=await Q.queueSyncBatch(B,"periodic-sync");return{files:F.files,result:K}});if(W.length>0)$.info("Periodic sync: pulled changes",{filesChanged:W.length});if(H)$.debug("Periodic sync: queued imports",{importOperations:H.importOperationsCount,totalFiles:H.totalFiles})}catch(W){$.error("Periodic git sync failed",{error:W})}finally{I=!1}},X=setInterval(()=>{Y()},D);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(X)}}import{spawnSync as XQ1}from"child_process";import{cpSync as ee2,existsSync as YQ1,mkdirSync as AAQ,mkdtempSync as QAQ,rmSync as BAQ}from"fs";import{tmpdir as wAQ}from"os";import{fileURLToPath as $AQ}from"url";import{join as DAQ,resolve as IAQ}from"path";function fN(A,Q){let B=XQ1("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 YAQ(A){return A.startsWith("file://")}function XAQ(A){return $AQ(A)}function WAQ(A,Q){return XQ1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function WQ1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!YAQ(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=XAQ(A.gitUrl),w=IAQ(A.seedContentPath);if(!YQ1(w))throw Error(`Seed content path not found: ${w}`);if(!YQ1(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),AAQ(B,{recursive:!0}),fN(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(WAQ(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 $=QAQ(DAQ(wAQ(),"directory-sync-seed-"));try{fN($,["init",`--initial-branch=${Q}`]),fN($,["config","user.name",A.authorName??"Brain"]),fN($,["config","user.email",A.authorEmail??"brain@localhost"]),ee2(w,$,{recursive:!0}),fN($,["add","."]),fN($,["commit","-m","seed content remote"]),fN($,["remote","add","origin",A.gitUrl]),fN($,["push","-u","origin",Q])}finally{BAQ($,{recursive:!0,force:!0})}}function fQ1(A,Q,B,w,$){let{subscribe:D}=A.messaging;D("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Export failed"}}}),D("entity:import:request",async(I)=>{try{let Y=Q(),X=I.payload.paths,W=await Y.importEntities(X);if(X&&X.length>0)await Y.removeOrphanedEntities();return{success:!0,data:W}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Import failed"}}}),D("sync:status:request",async()=>{try{let Y=await Q().getStatus();return{success:!0,data:{syncPath:Y.syncPath,isInitialized:Y.exists,watchEnabled:Y.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),D("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Configuration failed"}}}),D("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")}sA();HA();sA();HA();function HQ1(A,Q){return uQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",J.object({entityType:J.string().describe("Entity type (e.g. post, note, link)"),id:J.string().describe("Entity ID"),sha:J.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:J.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 D=await Q.show(B.sha,w);return K8({sha:B.sha,entityType:B.entityType,id:B.id,content:D},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return K8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return K8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return i5($ instanceof Error?$.message:"History lookup failed")}})}function UQ1(A,Q,B,w){let $=[uQ(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.",J.object({}),async(D,I)=>{try{let Y=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,X={interfaceType:I.interfaceType,channelId:I.channelId},W=w!==void 0,H=()=>A.queueSyncBatch(Q,Y,X),F=w?await w.withLock(async()=>{return await w.pull(),H()}):await H();if(!F)return K8({gitPulled:W},"No files to sync");return K8({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:W},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${W?" (pulled from git)":""}`)}catch(Y){return i5(Y instanceof Error?Y.message:"Sync failed")}},{cli:{name:"sync"}}),uQ(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.",J.object({}),async()=>{try{let D=await A.getStatus(),I={syncPath:D.syncPath,lastSync:D.lastSync?.toISOString(),watching:D.watching};if(w){let Y=await w.getStatus();I.git={isRepo:Y.isRepo,branch:Y.branch,hasChanges:Y.hasChanges,ahead:Y.ahead,behind:Y.behind,remote:Y.remote}}return K8(I)}catch(D){return i5(D instanceof Error?D.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(HQ1(B,w));return $}var JQ1={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.108",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:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class LPA extends QB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",JQ1,A,nu)}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:ou,basePrompt:"",formatter:new $QA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new gu({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(a21(A,$,this.logger,this.config.entityTypes),this.config.autoSync)t21(A,$,this.config.syncPath??A.dataDir);let D=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!D)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(D&&this.config.git){await WQ1({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 GPA({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}),this.gitCleanups.push(DQ1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(IQ1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)$Q1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);fQ1(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return UQ1(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 gu({...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){s21(A,this.requireDirectorySync(),this.logger)}}function XV(A={}){return new LPA(A)}sA();HA();var GQ1={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.108",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 UAQ=J.object({apiKey:J.string().min(1).optional(),from:J.string().min(1).optional()});class FQ1 extends QB{fetchImpl;constructor(A={},Q={}){super("email-resend",GQ1,A,UAQ);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(ve,async(B)=>{let w=a30.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 UQA(A={}){return new FQ1(A)}sA();import{render as RW1}from"preact-render-to-string";import{h as iV}from"preact";function KQ1(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=KQ1(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function ek(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=KQ1(A))&&(w&&(w+=" "),w+=Q);return w}var JAQ=(A)=>{let Q=FAQ(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let Y=I.split("-");if(Y[0]===""&&Y.length!==1)Y.shift();return LQ1(Y,Q)||GAQ(I)},getConflictingClassGroupIds:(I,Y)=>{let X=B[I]||[];if(Y&&w[I])return[...X,...w[I]];return X}}},LQ1=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?LQ1(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let D=A.join("-");return Q.validators.find(({validator:I})=>I(D))?.classGroupId},ZQ1=/^\[(.+)\]$/,GAQ=(A)=>{if(ZQ1.test(A)){let Q=ZQ1.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},FAQ=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return ZAQ(Object.entries(A.classGroups),B).forEach(([D,I])=>{VPA(I,w,D,Q)}),w},VPA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let D=$===""?Q:NQ1(Q,$);D.classGroupId=B;return}if(typeof $==="function"){if(KAQ($)){VPA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([D,I])=>{VPA(I,NQ1(Q,D),B,w)})})},NQ1=(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},KAQ=(A)=>A.isThemeGetter,ZAQ=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((D)=>{if(typeof D==="string")return Q+D;if(typeof D==="object")return Object.fromEntries(Object.entries(D).map(([I,Y])=>[Q+I,Y]));return D});return[B,$]})},NAQ=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(D,I)=>{if(B.set(D,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(D){let I=B.get(D);if(I!==void 0)return I;if((I=w.get(D))!==void 0)return $(D,I),I},set(D,I){if(B.has(D))B.set(D,I);else $(D,I)}}};var zAQ=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],D=Q.length,I=(Y)=>{let X=[],W=0,H=0,F;for(let E=0;E<Y.length;E++){let R=Y[E];if(W===0){if(R===$&&(w||Y.slice(E,E+D)===Q)){X.push(Y.slice(H,E)),H=E+D;continue}if(R==="/"){F=E;continue}}if(R==="[")W++;else if(R==="]")W--}let K=X.length===0?Y:Y.substring(H),Z=K.startsWith("!"),q=Z?K.substring(1):K,L=F&&F>H?F-H:void 0;return{modifiers:X,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(Y)=>B({className:Y,parseClassName:I});return I},qAQ=(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},LAQ=(A)=>({cache:NAQ(A.cacheSize),parseClassName:zAQ(A),...JAQ(A)}),EAQ=/\s+/,VAQ=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,D=[],I=A.trim().split(EAQ),Y="";for(let X=I.length-1;X>=0;X-=1){let W=I[X],{modifiers:H,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(W),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){Y=W+(Y.length>0?" "+Y:Y);continue}if(L=w(K),!L){Y=W+(Y.length>0?" "+Y:Y);continue}q=!1}let E=qAQ(H).join(":"),R=F?E+"!":E,j=R+L;if(D.includes(j))continue;D.push(j);let C=$(L,q);for(let m=0;m<C.length;++m){let i=C[m];D.push(R+i)}Y=W+(Y.length>0?" "+Y:Y)}return Y};function MAQ(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=EQ1(Q))w&&(w+=" "),w+=B}return w}var EQ1=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=EQ1(A[w]))B&&(B+=" "),B+=Q}return B};function zQ1(A,...Q){let B,w,$,D=I;function I(X){let W=Q.reduce((H,F)=>F(H),A());return B=LAQ(W),w=B.cache.get,$=B.cache.set,D=Y,Y(X)}function Y(X){let W=w(X);if(W)return W;let H=VAQ(X,B);return $(X,H),H}return function(){return D(MAQ.apply(null,arguments))}}var M8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},VQ1=/^\[(?:([a-z-]+):)?(.+)\]$/i,OAQ=/^\d+\/\d+$/,CAQ=new Set(["px","full","screen"]),bAQ=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,RAQ=/\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$/,PAQ=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,kAQ=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,jAQ=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,GF=(A)=>Aj(A)||CAQ.has(A)||OAQ.test(A),HN=(A)=>Qj(A,"length",hAQ),Aj=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),EPA=(A)=>Qj(A,"number",Aj),su=(A)=>Boolean(A)&&Number.isInteger(Number(A)),_AQ=(A)=>A.endsWith("%")&&Aj(A.slice(0,-1)),SQ=(A)=>VQ1.test(A),UN=(A)=>bAQ.test(A),yAQ=new Set(["length","size","percentage"]),xAQ=(A)=>Qj(A,yAQ,MQ1),vAQ=(A)=>Qj(A,"position",MQ1),TAQ=new Set(["image","url"]),gAQ=(A)=>Qj(A,TAQ,uAQ),SAQ=(A)=>Qj(A,"",mAQ),au=()=>!0,Qj=(A,Q,B)=>{let w=VQ1.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},hAQ=(A)=>RAQ.test(A)&&!PAQ.test(A),MQ1=()=>!1,mAQ=(A)=>kAQ.test(A),uAQ=(A)=>jAQ.test(A);var qQ1=()=>{let A=M8("colors"),Q=M8("spacing"),B=M8("blur"),w=M8("brightness"),$=M8("borderColor"),D=M8("borderRadius"),I=M8("borderSpacing"),Y=M8("borderWidth"),X=M8("contrast"),W=M8("grayscale"),H=M8("hueRotate"),F=M8("invert"),K=M8("gap"),Z=M8("gradientColorStops"),q=M8("gradientColorStopPositions"),L=M8("inset"),E=M8("margin"),R=M8("opacity"),j=M8("padding"),C=M8("saturate"),m=M8("scale"),i=M8("sepia"),g=M8("skew"),x=M8("space"),T=M8("translate"),S=()=>["auto","contain","none"],e=()=>["auto","hidden","clip","visible","scroll"],h=()=>["auto",SQ,Q],XA=()=>[SQ,Q],BA=()=>["",GF,HN],_=()=>["auto",Aj,SQ],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["solid","dashed","dotted","double","none"],r=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],p=()=>["start","end","center","between","around","evenly","stretch"],AA=()=>["","0",SQ],o=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[Aj,SQ];return{cacheSize:500,separator:":",theme:{colors:[au],spacing:[GF,HN],blur:["none","",UN,SQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",UN,SQ],borderSpacing:XA(),borderWidth:BA(),contrast:UA(),grayscale:AA(),hueRotate:UA(),invert:AA(),gap:XA(),gradientColorStops:[A],gradientColorStopPositions:[_AQ,HN],inset:h(),margin:h(),opacity:UA(),padding:XA(),saturate:UA(),scale:UA(),sepia:AA(),skew:UA(),space:XA(),translate:XA()},classGroups:{aspect:[{aspect:["auto","square","video",SQ]}],container:["container"],columns:[{columns:[UN]}],"break-after":[{"break-after":o()}],"break-before":[{"break-before":o()}],"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:[...O(),SQ]}],overflow:[{overflow:e()}],"overflow-x":[{"overflow-x":e()}],"overflow-y":[{"overflow-y":e()}],overscroll:[{overscroll:S()}],"overscroll-x":[{"overscroll-x":S()}],"overscroll-y":[{"overscroll-y":S()}],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",su,SQ]}],basis:[{basis:h()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",SQ]}],grow:[{grow:AA()}],shrink:[{shrink:AA()}],order:[{order:["first","last","none",su,SQ]}],"grid-cols":[{"grid-cols":[au]}],"col-start-end":[{col:["auto",{span:["full",su,SQ]},SQ]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[au]}],"row-start-end":[{row:["auto",{span:[su,SQ]},SQ]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",SQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",SQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...p()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...p(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...p(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[E]}],mx:[{mx:[E]}],my:[{my:[E]}],ms:[{ms:[E]}],me:[{me:[E]}],mt:[{mt:[E]}],mr:[{mr:[E]}],mb:[{mb:[E]}],ml:[{ml:[E]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",SQ,Q]}],"min-w":[{"min-w":[SQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[SQ,Q,"none","full","min","max","fit","prose",{screen:[UN]},UN]}],h:[{h:[SQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[SQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[SQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[SQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",UN,HN]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",EPA]}],"font-family":[{font:[au]}],"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",SQ]}],"line-clamp":[{"line-clamp":["none",Aj,EPA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",GF,SQ]}],"list-image":[{"list-image":["none",SQ]}],"list-style-type":[{list:["none","disc","decimal",SQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",GF,HN]}],"underline-offset":[{"underline-offset":["auto",GF,SQ]}],"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:XA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",SQ]}],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",SQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),vAQ]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",xAQ]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},gAQ]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[q]}],"gradient-via-pos":[{via:[q]}],"gradient-to-pos":[{to:[q]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[D]}],"rounded-s":[{"rounded-s":[D]}],"rounded-e":[{"rounded-e":[D]}],"rounded-t":[{"rounded-t":[D]}],"rounded-r":[{"rounded-r":[D]}],"rounded-b":[{"rounded-b":[D]}],"rounded-l":[{"rounded-l":[D]}],"rounded-ss":[{"rounded-ss":[D]}],"rounded-se":[{"rounded-se":[D]}],"rounded-ee":[{"rounded-ee":[D]}],"rounded-es":[{"rounded-es":[D]}],"rounded-tl":[{"rounded-tl":[D]}],"rounded-tr":[{"rounded-tr":[D]}],"rounded-br":[{"rounded-br":[D]}],"rounded-bl":[{"rounded-bl":[D]}],"border-w":[{border:[Y]}],"border-w-x":[{"border-x":[Y]}],"border-w-y":[{"border-y":[Y]}],"border-w-s":[{"border-s":[Y]}],"border-w-e":[{"border-e":[Y]}],"border-w-t":[{"border-t":[Y]}],"border-w-r":[{"border-r":[Y]}],"border-w-b":[{"border-b":[Y]}],"border-w-l":[{"border-l":[Y]}],"border-opacity":[{"border-opacity":[R]}],"border-style":[{border:[...k(),"hidden"]}],"divide-x":[{"divide-x":[Y]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[Y]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:k()}],"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:["",...k()]}],"outline-offset":[{"outline-offset":[GF,SQ]}],"outline-w":[{outline:[GF,HN]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:BA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[GF,HN]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",UN,SAQ]}],"shadow-color":[{shadow:[au]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...r(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":r()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[X]}],"drop-shadow":[{"drop-shadow":["","none",UN,SQ]}],grayscale:[{grayscale:[W]}],"hue-rotate":[{"hue-rotate":[H]}],invert:[{invert:[F]}],saturate:[{saturate:[C]}],sepia:[{sepia:[i]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[X]}],"backdrop-grayscale":[{"backdrop-grayscale":[W]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[H]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[C]}],"backdrop-sepia":[{"backdrop-sepia":[i]}],"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",SQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",SQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",SQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[m]}],"scale-x":[{"scale-x":[m]}],"scale-y":[{"scale-y":[m]}],rotate:[{rotate:[su,SQ]}],"translate-x":[{"translate-x":[T]}],"translate-y":[{"translate-y":[T]}],"skew-x":[{"skew-x":[g]}],"skew-y":[{"skew-y":[g]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",SQ]}],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",SQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":XA()}],"scroll-mx":[{"scroll-mx":XA()}],"scroll-my":[{"scroll-my":XA()}],"scroll-ms":[{"scroll-ms":XA()}],"scroll-me":[{"scroll-me":XA()}],"scroll-mt":[{"scroll-mt":XA()}],"scroll-mr":[{"scroll-mr":XA()}],"scroll-mb":[{"scroll-mb":XA()}],"scroll-ml":[{"scroll-ml":XA()}],"scroll-p":[{"scroll-p":XA()}],"scroll-px":[{"scroll-px":XA()}],"scroll-py":[{"scroll-py":XA()}],"scroll-ps":[{"scroll-ps":XA()}],"scroll-pe":[{"scroll-pe":XA()}],"scroll-pt":[{"scroll-pt":XA()}],"scroll-pr":[{"scroll-pr":XA()}],"scroll-pb":[{"scroll-pb":XA()}],"scroll-pl":[{"scroll-pl":XA()}],"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",SQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[GF,HN,EPA]}],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"]}}},cAQ=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:D={},override:I={}})=>{tu(A,"cacheSize",Q),tu(A,"prefix",B),tu(A,"separator",w),tu(A,"experimentalParseClassName",$);for(let Y in I)pAQ(A[Y],I[Y]);for(let Y in D)lAQ(A[Y],D[Y]);return A},tu=(A,Q,B)=>{if(B!==void 0)A[Q]=B},pAQ=(A,Q)=>{if(Q)for(let B in Q)tu(A,B,Q[B])},lAQ=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},JQA=(A,...Q)=>typeof A==="function"?zQ1(qQ1,A,...Q):zQ1(()=>cAQ(qQ1(),A),...Q);var iAQ=JQA({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 Q2(...A){return iAQ(ek(A))}var OQ1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,CQ1=ek,vw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return CQ1(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:D}=Q,I=Object.keys($).map((W)=>{let H=B===null||B===void 0?void 0:B[W],F=D===null||D===void 0?void 0:D[W];if(H===null)return null;let K=OQ1(H)||OQ1(F);return $[W][K]}),Y=B&&Object.entries(B).reduce((W,H)=>{let[F,K]=H;if(K===void 0)return W;return W[F]=K,W},{}),X=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((W,H)=>{let{class:F,className:K,...Z}=H;return Object.entries(Z).every((q)=>{let[L,E]=q;return Array.isArray(E)?E.includes({...D,...Y}[L]):{...D,...Y}[L]===E})?[...W,F,K]:W},[]);return CQ1(A,I,X,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as MPA}from"preact/jsx-dev-runtime";var bQ1=vw("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 OPA({variant:A,title:Q,children:B,className:w}){return MPA("div",{className:Q2(bQ1({variant:A}),w),role:"alert",children:[Q&&MPA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),MPA("div",{className:Q2(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 dAQ}from"preact/jsx-dev-runtime";var RQ1=vw("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 WV({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:D="button",...I}){return dAQ("button",{type:D,className:Q2(RQ1({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as rAQ}from"preact/jsx-dev-runtime";var PQ1=vw("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 Q$({href:A,children:Q,variant:B,size:w,external:$=!1,className:D,"aria-label":I}){let Y=$?{target:"_blank",rel:"noopener noreferrer"}:{};return rAQ("a",{href:A,className:Q2(PQ1({variant:B,size:w}),D),"aria-label":I,...Y,children:Q},void 0,!1,void 0,this)}import{jsxDEV as GQA}from"preact/jsx-dev-runtime";var kQ1=vw("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"}}),nAQ={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function Bj({variant:A,size:Q,className:B}){let w=nAQ[Q??"md"];return GQA("button",{onclick:"toggleTheme()",type:"button",className:Q2(kQ1({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:GQA("svg",{className:Q2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[GQA("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),GQA("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 CPA}from"preact/jsx-dev-runtime";var jQ1=vw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function FQA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let D=[...A].sort((I,Y)=>I.priority-Y.priority);return CPA("ul",{className:Q2(jQ1({orientation:w}),Q),children:[D.map((I)=>CPA("li",{children:CPA("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 QKw}from"preact/jsx-dev-runtime";import{jsxDEV as $Kw}from"preact/jsx-dev-runtime";import{createContext as oAQ,h as sAQ}from"preact";import{useContext as aAQ}from"preact/hooks";var bPA=oAQ(null);function wj({headCollector:A,children:Q}){return sAQ(bPA.Provider,{value:A},Q)}function _Q1(){return aAQ(bPA)}function fQ(A){let Q=_Q1();if(Q)Q.setHeadProps(A);return null}import{createContext as C8Q,h as b8Q}from"preact";import{useContext as R8Q}from"preact/hooks";dKA();var c61=X1(u61(),1),M8Q=new xg({gfm:!0,breaks:!0}),O8Q={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 skA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new xg({gfm:!0,breaks:!0}).use({renderer:{image(D,I,Y){return B(D,I,Y)??!1}}}):M8Q).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
4410
+ `)}}sA();class DQA extends Uw{directorySync;constructor(A,Q,B){super(A,{schema:ZPA,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}}}sA();class IQA extends Uw{directorySync;constructor(A,Q,B){super(A,{schema:KPA,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}}}sA();class YQA extends Uw{directorySync;context;constructor(A,Q,B){super(A,{schema:FPA,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 D={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"}),D=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(D.jobIds,B),await B.report({progress:100,message:`Import complete: ${D.imported} imported`});else await B.report({progress:50,message:`Imported ${D.imported} entities`}),await this.waitForImportJobs(D.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let X=$==="export"?10:60;await B.report({progress:X,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: ${D.imported} imported, ${I.exported} exported`})}let Y=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:Y,imported:D.imported,exported:I.exported}),{import:D,export:I,duration:Y}}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,D=Date.now(),I=async()=>{let X=(await Promise.all(A.map((H)=>B.getAsyncJobStatus(H)))).filter((H)=>H&&(H.status==="completed"||H.status==="failed")).length;if(X===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-D>w){this.logger.warn(`Timeout waiting for import jobs (${X}/${A.length} completed)`);return}let W=Math.round(X/A.length*100);return await Q.report({progress:50+Math.round(W*0.05),message:`Processing ${X}/${A.length} entities`}),await new Promise((H)=>setTimeout(H,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}sA();class XQA extends Uw{context;constructor(A,Q,B){super(A,{schema:wQA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=wQA.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}}}sA();HA();var ue2=J.object({});class WQA extends Uw{directorySync;constructor(A,Q){super(A,{schema:ue2,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}}sA();d7();HA();e8();d7();import{readFile as ce2,writeFile as pe2}from"fs/promises";var le2=NPA;class fQA extends Uw{context;fetcher;constructor(A,Q,B=zW){super(Q,{schema:le2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:D,postSlug:I,customAlt:Y}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:JQ.INIT,message:`Reading file: ${w}`});let X;try{X=await ce2(w,"utf-8")}catch(L){return this.logger.error("Failed to read file",{filePath:w,error:x0(L)}),m6.failure(L)}let W;try{W=yB(X)}catch(L){return this.logger.warn("Failed to parse markdown",{filePath:w,error:x0(L)}),m6.failure(L)}let H=W.frontmatter;if(H.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:JQ.FETCH,message:"Checking for existing image"});let F=await this.context.entityService.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}}),K;if(F[0])K=F[0].id,this.logger.debug("Reusing existing image entity",{sourceUrl:$,imageId:K}),await this.reportProgress(B,{progress:JQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:JQ.PROCESS,message:`Fetching image from ${$}`});let L;try{L=await this.fetcher($)}catch(i){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:x0(i)}),m6.failure(i)}await this.reportProgress(B,{progress:JQ.GENERATE,message:"Creating image entity"});let{base64:E}=PZ(L),R=wL(E),j=kZ(E);if(!R||!j)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),m6.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let C=`Cover image for ${D}`,m=Y??C;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:L,metadata:{title:C,alt:m,format:R,width:j.width,height:j.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:JQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:JQ.SAVE,message:"Updating file"});let Z={...H};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=xJ(Z,W.content);try{await pe2(w,q,"utf-8")}catch(L){return this.logger.error("Failed to write file",{filePath:w,error:x0(L)}),m6.failure(L)}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(X){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:x0(X)}),m6.failure(X)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}sA();d7();HA();e8();import{readFile as ie2,writeFile as de2}from"fs/promises";class HQA extends Uw{converter;constructor(A,Q,B=zW){super(Q,{schema:zPA,jobTypeName:"inline-image-convert"});this.converter=new Tu(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:JQ.INIT,message:`Reading file: ${w}`});let D;try{D=await ie2(w,"utf-8")}catch(X){let W=x0(X);return this.logger.error("Failed to read file",{filePath:w,error:W}),{success:!1,error:W}}await this.reportProgress(B,{progress:JQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(D,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:JQ.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:JQ.PROCESS,message:`Converting ${I.length} images`});let Y=await this.converter.convert(D,$);if(!Y.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:JQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:JQ.SAVE,message:"Writing updated file"});try{await de2(w,Y.content,"utf-8")}catch(X){let W=x0(X);return this.logger.error("Failed to write file",{filePath:w,error:W}),{success:!1,error:W}}return await this.reportProgress(B,{progress:JQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:Y.convertedCount}),{success:!0,convertedCount:Y.convertedCount}}catch(D){let I=x0(D);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 s21(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new YQA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new DQA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new IQA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new XQA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new WQA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new fQA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new HQA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}sA();import{unlink as re2,access as ne2}from"fs/promises";function a21(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:D}=A;$("entity:created",async(I)=>{let{entity:Y}=I.payload;try{await Q.fileOps.writeEntity(Y),B.debug("Auto-exported created entity",{id:Y.id,entityType:Y.entityType})}catch(X){B.error("Auto-export FAILED for created entity",{id:Y.id,entityType:Y.entityType,error:X instanceof Error?X.message:String(X),stack:X instanceof Error?X.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:Y,entityId:X}=I.payload;try{let W=await D.getEntity({entityType:Y,id:X});if(!W)return B.debug("Entity not found in DB, skipping export",{entityType:Y,entityId:X}),{success:!1};await Q.fileOps.writeEntity(W),B.debug("Auto-exported updated entity",{id:W.id,entityType:W.entityType})}catch(W){B.error("Auto-export FAILED for updated entity",{entityType:Y,entityId:X,error:W instanceof Error?W.message:String(W),stack:W instanceof Error?W.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:Y,entityType:X}=I.payload,W=Q.fileOps.getFilePath(Y,X);if(await ne2(W).then(()=>!0,()=>!1))await re2(W),B.debug("Auto-deleted entity file",{id:Y,entityType:X,path:W});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function t21(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:l5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}HA();sA();import{readdir as QQ1,mkdir as se2,copyFile as ae2}from"fs/promises";import{join as AQ1,resolve as qPA}from"path";import{join as oe2}from"path";async function e21(A){if(!await n6(oe2(A,".git")))return!1;try{return await JF(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function te2(A,Q){if(!await n6(A))return!0;if((await QQ1(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await e21(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function BQ1(A,Q){let B=await QQ1(A,{withFileTypes:!0});for(let w of B){let $=AQ1(A,w.name),D=AQ1(Q,w.name);if(w.isDirectory()){if(!await n6(D))await se2(D,{recursive:!0});await BQ1($,D)}else await ae2($,D)}}async function wQ1(A,Q,B){let w=qPA(process.cwd(),A);B=B?qPA(B):qPA(process.cwd(),"seed-content");let $=await te2(w,Q);if($&&await n6(B))Q.debug("Copying seed content to brain-data directory"),await BQ1(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 $Q1(A,Q,B,w,$){let D=!1,I=async()=>{if(D)return;D=!0;let Y=Q();if(B.seedContent){let X=B.syncPath??A.dataDir;await wQ1(X,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let W=await $.pull();if(W.files.length>0)w.info("Pulled changes from remote",{filesChanged:W.files.length})}w.debug("Starting initial sync");let X=await Y.sync();w.debug("Initial sync completed",{imported:X.import.imported,failed:X.import.failed,duration:X.duration}),await A.messaging.send({type:Cq.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(X){w.error("Initial sync failed",X),await A.messaging.send({type:Cq.initialSyncCompleted,payload:{success:!1,error:x0(X)},...{broadcast:!0}})}};A.messaging.subscribe(Cq.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}HA();function DQ1(A,Q,B,w){let $=new Wq(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(Y){w.error("Git auto-commit failed",{error:Y})}})},B),D=["entity:created","entity:updated","entity:deleted"],I=[];for(let Y of D){let X=A.subscribe(Y,async()=>{return $.trigger(),{success:!0}});I.push(X)}return()=>{$.dispose();for(let Y of I)Y()}}function IQ1(A,Q,B,w,$){if(w<=0)return()=>{};let D=w*60*1000,I=!1,Y=async()=>{if(I)return;I=!0;try{let{files:W,result:H}=await A.withLock(async()=>{let F=await A.pull();if(F.files.length===0)return{files:[],result:null};let K=await Q.queueSyncBatch(B,"periodic-sync");return{files:F.files,result:K}});if(W.length>0)$.info("Periodic sync: pulled changes",{filesChanged:W.length});if(H)$.debug("Periodic sync: queued imports",{importOperations:H.importOperationsCount,totalFiles:H.totalFiles})}catch(W){$.error("Periodic git sync failed",{error:W})}finally{I=!1}},X=setInterval(()=>{Y()},D);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(X)}}import{spawnSync as XQ1}from"child_process";import{cpSync as ee2,existsSync as YQ1,mkdirSync as AAQ,mkdtempSync as QAQ,rmSync as BAQ}from"fs";import{tmpdir as wAQ}from"os";import{fileURLToPath as $AQ}from"url";import{join as DAQ,resolve as IAQ}from"path";function fN(A,Q){let B=XQ1("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 YAQ(A){return A.startsWith("file://")}function XAQ(A){return $AQ(A)}function WAQ(A,Q){return XQ1("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function WQ1(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!YAQ(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=XAQ(A.gitUrl),w=IAQ(A.seedContentPath);if(!YQ1(w))throw Error(`Seed content path not found: ${w}`);if(!YQ1(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),AAQ(B,{recursive:!0}),fN(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(WAQ(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 $=QAQ(DAQ(wAQ(),"directory-sync-seed-"));try{fN($,["init",`--initial-branch=${Q}`]),fN($,["config","user.name",A.authorName??"Brain"]),fN($,["config","user.email",A.authorEmail??"brain@localhost"]),ee2(w,$,{recursive:!0}),fN($,["add","."]),fN($,["commit","-m","seed content remote"]),fN($,["remote","add","origin",A.gitUrl]),fN($,["push","-u","origin",Q])}finally{BAQ($,{recursive:!0,force:!0})}}function fQ1(A,Q,B,w,$){let{subscribe:D}=A.messaging;D("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Export failed"}}}),D("entity:import:request",async(I)=>{try{let Y=Q(),X=I.payload.paths,W=await Y.importEntities(X);if(X&&X.length>0)await Y.removeOrphanedEntities();return{success:!0,data:W}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Import failed"}}}),D("sync:status:request",async()=>{try{let Y=await Q().getStatus();return{success:!0,data:{syncPath:Y.syncPath,isInitialized:Y.exists,watchEnabled:Y.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),D("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(Y){return{success:!1,error:Y instanceof Error?Y.message:"Configuration failed"}}}),D("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")}sA();HA();sA();HA();function HQ1(A,Q){return uQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",J.object({entityType:J.string().describe("Entity type (e.g. post, note, link)"),id:J.string().describe("Entity ID"),sha:J.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:J.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 D=await Q.show(B.sha,w);return K8({sha:B.sha,entityType:B.entityType,id:B.id,content:D},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return K8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return K8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return i5($ instanceof Error?$.message:"History lookup failed")}})}function UQ1(A,Q,B,w){let $=[uQ(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.",J.object({}),async(D,I)=>{try{let Y=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,X={interfaceType:I.interfaceType,channelId:I.channelId},W=w!==void 0,H=()=>A.queueSyncBatch(Q,Y,X),F=w?await w.withLock(async()=>{return await w.pull(),H()}):await H();if(!F)return K8({gitPulled:W},"No files to sync");return K8({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:W},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${W?" (pulled from git)":""}`)}catch(Y){return i5(Y instanceof Error?Y.message:"Sync failed")}},{cli:{name:"sync"}}),uQ(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.",J.object({}),async()=>{try{let D=await A.getStatus(),I={syncPath:D.syncPath,lastSync:D.lastSync?.toISOString(),watching:D.watching};if(w){let Y=await w.getStatus();I.git={isRepo:Y.isRepo,branch:Y.branch,hasChanges:Y.hasChanges,ahead:Y.ahead,behind:Y.behind,remote:Y.remote}}return K8(I)}catch(D){return i5(D instanceof Error?D.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(HQ1(B,w));return $}var JQ1={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.109",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:{"@types/bun":"latest","@types/node":"^20.0.0",typescript:"^5.3.3"},peerDependencies:{}};class LPA extends QB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",JQ1,A,nu)}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:ou,basePrompt:"",formatter:new $QA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new gu({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(a21(A,$,this.logger,this.config.entityTypes),this.config.autoSync)t21(A,$,this.config.syncPath??A.dataDir);let D=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!D)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(D&&this.config.git){await WQ1({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 GPA({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}),this.gitCleanups.push(DQ1(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(IQ1(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)$Q1(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);fQ1(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return UQ1(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 gu({...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){s21(A,this.requireDirectorySync(),this.logger)}}function XV(A={}){return new LPA(A)}sA();HA();var GQ1={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.109",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 UAQ=J.object({apiKey:J.string().min(1).optional(),from:J.string().min(1).optional()});class FQ1 extends QB{fetchImpl;constructor(A={},Q={}){super("email-resend",GQ1,A,UAQ);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(ve,async(B)=>{let w=a30.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 UQA(A={}){return new FQ1(A)}sA();import{render as RW1}from"preact-render-to-string";import{h as iV}from"preact";function KQ1(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=KQ1(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function ek(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=KQ1(A))&&(w&&(w+=" "),w+=Q);return w}var JAQ=(A)=>{let Q=FAQ(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let Y=I.split("-");if(Y[0]===""&&Y.length!==1)Y.shift();return LQ1(Y,Q)||GAQ(I)},getConflictingClassGroupIds:(I,Y)=>{let X=B[I]||[];if(Y&&w[I])return[...X,...w[I]];return X}}},LQ1=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?LQ1(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let D=A.join("-");return Q.validators.find(({validator:I})=>I(D))?.classGroupId},ZQ1=/^\[(.+)\]$/,GAQ=(A)=>{if(ZQ1.test(A)){let Q=ZQ1.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},FAQ=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return ZAQ(Object.entries(A.classGroups),B).forEach(([D,I])=>{VPA(I,w,D,Q)}),w},VPA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let D=$===""?Q:NQ1(Q,$);D.classGroupId=B;return}if(typeof $==="function"){if(KAQ($)){VPA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([D,I])=>{VPA(I,NQ1(Q,D),B,w)})})},NQ1=(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},KAQ=(A)=>A.isThemeGetter,ZAQ=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((D)=>{if(typeof D==="string")return Q+D;if(typeof D==="object")return Object.fromEntries(Object.entries(D).map(([I,Y])=>[Q+I,Y]));return D});return[B,$]})},NAQ=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(D,I)=>{if(B.set(D,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(D){let I=B.get(D);if(I!==void 0)return I;if((I=w.get(D))!==void 0)return $(D,I),I},set(D,I){if(B.has(D))B.set(D,I);else $(D,I)}}};var zAQ=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],D=Q.length,I=(Y)=>{let X=[],W=0,H=0,F;for(let E=0;E<Y.length;E++){let R=Y[E];if(W===0){if(R===$&&(w||Y.slice(E,E+D)===Q)){X.push(Y.slice(H,E)),H=E+D;continue}if(R==="/"){F=E;continue}}if(R==="[")W++;else if(R==="]")W--}let K=X.length===0?Y:Y.substring(H),Z=K.startsWith("!"),q=Z?K.substring(1):K,L=F&&F>H?F-H:void 0;return{modifiers:X,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:L}};if(B)return(Y)=>B({className:Y,parseClassName:I});return I},qAQ=(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},LAQ=(A)=>({cache:NAQ(A.cacheSize),parseClassName:zAQ(A),...JAQ(A)}),EAQ=/\s+/,VAQ=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,D=[],I=A.trim().split(EAQ),Y="";for(let X=I.length-1;X>=0;X-=1){let W=I[X],{modifiers:H,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(W),q=Boolean(Z),L=w(q?K.substring(0,Z):K);if(!L){if(!q){Y=W+(Y.length>0?" "+Y:Y);continue}if(L=w(K),!L){Y=W+(Y.length>0?" "+Y:Y);continue}q=!1}let E=qAQ(H).join(":"),R=F?E+"!":E,j=R+L;if(D.includes(j))continue;D.push(j);let C=$(L,q);for(let m=0;m<C.length;++m){let i=C[m];D.push(R+i)}Y=W+(Y.length>0?" "+Y:Y)}return Y};function MAQ(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=EQ1(Q))w&&(w+=" "),w+=B}return w}var EQ1=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=EQ1(A[w]))B&&(B+=" "),B+=Q}return B};function zQ1(A,...Q){let B,w,$,D=I;function I(X){let W=Q.reduce((H,F)=>F(H),A());return B=LAQ(W),w=B.cache.get,$=B.cache.set,D=Y,Y(X)}function Y(X){let W=w(X);if(W)return W;let H=VAQ(X,B);return $(X,H),H}return function(){return D(MAQ.apply(null,arguments))}}var M8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},VQ1=/^\[(?:([a-z-]+):)?(.+)\]$/i,OAQ=/^\d+\/\d+$/,CAQ=new Set(["px","full","screen"]),bAQ=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,RAQ=/\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$/,PAQ=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,kAQ=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,jAQ=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,GF=(A)=>Aj(A)||CAQ.has(A)||OAQ.test(A),HN=(A)=>Qj(A,"length",hAQ),Aj=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),EPA=(A)=>Qj(A,"number",Aj),su=(A)=>Boolean(A)&&Number.isInteger(Number(A)),_AQ=(A)=>A.endsWith("%")&&Aj(A.slice(0,-1)),SQ=(A)=>VQ1.test(A),UN=(A)=>bAQ.test(A),yAQ=new Set(["length","size","percentage"]),xAQ=(A)=>Qj(A,yAQ,MQ1),vAQ=(A)=>Qj(A,"position",MQ1),TAQ=new Set(["image","url"]),gAQ=(A)=>Qj(A,TAQ,uAQ),SAQ=(A)=>Qj(A,"",mAQ),au=()=>!0,Qj=(A,Q,B)=>{let w=VQ1.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},hAQ=(A)=>RAQ.test(A)&&!PAQ.test(A),MQ1=()=>!1,mAQ=(A)=>kAQ.test(A),uAQ=(A)=>jAQ.test(A);var qQ1=()=>{let A=M8("colors"),Q=M8("spacing"),B=M8("blur"),w=M8("brightness"),$=M8("borderColor"),D=M8("borderRadius"),I=M8("borderSpacing"),Y=M8("borderWidth"),X=M8("contrast"),W=M8("grayscale"),H=M8("hueRotate"),F=M8("invert"),K=M8("gap"),Z=M8("gradientColorStops"),q=M8("gradientColorStopPositions"),L=M8("inset"),E=M8("margin"),R=M8("opacity"),j=M8("padding"),C=M8("saturate"),m=M8("scale"),i=M8("sepia"),g=M8("skew"),x=M8("space"),T=M8("translate"),S=()=>["auto","contain","none"],e=()=>["auto","hidden","clip","visible","scroll"],h=()=>["auto",SQ,Q],XA=()=>[SQ,Q],BA=()=>["",GF,HN],_=()=>["auto",Aj,SQ],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["solid","dashed","dotted","double","none"],r=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],p=()=>["start","end","center","between","around","evenly","stretch"],AA=()=>["","0",SQ],o=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[Aj,SQ];return{cacheSize:500,separator:":",theme:{colors:[au],spacing:[GF,HN],blur:["none","",UN,SQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",UN,SQ],borderSpacing:XA(),borderWidth:BA(),contrast:UA(),grayscale:AA(),hueRotate:UA(),invert:AA(),gap:XA(),gradientColorStops:[A],gradientColorStopPositions:[_AQ,HN],inset:h(),margin:h(),opacity:UA(),padding:XA(),saturate:UA(),scale:UA(),sepia:AA(),skew:UA(),space:XA(),translate:XA()},classGroups:{aspect:[{aspect:["auto","square","video",SQ]}],container:["container"],columns:[{columns:[UN]}],"break-after":[{"break-after":o()}],"break-before":[{"break-before":o()}],"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:[...O(),SQ]}],overflow:[{overflow:e()}],"overflow-x":[{"overflow-x":e()}],"overflow-y":[{"overflow-y":e()}],overscroll:[{overscroll:S()}],"overscroll-x":[{"overscroll-x":S()}],"overscroll-y":[{"overscroll-y":S()}],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",su,SQ]}],basis:[{basis:h()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",SQ]}],grow:[{grow:AA()}],shrink:[{shrink:AA()}],order:[{order:["first","last","none",su,SQ]}],"grid-cols":[{"grid-cols":[au]}],"col-start-end":[{col:["auto",{span:["full",su,SQ]},SQ]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[au]}],"row-start-end":[{row:["auto",{span:[su,SQ]},SQ]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",SQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",SQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...p()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...p(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...p(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[E]}],mx:[{mx:[E]}],my:[{my:[E]}],ms:[{ms:[E]}],me:[{me:[E]}],mt:[{mt:[E]}],mr:[{mr:[E]}],mb:[{mb:[E]}],ml:[{ml:[E]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",SQ,Q]}],"min-w":[{"min-w":[SQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[SQ,Q,"none","full","min","max","fit","prose",{screen:[UN]},UN]}],h:[{h:[SQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[SQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[SQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[SQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",UN,HN]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",EPA]}],"font-family":[{font:[au]}],"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",SQ]}],"line-clamp":[{"line-clamp":["none",Aj,EPA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",GF,SQ]}],"list-image":[{"list-image":["none",SQ]}],"list-style-type":[{list:["none","disc","decimal",SQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",GF,HN]}],"underline-offset":[{"underline-offset":["auto",GF,SQ]}],"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:XA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",SQ]}],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",SQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),vAQ]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",xAQ]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},gAQ]}],"bg-color":[{bg:[A]}],"gradient-from-pos":[{from:[q]}],"gradient-via-pos":[{via:[q]}],"gradient-to-pos":[{to:[q]}],"gradient-from":[{from:[Z]}],"gradient-via":[{via:[Z]}],"gradient-to":[{to:[Z]}],rounded:[{rounded:[D]}],"rounded-s":[{"rounded-s":[D]}],"rounded-e":[{"rounded-e":[D]}],"rounded-t":[{"rounded-t":[D]}],"rounded-r":[{"rounded-r":[D]}],"rounded-b":[{"rounded-b":[D]}],"rounded-l":[{"rounded-l":[D]}],"rounded-ss":[{"rounded-ss":[D]}],"rounded-se":[{"rounded-se":[D]}],"rounded-ee":[{"rounded-ee":[D]}],"rounded-es":[{"rounded-es":[D]}],"rounded-tl":[{"rounded-tl":[D]}],"rounded-tr":[{"rounded-tr":[D]}],"rounded-br":[{"rounded-br":[D]}],"rounded-bl":[{"rounded-bl":[D]}],"border-w":[{border:[Y]}],"border-w-x":[{"border-x":[Y]}],"border-w-y":[{"border-y":[Y]}],"border-w-s":[{"border-s":[Y]}],"border-w-e":[{"border-e":[Y]}],"border-w-t":[{"border-t":[Y]}],"border-w-r":[{"border-r":[Y]}],"border-w-b":[{"border-b":[Y]}],"border-w-l":[{"border-l":[Y]}],"border-opacity":[{"border-opacity":[R]}],"border-style":[{border:[...k(),"hidden"]}],"divide-x":[{"divide-x":[Y]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[Y]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[R]}],"divide-style":[{divide:k()}],"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:["",...k()]}],"outline-offset":[{"outline-offset":[GF,SQ]}],"outline-w":[{outline:[GF,HN]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:BA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[GF,HN]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",UN,SAQ]}],"shadow-color":[{shadow:[au]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...r(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":r()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[X]}],"drop-shadow":[{"drop-shadow":["","none",UN,SQ]}],grayscale:[{grayscale:[W]}],"hue-rotate":[{"hue-rotate":[H]}],invert:[{invert:[F]}],saturate:[{saturate:[C]}],sepia:[{sepia:[i]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[X]}],"backdrop-grayscale":[{"backdrop-grayscale":[W]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[H]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[C]}],"backdrop-sepia":[{"backdrop-sepia":[i]}],"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",SQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",SQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",SQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[m]}],"scale-x":[{"scale-x":[m]}],"scale-y":[{"scale-y":[m]}],rotate:[{rotate:[su,SQ]}],"translate-x":[{"translate-x":[T]}],"translate-y":[{"translate-y":[T]}],"skew-x":[{"skew-x":[g]}],"skew-y":[{"skew-y":[g]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",SQ]}],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",SQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":XA()}],"scroll-mx":[{"scroll-mx":XA()}],"scroll-my":[{"scroll-my":XA()}],"scroll-ms":[{"scroll-ms":XA()}],"scroll-me":[{"scroll-me":XA()}],"scroll-mt":[{"scroll-mt":XA()}],"scroll-mr":[{"scroll-mr":XA()}],"scroll-mb":[{"scroll-mb":XA()}],"scroll-ml":[{"scroll-ml":XA()}],"scroll-p":[{"scroll-p":XA()}],"scroll-px":[{"scroll-px":XA()}],"scroll-py":[{"scroll-py":XA()}],"scroll-ps":[{"scroll-ps":XA()}],"scroll-pe":[{"scroll-pe":XA()}],"scroll-pt":[{"scroll-pt":XA()}],"scroll-pr":[{"scroll-pr":XA()}],"scroll-pb":[{"scroll-pb":XA()}],"scroll-pl":[{"scroll-pl":XA()}],"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",SQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[GF,HN,EPA]}],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"]}}},cAQ=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:D={},override:I={}})=>{tu(A,"cacheSize",Q),tu(A,"prefix",B),tu(A,"separator",w),tu(A,"experimentalParseClassName",$);for(let Y in I)pAQ(A[Y],I[Y]);for(let Y in D)lAQ(A[Y],D[Y]);return A},tu=(A,Q,B)=>{if(B!==void 0)A[Q]=B},pAQ=(A,Q)=>{if(Q)for(let B in Q)tu(A,B,Q[B])},lAQ=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},JQA=(A,...Q)=>typeof A==="function"?zQ1(qQ1,A,...Q):zQ1(()=>cAQ(qQ1(),A),...Q);var iAQ=JQA({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 Q2(...A){return iAQ(ek(A))}var OQ1=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,CQ1=ek,vw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return CQ1(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:D}=Q,I=Object.keys($).map((W)=>{let H=B===null||B===void 0?void 0:B[W],F=D===null||D===void 0?void 0:D[W];if(H===null)return null;let K=OQ1(H)||OQ1(F);return $[W][K]}),Y=B&&Object.entries(B).reduce((W,H)=>{let[F,K]=H;if(K===void 0)return W;return W[F]=K,W},{}),X=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((W,H)=>{let{class:F,className:K,...Z}=H;return Object.entries(Z).every((q)=>{let[L,E]=q;return Array.isArray(E)?E.includes({...D,...Y}[L]):{...D,...Y}[L]===E})?[...W,F,K]:W},[]);return CQ1(A,I,X,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as MPA}from"preact/jsx-dev-runtime";var bQ1=vw("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 OPA({variant:A,title:Q,children:B,className:w}){return MPA("div",{className:Q2(bQ1({variant:A}),w),role:"alert",children:[Q&&MPA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),MPA("div",{className:Q2(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 dAQ}from"preact/jsx-dev-runtime";var RQ1=vw("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 WV({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:D="button",...I}){return dAQ("button",{type:D,className:Q2(RQ1({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as rAQ}from"preact/jsx-dev-runtime";var PQ1=vw("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 Q$({href:A,children:Q,variant:B,size:w,external:$=!1,className:D,"aria-label":I}){let Y=$?{target:"_blank",rel:"noopener noreferrer"}:{};return rAQ("a",{href:A,className:Q2(PQ1({variant:B,size:w}),D),"aria-label":I,...Y,children:Q},void 0,!1,void 0,this)}import{jsxDEV as GQA}from"preact/jsx-dev-runtime";var kQ1=vw("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"}}),nAQ={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function Bj({variant:A,size:Q,className:B}){let w=nAQ[Q??"md"];return GQA("button",{onclick:"toggleTheme()",type:"button",className:Q2(kQ1({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:GQA("svg",{className:Q2(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[GQA("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),GQA("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 CPA}from"preact/jsx-dev-runtime";var jQ1=vw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function FQA({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let D=[...A].sort((I,Y)=>I.priority-Y.priority);return CPA("ul",{className:Q2(jQ1({orientation:w}),Q),children:[D.map((I)=>CPA("li",{children:CPA("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 QKw}from"preact/jsx-dev-runtime";import{jsxDEV as $Kw}from"preact/jsx-dev-runtime";import{createContext as oAQ,h as sAQ}from"preact";import{useContext as aAQ}from"preact/hooks";var bPA=oAQ(null);function wj({headCollector:A,children:Q}){return sAQ(bPA.Provider,{value:A},Q)}function _Q1(){return aAQ(bPA)}function fQ(A){let Q=_Q1();if(Q)Q.setHeadProps(A);return null}import{createContext as C8Q,h as b8Q}from"preact";import{useContext as R8Q}from"preact/hooks";dKA();var c61=X1(u61(),1),M8Q=new xg({gfm:!0,breaks:!0}),O8Q={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 skA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new xg({gfm:!0,breaks:!0}).use({renderer:{image(D,I,Y){return B(D,I,Y)??!1}}}):M8Q).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
4411
4411
  <cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),c61.default($,O8Q)}var p61=C8Q(null);function qj({imageRenderer:A,children:Q}){return b8Q(p61.Provider,{value:A??null},Q)}function l61(){return R8Q(p61)}function VF(){let A=l61();return(Q)=>skA(Q,A?{imageRenderer:A}:void 0)}var P8Q=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,k8Q={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"},j8Q=/&(?:amp|lt|gt|quot|#39);/g;function _8Q(A){return A.replace(j8Q,(Q)=>k8Q[Q]??Q)}function akA(A){return A.replace(P8Q,(Q,B)=>{return`<div class="mermaid">${_8Q(B)}</div>`})}var i61=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function d61(A){let Q={};for(let w of A.matchAll(i61)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let Y=I[1],X=I[2];if(Y&&X!==void 0)Q[Y]=X}let D=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(D)for(let I of D.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let Y=I[1];if(Y)Q[Y]="true"}}let B=A.replace(i61,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
4412
4412
 
4413
4413
  `).trim();return{attributes:Q,markdown:B}}var y8Q=/<!--\s*\.break\s*-->/;function r61(A){let Q=A.split(y8Q);return Q.length>1?Q:null}import{jsxDEV as EU}from"preact/jsx-dev-runtime";var tkA=({markdown:A,deck:Q})=>{let B=VF(),$=A.split(/^---$/gm).map((H)=>H.trim()).map((H)=>{let{attributes:F,markdown:K}=d61(H),Z=r61(K),q;if(Z)q=`<div class="slide-columns">${Z.map((E)=>`<div class="slide-column">${akA(B(E.trim()))}</div>`).join("")}</div>`;else q=akA(B(K));return{attributes:F,htmlContent:q}}),D=$.some((H)=>H.htmlContent.includes('class="mermaid"')),I=Q?.frontmatter?.title??Q?.metadata?.title,Y=Q?.frontmatter?.description??Q?.metadata?.description,X=Q?.ogImageUrl??Q?.coverImageUrl,W=$.map(({attributes:H,htmlContent:F},K)=>EU("section",{...H,dangerouslySetInnerHTML:{__html:F}},K,!1,void 0,this));return EU("section",{className:"presentation-section",children:[I&&EU(fQ,{title:I,...Y?{description:Y}:{},...X?{ogImage:X}:{},ogType:"article"},void 0,!1,void 0,this),EU("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),EU("div",{className:"reveal",children:EU("div",{className:"slides",children:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),EU("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),D&&EU("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),EU("script",{dangerouslySetInnerHTML:{__html:`
@@ -5394,13 +5394,13 @@ ${A.map((D)=>({url:`${Q}${D.path}`,lastmod:B,changefreq:D.path==="/"?"daily":"we
5394
5394
  `+$:B,I=xU(this.outputDir,"styles","main.css");await this.cssProcessor.process(D,I,this.workingDir,this.outputDir,this.logger);let Y=await E9.readFile(I,"utf-8"),X=w.length>0?w:Q;if(X.length>0){let W=X.join(`
5395
5395
  `)+`
5396
5396
 
5397
- `+Y;await E9.writeFile(I,W,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=xU(process.cwd(),"public");try{await E9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await E9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=xU(A,B.name),$=xU(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await E9.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,D=xU(this.outputDir,$);await E9.mkdir(gJQ(D),{recursive:!0}),await E9.writeFile(D,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await E9.mkdir(Q,{recursive:!0});let B=await E9.readdir(A,{withFileTypes:!0});for(let w of B){let $=xU(A,w.name),D=xU(Q,w.name);if(w.isDirectory())await this.copyDirectory($,D);else await E9.copyFile($,D)}}}function jyA(A){return new PW1(A)}u6();HA();HA();u6();var kW1=J.object({environment:J.enum(["preview","production"]),outputDir:J.string(),workingDir:J.string().optional(),sharedImagesDir:J.string().default("./dist/images"),enableContentGeneration:J.boolean().default(!1),cleanBeforeBuild:J.boolean().default(!0),siteConfig:iD,layouts:J.record(J.any()),themeCSS:J.string().optional()}),$bw=J.object({success:J.boolean(),outputDir:J.string(),filesGenerated:J.number(),routesBuilt:J.number(),errors:J.array(J.string()).optional(),warnings:J.array(J.string()).optional()});function jW1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function _W1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),D=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:D},copyright:A.copyright??"Powered by Rizom"}}u6();d7();u6();HA();var SJQ=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),hJQ=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function iwA(A,Q){let B=Q.urlGenerator??p9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((m)=>iwA(m,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),D=await Promise.all($.map(([,m])=>iwA(m,{...Q,urlGenerator:B})));for(let m=0;m<$.length;m++){let i=$[m];if(i)w[i[0]]=D[m]}let I=SJQ.safeParse(A);if(!I.success)return w;let Y=I.data,X=Y.entityType,W=Y.metadata.slug,H=Q.pipelineContext.entityDisplay?.[X],F=H?H.label:X.charAt(0).toUpperCase()+X.slice(1),K=H?H.pluralName??H.label.toLowerCase()+"s":cD(X),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=cT(Y),E=await mJQ(L,Q),R=Ns(Y)??L,j=await uJQ(R,Q);return{...w,...Y,url:B.generateUrl(X,W),typeLabel:F,listUrl:Z,listLabel:q,...E,...j&&{ogImageUrl:j}}}async function mJQ(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 xW1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function uJQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return yW1(B.src,Q.siteUrl);let w=await xW1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return yW1(w.url,Q.siteUrl)}function yW1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function xW1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=hJQ.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 vW1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let D=await A.listEntities({entityType:$});for(let I of D){let Y=cT(I);if(Y)B.add(Y);let X=Ns(I);if(X)B.add(X)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:x0(w)})}return[...B]}async function TW1(A,Q,B,w,$){if(!A.template)return A.content??null;let D=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},Y=await $.pipelineContext.services.resolveTemplateContent(D,I);if(!Y)return null;return iwA(Y,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:p9.getInstance()})}function gW1(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 TW1(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 _W1(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 cJQ}from"path";async function SW1(A){let Q=A.parsedOptions.workingDir??cJQ(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 hW1(A){await new pwA({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 mW1(A){let Q=new cwA(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await vW1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function uW1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function cW1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function pW1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function lW1(A){let Q=kW1.parse(A.buildOptions),B=e$.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 hW1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await SW1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),D=jW1(A.pipelineContext.routeRegistry);w.push(...D.warnings);let{routes:I}=D;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let Y=await mW1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),X=gW1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Y,siteMetadata:Q.siteConfig});return await uW1({staticSiteBuilder:$,buildContext:X,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),cW1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let D=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:D,originalError:$}),pW1({outputDir:Q.outputDir,errorMessage:D.message})}}class gI{static instance=null;static defaultStaticSiteBuilderFactory=jyA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){gI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return gI.instance??=new gI(A,gI.defaultStaticSiteBuilderFactory,Q,B,w,$),gI.instance}static resetInstance(){gI.instance=null}static createFresh(A,Q,B,w,$,D=void 0){return new gI(A,$??gI.defaultStaticSiteBuilderFactory,Q,B,w,D)}constructor(A,Q,B,w,$,D){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:D},this.staticSiteBuilderFactory=Q,p9.getInstance().configure(D)}async build(A,Q){return lW1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}HA();class _yA{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 Wq(()=>{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})}}}u6();function pJQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function dwA(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?pJQ(w.sections,Q):[]})}function iW1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=fr.parse(w.payload),{routes:D,pluginId:I}=$;return dwA(D,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 $=Hr.parse(w.payload),{paths:D,pluginId:I}=$;if(D)for(let Y of D)Q.unregister(Y);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 $=Ur.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 $=Jr.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 dW1}from"fs";import{join as rW1}from"path";async function lJQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),D=PyA(w,A.environment);await dW1.writeFile(rW1(A.outputDir,"robots.txt"),D,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=kyA($,w);await dW1.writeFile(rW1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function nW1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let D=$.payload;return w.info(`Received site:build:completed event for ${D.environment} environment - generating SEO files`),await lJQ(D,B,w),{success:!0}}catch(D){return w.error("Failed to generate SEO files",D),{success:!1}}})}sA();HA();u6();var oW1=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:iD.optional()});u6();u6();async function Lp(A,Q){try{let B=await A({type:yx,payload:void 0});if("success"in B&&B.success&&B.data){let w=iD.safeParse(B.data);if(w.success)return iD.parse({...Q,...w.data})}}catch{}return Q}class yyA extends Uw{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:oW1,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 D=B.createSub({scale:{start:10,end:90}}),I=await Lp(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Y=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}},D.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${Y.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:Y.routesBuilt,success:Y.success}),Y.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let X=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:Y.routesBuilt,siteConfig:{...I,url:X},generateEntityUrl:(W,H)=>p9.getInstance().generateUrl(W,H)},broadcast:!0})}return{success:Y.success,routesBuilt:Y.routesBuilt,outputDir:A.outputDir,environment:w,...Y.errors&&{errors:Y.errors},...Y.warnings&&{warnings:Y.warnings}}}catch(D){throw this.logger.error("Site build job failed",D),D}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}HA();u6();var iJQ=J.object({slot:J.enum(Uq).optional().default("primary"),limit:J.number().optional()});class xyA{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=iJQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),D=w.limit?$.slice(0,w.limit):$,I=D.map((X)=>({label:X.label,href:X.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:D.length,items:I});let Y={navigation:I};return Q.parse(Y)}}u6();sA();HA();var dJQ=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function sW1(A,Q){return[uQ(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'.",dJQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}HA();u6();var aW1=J.object({previewOutputDir:J.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:J.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:J.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:J.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:iD.default({title:"Brain",description:"A knowledge management system"}),themeCSS:J.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:J.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:J.any().optional().describe("Template definitions to register"),routes:J.array(Jq).optional().describe("Routes to register"),layouts:J.record(J.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:J.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:J.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:J.record(J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:J.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:J.boolean().optional().describe("Enable pagination for list pages"),pageSize:J.number().optional().describe("Items per page (default: 10)"),navigation:J.object({show:J.boolean().optional().describe("Show in navigation"),slot:J.enum(Uq).optional().describe("Navigation slot (primary or secondary)"),priority:J.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:J.record(J.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 tW1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.108",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 vyA extends QB{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",tW1,{...A,layouts:Q},aW1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new lwA(A.logger),this._slotRegistry=new VwA,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:D,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:D,...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 xyA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=u7.getInstance(A.entityService,A.logger),iW1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)dwA(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=gI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new yyA(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 _yA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(xx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),nW1({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 sW1(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 Lp(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 Lp(A.messaging.send,this.config.siteInfo);return`## Your Site
5397
+ `+Y;await E9.writeFile(I,W,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=xU(process.cwd(),"public");try{await E9.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await E9.readdir(A,{withFileTypes:!0});for(let B of Q){let w=xU(A,B.name),$=xU(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await E9.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,D=xU(this.outputDir,$);await E9.mkdir(gJQ(D),{recursive:!0}),await E9.writeFile(D,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await E9.mkdir(Q,{recursive:!0});let B=await E9.readdir(A,{withFileTypes:!0});for(let w of B){let $=xU(A,w.name),D=xU(Q,w.name);if(w.isDirectory())await this.copyDirectory($,D);else await E9.copyFile($,D)}}}function jyA(A){return new PW1(A)}u6();HA();HA();u6();var kW1=J.object({environment:J.enum(["preview","production"]),outputDir:J.string(),workingDir:J.string().optional(),sharedImagesDir:J.string().default("./dist/images"),enableContentGeneration:J.boolean().default(!1),cleanBeforeBuild:J.boolean().default(!0),siteConfig:iD,layouts:J.record(J.any()),themeCSS:J.string().optional()}),$bw=J.object({success:J.boolean(),outputDir:J.string(),filesGenerated:J.number(),routesBuilt:J.number(),errors:J.array(J.string()).optional(),warnings:J.array(J.string()).optional()});function jW1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function _W1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),D=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:D},copyright:A.copyright??"Powered by Rizom"}}u6();d7();u6();HA();var SJQ=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),hJQ=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function iwA(A,Q){let B=Q.urlGenerator??p9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((m)=>iwA(m,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),D=await Promise.all($.map(([,m])=>iwA(m,{...Q,urlGenerator:B})));for(let m=0;m<$.length;m++){let i=$[m];if(i)w[i[0]]=D[m]}let I=SJQ.safeParse(A);if(!I.success)return w;let Y=I.data,X=Y.entityType,W=Y.metadata.slug,H=Q.pipelineContext.entityDisplay?.[X],F=H?H.label:X.charAt(0).toUpperCase()+X.slice(1),K=H?H.pluralName??H.label.toLowerCase()+"s":cD(X),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),L=cT(Y),E=await mJQ(L,Q),R=Ns(Y)??L,j=await uJQ(R,Q);return{...w,...Y,url:B.generateUrl(X,W),typeLabel:F,listUrl:Z,listLabel:q,...E,...j&&{ogImageUrl:j}}}async function mJQ(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 xW1(A,Q.pipelineContext.services.entityService);if(!w)return{};return{coverImageUrl:w.url,...w.width&&{coverImageWidth:w.width},...w.height&&{coverImageHeight:w.height}}}async function uJQ(A,Q){if(!A)return;let B=Q.imageBuildService?.get(A);if(B)return yW1(B.src,Q.siteUrl);let w=await xW1(A,Q.pipelineContext.services.entityService);if(!w)return;if(w.url.startsWith("data:"))return;return yW1(w.url,Q.siteUrl)}function yW1(A,Q){if(/^https?:\/\//i.test(A)||A.startsWith("data:"))return A;if(!Q)return A;return`${Q.replace(/\/$/,"")}/${A.replace(/^\//,"")}`}async function xW1(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=hJQ.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 vW1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let D=await A.listEntities({entityType:$});for(let I of D){let Y=cT(I);if(Y)B.add(Y);let X=Ns(I);if(X)B.add(X)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:x0(w)})}return[...B]}async function TW1(A,Q,B,w,$){if(!A.template)return A.content??null;let D=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},Y=await $.pipelineContext.services.resolveTemplateContent(D,I);if(!Y)return null;return iwA(Y,{pipelineContext:$.pipelineContext,imageBuildService:$.imageBuildService,siteUrl:$.siteUrl,urlGenerator:p9.getInstance()})}function gW1(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 TW1(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 _W1(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 cJQ}from"path";async function SW1(A){let Q=A.parsedOptions.workingDir??cJQ(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 hW1(A){await new pwA({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 mW1(A){let Q=new cwA(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await vW1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function uW1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function cW1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function pW1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function lW1(A){let Q=kW1.parse(A.buildOptions),B=e$.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 hW1({pipelineContext:A.pipelineContext,publishedOnly:Q.environment==="production"});let $=await SW1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),D=jW1(A.pipelineContext.routeRegistry);w.push(...D.warnings);let{routes:I}=D;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let Y=await mW1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),X=gW1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:Y,siteMetadata:Q.siteConfig});return await uW1({staticSiteBuilder:$,buildContext:X,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),cW1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let D=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:D,originalError:$}),pW1({outputDir:Q.outputDir,errorMessage:D.message})}}class gI{static instance=null;static defaultStaticSiteBuilderFactory=jyA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){gI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return gI.instance??=new gI(A,gI.defaultStaticSiteBuilderFactory,Q,B,w,$),gI.instance}static resetInstance(){gI.instance=null}static createFresh(A,Q,B,w,$,D=void 0){return new gI(A,$??gI.defaultStaticSiteBuilderFactory,Q,B,w,D)}constructor(A,Q,B,w,$,D){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:D},this.staticSiteBuilderFactory=Q,p9.getInstance().configure(D)}async build(A,Q){return lW1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}HA();class _yA{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 Wq(()=>{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})}}}u6();function pJQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function dwA(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?pJQ(w.sections,Q):[]})}function iW1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=fr.parse(w.payload),{routes:D,pluginId:I}=$;return dwA(D,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 $=Hr.parse(w.payload),{paths:D,pluginId:I}=$;if(D)for(let Y of D)Q.unregister(Y);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 $=Ur.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 $=Jr.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 dW1}from"fs";import{join as rW1}from"path";async function lJQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),D=PyA(w,A.environment);await dW1.writeFile(rW1(A.outputDir,"robots.txt"),D,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=kyA($,w);await dW1.writeFile(rW1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function nW1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let D=$.payload;return w.info(`Received site:build:completed event for ${D.environment} environment - generating SEO files`),await lJQ(D,B,w),{success:!0}}catch(D){return w.error("Failed to generate SEO files",D),{success:!1}}})}sA();HA();u6();var oW1=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:iD.optional()});u6();u6();async function Lp(A,Q){try{let B=await A({type:yx,payload:void 0});if("success"in B&&B.success&&B.data){let w=iD.safeParse(B.data);if(w.success)return iD.parse({...Q,...w.data})}}catch{}return Q}class yyA extends Uw{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:oW1,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 D=B.createSub({scale:{start:10,end:90}}),I=await Lp(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),Y=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}},D.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${Y.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:Y.routesBuilt,success:Y.success}),Y.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let X=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:Y.routesBuilt,siteConfig:{...I,url:X},generateEntityUrl:(W,H)=>p9.getInstance().generateUrl(W,H)},broadcast:!0})}return{success:Y.success,routesBuilt:Y.routesBuilt,outputDir:A.outputDir,environment:w,...Y.errors&&{errors:Y.errors},...Y.warnings&&{warnings:Y.warnings}}}catch(D){throw this.logger.error("Site build job failed",D),D}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}HA();u6();var iJQ=J.object({slot:J.enum(Uq).optional().default("primary"),limit:J.number().optional()});class xyA{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=iJQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),D=w.limit?$.slice(0,w.limit):$,I=D.map((X)=>({label:X.label,href:X.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:D.length,items:I});let Y={navigation:I};return Q.parse(Y)}}u6();sA();HA();var dJQ=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function sW1(A,Q){return[uQ(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'.",dJQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}HA();u6();var aW1=J.object({previewOutputDir:J.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:J.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:J.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:J.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:iD.default({title:"Brain",description:"A knowledge management system"}),themeCSS:J.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:J.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:J.any().optional().describe("Template definitions to register"),routes:J.array(Jq).optional().describe("Routes to register"),layouts:J.record(J.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:J.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:J.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:J.record(J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:J.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:J.boolean().optional().describe("Enable pagination for list pages"),pageSize:J.number().optional().describe("Items per page (default: 10)"),navigation:J.object({show:J.boolean().optional().describe("Show in navigation"),slot:J.enum(Uq).optional().describe("Navigation slot (primary or secondary)"),priority:J.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:J.record(J.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 tW1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.109",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 vyA extends QB{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",tW1,{...A,layouts:Q},aW1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new lwA(A.logger),this._slotRegistry=new VwA,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:D,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:D,...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 xyA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=u7.getInstance(A.entityService,A.logger),iW1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)dwA(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=gI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new yyA(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 _yA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(xx,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),nW1({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 sW1(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 Lp(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 Lp(A.messaging.send,this.config.siteInfo);return`## Your Site
5398
5398
  ${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
5399
5399
  `)}
5400
5400
 
5401
5401
  ## Site Builder Actions
5402
5402
  - When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
5403
- - 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(),gI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function dV(A={}){return new vyA(A)}sA();u6();HA();sA();u6();var eW1=J.object({}),Ep=e1.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:eW1}),TyA=Fr,sj=iD.omit({url:!0,analyticsScript:!0});sA();class vU extends N2{constructor(){super({entityType:"site-info",schema:Ep,frontmatterSchema:sj,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=sj.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 TU{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return TU.instance??=new TU(A,Q,B),TU.instance}static resetInstance(){TU.instance=null}static createFresh(A,Q,B){return new TU(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new vU;let w=TU.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 nJQ=new vU;class rwA{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 Y=await w.getEntity({entityType:"site-info",id:"site-info"});$=Y?nJQ.parseSiteInfoBody(Y.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let D;try{let Y=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Y)D=Y.metadata.socialLinks}catch{}let I={...$,socialLinks:D,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var Af1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.108",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 sJQ=new vU;class gyA extends MQ{entityType="site-info";schema=Ep;adapter=sJQ;defaultSiteInfo;constructor(A){super("site-info",Af1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new rwA(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=TU.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(yx,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:xx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function rV(A){return new gyA(A)}var aJQ=new vU;async function Vp(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 aJQ.parseSiteInfoBody(B.content)}HA();var tJQ=sj.extend({navigation:J.object({primary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()})),secondary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()}))}),copyright:J.string(),socialLinks:J.array(J.object({platform:J.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:J.string().describe("Profile or contact URL"),label:J.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});sA();HA();var Qf1={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 Bf1={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 wf1={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 $f1={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 Df1={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 If1={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 Yf1={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 Xf1={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 Wf1={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 XGQ=J.object({type:J.string()}).catchall(J.unknown()),WGQ=J.object({lexicon:J.literal(1),id:J.string(),defs:J.object({main:J.object({type:J.literal("record"),key:J.string().min(1),record:J.object({type:J.literal("object"),required:J.array(J.string()).optional(),properties:J.record(XGQ)})})})});function gU(A){return WGQ.parse(A)}var ww={"ai.rizom.brain.card":gU(Qf1),"ai.rizom.brain.deck":gU(Bf1),"ai.rizom.brain.link":gU(wf1),"ai.rizom.brain.note":gU($f1),"ai.rizom.brain.post":gU(Df1),"ai.rizom.brain.project":gU(If1),"ai.rizom.brain.series":gU(Yf1),"ai.rizom.brain.socialPost":gU(Xf1),"ai.rizom.brain.topic":gU(Wf1)},fGQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function uF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:fGQ}}var HGQ={"ai.rizom.brain.card":uF("@brains/atproto"),"ai.rizom.brain.deck":uF("@brains/decks"),"ai.rizom.brain.link":uF("@brains/link"),"ai.rizom.brain.note":uF("@brains/note"),"ai.rizom.brain.post":uF("@brains/blog"),"ai.rizom.brain.project":uF("@brains/portfolio"),"ai.rizom.brain.series":uF("@brains/series"),"ai.rizom.brain.socialPost":uF("@brains/social-media"),"ai.rizom.brain.topic":uF("@brains/topics")};function nV(){return Object.values(ww)}function myA(A){return ww[A]}function uyA(){return Object.entries(HGQ).map(([A,Q])=>({id:A,...Q}))}function hyA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var UGQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function JGQ(A){let Q=J.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)=>UGQ.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 ff1(A){switch(A.type){case"string":return JGQ(A);case"integer":return J.number().int();case"boolean":return J.boolean();case"array":{let Q=A.items?ff1(A.items):J.unknown(),B=J.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return GGQ(A);case"blob":return J.custom(hyA,{message:"expected blob"});default:return J.unknown()}}function Hf1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let D=ff1($);B[w]=Q.has(w)?D:D.optional()}return B}function GGQ(A){return J.object(Hf1(A)).passthrough()}function SyA(A,Q,B,w=[]){let $=Object.keys(A).filter((D)=>!Q.has(D));if($.length===0)return;B.addIssue({code:J.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function FGQ(A,Q){if(SyA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),hyA(A.brain))SyA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(hyA(A.anchor))SyA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function SU(A){let Q=J.object({...Hf1(A.defs.main.record),$type:J.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(FGQ):Q}var KGQ={"ai.rizom.brain.card":SU(ww["ai.rizom.brain.card"]),"ai.rizom.brain.deck":SU(ww["ai.rizom.brain.deck"]),"ai.rizom.brain.link":SU(ww["ai.rizom.brain.link"]),"ai.rizom.brain.note":SU(ww["ai.rizom.brain.note"]),"ai.rizom.brain.post":SU(ww["ai.rizom.brain.post"]),"ai.rizom.brain.project":SU(ww["ai.rizom.brain.project"]),"ai.rizom.brain.series":SU(ww["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":SU(ww["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":SU(ww["ai.rizom.brain.topic"])};function ZGQ(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 TN(A,Q){let B=SU(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(ZGQ(A,Q,w))}var nwA="atproto:brain-card-discovered",Uf1="atproto:brain-discovered",Jf1="atproto:brain-card-refreshed",Gf1=J.object({repoDid:J.string().min(1),uri:J.string().min(1),cid:J.string().min(1),record:KGQ["ai.rizom.brain.card"]}).strict(),xPw=J.object({agentId:J.string().min(1),name:J.string().min(1),url:J.string().url(),status:J.enum(["discovered","approved"]),repoDid:J.string().min(1).optional(),brainDid:J.string().min(1).optional(),anchorDid:J.string().min(1).optional(),cardUri:J.string().min(1).optional(),cardCid:J.string().min(1).optional()}).strict();class k6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new k6,this.instance}static createFresh(){return new k6}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}`)}}SI();tj();HA();var cyA=J.object({defaultPrompt:J.string().default("Write a blog post about my recent work and insights"),paginate:J.boolean().default(!0),pageSize:J.number().default(10)});sA();HA();e8();var qGQ=J.object({prompt:J.string().optional(),title:J.string().optional(),content:J.string().optional(),excerpt:J.string().optional(),coverImageId:J.string().optional(),seriesName:J.string().optional(),seriesIndex:J.number().optional(),skipAi:J.boolean().optional()}),rPw=pD.extend({title:J.string().optional(),slug:J.string().optional()});class pyA extends r9{constructor(A,Q){super(A,Q,{schema:qGQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:D,skipAi:I}=A,{title:Y,content:X,excerpt:W}=A;if(I){if(!Y)this.failEarly("Title is required when skipAi is true");X=X??`## Introduction
5403
+ - 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(),gI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function dV(A={}){return new vyA(A)}sA();u6();HA();sA();u6();var eW1=J.object({}),Ep=e1.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:eW1}),TyA=Fr,sj=iD.omit({url:!0,analyticsScript:!0});sA();class vU extends N2{constructor(){super({entityType:"site-info",schema:Ep,frontmatterSchema:sj,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=sj.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 TU{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return TU.instance??=new TU(A,Q,B),TU.instance}static resetInstance(){TU.instance=null}static createFresh(A,Q,B){return new TU(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new vU;let w=TU.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 nJQ=new vU;class rwA{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 Y=await w.getEntity({entityType:"site-info",id:"site-info"});$=Y?nJQ.parseSiteInfoBody(Y.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let D;try{let Y=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(Y)D=Y.metadata.socialLinks}catch{}let I={...$,socialLinks:D,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var Af1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.109",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 sJQ=new vU;class gyA extends MQ{entityType="site-info";schema=Ep;adapter=sJQ;defaultSiteInfo;constructor(A){super("site-info",Af1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new rwA(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=TU.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(yx,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:xx,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function rV(A){return new gyA(A)}var aJQ=new vU;async function Vp(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 aJQ.parseSiteInfoBody(B.content)}HA();var tJQ=sj.extend({navigation:J.object({primary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()})),secondary:J.array(J.object({label:J.string(),href:J.string(),priority:J.number()}))}),copyright:J.string(),socialLinks:J.array(J.object({platform:J.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:J.string().describe("Profile or contact URL"),label:J.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});sA();HA();var Qf1={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 Bf1={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 wf1={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 $f1={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 Df1={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 If1={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 Yf1={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 Xf1={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 Wf1={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 XGQ=J.object({type:J.string()}).catchall(J.unknown()),WGQ=J.object({lexicon:J.literal(1),id:J.string(),defs:J.object({main:J.object({type:J.literal("record"),key:J.string().min(1),record:J.object({type:J.literal("object"),required:J.array(J.string()).optional(),properties:J.record(XGQ)})})})});function gU(A){return WGQ.parse(A)}var ww={"ai.rizom.brain.card":gU(Qf1),"ai.rizom.brain.deck":gU(Bf1),"ai.rizom.brain.link":gU(wf1),"ai.rizom.brain.note":gU($f1),"ai.rizom.brain.post":gU(Df1),"ai.rizom.brain.project":gU(If1),"ai.rizom.brain.series":gU(Yf1),"ai.rizom.brain.socialPost":gU(Xf1),"ai.rizom.brain.topic":gU(Wf1)},fGQ="Additive optional fields are compatible; required-field, type, or constraint changes require a migration plan or new NSID.";function uF(A){return{status:"approved",version:"1.0.0",revision:1,owner:"Rizom",steward:"Rizom protocol registry",projectionPackage:A,compatibility:fGQ}}var HGQ={"ai.rizom.brain.card":uF("@brains/atproto"),"ai.rizom.brain.deck":uF("@brains/decks"),"ai.rizom.brain.link":uF("@brains/link"),"ai.rizom.brain.note":uF("@brains/note"),"ai.rizom.brain.post":uF("@brains/blog"),"ai.rizom.brain.project":uF("@brains/portfolio"),"ai.rizom.brain.series":uF("@brains/series"),"ai.rizom.brain.socialPost":uF("@brains/social-media"),"ai.rizom.brain.topic":uF("@brains/topics")};function nV(){return Object.values(ww)}function myA(A){return ww[A]}function uyA(){return Object.entries(HGQ).map(([A,Q])=>({id:A,...Q}))}function hyA(A){return typeof A==="object"&&A!==null&&!Array.isArray(A)}var UGQ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;function JGQ(A){let Q=J.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)=>UGQ.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 ff1(A){switch(A.type){case"string":return JGQ(A);case"integer":return J.number().int();case"boolean":return J.boolean();case"array":{let Q=A.items?ff1(A.items):J.unknown(),B=J.array(Q);if(A.maxLength!==void 0)B=B.max(A.maxLength);return B}case"object":return GGQ(A);case"blob":return J.custom(hyA,{message:"expected blob"});default:return J.unknown()}}function Hf1(A){let Q=new Set(A.required??[]),B={};for(let[w,$]of Object.entries(A.properties??{})){let D=ff1($);B[w]=Q.has(w)?D:D.optional()}return B}function GGQ(A){return J.object(Hf1(A)).passthrough()}function SyA(A,Q,B,w=[]){let $=Object.keys(A).filter((D)=>!Q.has(D));if($.length===0)return;B.addIssue({code:J.ZodIssueCode.custom,path:w,message:`unrecognized field(s): ${$.join(", ")}`})}function FGQ(A,Q){if(SyA(A,new Set(["$type","siteUrl","brain","anchor","skills","model","version","createdAt","updatedAt"]),Q),hyA(A.brain))SyA(A.brain,new Set(["did","name","role","purpose","values"]),Q,["brain"]);if(hyA(A.anchor))SyA(A.anchor,new Set(["did","name","kind"]),Q,["anchor"])}function SU(A){let Q=J.object({...Hf1(A.defs.main.record),$type:J.literal(A.id).optional()}).passthrough();return A.id==="ai.rizom.brain.card"?Q.superRefine(FGQ):Q}var KGQ={"ai.rizom.brain.card":SU(ww["ai.rizom.brain.card"]),"ai.rizom.brain.deck":SU(ww["ai.rizom.brain.deck"]),"ai.rizom.brain.link":SU(ww["ai.rizom.brain.link"]),"ai.rizom.brain.note":SU(ww["ai.rizom.brain.note"]),"ai.rizom.brain.post":SU(ww["ai.rizom.brain.post"]),"ai.rizom.brain.project":SU(ww["ai.rizom.brain.project"]),"ai.rizom.brain.series":SU(ww["ai.rizom.brain.series"]),"ai.rizom.brain.socialPost":SU(ww["ai.rizom.brain.socialPost"]),"ai.rizom.brain.topic":SU(ww["ai.rizom.brain.topic"])};function ZGQ(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 TN(A,Q){let B=SU(A).safeParse(Q);if(B.success)return;let w=B.error.issues[0];if(!w)throw B.error;throw Error(ZGQ(A,Q,w))}var nwA="atproto:brain-card-discovered",Uf1="atproto:brain-discovered",Jf1="atproto:brain-card-refreshed",Gf1=J.object({repoDid:J.string().min(1),uri:J.string().min(1),cid:J.string().min(1),record:KGQ["ai.rizom.brain.card"]}).strict(),xPw=J.object({agentId:J.string().min(1),name:J.string().min(1),url:J.string().url(),status:J.enum(["discovered","approved"]),repoDid:J.string().min(1).optional(),brainDid:J.string().min(1).optional(),anchorDid:J.string().min(1).optional(),cardUri:J.string().min(1).optional(),cardCid:J.string().min(1).optional()}).strict();class k6{static instance;projections=new Map;registrationCounts=new Map;static getInstance(){return this.instance??=new k6,this.instance}static createFresh(){return new k6}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}`)}}SI();tj();HA();var cyA=J.object({defaultPrompt:J.string().default("Write a blog post about my recent work and insights"),paginate:J.boolean().default(!0),pageSize:J.number().default(10)});sA();HA();e8();var qGQ=J.object({prompt:J.string().optional(),title:J.string().optional(),content:J.string().optional(),excerpt:J.string().optional(),coverImageId:J.string().optional(),seriesName:J.string().optional(),seriesIndex:J.number().optional(),skipAi:J.boolean().optional()}),rPw=pD.extend({title:J.string().optional(),slug:J.string().optional()});class pyA extends r9{constructor(A,Q){super(A,Q,{schema:qGQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:D,skipAi:I}=A,{title:Y,content:X,excerpt:W}=A;if(I){if(!Y)this.failEarly("Title is required when skipAi is true");X=X??`## Introduction
5404
5404
 
5405
5405
  Add your introduction here.
5406
5406
 
@@ -5620,7 +5620,7 @@ ${B.content}`,templateName:"blog:excerpt"})})}sA();tj();SI();function pGQ(A){let
5620
5620
  letter-spacing: 0.02em;
5621
5621
  }
5622
5622
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
5623
- `}},void 0,!1,void 0,this),V9("header",{className:"printable-hero",children:[V9("div",{className:"printable-masthead",children:Q.brandLabel&&V9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),V9("div",{children:[V9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&V9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),V9("div",{className:"printable-meta",children:[Q.author&&V9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&V9("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&&V9("figure",{className:"printable-cover-wrap",children:V9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),V9(B$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&V9("footer",{className:"printable-footer",children:[V9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&V9("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 OFQ=26214400,CFQ=60000;class AxA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==twA)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=bFQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await LFQ(MFQ(VFQ(),"brain-blog-printable-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:yf1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"document",data:await this.renderPdf(D.urlFor($.urlPath),{maxBytes:OFQ,timeoutMs:CFQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${RFQ(Q)}-printable.pdf`}}finally{await D.close()}}finally{await EFQ(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}=yB(A.content),B=Y8.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 bFQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=Y8.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 RFQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}import{mkdtemp as yFQ,rm as xFQ}from"fs/promises";import{tmpdir as vFQ}from"os";import{join as TFQ}from"path";HA();SI();HA();import{jsxDEV as _FQ}from"preact/jsx-dev-runtime";var ewA="og-image",PFQ="blog:og-image",xf1=J.object({title:J.string().min(1),excerpt:J.string().optional(),author:J.string().optional(),publishedAt:J.string().optional(),brandLabel:J.string().optional(),coverImageUrl:J.string().optional()}),vf1={name:PFQ,pluginId:"blog",schema:xf1,renderers:{image:jFQ}};function kFQ(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 jFQ(A){let Q=xf1.parse(A);return _FQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:kFQ(Q.publishedAt)},void 0,!1,void 0,this)}var gFQ={width:1200,height:630},SFQ=60000;class QxA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??Pp}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==ewA)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=hFQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await yFQ(TFQ(vFQ(),"brain-blog-og-image-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:vf1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"image",data:await this.screenshotPng(D.urlFor($.urlPath),gFQ,{timeoutMs:SFQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${mFQ(Q)}-og.png`}}finally{await D.close()}}finally{await xFQ(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}=yB(A.content),B=Y8.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 hFQ(A,Q={}){let{frontmatter:B}=yB(A.content),w=Y8.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 mFQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}var Tf1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.108",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 BxA extends MQ{entityType=pF.entityType;schema=aj;adapter=pF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",Tf1,A,cyA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new pyA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return zf1()}getDataSources(){return[new iyA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (hf1(),Sf1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await qf1(A,this.logger),Lf1(A,this.logger),Vf1(A,this.logger),Mf1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",twA,new AxA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",ewA,new QxA(A)),this.unregisterAtprotoProjection=k6.getInstance().register(nyA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function wxA(A={}){return new BxA(A)}SI();tj();sA();HA();HA();b$();sA();var IX=J.object({title:J.string(),slug:J.string(),coverImageId:J.string().optional()}),mf1=IX.pick({title:!0,slug:!0}),gN=e1.extend({metadata:mf1}),A8A=gN.extend({frontmatter:IX}),Q8A=A8A.extend({description:J.string().optional(),postCount:J.number(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),uf1=J.object({description:J.string().optional()});function aV(A){return new xB(uf1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}sA();class $xA extends N2{constructor(){super({entityType:"series",schema:gN,frontmatterSchema:IX,supportsCoverImage:!0,bodyFormatter:aV("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,IX).coverImageId,B=aV(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},D=aV(A.metadata.title).format(B);return this.buildMarkdown(D,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,IX);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,IX);return aV(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var SN=new $xA;sA();HA();LY();HA();var pFQ=J.object({seriesName:J.string().optional(),seriesIndex:J.number().optional()});function B8A(A){let Q=pFQ.safeParse(A);return Q.success?Q.data:{}}function tV(A){return B8A(A.metadata).seriesName}function cf1(A){return B8A(A.metadata).seriesIndex}function pf1(A,Q){let B=cf1(A)??Number.MAX_SAFE_INTEGER,w=cf1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class DxA{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 D=b1($);w.add(D);let I=B.get(D),Y=I?.content??this.createSeriesContent($),X=bB(Y);if(I?.contentHash===X)continue;let W={id:D,entityType:"series",content:Y,contentHash:X,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:b1($)}};await this.entityService.upsertEntity({entity:W}),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=tV(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=b1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:bB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:b1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=b1(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 D=tV($);if(D)A.add(D)}}return A}createSeriesContent(A){let Q={title:A,slug:b1(A)};return w9("",Q)}}sA();HA();var lFQ=J.object({entityType:J.literal("series"),query:J.object({id:J.string().optional(),limit:J.number().optional(),page:J.number().optional(),pageSize:J.number().optional()}).passthrough()}),iFQ=J.object({type:J.enum(["list","detail"]),seriesName:J.string().optional()});function dFQ(A){let Q=iFQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=lFQ.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 lf1(A){let Q=O2(A.content,IX);return A8A.parse({...A,frontmatter:Q.metadata})}class IxA{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=dFQ(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((D)=>{let I=lf1(D),Y=SN.parseBody(D.content);return{...I,description:Y.description,postCount:w.get(D.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 $=lf1(w),D=SN.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:D.description,postCount:I.length},description:D.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 D of $){let I=tV(D);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 D=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...D)}return B.sort(pf1),B}}sA();HA();LY();var rFQ=J.object({prompt:J.string().optional(),title:J.string().optional(),seriesId:J.string().optional()}),nFQ=J.object({title:J.string().optional(),excerpt:J.string().optional()});class w8A{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}
5623
+ `}},void 0,!1,void 0,this),V9("header",{className:"printable-hero",children:[V9("div",{className:"printable-masthead",children:Q.brandLabel&&V9("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this)},void 0,!1,void 0,this),V9("div",{children:[V9("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.excerpt&&V9("p",{className:"printable-excerpt",children:Q.excerpt},void 0,!1,void 0,this),V9("div",{className:"printable-meta",children:[Q.author&&V9("span",{children:["By ",Q.author]},void 0,!0,void 0,this),B&&V9("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&&V9("figure",{className:"printable-cover-wrap",children:V9("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this)},void 0,!1,void 0,this),V9(B$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.brandLabel)&&V9("footer",{className:"printable-footer",children:[V9("span",{children:Q.brandLabel??"Printable PDF"},void 0,!1,void 0,this),Q.canonicalUrl&&V9("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 OFQ=26214400,CFQ=60000;class AxA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==twA)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=bFQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await LFQ(MFQ(VFQ(),"brain-blog-printable-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/printable/post/${Q.id}`,template:yf1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"document",data:await this.renderPdf(D.urlFor($.urlPath),{maxBytes:OFQ,timeoutMs:CFQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${RFQ(Q)}-printable.pdf`}}finally{await D.close()}}finally{await EFQ(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}=yB(A.content),B=Y8.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 bFQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=Y8.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 RFQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}import{mkdtemp as yFQ,rm as xFQ}from"fs/promises";import{tmpdir as vFQ}from"os";import{join as TFQ}from"path";HA();SI();HA();import{jsxDEV as _FQ}from"preact/jsx-dev-runtime";var ewA="og-image",PFQ="blog:og-image",xf1=J.object({title:J.string().min(1),excerpt:J.string().optional(),author:J.string().optional(),publishedAt:J.string().optional(),brandLabel:J.string().optional(),coverImageUrl:J.string().optional()}),vf1={name:PFQ,pluginId:"blog",schema:xf1,renderers:{image:jFQ}};function kFQ(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 jFQ(A){let Q=xf1.parse(A);return _FQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Journal",title:Q.title,subtitle:Q.excerpt,meta:[Q.author],tag:kFQ(Q.publishedAt)},void 0,!1,void 0,this)}var gFQ={width:1200,height:630},SFQ=60000;class QxA{context;screenshotPng;constructor(A,Q={}){this.context=A;this.screenshotPng=Q.screenshotPng??Pp}async resolve(A){if(A.sourceEntityType!=="post"||A.attachmentType!==ewA)return;let Q=await this.context.entityService.getEntity({entityType:"post",id:A.sourceEntityId});if(!Q)return;let B=hFQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await yFQ(TFQ(vFQ(),"brain-blog-og-image-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/og/post/${Q.id}`,template:vf1,format:"image",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"image",data:await this.screenshotPng(D.urlFor($.urlPath),gFQ,{timeoutMs:SFQ,fullPage:!1,omitBackground:!1}),mimeType:"image/png",filename:`${mFQ(Q)}-og.png`}}finally{await D.close()}}finally{await xFQ(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}=yB(A.content),B=Y8.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 hFQ(A,Q={}){let{frontmatter:B}=yB(A.content),w=Y8.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 mFQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}var Tf1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.109",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 BxA extends MQ{entityType=pF.entityType;schema=aj;adapter=pF;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("blog",Tf1,A,cyA)}getEntityTypeConfig(){return{weight:2,publish:{publishStatuses:["queued","published"]}}}createGenerationHandler(A){return new pyA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return zf1()}getDataSources(){return[new iyA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (hf1(),Sf1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await qf1(A,this.logger),Lf1(A,this.logger),Vf1(A,this.logger),Mf1(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("post",twA,new AxA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("post",ewA,new QxA(A)),this.unregisterAtprotoProjection=k6.getInstance().register(nyA()),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0,this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function wxA(A={}){return new BxA(A)}SI();tj();sA();HA();HA();b$();sA();var IX=J.object({title:J.string(),slug:J.string(),coverImageId:J.string().optional()}),mf1=IX.pick({title:!0,slug:!0}),gN=e1.extend({metadata:mf1}),A8A=gN.extend({frontmatter:IX}),Q8A=A8A.extend({description:J.string().optional(),postCount:J.number(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),uf1=J.object({description:J.string().optional()});function aV(A){return new xB(uf1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}sA();class $xA extends N2{constructor(){super({entityType:"series",schema:gN,frontmatterSchema:IX,supportsCoverImage:!0,bodyFormatter:aV("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,IX).coverImageId,B=aV(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},D=aV(A.metadata.title).format(B);return this.buildMarkdown(D,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,IX);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,IX);return aV(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var SN=new $xA;sA();HA();LY();HA();var pFQ=J.object({seriesName:J.string().optional(),seriesIndex:J.number().optional()});function B8A(A){let Q=pFQ.safeParse(A);return Q.success?Q.data:{}}function tV(A){return B8A(A.metadata).seriesName}function cf1(A){return B8A(A.metadata).seriesIndex}function pf1(A,Q){let B=cf1(A)??Number.MAX_SAFE_INTEGER,w=cf1(Q)??Number.MAX_SAFE_INTEGER;return B-w}class DxA{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 D=b1($);w.add(D);let I=B.get(D),Y=I?.content??this.createSeriesContent($),X=bB(Y);if(I?.contentHash===X)continue;let W={id:D,entityType:"series",content:Y,contentHash:X,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:$,slug:b1($)}};await this.entityService.upsertEntity({entity:W}),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=tV(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=b1(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:bB(w),created:new Date().toISOString(),updated:new Date().toISOString(),visibility:"public",metadata:{title:A,slug:b1(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=b1(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 D=tV($);if(D)A.add(D)}}return A}createSeriesContent(A){let Q={title:A,slug:b1(A)};return w9("",Q)}}sA();HA();var lFQ=J.object({entityType:J.literal("series"),query:J.object({id:J.string().optional(),limit:J.number().optional(),page:J.number().optional(),pageSize:J.number().optional()}).passthrough()}),iFQ=J.object({type:J.enum(["list","detail"]),seriesName:J.string().optional()});function dFQ(A){let Q=iFQ.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=lFQ.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 lf1(A){let Q=O2(A.content,IX);return A8A.parse({...A,frontmatter:Q.metadata})}class IxA{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=dFQ(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((D)=>{let I=lf1(D),Y=SN.parseBody(D.content);return{...I,description:Y.description,postCount:w.get(D.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 $=lf1(w),D=SN.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:D.description,postCount:I.length},description:D.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 D of $){let I=tV(D);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 D=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...D)}return B.sort(pf1),B}}sA();HA();LY();var rFQ=J.object({prompt:J.string().optional(),title:J.string().optional(),seriesId:J.string().optional()}),nFQ=J.object({title:J.string().optional(),excerpt:J.string().optional()});class w8A{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}
5624
5624
 
5625
5625
  Content in this series:
5626
5626
  ${w.join(`
@@ -5632,7 +5632,7 @@ Your task is to write a series description (2-3 sentences) that:
5632
5632
  3. Is engaging and makes readers want to explore the content
5633
5633
  4. Works well as a series overview on a website
5634
5634
 
5635
- Be concise and focus on what makes this series unique and valuable.`});async function af1({entity:A,config:Q}){let B=gN.parse(A),w=SN.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 YxA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:ww["ai.rizom.brain.series"],validate:!1,buildRecord:af1}}var tf1={name:"@brains/series",private:!0,version:"0.2.0-alpha.108",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 ef1=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("source"),entityId:J.string(),entityType:J.string(),seriesName:J.string().optional(),previousSeriesName:J.string().optional()})]);class XxA extends MQ{entityType="series";schema=gN;adapter=SN;manager;unregisterAtprotoProjection;constructor(){super("series",tf1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new w8A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...of1(),description:sf1}}getDataSources(){return[new IxA(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=tV(Q.entity),w=B8A(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 DxA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=k6.getInstance().register(YxA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=ef1.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 D of[B.seriesName,B.previousSeriesName])if(D)await $.cleanupOrphanedSeries(D)}return{success:!0}},validateAndParse:(Q)=>{let B=ef1.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 w8A(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 WxA(){return new XxA}sA();HA();sA();HA();HA();sA();var eFQ=J.enum(["generating","draft","queued","published","failed"]),AH1="publishedAt is required when deck status is published",QH1=(A)=>A.status==="published"&&!A.publishedAt,fxA=(A)=>{if(QH1(A))throw Error(AH1)},YX=J.object({title:J.string(),slug:J.string().optional(),description:J.string().optional(),author:J.string().optional(),status:eFQ,publishedAt:J.string().datetime().optional(),event:J.string().optional(),coverImageId:J.string().optional(),ogImageId:J.string().optional()}),AKQ=YX.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:J.string(),error:J.string().optional()}).superRefine((A,Q)=>{if(!QH1(A))return;Q.addIssue({code:J.ZodIssueCode.custom,path:["publishedAt"],message:AH1})}),A_=e1.extend({entityType:J.literal("deck"),metadata:AKQ}),$8A=A_.extend({frontmatter:YX,body:J.string(),ogImageUrl:J.string().optional()}),eV=$8A.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),coverImageUrl:J.string().optional(),ogImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});class HxA extends N2{constructor(){super({entityType:"deck",schema:A_,frontmatterSchema:YX,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,YX);fxA(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);fxA(Q),this.validateSlideStructure(B);let w=Q.slug??b1(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(`---
5635
+ Be concise and focus on what makes this series unique and valuable.`});async function af1({entity:A,config:Q}){let B=gN.parse(A),w=SN.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 YxA(){return{entityType:"series",collection:"ai.rizom.brain.series",lexicon:ww["ai.rizom.brain.series"],validate:!1,buildRecord:af1}}var tf1={name:"@brains/series",private:!0,version:"0.2.0-alpha.109",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 ef1=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("source"),entityId:J.string(),entityType:J.string(),seriesName:J.string().optional(),previousSeriesName:J.string().optional()})]);class XxA extends MQ{entityType="series";schema=gN;adapter=SN;manager;unregisterAtprotoProjection;constructor(){super("series",tf1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new w8A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...of1(),description:sf1}}getDataSources(){return[new IxA(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=tV(Q.entity),w=B8A(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 DxA(A.entityService,this.logger.child("SeriesManager")),this.unregisterAtprotoProjection=k6.getInstance().register(YxA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=ef1.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 D of[B.seriesName,B.previousSeriesName])if(D)await $.cleanupOrphanedSeries(D)}return{success:!0}},validateAndParse:(Q)=>{let B=ef1.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 w8A(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 WxA(){return new XxA}sA();HA();sA();HA();HA();sA();var eFQ=J.enum(["generating","draft","queued","published","failed"]),AH1="publishedAt is required when deck status is published",QH1=(A)=>A.status==="published"&&!A.publishedAt,fxA=(A)=>{if(QH1(A))throw Error(AH1)},YX=J.object({title:J.string(),slug:J.string().optional(),description:J.string().optional(),author:J.string().optional(),status:eFQ,publishedAt:J.string().datetime().optional(),event:J.string().optional(),coverImageId:J.string().optional(),ogImageId:J.string().optional()}),AKQ=YX.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:J.string(),error:J.string().optional()}).superRefine((A,Q)=>{if(!QH1(A))return;Q.addIssue({code:J.ZodIssueCode.custom,path:["publishedAt"],message:AH1})}),A_=e1.extend({entityType:J.literal("deck"),metadata:AKQ}),$8A=A_.extend({frontmatter:YX,body:J.string(),ogImageUrl:J.string().optional()}),eV=$8A.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),coverImageUrl:J.string().optional(),ogImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});class HxA extends N2{constructor(){super({entityType:"deck",schema:A_,frontmatterSchema:YX,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,YX);fxA(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);fxA(Q),this.validateSlideStructure(B);let w=Q.slug??b1(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(`---
5636
5636
  `,Q),metadata:{title:A.title,slug:A.id,status:"generating"}}}}var kp=new HxA;HA();Hw();var QKQ=J.object({markdown:J.string().describe("Markdown content with slide separators (---)"),deck:eV.optional()}),UxA=R1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:QKQ,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:tkA,fullscreen:!0}});Hw();HA();var JxA=J.object({decks:J.array($8A)}),GxA=J.object({decks:J.array(eV),pageTitle:J.string().optional(),pageLabel:J.string().optional()});import{jsxDEV as FxA}from"preact/jsx-dev-runtime";var BKQ="Presentations",KxA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return FxA("div",{className:"deck-list bg-theme",children:FxA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:FxA(Cc,{label:Q&&Q!=="Decks"?Q:BKQ,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};b$();class D8A extends xB{constructor(){super(JxA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var ZxA=R1({name:"deck-list",description:"List view of all presentation decks",schema:GxA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new D8A,layout:{component:KxA}});HA();sA();var wKQ=J.object({title:J.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:J.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:J.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),BH1=R1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:wKQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
5637
5637
 
5638
5638
  Your task is to generate a complete slide deck based on the user's prompt.
@@ -5940,12 +5940,12 @@ ${Y}`,templateName:"decks:description"})).description,await this.reportProgress(
5940
5940
  color: var(--carousel-accent);
5941
5941
  font-weight: 600;
5942
5942
  }
5943
- `}},void 0,!1,void 0,this),$.map((W,H)=>J7("section",{className:`deck-carousel-slide${H===0?" is-cover":""}`,children:[J7("header",{className:"deck-carousel-header",children:J7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[J7("span",{className:"wm-primary",children:D.primary},void 0,!1,void 0,this),D.secondary!==void 0&&J7(WKQ,{children:[J7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),J7("span",{className:"wm-secondary",children:D.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),J7("div",{className:"deck-carousel-body",children:J7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:X(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),J7("footer",{className:"deck-carousel-footer",children:[J7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),J7("span",{className:"deck-carousel-counter","aria-label":`Slide ${H+1} of ${I}`,children:[J7("span",{className:"deck-carousel-counter-current",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",J7("span",{children:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},H,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as fKQ,rm as HKQ}from"fs/promises";import{tmpdir as UKQ}from"os";import{join as JKQ}from"path";HA();var GKQ=26214400,FKQ=60000,YH1=20;class qxA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf,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=KKQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>YH1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${YH1}`);let w=await this.getThemeMode(),$=await fKQ(JKQ(UKQ(),"brain-deck-carousel-"));try{let D=await mI({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:IH1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await uI({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(D.urlPath),{maxBytes:GKQ,timeoutMs:FKQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${ZKQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await HKQ($,{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 KKQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,D=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((Y)=>Y.trim()).filter((Y)=>Y.length>0).map((Y)=>({markdown:Y}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...D?{eyebrow:D}:{}}}function ZKQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}HA();import{jsxDEV as qKQ}from"preact/jsx-dev-runtime";var I8A="og-image",NKQ="decks:og-image",XH1=J.object({title:J.string().min(1),description:J.string().optional(),event:J.string().optional(),brandLabel:J.string().optional(),slideCount:J.number().int().positive().optional(),coverImageUrl:J.string().optional()}),WH1={name:NKQ,pluginId:"decks",schema:XH1,renderers:{image:zKQ}};function zKQ(A){let Q=XH1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return qKQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}HA();class LxA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==I8A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=yB(Q.content),$=YX.parse(B),D=LKQ(w),I=this.resolveBrandLabel(),Y=await this.resolveCoverImageUrl($.coverImageId),X={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...D?{slideCount:D}:{},...Y?{coverImageUrl:Y}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await sV({mediaPath:`/_media/og/deck/${Q.id}`,template:WH1,content:X,title:X.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${EKQ(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 LKQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function EKQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}sA();async function fH1({entity:A,config:Q}){let B=A_.parse(A),w=O2(B.content,YX),$=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 ExA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:ww["ai.rizom.brain.deck"],validate:!1,buildRecord:fH1}}var HH1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.108",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 VxA extends MQ{deps;entityType=kp.entityType;schema=kp.schema;adapter=kp;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",HH1);this.deps=A}createGenerationHandler(A){return new zxA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":UxA,"deck-list":ZxA,generation:BH1,description:wH1}}getDataSources(){return[new NxA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerOgImageAttachmentProvider(A),this.registerEvalHandlers(A),this.unregisterAtprotoProjection=k6.getInstance().register(ExA()),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}async registerWithPublishPipeline(A){await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})}}})}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 D=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:D}};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:x0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Vp(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",$H1,new qxA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",I8A,new LxA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=J.object({prompt:J.string(),event:J.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
5943
+ `}},void 0,!1,void 0,this),$.map((W,H)=>J7("section",{className:`deck-carousel-slide${H===0?" is-cover":""}`,children:[J7("header",{className:"deck-carousel-header",children:J7("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[J7("span",{className:"wm-primary",children:D.primary},void 0,!1,void 0,this),D.secondary!==void 0&&J7(WKQ,{children:[J7("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),J7("span",{className:"wm-secondary",children:D.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),J7("div",{className:"deck-carousel-body",children:J7("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:X(W.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),J7("footer",{className:"deck-carousel-footer",children:[J7("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),J7("span",{className:"deck-carousel-counter","aria-label":`Slide ${H+1} of ${I}`,children:[J7("span",{className:"deck-carousel-counter-current",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",J7("span",{children:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},H,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as fKQ,rm as HKQ}from"fs/promises";import{tmpdir as UKQ}from"os";import{join as JKQ}from"path";HA();var GKQ=26214400,FKQ=60000,YH1=20;class qxA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf,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=KKQ(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>YH1)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${YH1}`);let w=await this.getThemeMode(),$=await fKQ(JKQ(UKQ(),"brain-deck-carousel-"));try{let D=await mI({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:IH1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await uI({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(D.urlPath),{maxBytes:GKQ,timeoutMs:FKQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${ZKQ(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await HKQ($,{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 KKQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,D=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((Y)=>Y.trim()).filter((Y)=>Y.length>0).map((Y)=>({markdown:Y}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...D?{eyebrow:D}:{}}}function ZKQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}HA();import{jsxDEV as qKQ}from"preact/jsx-dev-runtime";var I8A="og-image",NKQ="decks:og-image",XH1=J.object({title:J.string().min(1),description:J.string().optional(),event:J.string().optional(),brandLabel:J.string().optional(),slideCount:J.number().int().positive().optional(),coverImageUrl:J.string().optional()}),WH1={name:NKQ,pluginId:"decks",schema:XH1,renderers:{image:zKQ}};function zKQ(A){let Q=XH1.parse(A),B=Q.slideCount?`${Q.slideCount} slide${Q.slideCount===1?"":"s"}`:void 0;return qKQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Deck",title:Q.title,subtitle:Q.description,meta:[Q.event],tag:B},void 0,!1,void 0,this)}HA();class LxA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="deck"||A.attachmentType!==I8A)return;let Q=await this.context.entityService.getEntity({entityType:"deck",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=yB(Q.content),$=YX.parse(B),D=LKQ(w),I=this.resolveBrandLabel(),Y=await this.resolveCoverImageUrl($.coverImageId),X={title:$.title,...$.description?{description:$.description}:{},...$.event?{event:$.event}:{},...D?{slideCount:D}:{},...Y?{coverImageUrl:Y}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await sV({mediaPath:`/_media/og/deck/${Q.id}`,template:WH1,content:X,title:X.title,themeMode:"dark",themeCSS:this.context.themeCSS,tmpPrefix:"brain-deck-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${EKQ(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 LKQ(A){return A.split(/^---$/gm).map((Q)=>Q.trim()).filter((Q)=>Q.length>0).length}function EKQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}sA();async function fH1({entity:A,config:Q}){let B=A_.parse(A),w=O2(B.content,YX),$=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 ExA(){return{entityType:"deck",collection:"ai.rizom.brain.deck",lexicon:ww["ai.rizom.brain.deck"],validate:!1,buildRecord:fH1}}var HH1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.109",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 VxA extends MQ{deps;entityType=kp.entityType;schema=kp.schema;adapter=kp;unregisterCarouselAttachmentProvider;unregisterOgImageAttachmentProvider;unregisterAtprotoProjection;constructor(A={}){super("decks",HH1);this.deps=A}createGenerationHandler(A){return new zxA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":UxA,"deck-list":ZxA,generation:BH1,description:wH1}}getDataSources(){return[new NxA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerOgImageAttachmentProvider(A),this.registerEvalHandlers(A),this.unregisterAtprotoProjection=k6.getInstance().register(ExA()),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}async registerWithPublishPipeline(A){await A.messaging.send({type:"publish:register",payload:{entityType:"deck",provider:{name:"internal",publish:async()=>({id:"internal"})}}})}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 D=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:D}};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:x0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Vp(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",$H1,new qxA(A,Q))}registerOgImageAttachmentProvider(A){this.unregisterOgImageAttachmentProvider=A.attachments.register("deck",I8A,new LxA(A))}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=J.object({prompt:J.string(),event:J.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
5944
5944
 
5945
5945
  Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=J.object({title:J.string(),content:J.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
5946
5946
 
5947
5947
  Content:
5948
- ${B.content}`,templateName:"decks:description"})})}}function _p(){return new VxA}sA();HA();HA();aw();var MxA=J.literal("application/pdf"),OxA=J.object({title:J.string().optional(),mimeType:MxA,filename:J.string().min(1),pageCount:J.number().int().min(0).optional(),sourceEntityType:J.string().min(1).optional(),sourceEntityId:J.string().min(1).optional(),attachmentType:J.string().min(1).optional(),dedupKey:J.string().min(1).optional()}),Q_=e1.extend({entityType:J.literal("document"),content:J.string().regex(/^data:application\/pdf;base64,.+$/),metadata:OxA});function yp(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 Y8A(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function CxA(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 D of Q.matchAll(w)){let I=parseInt(D[1]??D[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class X8A{entityType="document";schema=Q_;toMarkdown(A){return A.content}fromMarkdown(A){return yp(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}=yp(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var AM=new X8A;sA();HA();var OKQ=26214400,CKQ=20,bKQ=60000,W8A=J.object({renderUrl:J.string().url().optional(),sourceEntityType:J.string().min(1),sourceEntityId:J.string().min(1),attachmentType:J.string().min(1),documentId:J.string().min(1).optional(),title:J.string().min(1).optional(),filename:J.string().min(1).optional(),dedupKey:J.string().min(1).optional(),replace:J.boolean().optional(),pageCount:J.number().int().min(0).optional(),maxPageCount:J.number().int().positive().optional(),maxBytes:J.number().int().positive().optional(),timeoutMs:J.number().int().positive().optional(),width:J.union([J.string(),J.number()]).optional(),height:J.union([J.string(),J.number()]).optional(),format:J.string().optional(),targetEntityType:J.string().min(1).optional(),targetEntityId:J.string().min(1).optional()}),B_=W8A.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 f8A extends Uw{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:B_,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??Nf}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??CKQ,$=A.maxBytes??OKQ,D=A.timeoutMs??bKQ;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),Y=xp(A,I);if(A.replace!==!0){let X=await this.findDocumentByDedupKey(I);if(X){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,X.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:X.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let X=await this.resolveDocumentAttachment(A,Y,{timeoutMs:D,maxBytes:$}),W=X.data;if(W.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${W.byteLength} bytes`);let H=CxA(W);if(H>w)throw Error(`Rendered PDF has ${H} pages, exceeding maxPageCount=${w}`);let F=H>0?H:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let K=A.filename??(A.renderUrl===void 0?X.filename:`${Y}.pdf`),Z=AM.createDocumentEntity({dataUrl:Y8A(W),filename:K,...A.title&&{title:A.title},...F!==void 0&&{pageCount:F},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:Y}))await this.context.entityService.deleteEntity({entityType:"document",id:Y});if(await this.context.entityService.createEntity({entity:{...Z,id:Y}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:Y,reused:!1}}catch(X){throw this.logger.error("Document generation failed",{jobId:Q,error:x0(X)}),X}}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){let Q=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(Q.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:Q.length,ids:Q.map((B)=>B.id)});return Q[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:D}=yB($.content),I=Array.isArray(D.documents)?D.documents.filter(RKQ):[],Y=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,X=Y.some((W)=>W.id===B)?Y:[...Y,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:hX($.content,"documents",X)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let D=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!D||!PKQ(D,B))w.push($)}return w}}function xp(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 b1($)}function RKQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function PKQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}sA();function bxA(A,Q){return[uQ(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.',W8A,async(B,w)=>{let $=B_.safeParse(B);if(!$.success)return i5($.error.message);let D=xp($.data),I=await Q({...$.data,documentId:D},w),Y=$.data.filename??`${D}.pdf`;return K8({jobId:I,documentId:D,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(D)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(D)}&download=1`,filename:Y,source:{entityType:"document",entityId:D,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var UH1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.108",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 jKQ=J.object({});class RxA extends QB{entityType=AM.entityType;schema=Q_;adapter=AM;pluginContext;constructor(){super("document",UH1,{},jKQ)}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 f8A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){if(!A.from)return{kind:"continue",input:A};let Q=this.pluginContext;if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=B_.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),D=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??xp(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:D}}),Y=`${D}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:D,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(D)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(D)}&download=1`,filename:Y,source:{entityType:"document",entityId:D,attachmentType:B.attachmentType}}}}}}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 PDF saves, call system_create with entityType: "document" and a source attachment in from. Deck carousel PDFs use from: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use attachmentType: "printable" with sourceEntityType "post", "project", or "product". 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 bxA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function PxA(){return new RxA}sA();HA();HA();sA();var _KQ=J.enum(["generating","failed"]),lF=J.object({title:J.string().optional(),status:_KQ.optional(),error:J.string().optional()}),JH1=lF.pick({title:!0,status:!0,error:!0}).extend({title:J.string()}),hN=e1.extend({entityType:J.literal("base"),metadata:JH1}),yKQ=hN.extend({frontmatter:lF,body:J.string()});sA();HA();class kxA extends N2{constructor(){super({entityType:"base",schema:hN,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,J.record(J.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 w_=new kxA;HA();var jxA=J.object({defaultPrompt:J.string().default("Create a note summarizing key concepts from my knowledge base")});HA();sA();var GH1=J.object({title:J.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:J.string().describe("Note content in markdown format with clear organization and structure")}),_xA=R1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:GH1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
5948
+ ${B.content}`,templateName:"decks:description"})})}}function _p(){return new VxA}sA();HA();HA();aw();var MxA=J.literal("application/pdf"),OxA=J.object({title:J.string().optional(),mimeType:MxA,filename:J.string().min(1),pageCount:J.number().int().min(0).optional(),sourceEntityType:J.string().min(1).optional(),sourceEntityId:J.string().min(1).optional(),attachmentType:J.string().min(1).optional(),dedupKey:J.string().min(1).optional()}),Q_=e1.extend({entityType:J.literal("document"),content:J.string().regex(/^data:application\/pdf;base64,.+$/),metadata:OxA});function yp(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 Y8A(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function CxA(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 D of Q.matchAll(w)){let I=parseInt(D[1]??D[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class X8A{entityType="document";schema=Q_;toMarkdown(A){return A.content}fromMarkdown(A){return yp(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}=yp(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var AM=new X8A;sA();HA();var OKQ=26214400,CKQ=20,bKQ=60000,W8A=J.object({renderUrl:J.string().url().optional(),sourceEntityType:J.string().min(1),sourceEntityId:J.string().min(1),attachmentType:J.string().min(1),documentId:J.string().min(1).optional(),title:J.string().min(1).optional(),filename:J.string().min(1).optional(),dedupKey:J.string().min(1).optional(),replace:J.boolean().optional(),pageCount:J.number().int().min(0).optional(),maxPageCount:J.number().int().positive().optional(),maxBytes:J.number().int().positive().optional(),timeoutMs:J.number().int().positive().optional(),width:J.union([J.string(),J.number()]).optional(),height:J.union([J.string(),J.number()]).optional(),format:J.string().optional(),targetEntityType:J.string().min(1).optional(),targetEntityId:J.string().min(1).optional()}),B_=W8A.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 f8A extends Uw{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:B_,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??Nf}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??CKQ,$=A.maxBytes??OKQ,D=A.timeoutMs??bKQ;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),Y=xp(A,I);if(A.replace!==!0){let X=await this.findDocumentByDedupKey(I);if(X){if(A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,X.id,A);return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:X.id,reused:!0}}}await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let X=await this.resolveDocumentAttachment(A,Y,{timeoutMs:D,maxBytes:$}),W=X.data;if(W.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${W.byteLength} bytes`);let H=CxA(W);if(H>w)throw Error(`Rendered PDF has ${H} pages, exceeding maxPageCount=${w}`);let F=H>0?H:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let K=A.filename??(A.renderUrl===void 0?X.filename:`${Y}.pdf`),Z=AM.createDocumentEntity({dataUrl:Y8A(W),filename:K,...A.title&&{title:A.title},...F!==void 0&&{pageCount:F},sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType,dedupKey:I});if(await this.context.entityService.getEntity({entityType:"document",id:Y}))await this.context.entityService.deleteEntity({entityType:"document",id:Y});if(await this.context.entityService.createEntity({entity:{...Z,id:Y}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,Y,A);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:Y,reused:!1}}catch(X){throw this.logger.error("Document generation failed",{jobId:Q,error:x0(X)}),X}}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){let Q=await this.context.entityService.listEntities({entityType:"document",options:{filter:{metadata:{dedupKey:A}}}});if(Q.length>1)this.logger.warn("Multiple documents share dedupKey; using first",{dedupKey:A,count:Q.length,ids:Q.map((B)=>B.id)});return Q[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:D}=yB($.content),I=Array.isArray(D.documents)?D.documents.filter(RKQ):[],Y=w.replace?await this.removeReferencesForSameSourceAttachment(I,B,w):I,X=Y.some((W)=>W.id===B)?Y:[...Y,{id:B}];await this.context.entityService.updateEntity({entity:{...$,content:hX($.content,"documents",X)}})}async removeReferencesForSameSourceAttachment(A,Q,B){let w=[];for(let $ of A){if($.id===Q){w.push($);continue}let D=await this.context.entityService.getEntity({entityType:"document",id:$.id});if(!D||!PKQ(D,B))w.push($)}return w}}function xp(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 b1($)}function RKQ(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}function PKQ(A,Q){return A.metadata.sourceEntityType===Q.sourceEntityType&&A.metadata.sourceEntityId===Q.sourceEntityId&&A.metadata.attachmentType===Q.attachmentType}sA();function bxA(A,Q){return[uQ(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.',W8A,async(B,w)=>{let $=B_.safeParse(B);if(!$.success)return i5($.error.message);let D=xp($.data),I=await Q({...$.data,documentId:D},w),Y=$.data.filename??`${D}.pdf`;return K8({jobId:I,documentId:D,attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(D)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(D)}&download=1`,filename:Y,source:{entityType:"document",entityId:D,attachmentType:$.data.attachmentType}}})},{cli:{name:"document-generate"}})]}var UH1={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.109",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 jKQ=J.object({});class RxA extends QB{entityType=AM.entityType;schema=Q_;adapter=AM;pluginContext;constructor(){super("document",UH1,{},jKQ)}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 f8A(this.logger.child("DocumentGenerationJobHandler"),A))}async interceptCreate(A){if(!A.from)return{kind:"continue",input:A};let Q=this.pluginContext;if(!Q)return{kind:"handled",result:{success:!1,error:"Plugin context not initialized"}};let B=B_.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),D=(B.replace===!0?void 0:await this.findExistingDocument(w,Q))?.id??xp(B,w),I=await Q.jobs.enqueue({type:"generate",data:{...B,dedupKey:w,documentId:D}}),Y=`${D}.pdf`;return{kind:"handled",result:{success:!0,data:{entityId:D,jobId:I,status:"generating",attachment:{mediaType:"application/pdf",url:`/api/chat/attachments/document?id=${encodeURIComponent(D)}`,downloadUrl:`/api/chat/attachments/document?id=${encodeURIComponent(D)}&download=1`,filename:Y,source:{entityType:"document",entityId:D,attachmentType:B.attachmentType}}}}}}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 PDF saves, call system_create with entityType: "document" and a source attachment in from. Deck carousel PDFs use from: { sourceEntityType: "deck", sourceEntityId: <deck ID>, attachmentType: "carousel" }. Printable PDFs for blog posts, projects, and products use attachmentType: "printable" with sourceEntityType "post", "project", or "product". 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 bxA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function PxA(){return new RxA}sA();HA();HA();sA();var _KQ=J.enum(["generating","failed"]),lF=J.object({title:J.string().optional(),status:_KQ.optional(),error:J.string().optional()}),JH1=lF.pick({title:!0,status:!0,error:!0}).extend({title:J.string()}),hN=e1.extend({entityType:J.literal("base"),metadata:JH1}),yKQ=hN.extend({frontmatter:lF,body:J.string()});sA();HA();class kxA extends N2{constructor(){super({entityType:"base",schema:hN,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,J.record(J.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 w_=new kxA;HA();var jxA=J.object({defaultPrompt:J.string().default("Create a note summarizing key concepts from my knowledge base")});HA();sA();var GH1=J.object({title:J.string().max(80).describe("A clear, descriptive title for the note (3-8 words)"),body:J.string().describe("Note content in markdown format with clear organization and structure")}),_xA=R1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:GH1,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
5949
5949
 
5950
5950
  Your task is to generate a well-structured note based on the user's prompt.
5951
5951
 
@@ -5955,7 +5955,7 @@ Guidelines:
5955
5955
  3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
5956
5956
  4. Style: Informative and educational. Write as if explaining to yourself for future reference.
5957
5957
  5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
5958
- 6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});sA();HA();e8();var FH1=J.object({prompt:J.string(),title:J.string().optional()}),xKQ=pD.extend({title:J.string().optional()});class H8A extends r9{constructor(A,Q){super(A,Q,{schema:FH1,jobTypeName:"note-generation",entityType:"base"})}async generate(A,Q){await this.reportProgress(Q,{progress:10,message:"Generating note content with AI"});let B=await this.context.ai.generate({prompt:A.prompt,templateName:"note:generation"}),w=A.title??B.title;return await this.reportProgress(Q,{progress:50,message:`Generated note: "${w}"`}),{id:w,content:w_.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}sA();async function KH1({entity:A,config:Q}){let B=hN.parse(A),w=O2(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 yxA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:ww["ai.rizom.brain.note"],validate:!1,buildRecord:KH1}}var ZH1={name:"@brains/note",private:!0,version:"0.2.0-alpha.108",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/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 xxA extends MQ{entityType=w_.entityType;schema=hN;adapter=w_;unregisterAtprotoProjection;constructor(A={}){super("note",ZH1,A,jxA)}createGenerationHandler(A){return new H8A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:_xA}}async onRegister(A){A.eval.registerHandler("generateNote",async(Q)=>{let B=J.object({prompt:J.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=k6.getInstance().register(yxA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function QM(A={}){return new xxA(A)}sA();HA();HA();sA();var NH1=J.object({ref:J.string(),label:J.string()}),zH1=J.enum(["pending","draft","published"]),iF=J.object({status:zH1,title:J.string(),url:J.string().url(),description:J.string().optional(),domain:J.string(),capturedAt:J.string().datetime(),source:NH1}),qH1=iF.pick({title:!0,status:!0}),BM=e1.extend({entityType:J.literal("link"),metadata:qH1}),vxA=J.object({enableSummarization:J.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:J.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});sA();class mN extends N2{constructor(){super({entityType:"link",schema:BM,frontmatterSchema:iF})}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,iF),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 $_=new mN;sA();HA();var TKQ=J.object({success:J.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:J.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:J.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:J.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:J.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),LH1=R1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:TKQ,basePrompt:`You are an expert at extracting key information from webpage content.
5958
+ 6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});sA();HA();e8();var FH1=J.object({prompt:J.string(),title:J.string().optional()}),xKQ=pD.extend({title:J.string().optional()});class H8A extends r9{constructor(A,Q){super(A,Q,{schema:FH1,jobTypeName:"note-generation",entityType:"base"})}async generate(A,Q){await this.reportProgress(Q,{progress:10,message:"Generating note content with AI"});let B=await this.context.ai.generate({prompt:A.prompt,templateName:"note:generation"}),w=A.title??B.title;return await this.reportProgress(Q,{progress:50,message:`Generated note: "${w}"`}),{id:w,content:w_.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}sA();async function KH1({entity:A,config:Q}){let B=hN.parse(A),w=O2(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 yxA(){return{entityType:"base",collection:"ai.rizom.brain.note",lexicon:ww["ai.rizom.brain.note"],validate:!1,buildRecord:KH1}}var ZH1={name:"@brains/note",private:!0,version:"0.2.0-alpha.109",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/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 xxA extends MQ{entityType=w_.entityType;schema=hN;adapter=w_;unregisterAtprotoProjection;constructor(A={}){super("note",ZH1,A,jxA)}createGenerationHandler(A){return new H8A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:_xA}}async onRegister(A){A.eval.registerHandler("generateNote",async(Q)=>{let B=J.object({prompt:J.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})}),this.unregisterAtprotoProjection=k6.getInstance().register(yxA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function QM(A={}){return new xxA(A)}sA();HA();HA();sA();var NH1=J.object({ref:J.string(),label:J.string()}),zH1=J.enum(["pending","draft","published"]),iF=J.object({status:zH1,title:J.string(),url:J.string().url(),description:J.string().optional(),domain:J.string(),capturedAt:J.string().datetime(),source:NH1}),qH1=iF.pick({title:!0,status:!0}),BM=e1.extend({entityType:J.literal("link"),metadata:qH1}),vxA=J.object({enableSummarization:J.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:J.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});sA();class mN extends N2{constructor(){super({entityType:"link",schema:BM,frontmatterSchema:iF})}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,iF),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 $_=new mN;sA();HA();var TKQ=J.object({success:J.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:J.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:J.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:J.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:J.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),LH1=R1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:TKQ,basePrompt:`You are an expert at extracting key information from webpage content.
5959
5959
 
5960
5960
  You will receive webpage content in markdown format. Your job is to extract structured information from it.
5961
5961
 
@@ -5977,7 +5977,7 @@ Accuracy rules:
5977
5977
 
5978
5978
  `))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 mKQ}from"crypto";class wM{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(wM.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=mKQ("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}}}sA();HA();e8();var uKQ=J.object({url:J.string().url(),metadata:J.object({interfaceId:J.string().optional(),userId:J.string().optional(),channelId:J.string().optional(),channelName:J.string().optional(),timestamp:J.string().optional()}).optional()}),pgw=J.object({success:J.boolean(),entityId:J.string().optional(),title:J.string().optional(),url:J.string().optional(),status:J.enum(["pending","draft","published"]).optional(),error:J.string().optional()});class J8A extends Uw{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:uKQ,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new mN,this.urlFetcher=new D_(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:JQ.START,total:100,message:"Starting link capture"});let D=wM.generateEntityId(w);await B.report({progress:JQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:D});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:D});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:JQ.FETCH,total:100,message:"Fetching webpage content"});let Y=await this.urlFetcher.fetch(w);if(!Y.success){if(Y.errorType==="url_not_found"||Y.errorType==="url_unreachable")return this.logger.warn("Link URL not accessible",{url:w,errorType:Y.errorType,error:Y.error}),{success:!1,error:`Could not capture link: ${Y.error}`}}await B.report({progress:JQ.PROCESS,total:100,message:"Extracting content with AI"});let X=await this.context.ai.generate({templateName:"link:extraction",prompt:Y.success?`Extract structured information from this webpage content:
5979
5979
 
5980
- ${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:X}),await B.report({progress:JQ.EXTRACT,total:100,message:"Processing extraction results"});let W=this.resolveSource($),H=new Date().toISOString();if(X.success===!1||!X.title||!X.description||!X.summary){let Z=X.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:JQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:H,source:W}),L=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:JQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:JQ.SAVE,total:100,message:`Saving link: "${X.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:X.title,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:H,source:W}),K=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:F,metadata:{status:"draft",title:X.title}}});return await B.report({progress:JQ.COMPLETE,total:100,message:`Link captured: "${X.title}"`}),{success:!0,entityId:K.entityId,title:X.title,url:w,status:"draft"}}catch(D){return this.logger.error("Link capture job failed",{error:D,jobId:Q,data:A}),m6.failure(D)}}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 MH1({entity:A,config:Q}){let B=BM.parse(A),{frontmatter:w,summary:$}=$_.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 uxA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:ww["ai.rizom.brain.link"],validate:!1,buildRecord:MH1}}var OH1={name:"@brains/link",private:!0,version:"0.2.0-alpha.108",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 cxA extends MQ{entityType=$_.entityType;schema=BM;adapter=$_;shell;unregisterAtprotoProjection;constructor(A={}){super("link",OH1,A,vxA)}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 J8A(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 D=this.adapter.fromMarkdown(A.content).metadata,I=typeof D?.title==="string"?D.title:void 0,Y=typeof D?.status==="string"?D.status:void 0,X=this.extractFirstUrl(A.content);if(I&&Y&&X){let W=b1(X)||b1(I)||`${A.entityType}-${Date.now()}`,H=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:W,entityType:A.entityType,content:A.content,metadata:{title:I,status:Y},created:H,updated:H}})).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 J8A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:LH1,"link-list":EH1,"link-detail":VH1}}getDataSources(){return[new mxA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=k6.getInstance().register(uxA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=J.object({url:J.string().url()}).parse(Q),$=await new D_(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:
5980
+ ${Y.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${Y.error}"`,data:{url:w,hasContent:Y.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:X}),await B.report({progress:JQ.EXTRACT,total:100,message:"Processing extraction results"});let W=this.resolveSource($),H=new Date().toISOString();if(X.success===!1||!X.title||!X.description||!X.summary){let Z=X.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:JQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:H,source:W}),L=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:JQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:L.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:JQ.SAVE,total:100,message:`Saving link: "${X.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:X.title,url:w,description:X.description,summary:X.summary,domain:new URL(w).hostname,capturedAt:H,source:W}),K=await this.context.entityService.createEntity({entity:{id:D,entityType:"link",content:F,metadata:{status:"draft",title:X.title}}});return await B.report({progress:JQ.COMPLETE,total:100,message:`Link captured: "${X.title}"`}),{success:!0,entityId:K.entityId,title:X.title,url:w,status:"draft"}}catch(D){return this.logger.error("Link capture job failed",{error:D,jobId:Q,data:A}),m6.failure(D)}}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 MH1({entity:A,config:Q}){let B=BM.parse(A),{frontmatter:w,summary:$}=$_.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 uxA(){return{entityType:"link",collection:"ai.rizom.brain.link",lexicon:ww["ai.rizom.brain.link"],validate:!1,buildRecord:MH1}}var OH1={name:"@brains/link",private:!0,version:"0.2.0-alpha.109",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 cxA extends MQ{entityType=$_.entityType;schema=BM;adapter=$_;shell;unregisterAtprotoProjection;constructor(A={}){super("link",OH1,A,vxA)}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 J8A(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 D=this.adapter.fromMarkdown(A.content).metadata,I=typeof D?.title==="string"?D.title:void 0,Y=typeof D?.status==="string"?D.status:void 0,X=this.extractFirstUrl(A.content);if(I&&Y&&X){let W=b1(X)||b1(I)||`${A.entityType}-${Date.now()}`,H=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:W,entityType:A.entityType,content:A.content,metadata:{title:I,status:Y},created:H,updated:H}})).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 J8A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:LH1,"link-list":EH1,"link-detail":VH1}}getDataSources(){return[new mxA(this.logger.child("LinksDataSource"))]}async onRegister(A){this.unregisterAtprotoProjection=k6.getInstance().register(uxA()),A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=J.object({url:J.string().url()}).parse(Q),$=await new D_(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:
5981
5981
 
5982
5982
  ${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=wM.extractUrls(Q);if(B)return B}return}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}}function CH1(A={}){return new cxA(A)}var $M=CH1;HA();var FSw=J.object({id:J.string().optional(),metadata:J.object({conversationId:J.string().optional(),interfaceId:J.string().optional(),userId:J.string().optional(),messageId:J.string().optional(),timestamp:J.string().optional()}).optional()});sA();HA();Hw();HA();sA();var bH1=J.enum(["generating","draft","published","failed"]),D$=J.object({title:J.string(),slug:J.string().optional(),status:bH1,publishedAt:J.string().datetime().optional(),description:J.string(),year:J.number(),coverImageId:J.string().optional(),ogImageId:J.string().optional(),url:J.string().url().optional()}),RH1=D$.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:J.string(),error:J.string().optional()}),uN=e1.extend({entityType:J.literal("project"),metadata:RH1}),G8A=J.object({context:J.string(),problem:J.string(),solution:J.string(),outcome:J.string()}),Tp=uN.extend({frontmatter:D$,body:J.string(),structuredContent:G8A.optional(),coverImageUrl:J.string().optional(),ogImageUrl:J.string().optional()}),I_=Tp.extend({url:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),ogImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),pKQ=Tp.extend({url:J.string(),typeLabel:J.string(),coverImageUrl:J.string().optional(),ogImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});sA();HA();b$();class pxA extends xB{constructor(){super(G8A,{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 lxA=new pxA;class ixA extends N2{constructor(){super({entityType:"project",schema:uN,frontmatterSchema:D$,supportsCoverImage:!0,bodyFormatter:lxA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,D$),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,D$),B=Q.slug??b1(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,D$)}parseStructuredContent(A){return lxA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=lxA.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 cN=new ixA;HA();var dxA=J.object({});import{jsxDEV as cI,Fragment as iKQ}from"preact/jsx-dev-runtime";var lKQ=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return cI(qB,{href:B,children:[w&&cI("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),cI(u$,{children:Q.title},void 0,!1,void 0,this),cI("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},rxA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",D=B?.totalItems??A.length,I=`Browse all ${D} ${D===1?"project":"projects"}`;return cI(iKQ,{children:[cI(fQ,{title:$,description:I},void 0,!1,void 0,this),cI("div",{className:"project-list bg-theme",children:cI("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[cI("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),cI("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((Y)=>cI(lKQ,{project:Y},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&cI("div",{className:"mt-12",children:cI(bF,{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 nB,Fragment as PH1}from"preact/jsx-dev-runtime";var dKQ=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return nB("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:nB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?nB(qB,{href:A.url,variant:"compact",children:[nB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),nB("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):nB("div",{},void 0,!1,void 0,this),Q&&nB(qB,{href:Q.url,variant:"compact",className:"md:text-right",children:[nB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),nB("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)},F8A=({title:A,content:Q})=>{if(!Q)return null;return nB("section",{className:"mb-12",children:[nB("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),nB(B$,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},nxA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:D,coverImageUrl:I}=A,Y=A.ogImageUrl??I;return nB(PH1,{children:[nB(fQ,{title:w.title,description:w.description,...Y?{ogImage:Y}:{},ogType:"article"},void 0,!1,void 0,this),nB("article",{className:"project-detail",children:nB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:nB("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&nB(OF,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),nB("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),nB("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[nB("span",{className:"text-sm",children:D.year},void 0,!1,void 0,this),w.url&&nB(PH1,{children:[nB("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),nB("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),nB("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&nB("div",{className:"case-study",children:[nB(F8A,{title:"Context",content:$.context},void 0,!1,void 0,this),nB(F8A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),nB(F8A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),nB(F8A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),nB(dKQ,{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)};HA();sA();var rKQ=J.object({title:J.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:J.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:J.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:J.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:J.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:J.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),oxA=R1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:rKQ,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
5983
5983
 
@@ -6153,7 +6153,7 @@ Use the project request as the primary source of truth. If retrieved knowledge c
6153
6153
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
6154
6154
  }
6155
6155
  .printable-footer a { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
6156
- `}},void 0,!1,void 0,this),I$("section",{className:"project-shell",children:[I$("header",{className:"project-hero",children:[I$("div",{className:"project-index",children:[Q.brandLabel&&I$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&I$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I$("div",{className:"project-title-panel",children:[I$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),I$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&I$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),I$("div",{className:"printable-meta",children:[Q.year&&I$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&I$("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&&I$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),I$(B$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&I$("footer",{className:"printable-footer",children:[I$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?I$("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 BZQ=26214400,wZQ=60000;class txA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==N8A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=$ZQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await tKQ(QZQ(AZQ(),"brain-project-printable-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:_H1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"document",data:await this.renderPdf(D.urlFor($.urlPath),{maxBytes:BZQ,timeoutMs:wZQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${DZQ(Q)}-printable.pdf`}}finally{await D.close()}}finally{await eKQ(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}=yB(A.content),B=D$.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 $ZQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=D$.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 DZQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}HA();HA();import{jsxDEV as XZQ}from"preact/jsx-dev-runtime";var z8A="og-image",IZQ="portfolio:og-image",yH1=J.object({title:J.string().min(1),description:J.string().optional(),year:J.number().optional(),brandLabel:J.string().optional(),coverImageUrl:J.string().optional()}),xH1={name:IZQ,pluginId:"portfolio",schema:yH1,renderers:{image:YZQ}};function YZQ(A){let Q=yH1.parse(A);return XZQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class exA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==z8A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=yB(Q.content),w=D$.parse(B),$=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...D?{coverImageUrl:D}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await sV({mediaPath:`/_media/og/project/${Q.id}`,template:xH1,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:`${WZQ(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 WZQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}var vH1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.108",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 HZQ=J.object({projects:J.array(I_),pageTitle:J.string().optional(),pagination:i9.nullable(),baseUrl:J.string().optional()});function UZQ(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 AvA extends MQ{entityType=cN.entityType;schema=uN;adapter=cN;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",vH1,A,dxA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=UZQ(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 K8A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":R1({name:"project-list",description:"Portfolio project list page template",schema:HZQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:rxA}}),"project-detail":R1({name:"project-detail",description:"Individual project case study template",schema:J.object({project:I_,prevProject:I_.nullable(),nextProject:I_.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:nxA}}),generation:oxA}}getDataSources(){return[new Z8A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",N8A,new txA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",z8A,new exA(A)),await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=k6.getInstance().register(axA())}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=J.object({prompt:J.string(),year:J.number()}).parse(Q);return A.ai.generate({prompt:sxA(B),templateName:"portfolio:generation"})})}async registerWithPublishPipeline(A){let Q={name:"internal",publish:async()=>({id:"internal"})};await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q}})}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 D=O2($.content,D$),I=new Date().toISOString(),Y=w9(D.content,{...D.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:Y,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:x0($)}})}return{success:!0}})}}function QvA(A={}){return new AvA(A)}sA();HA();var JZQ=J.enum(["public","shared","restricted"]),TH1=J.object({includeEntityTypes:J.array(J.string()).default([]),minRelevanceScore:J.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:J.number().min(0).max(1).default(0.85),autoMerge:J.boolean().default(!0),extractableStatuses:J.array(J.string()).default(["published"]),enableAutoExtraction:J.boolean().default(!0),extractionVisibility:JZQ.default("public"),sourceChangeBatchDelayMs:J.number().int().min(0).default(1000)});sA();HA();sA();var GZQ=J.object({}),Y_=e1.extend({entityType:J.literal("topic"),metadata:GZQ}),fmw=J.object({content:J.string()}),gH1=J.object({title:J.string().describe("Topic title")});var DM="topics",oB="topic",BvA="topics-projection",SH1="topic:project",q8A="topics-plugin",hH1="topics:batch-completed",mH1="topics-source-batch";class zf extends N2{constructor(){super({entityType:oB,schema:Y_,frontmatterSchema:gH1})}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:oB}}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))}}sA();HA();HA();var FZQ=J.object({title:J.string().max(100),content:J.string(),relevanceScore:J.number().min(0).max(1)}),uH1=J.array(FZQ);var KZQ=J.object({topics:uH1}),cH1=R1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:KZQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
6156
+ `}},void 0,!1,void 0,this),I$("section",{className:"project-shell",children:[I$("header",{className:"project-hero",children:[I$("div",{className:"project-index",children:[Q.brandLabel&&I$("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),Q.year&&I$("span",{className:"project-year",children:Q.year},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I$("div",{className:"project-title-panel",children:[I$("span",{className:"printable-kind",children:"Case study dossier"},void 0,!1,void 0,this),I$("h1",{className:"printable-title",children:Q.title},void 0,!1,void 0,this),Q.description&&I$("p",{className:"printable-description",children:Q.description},void 0,!1,void 0,this),I$("div",{className:"printable-meta",children:[Q.year&&I$("span",{children:Q.year},void 0,!1,void 0,this),Q.url&&I$("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&&I$("img",{className:"printable-cover",src:Q.coverImageUrl,alt:""},void 0,!1,void 0,this),I$(B$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this),(Q.canonicalUrl||Q.url||Q.brandLabel)&&I$("footer",{className:"printable-footer",children:[I$("span",{children:Q.brandLabel??"Project printable"},void 0,!1,void 0,this),Q.canonicalUrl||Q.url?I$("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 BZQ=26214400,wZQ=60000;class txA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==N8A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let B=$ZQ(Q,{brandLabel:this.resolveBrandLabel(),coverImageUrl:await this.resolveCoverImageUrl(Q)}),w=await tKQ(QZQ(AZQ(),"brain-project-printable-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/printable/project/${Q.id}`,template:_H1,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"document",data:await this.renderPdf(D.urlFor($.urlPath),{maxBytes:BZQ,timeoutMs:wZQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${DZQ(Q)}-printable.pdf`}}finally{await D.close()}}finally{await eKQ(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}=yB(A.content),B=D$.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 $ZQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=D$.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 DZQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}HA();HA();import{jsxDEV as XZQ}from"preact/jsx-dev-runtime";var z8A="og-image",IZQ="portfolio:og-image",yH1=J.object({title:J.string().min(1),description:J.string().optional(),year:J.number().optional(),brandLabel:J.string().optional(),coverImageUrl:J.string().optional()}),xH1={name:IZQ,pluginId:"portfolio",schema:yH1,renderers:{image:YZQ}};function YZQ(A){let Q=yH1.parse(A);return XZQ(MF,{brandLabel:Q.brandLabel??Q.title,eyebrow:"Project",title:Q.title,subtitle:Q.description,tag:Q.year},void 0,!1,void 0,this)}class exA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="project"||A.attachmentType!==z8A)return;let Q=await this.context.entityService.getEntity({entityType:"project",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B}=yB(Q.content),w=D$.parse(B),$=this.resolveBrandLabel(),D=await this.resolveCoverImageUrl(w.coverImageId),I={title:w.title,...w.description?{description:w.description}:{},year:w.year,...D?{coverImageUrl:D}:{},...$?{brandLabel:$}:{}};return{type:"image",data:await sV({mediaPath:`/_media/og/project/${Q.id}`,template:xH1,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:`${WZQ(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 WZQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.title)}var vH1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.109",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 HZQ=J.object({projects:J.array(I_),pageTitle:J.string().optional(),pagination:i9.nullable(),baseUrl:J.string().optional()});function UZQ(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 AvA extends MQ{entityType=cN.entityType;schema=uN;adapter=cN;unregisterAtprotoProjection;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("portfolio",vH1,A,dxA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=UZQ(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 K8A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":R1({name:"project-list",description:"Portfolio project list page template",schema:HZQ,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:rxA}}),"project-detail":R1({name:"project-detail",description:"Individual project case study template",schema:J.object({project:I_,prevProject:I_.nullable(),nextProject:I_.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:nxA}}),generation:oxA}}getDataSources(){return[new Z8A(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),this.unregisterPrintableAttachmentProvider=A.attachments.register("project",N8A,new txA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("project",z8A,new exA(A)),await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.unregisterAtprotoProjection=k6.getInstance().register(axA())}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=J.object({prompt:J.string(),year:J.number()}).parse(Q);return A.ai.generate({prompt:sxA(B),templateName:"portfolio:generation"})})}async registerWithPublishPipeline(A){let Q={name:"internal",publish:async()=>({id:"internal"})};await A.messaging.send({type:"publish:register",payload:{entityType:"project",provider:Q}})}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 D=O2($.content,D$),I=new Date().toISOString(),Y=w9(D.content,{...D.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:Y,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:x0($)}})}return{success:!0}})}}function QvA(A={}){return new AvA(A)}sA();HA();var JZQ=J.enum(["public","shared","restricted"]),TH1=J.object({includeEntityTypes:J.array(J.string()).default([]),minRelevanceScore:J.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:J.number().min(0).max(1).default(0.85),autoMerge:J.boolean().default(!0),extractableStatuses:J.array(J.string()).default(["published"]),enableAutoExtraction:J.boolean().default(!0),extractionVisibility:JZQ.default("public"),sourceChangeBatchDelayMs:J.number().int().min(0).default(1000)});sA();HA();sA();var GZQ=J.object({}),Y_=e1.extend({entityType:J.literal("topic"),metadata:GZQ}),fmw=J.object({content:J.string()}),gH1=J.object({title:J.string().describe("Topic title")});var DM="topics",oB="topic",BvA="topics-projection",SH1="topic:project",q8A="topics-plugin",hH1="topics:batch-completed",mH1="topics-source-batch";class zf extends N2{constructor(){super({entityType:oB,schema:Y_,frontmatterSchema:gH1})}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:oB}}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))}}sA();HA();HA();var FZQ=J.object({title:J.string().max(100),content:J.string(),relevanceScore:J.number().min(0).max(1)}),uH1=J.array(FZQ);var KZQ=J.object({topics:uH1}),cH1=R1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:KZQ,basePrompt:`You are an expert at analyzing content and extracting key topics.
6157
6157
 
6158
6158
  Analyze the provided content and extract meaningful topics discussed.
6159
6159
 
@@ -6256,13 +6256,13 @@ ${A.incomingTopic.content}`})}}function bZQ(A){if(A.length===0)return"";return A
6256
6256
 
6257
6257
  ${Q.content}`}).join(`
6258
6258
 
6259
- `)}async function IM(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,D=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,Y=w.targetVisibility??"public",X=eH1(A),W=new qf(Q.entityService,B),H=w.topicMergeSynthesizer??new XvA(Q,B),F=await O8A(Q.entityService,void 0,Y),K=new Map,Z=0,q=0,L=0;for(let R of X){B.info(`Processing batch of ${R.length} entities`);let j=bZQ(R),C=C8A({entityTitle:`Batch of ${R.length} entities`,entityType:"batch",content:j,existingTopicTitles:F});try{let i=(await Q.ai.generate({prompt:C,templateName:"topics:extraction"})).topics.filter((g)=>g.relevanceScore>=$);for(let g of i)try{if(D){let S=await W.findMergeCandidate({incoming:g,threshold:I,additionalCandidates:Array.from(K.values()),targetVisibility:Y});if(S){let e=await H.synthesize({existingTopic:S.topic,incomingTopic:g}),h=await W.applySynthesizedMerge({existingId:S.topic.id,synthesized:{...e,title:S.title},visibility:Y});if(!h)throw Error(`Failed to merge topic: ${g.title}`);K.set(h.id,h),q++;continue}}let x=W.getTopicIdForTitle(g.title,Y);if(K.has(x)){L++;continue}let T=await W.createTopicOptimistic({title:g.title,content:g.content,visibility:Y});if(T.topic)K.set(T.topic.id,T.topic);if(T.created)Z++;else L++}catch(x){B.error("Topic batch item failed",{title:g.title,error:x0(x)})}}catch(m){B.error("Batch topic extraction failed",{batchSize:R.length,promptChars:C.length,error:x0(m)})}}let E={created:Z,merged:q,skipped:L,batches:X.length};if(Z>0||q>0)await Q.messaging.send({type:hH1,payload:E,broadcast:!0});return E}sA();HA();var RZQ=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("rebuild"),reason:J.string().optional()}),J.object({mode:J.literal("source-batch"),minRelevanceScore:J.number().min(0).max(1).optional()})]);class WvA{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 DU1(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 PZQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let D=RZQ.safeParse($??{});return D.success?D.data:null}}}async function PZQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(W)=>({ref:W,entity:await A.context.entityService.getEntity({entityType:W.entityType,id:W.entityId})}))),w=0,$=0,D=0,I=0,Y=[];for(let{ref:W,entity:H}of B){if(!H){$++;continue}if(H.contentHash!==W.contentHash){w++;continue}if(!A.isEntityPublished(H)){D++;continue}if(!Nq(H.visibility,A.config.extractionVisibility)){I++;continue}Y.push(H)}if(Y.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:D,hidden:I};let X=await IM(Y,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,...X,stale:w,missing:$,unpublished:D,hidden:I}}function IU1(){return{priority:5,source:q8A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:DM}}}async function YU1(A){let Q=await WU1(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 IM(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 XU1(A){let Q=await WU1(A),B=await fvA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function fvA(A,Q,B,w){let $=new qf(Q.entityService,B),D=await $.listTopics({visibility:w.extractionVisibility});for(let Y of D)await $.deleteTopic(Y.id);if(A.length===0)return{deleted:D.length,created:0,merged:0,skipped:0,batches:0};let I=await IM(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:D.length,...I}}async function WU1(A){let Q=kZQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let D of $){if(!A.isEntityPublished(D))continue;B.push(D)}}return B}function kZQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var f_=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),jZQ=f_.extend({minRelevanceScore:J.number().optional()}),_ZQ=J.object({contentA:f_,contentB:f_,minRelevanceScore:J.number().optional(),threshold:J.number().min(0).max(1).optional()}),mp=J.object({title:J.string(),content:J.string()}),yZQ=J.object({existingTopics:J.array(mp),incomingTopic:mp,threshold:J.number().optional()}),xZQ=J.object({existingTopics:J.array(mp).default([]),incomingTopic:mp.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),vZQ=J.object({entities:J.array(f_).min(1),minRelevanceScore:J.number().optional()}),TZQ=J.object({existingTopics:J.array(mp).optional(),entities:J.array(f_)}),gZQ=J.object({entities:J.array(f_)});function W_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:bB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function fU1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function SZQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function hZQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:SZQ(Q)}]}}async function YM(A){let Q=await A.entityService.listEntities({entityType:oB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:oB,id:B.id})))}async function mZQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function HU1(A){let{context:Q,logger:B,config:w}=A,$=new YvA(Q,B),D=async(I,Y,X="")=>{let W=W_(I,X);return $.extractFromEntity(W,Y)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await YM(Q);let Y=jZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=W_(Y);return(await $.extractFromEntity(W,X)).map((F)=>hZQ(F,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await YM(Q);let Y=_ZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=Y.threshold??w.mergeSimilarityThreshold,[H,F]=await Promise.all([D(Y.contentA,X,"-a"),D(Y.contentB,X,"-b")]),K=new qf(Q.entityService,B),Z=[];for(let E of H){let R=await K.createTopic(E);if(R)Z.push(R)}let q=(await Promise.all(F.map(async(E)=>{let R=await K.findMergeCandidate({incoming:E,threshold:W,additionalCandidates:Z});if(!R)return null;return{incomingTitle:E.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((E)=>E!==null),L=q.map((E)=>E.candidateTitle);return{topicsA:H.map(fU1),topicsB:F.map(fU1),matchingTitles:L,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await YM(Q);let Y=yZQ.parse(I),X=Y.threshold??w.mergeSimilarityThreshold,W=new qf(Q.entityService,B),H=[];for(let K of Y.existingTopics){let Z=await W.createTopic(K);if(Z)H.push(Z)}let F=await W.findMergeCandidate({incoming:{title:Y.incomingTopic.title},threshold:X,additionalCandidates:H});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await YM(Q);let Y=xZQ.parse(I),X=new qf(Q.entityService,B);for(let K of Y.existingTopics)await X.createTopic({title:K.title,content:K.content});await mZQ(Q);let W=W_({entityType:"post",content:Y.incomingTopic.content,metadata:{title:Y.incomingTopic.title}},"-source"),H=await IM([W],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:Y.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:oB});return{...H,topicCount:F.length,topics:F.map(DvA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await YM(Q);let Y=TZQ.parse(I),X=new qf(Q.entityService,B);for(let K of Y.existingTopics??[])await X.createTopic(K);let W=Y.entities.map((K,Z)=>W_(K,`-rebuild-${Z}`)),H=await fvA(W,Q,B,w),F=await Q.entityService.listEntities({entityType:oB});return{...H,topicCount:F.length,topics:F.map(DvA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await YM(Q);let Y=vZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=new qf(Q.entityService,B),H=[];for(let[K,Z]of Y.entities.entries()){let q=W_(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,X);for(let E of L)await W.createTopic({title:E.title,content:E.content});H.push({extractedTitles:L.map((E)=>E.title)})}let F=await Q.entityService.listEntities({entityType:oB});return{totalTopics:F.length,perEntity:H,topics:F.map(X_)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await YM(Q);let X=gZQ.parse(I).entities.map((F,K)=>W_(F,`-batch-${K}`)),W=await IM(X,Q,B,{minRelevanceScore:w.minRelevanceScore}),H=await Q.entityService.listEntities({entityType:oB});return{...W,topics:H.map(X_)}})}var uZQ=new zf;async function UU1({entity:A,config:Q}){let B=Y_.parse(A),w=uZQ.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 HvA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:ww["ai.rizom.brain.topic"],validate:!1,buildRecord:UU1}}var JU1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.108",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 pZQ=new zf;class GU1 extends MQ{entityType=oB;schema=Y_;adapter=pZQ;unregisterAtprotoProjection;sourceBatch=new WvA;constructor(A={}){super(DM,JU1,A,TH1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:cH1,"merge-synthesis":pH1,"topic-list":lH1,"topic-detail":iH1}}getDataSources(){return[new IvA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:BvA,targetType:oB,job:{type:SH1,handler:DU1({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 Lq(A,oB,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:IU1()},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(!Nq(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:q8A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:mH1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:DM}})}}]}async onRegister(A){A.insights.register("topic-distribution",nH1()),oH1({context:A,pluginId:this.id}),HU1({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=k6.getInstance().register(HvA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(BvA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===oB)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 YU1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await XU1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function b8A(A){return new GU1(A)}sA();HA();sA();var UvA=J.enum(["linkedin"]),JvA=J.enum(["generating","draft","queued","published","failed"]),FU1=J.enum(["post","deck"]),KU1=J.object({id:J.string().min(1).describe("Document entity ID")}),XX=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:UvA.describe("Target platform"),status:JvA,coverImageId:J.string().optional().describe("Image entity ID for post image"),documents:J.array(KU1).optional().describe("Document attachments for publishing"),publishedAt:J.string().datetime().optional(),platformPostId:J.string().optional().describe("ID from platform after publishing"),sourceEntityId:J.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:FU1.optional().describe("Source entity type (post, deck)")}),ZU1=XX.extend({platform:UvA.optional(),status:JvA.optional()}),NU1=XX.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}"),error:J.string().optional()}),pN=e1.extend({entityType:J.literal("social-post"),metadata:NU1}),R8A=pN.extend({frontmatter:XX,body:J.string()}),P8A=R8A.extend({url:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});sA();HA();class GvA extends N2{constructor(){super({entityType:"social-post",schema:pN,frontmatterSchema:XX,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,XX),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,ZU1),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${b1(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,XX)}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-${b1(A.title)}`,platform:"linkedin",status:"generating"}}}}var M9=new GvA;sA();sA();HA();var lZQ=GH.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),iZQ=FH.extend({query:lZQ.optional()});function zU1(A){let Q=O2(A.content,XX);return R8A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class k8A extends L5{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=iZQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return zU1(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:H}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(H,null))}let D={};if(w.platform)D.platform=w.platform;if(w.status)D.status=w.status;let I=Object.keys(D).length>0,Y=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:X,pagination:W}=await this.fetchList(w,$,{...I&&{filter:{metadata:D}},sortFields:Y});return Q.parse(this.buildListResult(X,W,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?zU1(w):null;return A.parse({post:$})}}HA();var qU1=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional(),apiVersion:J.string().regex(/^\d{6}$/).optional()}),FvA=J.object({linkedin:qU1.optional(),publishInterval:J.number().default(3600000),enabled:J.boolean().default(!0),defaultPrompt:J.string().default("Create an engaging social media post that drives engagement"),maxRetries:J.number().default(3),autoGenerateOnBlogPublish:J.boolean().default(!1)});sA();HA();e8();ZvA();import{jsxDEV as e6,Fragment as nZQ}from"preact/jsx-dev-runtime";function dZQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function rZQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var _8A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",D=B?.totalItems??A.length,I=`Browse all ${D} social ${D===1?"post":"posts"}`;return e6(nZQ,{children:[e6(fQ,{title:$,description:I},void 0,!1,void 0,this),e6("div",{className:"social-post-list bg-theme",children:e6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[e6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?e6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):e6("ul",{className:"space-y-6",children:A.map((Y)=>e6("li",{children:e6(qB,{href:Y.url,variant:"horizontal",children:e6("div",{className:"flex flex-col sm:flex-row gap-4",children:[Y.coverImageUrl&&e6("img",{src:Y.coverImageUrl,alt:Y.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),e6("div",{className:"flex-1 min-w-0",children:[e6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[e6("h2",{className:"text-lg font-semibold text-heading",children:Y.frontmatter.title},void 0,!1,void 0,this),e6("time",{className:"text-sm text-theme-muted shrink-0",children:rZQ(Y.frontmatter.publishedAt??Y.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e6("div",{className:"flex items-center gap-2 mb-3",children:[e6(HD,{status:Y.frontmatter.status},void 0,!1,void 0,this),e6("span",{className:"text-xs text-theme-muted uppercase",children:Y.frontmatter.platform},void 0,!1,void 0,this),e6("span",{className:"text-xs text-theme-muted font-mono",children:Y.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e6("p",{className:"text-theme leading-relaxed",children:dZQ(Y.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)},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&e6(bF,{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 A5,Fragment as oZQ}from"preact/jsx-dev-runtime";function LU1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var y8A=({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 A5(oZQ,{children:[A5(fQ,{title:Q,description:B},void 0,!1,void 0,this),A5("section",{className:"social-post-detail",children:A5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:A5("div",{className:"max-w-3xl mx-auto",children:[A5(VU,{items:w},void 0,!1,void 0,this),A5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),A5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[A5(HD,{status:A.frontmatter.status},void 0,!1,void 0,this),A5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),A5("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&&A5(OF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),A5(qB,{className:"p-8 mb-8",children:A5("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),A5("div",{className:"space-y-4 text-sm text-theme-muted",children:[A5("div",{children:[A5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",LU1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&A5("div",{children:[A5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",LU1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&A5("div",{children:A5("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 up(A){return`social-media:${A}`}var sZQ=J.union([J.boolean(),J.object({generate:J.boolean().optional(),prompt:J.string().optional()})]),NvA=J.object({prompt:J.string().optional(),platform:J.enum(["linkedin"]).optional(),sourceEntityType:J.enum(["post","deck"]).optional(),sourceEntityId:J.string().optional(),title:J.string().optional().describe("Required when content is provided directly"),content:J.string().optional(),addToQueue:J.boolean().optional(),generateImage:J.boolean().optional().describe("Auto-generate cover image for post"),coverImage:sZQ.optional().describe("Generic cover image generation request")}),aZQ=pD.extend({slug:J.string().optional()});class XM extends r9{constructor(A,Q){super(A,Q,{schema:NvA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:D,sourceEntityId:I}=A,{content:Y,title:X}=A;if(Y&&X)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Y&&!X){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let E=await this.context.ai.generate({prompt:Y,templateName:up(B)});X=E.title,Y=E.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&D){await this.reportProgress(Q,{progress:10,message:`Fetching source ${D}`});let E=await this.context.entityService.getEntity({entityType:D,id:I});if(!E)this.failEarly(`Source entity not found: ${D}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=J.object({slug:J.string()}).safeParse(E.metadata),C=j.success?j.data.slug:I,m=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${D}:
6259
+ `)}async function IM(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,D=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,Y=w.targetVisibility??"public",X=eH1(A),W=new qf(Q.entityService,B),H=w.topicMergeSynthesizer??new XvA(Q,B),F=await O8A(Q.entityService,void 0,Y),K=new Map,Z=0,q=0,L=0;for(let R of X){B.info(`Processing batch of ${R.length} entities`);let j=bZQ(R),C=C8A({entityTitle:`Batch of ${R.length} entities`,entityType:"batch",content:j,existingTopicTitles:F});try{let i=(await Q.ai.generate({prompt:C,templateName:"topics:extraction"})).topics.filter((g)=>g.relevanceScore>=$);for(let g of i)try{if(D){let S=await W.findMergeCandidate({incoming:g,threshold:I,additionalCandidates:Array.from(K.values()),targetVisibility:Y});if(S){let e=await H.synthesize({existingTopic:S.topic,incomingTopic:g}),h=await W.applySynthesizedMerge({existingId:S.topic.id,synthesized:{...e,title:S.title},visibility:Y});if(!h)throw Error(`Failed to merge topic: ${g.title}`);K.set(h.id,h),q++;continue}}let x=W.getTopicIdForTitle(g.title,Y);if(K.has(x)){L++;continue}let T=await W.createTopicOptimistic({title:g.title,content:g.content,visibility:Y});if(T.topic)K.set(T.topic.id,T.topic);if(T.created)Z++;else L++}catch(x){B.error("Topic batch item failed",{title:g.title,error:x0(x)})}}catch(m){B.error("Batch topic extraction failed",{batchSize:R.length,promptChars:C.length,error:x0(m)})}}let E={created:Z,merged:q,skipped:L,batches:X.length};if(Z>0||q>0)await Q.messaging.send({type:hH1,payload:E,broadcast:!0});return E}sA();HA();var RZQ=J.discriminatedUnion("mode",[J.object({mode:J.literal("derive"),reason:J.string().optional()}),J.object({mode:J.literal("rebuild"),reason:J.string().optional()}),J.object({mode:J.literal("source-batch"),minRelevanceScore:J.number().min(0).max(1).optional()})]);class WvA{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 DU1(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 PZQ({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let D=RZQ.safeParse($??{});return D.success?D.data:null}}}async function PZQ(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(W)=>({ref:W,entity:await A.context.entityService.getEntity({entityType:W.entityType,id:W.entityId})}))),w=0,$=0,D=0,I=0,Y=[];for(let{ref:W,entity:H}of B){if(!H){$++;continue}if(H.contentHash!==W.contentHash){w++;continue}if(!A.isEntityPublished(H)){D++;continue}if(!Nq(H.visibility,A.config.extractionVisibility)){I++;continue}Y.push(H)}if(Y.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:D,hidden:I};let X=await IM(Y,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,...X,stale:w,missing:$,unpublished:D,hidden:I}}function IU1(){return{priority:5,source:q8A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:DM}}}async function YU1(A){let Q=await WU1(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 IM(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 XU1(A){let Q=await WU1(A),B=await fvA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function fvA(A,Q,B,w){let $=new qf(Q.entityService,B),D=await $.listTopics({visibility:w.extractionVisibility});for(let Y of D)await $.deleteTopic(Y.id);if(A.length===0)return{deleted:D.length,created:0,merged:0,skipped:0,batches:0};let I=await IM(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold,targetVisibility:w.extractionVisibility});return{deleted:D.length,...I}}async function WU1(A){let Q=kZQ(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w,options:{filter:{visibilityScope:A.config.extractionVisibility}}});for(let D of $){if(!A.isEntityPublished(D))continue;B.push(D)}}return B}function kZQ(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var f_=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),jZQ=f_.extend({minRelevanceScore:J.number().optional()}),_ZQ=J.object({contentA:f_,contentB:f_,minRelevanceScore:J.number().optional(),threshold:J.number().min(0).max(1).optional()}),mp=J.object({title:J.string(),content:J.string()}),yZQ=J.object({existingTopics:J.array(mp),incomingTopic:mp,threshold:J.number().optional()}),xZQ=J.object({existingTopics:J.array(mp).default([]),incomingTopic:mp.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),vZQ=J.object({entities:J.array(f_).min(1),minRelevanceScore:J.number().optional()}),TZQ=J.object({existingTopics:J.array(mp).optional(),entities:J.array(f_)}),gZQ=J.object({entities:J.array(f_)});function W_(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:bB(A.content),visibility:"public",metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function fU1(A){return{title:A.title,relevanceScore:A.relevanceScore}}function SZQ(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function hZQ(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:SZQ(Q)}]}}async function YM(A){let Q=await A.entityService.listEntities({entityType:oB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:oB,id:B.id})))}async function mZQ(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function HU1(A){let{context:Q,logger:B,config:w}=A,$=new YvA(Q,B),D=async(I,Y,X="")=>{let W=W_(I,X);return $.extractFromEntity(W,Y)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await YM(Q);let Y=jZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=W_(Y);return(await $.extractFromEntity(W,X)).map((F)=>hZQ(F,W))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await YM(Q);let Y=_ZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=Y.threshold??w.mergeSimilarityThreshold,[H,F]=await Promise.all([D(Y.contentA,X,"-a"),D(Y.contentB,X,"-b")]),K=new qf(Q.entityService,B),Z=[];for(let E of H){let R=await K.createTopic(E);if(R)Z.push(R)}let q=(await Promise.all(F.map(async(E)=>{let R=await K.findMergeCandidate({incoming:E,threshold:W,additionalCandidates:Z});if(!R)return null;return{incomingTitle:E.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((E)=>E!==null),L=q.map((E)=>E.candidateTitle);return{topicsA:H.map(fU1),topicsB:F.map(fU1),matchingTitles:L,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await YM(Q);let Y=yZQ.parse(I),X=Y.threshold??w.mergeSimilarityThreshold,W=new qf(Q.entityService,B),H=[];for(let K of Y.existingTopics){let Z=await W.createTopic(K);if(Z)H.push(Z)}let F=await W.findMergeCandidate({incoming:{title:Y.incomingTopic.title},threshold:X,additionalCandidates:H});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await YM(Q);let Y=xZQ.parse(I),X=new qf(Q.entityService,B);for(let K of Y.existingTopics)await X.createTopic({title:K.title,content:K.content});await mZQ(Q);let W=W_({entityType:"post",content:Y.incomingTopic.content,metadata:{title:Y.incomingTopic.title}},"-source"),H=await IM([W],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:Y.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:oB});return{...H,topicCount:F.length,topics:F.map(DvA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await YM(Q);let Y=TZQ.parse(I),X=new qf(Q.entityService,B);for(let K of Y.existingTopics??[])await X.createTopic(K);let W=Y.entities.map((K,Z)=>W_(K,`-rebuild-${Z}`)),H=await fvA(W,Q,B,w),F=await Q.entityService.listEntities({entityType:oB});return{...H,topicCount:F.length,topics:F.map(DvA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await YM(Q);let Y=vZQ.parse(I),X=Y.minRelevanceScore??w.minRelevanceScore,W=new qf(Q.entityService,B),H=[];for(let[K,Z]of Y.entities.entries()){let q=W_(Z,`-sequential-${K}`),L=await $.extractFromEntity(q,X);for(let E of L)await W.createTopic({title:E.title,content:E.content});H.push({extractedTitles:L.map((E)=>E.title)})}let F=await Q.entityService.listEntities({entityType:oB});return{totalTopics:F.length,perEntity:H,topics:F.map(X_)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await YM(Q);let X=gZQ.parse(I).entities.map((F,K)=>W_(F,`-batch-${K}`)),W=await IM(X,Q,B,{minRelevanceScore:w.minRelevanceScore}),H=await Q.entityService.listEntities({entityType:oB});return{...W,topics:H.map(X_)}})}var uZQ=new zf;async function UU1({entity:A,config:Q}){let B=Y_.parse(A),w=uZQ.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 HvA(){return{entityType:"topic",collection:"ai.rizom.brain.topic",lexicon:ww["ai.rizom.brain.topic"],validate:!1,buildRecord:UU1}}var JU1={name:"@brains/topics",private:!0,version:"0.2.0-alpha.109",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 pZQ=new zf;class GU1 extends MQ{entityType=oB;schema=Y_;adapter=pZQ;unregisterAtprotoProjection;sourceBatch=new WvA;constructor(A={}){super(DM,JU1,A,TH1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:cH1,"merge-synthesis":pH1,"topic-list":lH1,"topic-detail":iH1}}getDataSources(){return[new IvA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:BvA,targetType:oB,job:{type:SH1,handler:DU1({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 Lq(A,oB,{visibility:this.config.extractionVisibility}),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:IU1()},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(!Nq(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:q8A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:mH1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:DM}})}}]}async onRegister(A){A.insights.register("topic-distribution",nH1()),oH1({context:A,pluginId:this.id}),HU1({context:A,logger:this.logger,config:this.config}),this.unregisterAtprotoProjection=k6.getInstance().register(HvA())}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(BvA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===oB)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 YU1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await XU1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function b8A(A){return new GU1(A)}sA();HA();sA();var UvA=J.enum(["linkedin"]),JvA=J.enum(["generating","draft","queued","published","failed"]),FU1=J.enum(["post","deck"]),KU1=J.object({id:J.string().min(1).describe("Document entity ID")}),XX=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:UvA.describe("Target platform"),status:JvA,coverImageId:J.string().optional().describe("Image entity ID for post image"),documents:J.array(KU1).optional().describe("Document attachments for publishing"),publishedAt:J.string().datetime().optional(),platformPostId:J.string().optional().describe("ID from platform after publishing"),sourceEntityId:J.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:FU1.optional().describe("Source entity type (post, deck)")}),ZU1=XX.extend({platform:UvA.optional(),status:JvA.optional()}),NU1=XX.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}"),error:J.string().optional()}),pN=e1.extend({entityType:J.literal("social-post"),metadata:NU1}),R8A=pN.extend({frontmatter:XX,body:J.string()}),P8A=R8A.extend({url:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});sA();HA();class GvA extends N2{constructor(){super({entityType:"social-post",schema:pN,frontmatterSchema:XX,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,XX),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,ZU1),B=Q.platform??"linkedin",w=Q.status??"draft",$=`${B}-${b1(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,XX)}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-${b1(A.title)}`,platform:"linkedin",status:"generating"}}}}var M9=new GvA;sA();sA();HA();var lZQ=GH.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["generating","draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),iZQ=FH.extend({query:lZQ.optional()});function zU1(A){let Q=O2(A.content,XX);return R8A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class k8A extends L5{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=iZQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return zU1(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:H}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(H,null))}let D={};if(w.platform)D.platform=w.platform;if(w.status)D.status=w.status;let I=Object.keys(D).length>0,Y=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:X,pagination:W}=await this.fetchList(w,$,{...I&&{filter:{metadata:D}},sortFields:Y});return Q.parse(this.buildListResult(X,W,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?zU1(w):null;return A.parse({post:$})}}HA();var qU1=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional(),apiVersion:J.string().regex(/^\d{6}$/).optional()}),FvA=J.object({linkedin:qU1.optional(),publishInterval:J.number().default(3600000),enabled:J.boolean().default(!0),defaultPrompt:J.string().default("Create an engaging social media post that drives engagement"),maxRetries:J.number().default(3),autoGenerateOnBlogPublish:J.boolean().default(!1)});sA();HA();e8();ZvA();import{jsxDEV as e6,Fragment as nZQ}from"preact/jsx-dev-runtime";function dZQ(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function rZQ(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var _8A=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",D=B?.totalItems??A.length,I=`Browse all ${D} social ${D===1?"post":"posts"}`;return e6(nZQ,{children:[e6(fQ,{title:$,description:I},void 0,!1,void 0,this),e6("div",{className:"social-post-list bg-theme",children:e6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[e6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?e6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):e6("ul",{className:"space-y-6",children:A.map((Y)=>e6("li",{children:e6(qB,{href:Y.url,variant:"horizontal",children:e6("div",{className:"flex flex-col sm:flex-row gap-4",children:[Y.coverImageUrl&&e6("img",{src:Y.coverImageUrl,alt:Y.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),e6("div",{className:"flex-1 min-w-0",children:[e6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[e6("h2",{className:"text-lg font-semibold text-heading",children:Y.frontmatter.title},void 0,!1,void 0,this),e6("time",{className:"text-sm text-theme-muted shrink-0",children:rZQ(Y.frontmatter.publishedAt??Y.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e6("div",{className:"flex items-center gap-2 mb-3",children:[e6(HD,{status:Y.frontmatter.status},void 0,!1,void 0,this),e6("span",{className:"text-xs text-theme-muted uppercase",children:Y.frontmatter.platform},void 0,!1,void 0,this),e6("span",{className:"text-xs text-theme-muted font-mono",children:Y.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e6("p",{className:"text-theme leading-relaxed",children:dZQ(Y.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)},Y.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&e6(bF,{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 A5,Fragment as oZQ}from"preact/jsx-dev-runtime";function LU1(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var y8A=({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 A5(oZQ,{children:[A5(fQ,{title:Q,description:B},void 0,!1,void 0,this),A5("section",{className:"social-post-detail",children:A5("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:A5("div",{className:"max-w-3xl mx-auto",children:[A5(VU,{items:w},void 0,!1,void 0,this),A5("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),A5("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[A5(HD,{status:A.frontmatter.status},void 0,!1,void 0,this),A5("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),A5("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&&A5(OF,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),A5(qB,{className:"p-8 mb-8",children:A5("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),A5("div",{className:"space-y-4 text-sm text-theme-muted",children:[A5("div",{children:[A5("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",LU1(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&A5("div",{children:[A5("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",LU1(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&A5("div",{children:A5("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 up(A){return`social-media:${A}`}var sZQ=J.union([J.boolean(),J.object({generate:J.boolean().optional(),prompt:J.string().optional()})]),NvA=J.object({prompt:J.string().optional(),platform:J.enum(["linkedin"]).optional(),sourceEntityType:J.enum(["post","deck"]).optional(),sourceEntityId:J.string().optional(),title:J.string().optional().describe("Required when content is provided directly"),content:J.string().optional(),addToQueue:J.boolean().optional(),generateImage:J.boolean().optional().describe("Auto-generate cover image for post"),coverImage:sZQ.optional().describe("Generic cover image generation request")}),aZQ=pD.extend({slug:J.string().optional()});class XM extends r9{constructor(A,Q){super(A,Q,{schema:NvA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:D,sourceEntityId:I}=A,{content:Y,title:X}=A;if(Y&&X)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(Y&&!X){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let E=await this.context.ai.generate({prompt:Y,templateName:up(B)});X=E.title,Y=E.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&D){await this.reportProgress(Q,{progress:10,message:`Fetching source ${D}`});let E=await this.context.entityService.getEntity({entityType:D,id:I});if(!E)this.failEarly(`Source entity not found: ${D}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let j=J.object({slug:J.string()}).safeParse(E.metadata),C=j.success?j.data.slug:I,m=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${D}:
6260
6260
 
6261
6261
  Source: ${D}/${C}
6262
6262
 
6263
6263
  ${E.content}`,templateName:up(B)});X=m.title,Y=m.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 E=await this.context.ai.generate({prompt:$,templateName:up(B)});X=E.title,Y=E.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!Y||!X)this.failEarly("Content or title was not generated");let H={title:X,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...D&&{sourceEntityType:D}},F=M9.createPostContent(H,Y),Z=M9.fromMarkdown(F).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let q=await sJ({entityType:"social-post",title:X,deriveId:(E)=>`${B}-${b1(E)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),L=F;if(q!==X){Z.title=q,Z.slug=`${B}-${b1(q)}`;let E={...H,title:q};L=M9.createPostContent(E,Y)}return{id:Z.slug,content:L,metadata:Z,title:q,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 cp(A){if(A.length<=200)return A;return`${A.slice(0,200)}\u2026 (truncated, ${A.length} bytes)`}function tZQ(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function eZQ(A){if(!zvA(A))return null;let Q=x8A(A,"value");if(!Q)return null;let B=x8A(Q,"uploadMechanism");if(!B)return null;let w=x8A(B,"com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest");if(!w)return null;let $=w.uploadUrl,D=Q.asset;if(typeof $!=="string"||typeof D!=="string")return null;return{uploadUrl:$,assetUrn:D}}function A3Q(A){if(!zvA(A))return null;let Q=x8A(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 x8A(A,Q){let B=A[Q];return zvA(B)?B:null}function zvA(A){return typeof A==="object"&&A!==null}var Q3Q="202604";class qvA{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(),D=w?.[0];if(w&&w.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:w.length});let I=null;if(D){let F=await this.uploadDocument($,D);return this.publishDocumentPost($,A,F,D.filename)}else if(B){let F=await this.uploadImage($,B);if(F)I={category:"IMAGE",urn:F}}let Y={shareCommentary:{text:A},shareMediaCategory:I?.category??"NONE",...I&&{media:[tZQ(I)]}},X=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":Y},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!X.ok){let F=cp(await X.text());throw this.logger.error("LinkedIn API error",{status:X.status,error:F}),Error(`LinkedIn API error: ${X.status} - ${F}`)}let W=X.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:W,mediaCategory:I?.category??"NONE"});let H={id:W};if(W)H.url=`https://www.linkedin.com/feed/update/${W}`;return H}getRestHeaders(){return{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","Linkedin-Version":this.config.apiVersion??Q3Q,"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 Y=cp(await B.text());return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:Y}),null}let w=eZQ(await B.json());if(!w)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:D}=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:D}),D}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 D=cp(await B.text());throw Error(`LinkedIn document upload initialization failed: ${B.status} - ${D}`)}let w=A3Q(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 Y=cp(await $.text());throw this.logger.error("LinkedIn document post API error",{status:$.status,error:Y}),Error(`LinkedIn document post API error: ${$.status} - ${Y}`)}let D=$.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn document post created",{postId:D,documentUrn:B});let I={id:D};if(D)I.url=`https://www.linkedin.com/feed/update/${D}`;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=cp(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 LvA(A,Q,B={}){return new qvA(A,Q,B)}sA();HA();Hw();ZvA();var B3Q=J.object({posts:J.array(P8A),totalCount:J.number().optional(),pagination:i9.nullable(),baseUrl:J.string().optional()}),w3Q=J.object({post:P8A});function EU1(){return{linkedin:j8A,"social-post-list":R1({name:"social-post-list",description:"Social post list page template",schema:B3Q,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:_8A}}),"social-post-detail":R1({name:"social-post-detail",description:"Individual social post template",schema:w3Q,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:y8A}})}}HA();var $3Q=J.object({prompt:J.string().optional(),content:J.string().optional(),platform:J.enum(["linkedin"]).default("linkedin")}),D3Q=J.object({prompt:J.string().optional(),content:J.string().optional(),title:J.string().optional(),platform:J.enum(["linkedin"]).optional()});function VU1(A){A.eval.registerHandler("generation",async(Q)=>{let B=$3Q.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
6264
6264
 
6265
- ${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=D3Q.parse(Q),w=[],$=e$.from(async(W)=>{let H={progress:W.progress};if(W.message!==void 0)H.message=W.message;w.push(H)});if(!$)throw Error("Failed to create progress reporter");let I=await new XM(A.logger,A).process(B,`eval-${Date.now()}`,$),Y=!1,X;if(I.success&&I.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});Y=!!W,X=W?.content.slice(0,300)}return{...I,entityExists:Y,entityPreview:X,progressSteps:w}})}HA();sA();class pp{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 D=$.metadata.platform,I=this.providers.get(D);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${D}`);return}let Y=O2($.content,XX),X;if(Y.metadata.coverImageId)X=await this.fetchImageData(Y.metadata.coverImageId);let W=Y.metadata.documents??[],H=await this.fetchDocumentData(W);try{if(W.length>0&&H.length===0)throw Error(`Refusing to publish: ${W.length} document(s) referenced but none could be fetched`);let F=W.length===0?await this.resolveSourceAttachment(Y.metadata):[],K=H.length>0?H:F,Z=K.length?await I.publish(Y.content,$.metadata,X,K):await I.publish(Y.content,$.metadata,X),q=new Date().toISOString(),L=Z.id||void 0,E={...Y.metadata,status:"published",publishedAt:q,...L&&{platformPostId:L}},R=M9.createPostContent(E,Y.content);await this.entityService.updateEntity({entity:{...$,content:R,metadata:{...$.metadata,status:"published",publishedAt:q,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:D,platformPostId:L})}catch(F){let K=F instanceof Error?F.message:String(F),Z={...Y.metadata,status:"failed"},q=M9.createPostContent(Z,Y.content);await this.entityService.updateEntity({entity:{...$,content:q,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,K),this.logger.error(`Post publish failed: ${B}`,{platform:D,error:K})}}catch(w){let $=x0(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],D=w[2];return{data:Buffer.from(D,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function MU1(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}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function OU1(A,Q,B){let w=new pp({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")}HA();function CU1(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:D}=B.payload;if(w!=="post")return{success:!0};if(D.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(Y){let X=x0(Y);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:X}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function bU1(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:D}=B.payload;try{let I=await A.jobs.enqueue({type:`${M9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:D,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 Y=x0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:Y}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function RU1(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 D=null;for(let Y of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Y.id}},limit:1}})).length===0){D=Y;break}if(!D)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:`${M9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:D.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:D.id}),{success:!0}}catch($){let D=x0($);return Q.error("Failed to handle generate:execute:",{error:D}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:D}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function PU1({entity:A,config:Q}){let B=pN.parse(A),w=M9.parsePostFrontmatter(B),$=M9.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 EvA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:ww["ai.rizom.brain.socialPost"],validate:!1,buildRecord:PU1}}var kU1={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.108",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 VvA extends MQ{entityType=M9.entityType;schema=pN;adapter=M9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",kU1,A,FvA)}createGenerationHandler(A){return new XM(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return EU1()}getDataSources(){return[new k8A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),MU1(A,this.providers,this.logger),OU1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)CU1(A,this.logger),bU1(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");RU1(A,this.logger),VU1(A),this.unregisterAtprotoProjection=k6.getInstance().register(EvA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=LvA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function lp(A){return new VvA(A)}HA();var Y3Q=J.enum(["draft","queued","published","failed"]),Xlw=J.object({status:Y3Q.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class MvA{name="internal";async publish(A,Q){return{id:"internal"}}}var ip={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},G7={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",EXECUTE:"publish:execute",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},lN={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"};HA();var X3Q=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),jU1=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),X3Q).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class mU{static instance=null;queues=new Map;static getInstance(){return mU.instance??=new mU,mU.instance}static resetInstance(){mU.instance=null}static createFresh(){return new mU}constructor(){}async add(A,Q,B=ip){let w=this.getOrCreateQueue(A),$=w.find((Y)=>Y.entityId===Q);if($)return{position:$.position};let D=w.length+1,I={entityId:Q,entityType:A,position:D,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:D}}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((Y)=>Y.entityId===Q);if($===-1)return;let[D]=w.splice($,1);if(!D)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,D),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 uU{static instance=null;providers=new Map;defaultProvider=new MvA;static getInstance(){return uU.instance??=new uU,uU.instance}static resetInstance(){uU.instance=null}static createFresh(){return new uU}constructor(){}register(A,Q){let B=this.providers.get(A);if(B&&B.name!=="internal"&&Q.name==="internal")return;this.providers.set(A,Q)}get(A){return this.providers.get(A)??this.defaultProvider}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}HA();HA();async function _U1(A,Q){let B={entityType:A.entityType,entityId:A.entityId,authContext:A.authContext};if(Q.messageBus)await Q.messageBus.send({type:G7.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function yU1(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let D=x0($);Q.retryTracker.recordFailure(A.entityId,D);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:D,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function xU1(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:G7.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function vU1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),D={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:G7.FAILED,payload:D,sender:"publish-service"});w.onFailed?.(D)}async function TU1(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:lN.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:lN.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function gU1(A,Q,B){if(B)B.send({type:lN.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function SU1(A,Q,B){if(B)B.send({type:lN.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var W3Q=1000;class OvA{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(W3Q,()=>this.processUnscheduledTypes())}stop(){if(f3Q(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){if(await this.deps.config.queueManager.remove(A.entityType,A.entityId),this.deps.config.messageBus!==void 0)await _U1(A,this.deps.getPublishDeps());else await yU1(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function f3Q(A){for(let Q of A.values())Q.stop();A.clear()}class CvA{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(){H3Q(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await TU1(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 H3Q(A){for(let Q of A.values())Q.stop();A.clear()}class Lf{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return Lf.instance??=new Lf(A),Lf.instance}static resetInstance(){if(Lf.instance)Lf.instance.stop();Lf.instance=null}static createFresh(A){return new Lf(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new OvA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new CvA({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){xU1(A,Q,B,this.publishDeps)}failPublish(A,Q,B){vU1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){gU1(A,Q,this.config.messageBus)}failGeneration(A,Q){SU1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,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}" - ${x0(w)}`)}}}var hU1={maxRetries:3,baseDelayMs:5000};class cU{static instance=null;retries=new Map;config;static getInstance(A){return cU.instance??=new cU(A??hU1),cU.instance}static resetInstance(){cU.instance=null}static createFresh(A){return new cU(A??hU1)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),D=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:D})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}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,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function F7(A,Q,B,w,$,D,I,Y){return F7.fromTZ(F7.tp(A,Q,B,w,$,D,I),Y)}F7.fromTZISO=(A,Q,B)=>F7.fromTZ(U3Q(A,Q),B);F7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=bvA(A.tz,B),$=new Date(B.getTime()-w),D=bvA(A.tz,$);if(D-w===0)return $;{let I=new Date(B.getTime()-D),Y=bvA(A.tz,I);if(Y-D===0)return I;if(!Q&&Y-D>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};F7.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}};F7.tp=(A,Q,B,w,$,D,I)=>({y:A,m:Q,d:B,h:w,i:$,s:D,tz:I});function bvA(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 U3Q(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("+")?F7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):F7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}F7.minitz=F7;var RvA=32,rp=31|RvA,pU1=[1,2,4,8,16],mU1=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 WX(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,rp),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],D=A==="day"&&this.lastDayOfMonth;if(Q===""&&!D)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 Y=0;Y<I.length;Y++)this.partToArray(A,I[Y],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),D=parseInt($[0],10)+B;if(isNaN(D))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,D,$[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),D=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(D===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,Y,X]=D,W=parseInt(I,10)+B,H=parseInt(Y,10)+B,F=parseInt(X,10);if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(F))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(F===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(F>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(W>H)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=W;K<=H;K+=F)this.setPart(Q,K,$[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),D=$[0].split("-");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(D[0],10)+B,Y=parseInt(D[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>Y)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let X=I;X<=Y;X++)this.setPart(Q,X,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("/");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");D[0]===""&&(D[0]="*");let I=0;D[0]!=="*"&&(I=parseInt(D[0],10)+B);let Y=parseInt(D[1],10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(Y===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(Y>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let X=I;X<this[Q].length;X+=Y)this.setPart(Q,X,$[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]|RvA;else if(Q===rp)this.dayOfWeek[A]=rp;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|pU1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},uU1=[31,28,31,30,31,30,31,31,30,31,30,31],dF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],WX=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 D=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let Y=1;Y<=w;Y++)new Date(Date.UTC(Q,B,Y)).getUTCDay()===D&&I++;if($&rp&&pU1[I-1]&$)return!0;if($&RvA){let Y=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let X=w+1;X<=Y;X++)if(new Date(Date.UTC(Q,B,X)).getUTCDay()===D)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=F7.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>uU1[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=F7.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(F7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let D=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=uU1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let Y=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let X=this[B]+$;X<w[B].length;X++){let W=w[B][X];if(B==="day"&&w.lastDayOfMonth&&X-$==I&&(W=1),B==="day"&&!w.starDOW){let H=w.dayOfWeek[(Y+(X-$-1))%7];if(H&&H&rp)H=this.isNthWeekdayOfMonth(this.year,this.month,X-$,H)?1:0;else if(H)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${H}`);Q.legacyMode&&!w.starDOM?W=W||H:W=W&&H}if(W)return this[B]=X-$,D!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,dF[w][0],Q,dF[w][2]);if($>1){let D=w+1;for(;D<dF.length;)this[dF[D][0]]=-dF[D][2],D++;if($===3)return this[dF[w][1]]++,this[dF[w][0]]=-dF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=dF.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)):F7.fromTZ(F7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function J3Q(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 WX(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new WX(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 dp(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function G3Q(A){return dp(A)}function F3Q(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var cU1=30000,v8A=[],PvA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(dp(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(dp(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=J3Q(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 mU1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new WX(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new mU1(A,this.options.timezone),this.name){if(v8A.find((D)=>D.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");v8A.push(this)}return $!==void 0&&G3Q($)&&(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 WX||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new WX(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=v8A.indexOf(this);A>=0&&v8A.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>cU1&&(Q=cU1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&F3Q(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new WX(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){dp(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new WX(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&&dp(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 WX(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 WX(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 WX(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 WX(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 T8A{scheduleCron(A,Q){let B=new PvA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new PvA(A).stop()}}sA();HA();var kvA=J.object({action:J.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:J.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:J.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:J.number().optional().describe("New position for reorder action (1-based)")}),jvA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),K3Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(jvA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),Z3Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),_vA=J.union([K3Q,Z3Q]);function g8A(A,Q,B){return{...uQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",kvA,async($,D)=>{let{action:I,entityType:Y,entityId:X,position:W}=$;switch(I){case"list":return N3Q(B,Y);case"add":return z3Q(A,B,Y,X,D);case"remove":return q3Q(A,B,Y,X,D);case"reorder":return L3Q(A,B,Y,X,W,D);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:_vA}}async function N3Q(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let D of $){let I=await A.list(D);B.push(...I)}B.sort((D,I)=>new Date(D.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(($,D)=>({position:D+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function z3Q(A,Q,B,w,$){let D=yvA("add",B,w);if(!D.success)return D.error;A.permissions.assertEntityActionAllowed(D.entityType,"publish",$??{});let I=await Q.add(D.entityType,D.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:D.entityType,entityId:D.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function q3Q(A,Q,B,w,$){let D=yvA("remove",B,w);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(D.entityType,"update",$??{}),await Q.remove(D.entityType,D.entityId),{success:!0,data:{entityType:D.entityType,entityId:D.entityId},message:"Removed from queue"}}async function L3Q(A,Q,B,w,$,D){let I=yvA("reorder",B,w);if(!I.success)return I.error;let Y=E3Q($);if(!Y.success)return Y.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",D??{}),await Q.reorder(I.entityType,I.entityId,Y.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:Y.position},message:`Moved to position ${Y.position}`}}function yvA(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 E3Q(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}}sA();HA();sA();HA();var V3Q=J.object({id:J.string().min(1)});async function iU1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:D,sourceEntityId:I}=M3Q(Q.content),Y=w?await b3Q(A,w):void 0,X;if($&&$.length>0){let H=await R3Q(A,$);if(H.length>0)X=H}X??=await C3Q(A,D,I);let W={bodyContent:B};if(Y)W.imageData=Y;if(X&&X.length>0)W.documentData=X;return W}function M3Q(A){try{let Q=O2(A,J.record(J.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=O3Q(Q.metadata.documents),D=lU1(Q.metadata.sourceEntityType),I=lU1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...D&&{sourceEntityType:D},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function O3Q(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=V3Q.safeParse(Q);return B.success?[B.data]:[]})}function lU1(A){return typeof A==="string"&&A.length>0?A:void 0}async function C3Q(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 b3Q(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=dU1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function R3Q(A,Q){return(await Promise.all(Q.map((w)=>P3Q(A,w)))).filter((w)=>w!==void 0)}async function P3Q(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=dU1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:k3Q(B,Q.id)}}function dU1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function k3Q(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}var xvA=J.object({entityType:J.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:J.string().optional().describe("Entity ID to publish"),slug:J.string().optional().describe("Entity slug to publish")}),j3Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({entityType:J.string().optional(),entityId:J.string().optional(),platformId:J.string().optional(),url:J.string().optional()}).optional()}),_3Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),vvA=J.union([j3Q,_3Q]);function S8A(A,Q,B){return{...uQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",xvA,async($,D)=>{let{entityType:I,id:Y,slug:X}=$;if(A.permissions.assertEntityActionAllowed(I,"publish",D),!Y&&!X)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let W=await y3Q(A,I,Y,X);if(!W)return{success:!1,error:`Entity not found: ${I}:${Y??X}`};if(W.visibility!=="public")return{success:!1,error:`Cannot publish ${I}:${W.id} to a public provider because visibility is ${W.visibility}`};if(W.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(I))return{success:!1,error:`No publish provider registered for ${I}. Check that the required credentials are configured.`};let H=B.get(I),{bodyContent:F,imageData:K,documentData:Z}=await iU1(A,W),q=await H.publish(F,W.metadata,K,Z);return await A.entityService.updateEntity({entity:{...W,metadata:{...W.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:q.id}}}),{success:!0,data:{entityType:I,entityId:W.id,platformId:q.id,url:q.url},message:`Published ${I}:${W.id}`}}),outputSchema:vvA}}async function y3Q(A,Q,B,w){if(B)return A.entityService.getEntity({entityType:Q,id:B});if(!w)return null;return(await A.entityService.listEntities({entityType:Q,options:{filter:{metadata:{slug:w}},limit:1}}))[0]??null}sA();HA();function rU1(A,Q){x3Q(A,Q),v3Q(A,Q)}function x3Q(A,Q){A.messaging.subscribe(G7.REGISTER,async(B)=>T3Q(Q,B.payload)),A.messaging.subscribe(G7.QUEUE,async(B)=>g3Q(A,Q,B.payload)),A.messaging.subscribe(G7.DIRECT,async(B)=>S3Q(A,Q,B.payload)),A.messaging.subscribe(G7.REMOVE,async(B)=>h3Q(Q,B.payload)),A.messaging.subscribe(G7.REORDER,async(B)=>m3Q(Q,B.payload)),A.messaging.subscribe(G7.LIST,async(B)=>u3Q(A,Q,B.payload)),A.messaging.subscribe(G7.REPORT_SUCCESS,async(B)=>c3Q(Q,B.payload)),A.messaging.subscribe(G7.REPORT_FAILURE,async(B)=>p3Q(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function v3Q(A,Q){A.messaging.subscribe(lN.REPORT_SUCCESS,async(B)=>l3Q(Q,B.payload)),A.messaging.subscribe(lN.REPORT_FAILURE,async(B)=>i3Q(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function T3Q(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let D=x0($);return A.logger.error(`Failed to register provider: ${D}`),{success:!1}}}async function g3Q(A,Q,B){let{entityType:w,entityId:$}=B;try{let D=B.authContext??ip;A.permissions.assertEntityActionAllowed(w,"publish",D);let I=await Q.queueManager.add(w,$,D);return await A.messaging.send({type:G7.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(D){let I=x0(D);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function S3Q(A,Q,B){let{entityType:w,entityId:$}=B,D=B.authContext??ip;try{return A.permissions.assertEntityActionAllowed(w,"publish",D),await A.messaging.send({type:G7.EXECUTE,payload:{entityType:w,entityId:$,authContext:D}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}catch(I){let Y=x0(I);return Q.logger.error(`Failed direct publish request: ${Y}`),{success:!1}}}async function h3Q(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 D=x0($);return A.logger.error(`Failed to remove entity: ${D}`),{success:!1}}}async function m3Q(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(D){let I=x0(D);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function u3Q(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:G7.LIST_RESPONSE,payload:{entityType:w,queue:$.map((D)=>({entityId:D.entityId,position:D.position,queuedAt:D.queuedAt}))}}),{success:!0}}catch($){let D=x0($);return Q.logger.error(`Failed to list queue: ${D}`),{success:!1}}}async function c3Q(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 p3Q(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let D=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:D?.retryCount,willRetry:D?.willRetry}),{success:!0}}async function l3Q(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 i3Q(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}}HA();async function nU1(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:x0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${x0($)}`}}}function oU1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:D,logger:I}=A,Y=d3Q(Q);return Lf.createFresh({queueManager:w,providerRegistry:$,retryTracker:D,logger:I,backend:new T8A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,entityService:Q.entityService,onCheckGenerationConditions:(X,W)=>nU1(Q.entityService,I,X,W)})}function d3Q(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 sU1(A,Q,B){let w=A.getEntityTypes();for(let D of w){let I=await A.listEntities({entityType:D,options:{filter:{metadata:{status:"queued"}}}});for(let Y of I)await Q.add(Y.entityType,Y.id)}let $=0;for(let D of w){let I=await Q.list(D);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var r3Q=["draft","queued","published","failed"];async function aU1(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:()=>n3Q(A)}})}async function n3Q(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let D=await A.entityService.listEntities({entityType:$});for(let I of D){let Y=o3Q(I.metadata.status);if(!Y)continue;w[Y]++,B.push({id:I.id,title:s3Q(I.id,I.metadata.title),type:$,status:Y})}}return{summary:w,items:B}}function o3Q(A){return r3Q.find((Q)=>Q===A)}function s3Q(A,Q){return typeof Q==="string"?Q:A}var tU1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.108",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 TvA extends QB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",tU1,A??{},jU1)}async onRegister(A){this.pluginContext=A,this.queueManager=mU.createFresh(),this.providerRegistry=uU.createFresh(),this.retryTracker=cU.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=oU1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),rU1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await sU1(A.entityService,this.queueManager,this.logger),await aU1(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[g8A(this.pluginContext,this.id,this.queueManager),S8A(this.pluginContext,this.id,this.providerRegistry)]}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).\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}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),mU.resetInstance(),uU.resetInstance(),cU.resetInstance()}}function gvA(A){return new TvA(A)}sA();HA();var eU1=J.object({accountId:J.string().describe("Cloudflare account ID"),apiToken:J.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:J.string().describe("Cloudflare Web Analytics site tag")}),SvA=J.object({cloudflare:eU1.optional()});sA();HA();var t3Q=J.object({date:J.string().describe("Single date in YYYY-MM-DD format").optional(),days:J.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:J.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:J.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:J.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function e3Q(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 AJ1(A,Q,B){let w=[];if(!B)return w;return w.push(uQ(A,"query",`Query website analytics from Cloudflare.
6265
+ ${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=D3Q.parse(Q),w=[],$=e$.from(async(W)=>{let H={progress:W.progress};if(W.message!==void 0)H.message=W.message;w.push(H)});if(!$)throw Error("Failed to create progress reporter");let I=await new XM(A.logger,A).process(B,`eval-${Date.now()}`,$),Y=!1,X;if(I.success&&I.entityId){let W=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});Y=!!W,X=W?.content.slice(0,300)}return{...I,entityExists:Y,entityPreview:X,progressSteps:w}})}HA();sA();class pp{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 D=$.metadata.platform,I=this.providers.get(D);if(!I){await this.reportFailure(Q,B,`No provider configured for platform: ${D}`);return}let Y=O2($.content,XX),X;if(Y.metadata.coverImageId)X=await this.fetchImageData(Y.metadata.coverImageId);let W=Y.metadata.documents??[],H=await this.fetchDocumentData(W);try{if(W.length>0&&H.length===0)throw Error(`Refusing to publish: ${W.length} document(s) referenced but none could be fetched`);let F=W.length===0?await this.resolveSourceAttachment(Y.metadata):[],K=H.length>0?H:F,Z=K.length?await I.publish(Y.content,$.metadata,X,K):await I.publish(Y.content,$.metadata,X),q=new Date().toISOString(),L=Z.id||void 0,E={...Y.metadata,status:"published",publishedAt:q,...L&&{platformPostId:L}},R=M9.createPostContent(E,Y.content);await this.entityService.updateEntity({entity:{...$,content:R,metadata:{...$.metadata,status:"published",publishedAt:q,platformPostId:L}}}),await this.reportSuccess(Q,B,Z.id),this.logger.info(`Post published successfully: ${B}`,{platform:D,platformPostId:L})}catch(F){let K=F instanceof Error?F.message:String(F),Z={...Y.metadata,status:"failed"},q=M9.createPostContent(Z,Y.content);await this.entityService.updateEntity({entity:{...$,content:q,metadata:{...$.metadata,status:"failed"}}}),await this.reportFailure(Q,B,K),this.logger.error(`Post publish failed: ${B}`,{platform:D,error:K})}}catch(w){let $=x0(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],D=w[2];return{data:Buffer.from(D,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function MU1(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}}),B.info("Registered social-post with publish-pipeline"),{success:!0}})}function OU1(A,Q,B){let w=new pp({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")}HA();function CU1(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:D}=B.payload;if(w!=="post")return{success:!0};if(D.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(Y){let X=x0(Y);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:X}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function bU1(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:D}=B.payload;try{let I=await A.jobs.enqueue({type:`${M9.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:D,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 Y=x0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:Y}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function RU1(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 D=null;for(let Y of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:Y.id}},limit:1}})).length===0){D=Y;break}if(!D)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:`${M9.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:D.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:D.id}),{success:!0}}catch($){let D=x0($);return Q.error("Failed to handle generate:execute:",{error:D}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:D}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}async function PU1({entity:A,config:Q}){let B=pN.parse(A),w=M9.parsePostFrontmatter(B),$=M9.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 EvA(){return{entityType:"social-post",collection:"ai.rizom.brain.socialPost",lexicon:ww["ai.rizom.brain.socialPost"],validate:!1,buildRecord:PU1}}var kU1={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.109",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 VvA extends MQ{entityType=M9.entityType;schema=pN;adapter=M9;providers=new Map;unregisterAtprotoProjection;constructor(A){super("social-media",kU1,A,FvA)}createGenerationHandler(A){return new XM(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return EU1()}getDataSources(){return[new k8A(this.logger.child("SocialPostDataSource"))]}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}async onRegister(A){if(this.initializeProviders(),MU1(A,this.providers,this.logger),OU1(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)CU1(A,this.logger),bU1(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");RU1(A,this.logger),VU1(A),this.unregisterAtprotoProjection=k6.getInstance().register(EvA()),this.logger.info("Social media plugin registered successfully")}async onShutdown(){this.unregisterAtprotoProjection?.(),this.unregisterAtprotoProjection=void 0}initializeProviders(){if(this.config.linkedin?.accessToken){let A=LvA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function lp(A){return new VvA(A)}HA();var Y3Q=J.enum(["draft","queued","published","failed"]),Xlw=J.object({status:Y3Q.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class MvA{name="internal";async publish(A,Q){return{id:"internal"}}}var ip={interfaceType:"system",userId:"system",userPermissionLevel:"anchor",authorization:"system"},G7={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",EXECUTE:"publish:execute",QUEUED:"publish:queued",COMPLETED:"publish:completed",FAILED:"publish:failed",LIST_RESPONSE:"publish:list:response"},lN={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"};HA();var X3Q=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),jU1=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),X3Q).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class mU{static instance=null;queues=new Map;static getInstance(){return mU.instance??=new mU,mU.instance}static resetInstance(){mU.instance=null}static createFresh(){return new mU}constructor(){}async add(A,Q,B=ip){let w=this.getOrCreateQueue(A),$=w.find((Y)=>Y.entityId===Q);if($)return{position:$.position};let D=w.length+1,I={entityId:Q,entityType:A,position:D,queuedAt:new Date().toISOString(),authContext:{...B}};return w.push(I),{position:D}}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((Y)=>Y.entityId===Q);if($===-1)return;let[D]=w.splice($,1);if(!D)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,D),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 uU{static instance=null;providers=new Map;defaultProvider=new MvA;static getInstance(){return uU.instance??=new uU,uU.instance}static resetInstance(){uU.instance=null}static createFresh(){return new uU}constructor(){}register(A,Q){let B=this.providers.get(A);if(B&&B.name!=="internal"&&Q.name==="internal")return;this.providers.set(A,Q)}get(A){return this.providers.get(A)??this.defaultProvider}has(A){return this.providers.has(A)}unregister(A){this.providers.delete(A)}getRegisteredTypes(){return Array.from(this.providers.keys())}}HA();HA();async function _U1(A,Q){let B={entityType:A.entityType,entityId:A.entityId,authContext:A.authContext};if(Q.messageBus)await Q.messageBus.send({type:G7.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function yU1(A,Q){let B=Q.providerRegistry.get(A.entityType);if(!Q.entityService){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:"EntityService not available for provider mode",retryCount:0,willRetry:!1});return}let w=await Q.entityService.getEntity({entityType:A.entityType,id:A.entityId});if(!w){Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:`Entity not found: ${A.entityType}/${A.entityId}`,retryCount:0,willRetry:!1});return}try{let $=await B.publish(w.content,w.metadata);Q.retryTracker.clearRetries(A.entityId),Q.onPublish?.({entityType:A.entityType,entityId:A.entityId,result:$})}catch($){let D=x0($);Q.retryTracker.recordFailure(A.entityId,D);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:D,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function xU1(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:G7.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function vU1(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),D={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:G7.FAILED,payload:D,sender:"publish-service"});w.onFailed?.(D)}async function TU1(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:lN.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:lN.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function gU1(A,Q,B){if(B)B.send({type:lN.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function SU1(A,Q,B){if(B)B.send({type:lN.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var W3Q=1000;class OvA{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(W3Q,()=>this.processUnscheduledTypes())}stop(){if(f3Q(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){if(await this.deps.config.queueManager.remove(A.entityType,A.entityId),this.deps.config.messageBus!==void 0)await _U1(A,this.deps.getPublishDeps());else await yU1(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function f3Q(A){for(let Q of A.values())Q.stop();A.clear()}class CvA{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(){H3Q(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await TU1(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 H3Q(A){for(let Q of A.values())Q.stop();A.clear()}class Lf{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return Lf.instance??=new Lf(A),Lf.instance}static resetInstance(){if(Lf.instance)Lf.instance.stop();Lf.instance=null}static createFresh(A){return new Lf(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new OvA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new CvA({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){xU1(A,Q,B,this.publishDeps)}failPublish(A,Q,B){vU1(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){gU1(A,Q,this.config.messageBus)}failGeneration(A,Q){SU1(A,Q,this.config.messageBus)}get entitySchedules(){return this.config.entitySchedules}get generationSchedules(){return this.config.generationSchedules}get publishDeps(){return{providerRegistry:this.config.providerRegistry,retryTracker:this.config.retryTracker,messageBus:this.config.messageBus,entityService:this.config.entityService,onExecute:this.config.onExecute,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}" - ${x0(w)}`)}}}var hU1={maxRetries:3,baseDelayMs:5000};class cU{static instance=null;retries=new Map;config;static getInstance(A){return cU.instance??=new cU(A??hU1),cU.instance}static resetInstance(){cU.instance=null}static createFresh(A){return new cU(A??hU1)}constructor(A){this.config=A}recordFailure(A,Q){let w=(this.retries.get(A)?.retryCount??0)+1,$=this.config.baseDelayMs*Math.pow(2,w-1),D=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:D})}shouldRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Q.retryCount<this.config.maxRetries}isReadyForRetry(A){let Q=this.retries.get(A);if(!Q)return!1;return Date.now()>=Q.nextRetryAt}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,nextRetryAt:Q.nextRetryAt,willRetry:Q.retryCount<this.config.maxRetries}}}function F7(A,Q,B,w,$,D,I,Y){return F7.fromTZ(F7.tp(A,Q,B,w,$,D,I),Y)}F7.fromTZISO=(A,Q,B)=>F7.fromTZ(U3Q(A,Q),B);F7.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=bvA(A.tz,B),$=new Date(B.getTime()-w),D=bvA(A.tz,$);if(D-w===0)return $;{let I=new Date(B.getTime()-D),Y=bvA(A.tz,I);if(Y-D===0)return I;if(!Q&&Y-D>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};F7.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}};F7.tp=(A,Q,B,w,$,D,I)=>({y:A,m:Q,d:B,h:w,i:$,s:D,tz:I});function bvA(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 U3Q(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("+")?F7.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):F7.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}F7.minitz=F7;var RvA=32,rp=31|RvA,pU1=[1,2,4,8,16],mU1=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 WX(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,rp),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],D=A==="day"&&this.lastDayOfMonth;if(Q===""&&!D)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 Y=0;Y<I.length;Y++)this.partToArray(A,I[Y],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),D=parseInt($[0],10)+B;if(isNaN(D))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,D,$[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),D=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(D===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,Y,X]=D,W=parseInt(I,10)+B,H=parseInt(Y,10)+B,F=parseInt(X,10);if(isNaN(W))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(isNaN(F))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(F===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(F>this[Q].length)throw TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+this[Q].length+")");if(W>H)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=W;K<=H;K+=F)this.setPart(Q,K,$[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),D=$[0].split("-");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(D[0],10)+B,Y=parseInt(D[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>Y)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let X=I;X<=Y;X++)this.setPart(Q,X,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),D=$[0].split("/");if(D.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");D[0]===""&&(D[0]="*");let I=0;D[0]!=="*"&&(I=parseInt(D[0],10)+B);let Y=parseInt(D[1],10);if(isNaN(Y))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(Y===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(Y>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let X=I;X<this[Q].length;X+=Y)this.setPart(Q,X,$[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]|RvA;else if(Q===rp)this.dayOfWeek[A]=rp;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|pU1[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},uU1=[31,28,31,30,31,30,31,31,30,31,30,31],dF=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],WX=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 D=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let Y=1;Y<=w;Y++)new Date(Date.UTC(Q,B,Y)).getUTCDay()===D&&I++;if($&rp&&pU1[I-1]&$)return!0;if($&RvA){let Y=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let X=w+1;X<=Y;X++)if(new Date(Date.UTC(Q,B,X)).getUTCDay()===D)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=F7.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>uU1[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=F7.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(F7.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let D=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=uU1[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let Y=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let X=this[B]+$;X<w[B].length;X++){let W=w[B][X];if(B==="day"&&w.lastDayOfMonth&&X-$==I&&(W=1),B==="day"&&!w.starDOW){let H=w.dayOfWeek[(Y+(X-$-1))%7];if(H&&H&rp)H=this.isNthWeekdayOfMonth(this.year,this.month,X-$,H)?1:0;else if(H)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${H}`);Q.legacyMode&&!w.starDOM?W=W||H:W=W&&H}if(W)return this[B]=X-$,D!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,dF[w][0],Q,dF[w][2]);if($>1){let D=w+1;for(;D<dF.length;)this[dF[D][0]]=-dF[D][2],D++;if($===3)return this[dF[w][1]]++,this[dF[w][0]]=-dF[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=dF.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)):F7.fromTZ(F7.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function J3Q(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 WX(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new WX(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 dp(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function G3Q(A){return dp(A)}function F3Q(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var cU1=30000,v8A=[],PvA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(dp(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(dp(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=J3Q(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 mU1("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new WX(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new mU1(A,this.options.timezone),this.name){if(v8A.find((D)=>D.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");v8A.push(this)}return $!==void 0&&G3Q($)&&(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 WX||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new WX(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=v8A.indexOf(this);A>=0&&v8A.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>cU1&&(Q=cU1),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&F3Q(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new WX(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){dp(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new WX(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&&dp(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 WX(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 WX(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 WX(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 WX(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 T8A{scheduleCron(A,Q){let B=new PvA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new PvA(A).stop()}}sA();HA();var kvA=J.object({action:J.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:J.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:J.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:J.number().optional().describe("New position for reorder action (1-based)")}),jvA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),K3Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(jvA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),Z3Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),_vA=J.union([K3Q,Z3Q]);function g8A(A,Q,B){return{...uQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",kvA,async($,D)=>{let{action:I,entityType:Y,entityId:X,position:W}=$;switch(I){case"list":return N3Q(B,Y);case"add":return z3Q(A,B,Y,X,D);case"remove":return q3Q(A,B,Y,X,D);case"reorder":return L3Q(A,B,Y,X,W,D);default:return{success:!1,error:`Unknown action: ${I}`}}}),outputSchema:_vA}}async function N3Q(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let D of $){let I=await A.list(D);B.push(...I)}B.sort((D,I)=>new Date(D.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(($,D)=>({position:D+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function z3Q(A,Q,B,w,$){let D=yvA("add",B,w);if(!D.success)return D.error;A.permissions.assertEntityActionAllowed(D.entityType,"publish",$??{});let I=await Q.add(D.entityType,D.entityId,{...$,authorization:"user"});return{success:!0,data:{entityType:D.entityType,entityId:D.entityId,position:I.position},message:`Added to queue at position ${I.position}`}}async function q3Q(A,Q,B,w,$){let D=yvA("remove",B,w);if(!D.success)return D.error;return A.permissions.assertEntityActionAllowed(D.entityType,"update",$??{}),await Q.remove(D.entityType,D.entityId),{success:!0,data:{entityType:D.entityType,entityId:D.entityId},message:"Removed from queue"}}async function L3Q(A,Q,B,w,$,D){let I=yvA("reorder",B,w);if(!I.success)return I.error;let Y=E3Q($);if(!Y.success)return Y.error;return A.permissions.assertEntityActionAllowed(I.entityType,"update",D??{}),await Q.reorder(I.entityType,I.entityId,Y.position),{success:!0,data:{entityType:I.entityType,entityId:I.entityId,position:Y.position},message:`Moved to position ${Y.position}`}}function yvA(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 E3Q(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}}sA();HA();sA();HA();var V3Q=J.object({id:J.string().min(1)});async function iU1(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:D,sourceEntityId:I}=M3Q(Q.content),Y=w?await b3Q(A,w):void 0,X;if($&&$.length>0){let H=await R3Q(A,$);if(H.length>0)X=H}X??=await C3Q(A,D,I);let W={bodyContent:B};if(Y)W.imageData=Y;if(X&&X.length>0)W.documentData=X;return W}function M3Q(A){try{let Q=O2(A,J.record(J.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=O3Q(Q.metadata.documents),D=lU1(Q.metadata.sourceEntityType),I=lU1(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...D&&{sourceEntityType:D},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function O3Q(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=V3Q.safeParse(Q);return B.success?[B.data]:[]})}function lU1(A){return typeof A==="string"&&A.length>0?A:void 0}async function C3Q(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 b3Q(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=dU1(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function R3Q(A,Q){return(await Promise.all(Q.map((w)=>P3Q(A,w)))).filter((w)=>w!==void 0)}async function P3Q(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=dU1(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:k3Q(B,Q.id)}}function dU1(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function k3Q(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}var xvA=J.object({entityType:J.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:J.string().optional().describe("Entity ID to publish"),slug:J.string().optional().describe("Entity slug to publish")}),j3Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({entityType:J.string().optional(),entityId:J.string().optional(),platformId:J.string().optional(),url:J.string().optional()}).optional()}),_3Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),vvA=J.union([j3Q,_3Q]);function S8A(A,Q,B){return{...uQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",xvA,async($,D)=>{let{entityType:I,id:Y,slug:X}=$;if(A.permissions.assertEntityActionAllowed(I,"publish",D),!Y&&!X)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let W=await y3Q(A,I,Y,X);if(!W)return{success:!1,error:`Entity not found: ${I}:${Y??X}`};if(W.visibility!=="public")return{success:!1,error:`Cannot publish ${I}:${W.id} to a public provider because visibility is ${W.visibility}`};if(W.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(I))return{success:!1,error:`No publish provider registered for ${I}. Check that the required credentials are configured.`};let H=B.get(I),{bodyContent:F,imageData:K,documentData:Z}=await iU1(A,W),q=await H.publish(F,W.metadata,K,Z);return await A.entityService.updateEntity({entity:{...W,metadata:{...W.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:q.id}}}),{success:!0,data:{entityType:I,entityId:W.id,platformId:q.id,url:q.url},message:`Published ${I}:${W.id}`}}),outputSchema:vvA}}async function y3Q(A,Q,B,w){if(B)return A.entityService.getEntity({entityType:Q,id:B});if(!w)return null;return(await A.entityService.listEntities({entityType:Q,options:{filter:{metadata:{slug:w}},limit:1}}))[0]??null}sA();HA();function rU1(A,Q){x3Q(A,Q),v3Q(A,Q)}function x3Q(A,Q){A.messaging.subscribe(G7.REGISTER,async(B)=>T3Q(Q,B.payload)),A.messaging.subscribe(G7.QUEUE,async(B)=>g3Q(A,Q,B.payload)),A.messaging.subscribe(G7.DIRECT,async(B)=>S3Q(A,Q,B.payload)),A.messaging.subscribe(G7.REMOVE,async(B)=>h3Q(Q,B.payload)),A.messaging.subscribe(G7.REORDER,async(B)=>m3Q(Q,B.payload)),A.messaging.subscribe(G7.LIST,async(B)=>u3Q(A,Q,B.payload)),A.messaging.subscribe(G7.REPORT_SUCCESS,async(B)=>c3Q(Q,B.payload)),A.messaging.subscribe(G7.REPORT_FAILURE,async(B)=>p3Q(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function v3Q(A,Q){A.messaging.subscribe(lN.REPORT_SUCCESS,async(B)=>l3Q(Q,B.payload)),A.messaging.subscribe(lN.REPORT_FAILURE,async(B)=>i3Q(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function T3Q(A,Q){let{entityType:B,provider:w}=Q;try{if(w)A.providerRegistry.register(B,w),A.logger.info(`Registered provider for entity type: ${B}`,{providerName:w.name});return{success:!0}}catch($){let D=x0($);return A.logger.error(`Failed to register provider: ${D}`),{success:!1}}}async function g3Q(A,Q,B){let{entityType:w,entityId:$}=B;try{let D=B.authContext??ip;A.permissions.assertEntityActionAllowed(w,"publish",D);let I=await Q.queueManager.add(w,$,D);return await A.messaging.send({type:G7.QUEUED,payload:{entityType:w,entityId:$,position:I.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:I.position}),{success:!0}}catch(D){let I=x0(D);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function S3Q(A,Q,B){let{entityType:w,entityId:$}=B,D=B.authContext??ip;try{return A.permissions.assertEntityActionAllowed(w,"publish",D),await A.messaging.send({type:G7.EXECUTE,payload:{entityType:w,entityId:$,authContext:D}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}catch(I){let Y=x0(I);return Q.logger.error(`Failed direct publish request: ${Y}`),{success:!1}}}async function h3Q(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 D=x0($);return A.logger.error(`Failed to remove entity: ${D}`),{success:!1}}}async function m3Q(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(D){let I=x0(D);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function u3Q(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:G7.LIST_RESPONSE,payload:{entityType:w,queue:$.map((D)=>({entityId:D.entityId,position:D.position,queuedAt:D.queuedAt}))}}),{success:!0}}catch($){let D=x0($);return Q.logger.error(`Failed to list queue: ${D}`),{success:!1}}}async function c3Q(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 p3Q(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let D=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:D?.retryCount,willRetry:D?.willRetry}),{success:!0}}async function l3Q(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 i3Q(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}}HA();async function nU1(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:x0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${x0($)}`}}}function oU1(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:D,logger:I}=A,Y=d3Q(Q);return Lf.createFresh({queueManager:w,providerRegistry:$,retryTracker:D,logger:I,backend:new T8A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:Y,entityService:Q.entityService,onCheckGenerationConditions:(X,W)=>nU1(Q.entityService,I,X,W)})}function d3Q(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 sU1(A,Q,B){let w=A.getEntityTypes();for(let D of w){let I=await A.listEntities({entityType:D,options:{filter:{metadata:{status:"queued"}}}});for(let Y of I)await Q.add(Y.entityType,Y.id)}let $=0;for(let D of w){let I=await Q.list(D);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var r3Q=["draft","queued","published","failed"];async function aU1(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:()=>n3Q(A)}})}async function n3Q(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let D=await A.entityService.listEntities({entityType:$});for(let I of D){let Y=o3Q(I.metadata.status);if(!Y)continue;w[Y]++,B.push({id:I.id,title:s3Q(I.id,I.metadata.title),type:$,status:Y})}}return{summary:w,items:B}}function o3Q(A){return r3Q.find((Q)=>Q===A)}function s3Q(A,Q){return typeof Q==="string"?Q:A}var tU1={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.109",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 TvA extends QB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",tU1,A??{},jU1)}async onRegister(A){this.pluginContext=A,this.queueManager=mU.createFresh(),this.providerRegistry=uU.createFresh(),this.retryTracker=cU.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=oU1({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),rU1(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await sU1(A.entityService,this.queueManager,this.logger),await aU1(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[g8A(this.pluginContext,this.id,this.queueManager),S8A(this.pluginContext,this.id,this.providerRegistry)]}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).\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}getScheduler(){return this.scheduler}async onShutdown(){await this.scheduler.stop(),mU.resetInstance(),uU.resetInstance(),cU.resetInstance()}}function gvA(A){return new TvA(A)}sA();HA();var eU1=J.object({accountId:J.string().describe("Cloudflare account ID"),apiToken:J.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:J.string().describe("Cloudflare Web Analytics site tag")}),SvA=J.object({cloudflare:eU1.optional()});sA();HA();var t3Q=J.object({date:J.string().describe("Single date in YYYY-MM-DD format").optional(),days:J.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:J.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:J.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:J.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function e3Q(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 AJ1(A,Q,B){let w=[];if(!B)return w;return w.push(uQ(A,"query",`Query website analytics from Cloudflare.
6266
6266
 
6267
6267
  Date range options (use only one):
6268
6268
  - No params: yesterday only
@@ -6400,7 +6400,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,t3Q,
6400
6400
  }
6401
6401
  }
6402
6402
  }
6403
- `,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}))}}HA();var mvA=7,ANQ=10;function BJ1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=uO(),B=sd(mvA),w=QZ(B),$=QZ(Q);try{let[D,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:ANQ})]);return{days:mvA,startDate:w,endDate:$,pageviews:D.pageviews,visitors:D.visitors,topPages:I}}catch(D){return{error:D instanceof Error?D.message:"Failed to fetch analytics",days:mvA}}}}var wJ1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.108",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 $J1 extends QB{cloudflareClient;constructor(A={}){super("analytics",wJ1,A,SvA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new hvA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",BJ1(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:QJ1(Q)}})}async getTools(){return AJ1(this.id,this.getContext(),this.cloudflareClient)}}function BNQ(A={}){return new $J1(A)}var h8A=BNQ;import{randomBytes as XNQ}from"crypto";sA();HA();aw();var wNQ=new Set(["description","excerpt","summary","tagline","story"]);function $NQ(A){if(A.endsWith("s"))return A;return cD(A)}function uvA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return uvA(A._def.innerType,!0,B);if(w==="ZodDefault")return uvA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function cvA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=uvA(Q),D=B._def.typeName,I={name:A,label:wH(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(D){case"ZodString":{if((B._def.checks??[]).some((X)=>X.kind==="datetime"))return{...I,widget:"datetime"};if(wNQ.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 Y=B._def.values;return{...I,widget:"select",options:Y}}case"ZodArray":{let Y=B._def.type,X=cvA("item",Y);if(X.widget==="object"&&X.fields)return{...I,widget:"list",fields:X.fields};return{...I,widget:"list",field:{name:A,label:wH(A),widget:X.widget}}}case"ZodObject":{let Y=B.shape,X=Object.entries(Y).map(([W,H])=>cvA(W,H));return{...I,widget:"object",fields:X}}default:return{...I,widget:"string"}}}function DJ1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>cvA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function IJ1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let D=A.getAdapter(w),I=D?.hasBody!==!1,Y=A.entityDisplay?.[w],X=w===or?"Note":wH(w),W=Y?.label??X,H=Y?.pluralName??$NQ(W);if(D?.isSingleton){B.push({name:w,label:W,file:`${w}/${w}.md`,fields:DJ1($,I)});continue}if(w===or){Q.push({name:w,label:H,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:H,folder:w,create:!0,extension:"md",format:"frontmatter",fields:DJ1($,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 DNQ=new RegExp("[<>&\\u2028\\u2029]","g");function H_(A){return JSON.stringify(A).replace(DNQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var YJ1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function m8A(A){let Q=`<script src="${YJ1}"></script>`;return`<!doctype html>
6403
+ `,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}))}}HA();var mvA=7,ANQ=10;function BJ1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=uO(),B=sd(mvA),w=QZ(B),$=QZ(Q);try{let[D,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:ANQ})]);return{days:mvA,startDate:w,endDate:$,pageviews:D.pageviews,visitors:D.visitors,topPages:I}}catch(D){return{error:D instanceof Error?D.message:"Failed to fetch analytics",days:mvA}}}}var wJ1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.109",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 $J1 extends QB{cloudflareClient;constructor(A={}){super("analytics",wJ1,A,SvA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new hvA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",BJ1(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:QJ1(Q)}})}async getTools(){return AJ1(this.id,this.getContext(),this.cloudflareClient)}}function BNQ(A={}){return new $J1(A)}var h8A=BNQ;import{randomBytes as XNQ}from"crypto";sA();HA();aw();var wNQ=new Set(["description","excerpt","summary","tagline","story"]);function $NQ(A){if(A.endsWith("s"))return A;return cD(A)}function uvA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return uvA(A._def.innerType,!0,B);if(w==="ZodDefault")return uvA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function cvA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=uvA(Q),D=B._def.typeName,I={name:A,label:wH(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(D){case"ZodString":{if((B._def.checks??[]).some((X)=>X.kind==="datetime"))return{...I,widget:"datetime"};if(wNQ.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 Y=B._def.values;return{...I,widget:"select",options:Y}}case"ZodArray":{let Y=B._def.type,X=cvA("item",Y);if(X.widget==="object"&&X.fields)return{...I,widget:"list",fields:X.fields};return{...I,widget:"list",field:{name:A,label:wH(A),widget:X.widget}}}case"ZodObject":{let Y=B.shape,X=Object.entries(Y).map(([W,H])=>cvA(W,H));return{...I,widget:"object",fields:X}}default:return{...I,widget:"string"}}}function DJ1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>cvA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function IJ1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let D=A.getAdapter(w),I=D?.hasBody!==!1,Y=A.entityDisplay?.[w],X=w===or?"Note":wH(w),W=Y?.label??X,H=Y?.pluralName??$NQ(W);if(D?.isSingleton){B.push({name:w,label:W,file:`${w}/${w}.md`,fields:DJ1($,I)});continue}if(w===or){Q.push({name:w,label:H,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:H,folder:w,create:!0,extension:"md",format:"frontmatter",fields:DJ1($,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 DNQ=new RegExp("[<>&\\u2028\\u2029]","g");function H_(A){return JSON.stringify(A).replace(DNQ,(Q)=>`\\u${Q.charCodeAt(0).toString(16).padStart(4,"0")}`)}var YJ1="https://unpkg.com/@sveltia/cms@0.165.1/dist/sveltia-cms.js";function m8A(A){let Q=`<script src="${YJ1}"></script>`;return`<!doctype html>
6404
6404
  <html>
6405
6405
  <head>
6406
6406
  <meta charset="utf-8" />
@@ -6439,7 +6439,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,t3Q,
6439
6439
  showError(error instanceof Error ? error.message : String(error));
6440
6440
  }
6441
6441
  })();
6442
- `}HA();var XJ1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.108",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 lvA="brains_cms_oauth_state",WNQ=600,fNQ="auth",HNQ=J.object({label:J.string().optional(),pluralName:J.string().optional()}).passthrough(),UNQ=J.object({clientId:J.string().optional(),clientSecret:J.string().optional(),scope:J.string().optional()}),JNQ=J.object({contentRepoToken:J.string().optional()}),GNQ=J.object({entityDisplay:J.record(HNQ).optional(),routePath:J.string().default("/cms"),githubOAuth:UNQ.optional(),passkeyLogin:JNQ.optional()}).refine((A)=>{let Q=Boolean(WM(A.githubOAuth?.clientId)&&WM(A.githubOAuth?.clientSecret)),B=Boolean(WM(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function FNQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function WM(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function KNQ(A){let Q=WM(A.githubOAuth?.clientId),B=WM(A.githubOAuth?.clientSecret),w=WM(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:WM(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function ZNQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function NNQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...ZNQ(Q)?{authEndpoint:fNQ}:{}}}async function zNQ(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 qNQ(A,Q={}){let{repo:B,branch:w}=await zNQ(A);return IJ1({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 HJ1(A,Q={}){return BH(await qNQ(A,Q))}class ivA extends QB{constructor(A={}){super("cms",XJ1,A,GNQ)}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=FNQ(this.config.routePath),Q=KNQ(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 fJ1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return op(m8A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return op(m8A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=NNQ(this.config,Q,this.getContext()),D=await HJ1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:np(this.getContext(),w)}:{}});return new Response(D,{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 fJ1(A)?bNQ:CNQ;return op(B(np(this.getContext(),A)))}return ONQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=XNQ(32).toString("base64url"),w=`${np(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":VNQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let W=B.searchParams.get("error_description")??w;return u8A(`GitHub OAuth failed: ${W}`)}let $=B.searchParams.get("state"),D=MNQ(A.headers.get("cookie"),lvA);if(!$||!D||$!==D)return u8A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return u8A("GitHub OAuth callback did not include a code");let Y=`${np(this.getContext(),A)}/auth/callback`,X=await LNQ(Q,I,Y);if(!X.success)return u8A(X.error);return op(RNQ(X.token,np(this.getContext(),A)),200,{"Set-Cookie":JJ1()})}async handleCmsToken(A,Q){if(!await pY()?.getOperatorSession(A))return WJ1({error:"Operator session required"},401);return WJ1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function fM(A){return new ivA(A)}async function LNQ(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}),D;try{D=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:ENQ(D)??"GitHub token exchange failed"};if(pvA(D)&&typeof D.error==="string")return{success:!1,error:typeof D.error_description==="string"?D.error_description:D.error};let I=pvA(D)?D.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 ENQ(A){if(!pvA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function pvA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function np(A,Q){let B=new URL(Q.url).origin;if(UJ1(B))return B;return A.siteUrl??B}function UJ1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function VNQ(A,Q){let B=UJ1(new URL(Q.url).origin)?"":"; Secure";return`${lvA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${WNQ}${B}`}function JJ1(){return`${lvA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function MNQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function op(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function ONQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function WJ1(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 u8A(A){return op(`<!doctype html><html><body><h1>CMS login failed</h1><p>${jNQ(A)}</p></body></html>`,400,{"Set-Cookie":JJ1()})}async function fJ1(A){return Boolean(await pY()?.getOperatorSession(A))}function CNQ(A){return`<!doctype html>
6442
+ `}HA();var XJ1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.109",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 lvA="brains_cms_oauth_state",WNQ=600,fNQ="auth",HNQ=J.object({label:J.string().optional(),pluralName:J.string().optional()}).passthrough(),UNQ=J.object({clientId:J.string().optional(),clientSecret:J.string().optional(),scope:J.string().optional()}),JNQ=J.object({contentRepoToken:J.string().optional()}),GNQ=J.object({entityDisplay:J.record(HNQ).optional(),routePath:J.string().default("/cms"),githubOAuth:UNQ.optional(),passkeyLogin:JNQ.optional()}).refine((A)=>{let Q=Boolean(WM(A.githubOAuth?.clientId)&&WM(A.githubOAuth?.clientSecret)),B=Boolean(WM(A.passkeyLogin?.contentRepoToken));return!(Q&&B)},{message:"CMS login supports a single method per brain: configure githubOAuth or passkeyLogin, not both."});function FNQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function WM(A){if(!A)return;let Q=A.trim();return Q.length>0?Q:void 0}function KNQ(A){let Q=WM(A.githubOAuth?.clientId),B=WM(A.githubOAuth?.clientSecret),w=WM(A.passkeyLogin?.contentRepoToken);return{...Q&&B?{githubOAuth:{clientId:Q,clientSecret:B,scope:WM(A.githubOAuth?.scope)??"repo"}}:{},...w?{passkeyLogin:{contentRepoToken:w}}:{}}}function ZNQ(A){return Boolean(A.githubOAuth??A.passkeyLogin)}function NNQ(A,Q,B){let w=A.entityDisplay??B?.entityDisplay;return{...w?{entityDisplay:w}:{},...ZNQ(Q)?{authEndpoint:fNQ}:{}}}async function zNQ(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 qNQ(A,Q={}){let{repo:B,branch:w}=await zNQ(A);return IJ1({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 HJ1(A,Q={}){return BH(await qNQ(A,Q))}class ivA extends QB{constructor(A={}){super("cms",XJ1,A,GNQ)}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=FNQ(this.config.routePath),Q=KNQ(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 fJ1(w))return new Response(null,{status:302,headers:{Location:`/login?return_to=${encodeURIComponent(this.config.routePath)}`,"Cache-Control":"no-store"}});return op(m8A({cmsConfigPath:A,authTokenEndpoint:"/auth/cms-token"}))}return op(m8A({cmsConfigPath:A}))}},{path:A,method:"GET",public:!0,handler:async(w)=>{try{let $=NNQ(this.config,Q,this.getContext()),D=await HJ1(this.getContext(),{...$,...$.authEndpoint?{baseUrl:np(this.getContext(),w)}:{}});return new Response(D,{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 fJ1(A)?bNQ:CNQ;return op(B(np(this.getContext(),A)))}return ONQ("CMS login is not enabled",404)}redirectToGitHub(A,Q){let B=XNQ(32).toString("base64url"),w=`${np(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":VNQ(B,A),"Cache-Control":"no-store"}})}async handleGitHubCallback(A,Q){let B=new URL(A.url),w=B.searchParams.get("error");if(w){let W=B.searchParams.get("error_description")??w;return u8A(`GitHub OAuth failed: ${W}`)}let $=B.searchParams.get("state"),D=MNQ(A.headers.get("cookie"),lvA);if(!$||!D||$!==D)return u8A("GitHub OAuth state did not match");let I=B.searchParams.get("code");if(!I)return u8A("GitHub OAuth callback did not include a code");let Y=`${np(this.getContext(),A)}/auth/callback`,X=await LNQ(Q,I,Y);if(!X.success)return u8A(X.error);return op(RNQ(X.token,np(this.getContext(),A)),200,{"Set-Cookie":JJ1()})}async handleCmsToken(A,Q){if(!await pY()?.getOperatorSession(A))return WJ1({error:"Operator session required"},401);return WJ1({token:Q.contentRepoToken,provider:"github"},200,{"Cache-Control":"no-store"})}}function fM(A){return new ivA(A)}async function LNQ(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}),D;try{D=await $.json()}catch{return{success:!1,error:"GitHub token response was not JSON"}}if(!$.ok)return{success:!1,error:ENQ(D)??"GitHub token exchange failed"};if(pvA(D)&&typeof D.error==="string")return{success:!1,error:typeof D.error_description==="string"?D.error_description:D.error};let I=pvA(D)?D.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 ENQ(A){if(!pvA(A))return;if(typeof A.error_description==="string")return A.error_description;return typeof A.error==="string"?A.error:void 0}function pvA(A){return Boolean(A&&typeof A==="object"&&!Array.isArray(A))}function np(A,Q){let B=new URL(Q.url).origin;if(UJ1(B))return B;return A.siteUrl??B}function UJ1(A){let{hostname:Q}=new URL(A);return Q==="localhost"||Q==="127.0.0.1"||Q==="::1"||Q==="[::1]"}function VNQ(A,Q){let B=UJ1(new URL(Q.url).origin)?"":"; Secure";return`${lvA}=${A}; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=${WNQ}${B}`}function JJ1(){return`${lvA}=; Path=/auth; HttpOnly; SameSite=Lax; Max-Age=0`}function MNQ(A,Q){if(!A)return;for(let B of A.split(";")){let[w,...$]=B.trim().split("=");if(w===Q)return $.join("=")}return}function op(A,Q=200,B={}){return new Response(A,{status:Q,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store",...B}})}function ONQ(A,Q=200){return new Response(A,{status:Q,headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}})}function WJ1(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 u8A(A){return op(`<!doctype html><html><body><h1>CMS login failed</h1><p>${jNQ(A)}</p></body></html>`,400,{"Set-Cookie":JJ1()})}async function fJ1(A){return Boolean(await pY()?.getOperatorSession(A))}function CNQ(A){return`<!doctype html>
6443
6443
  <html lang="en">
6444
6444
  <head>
6445
6445
  <meta charset="utf-8" />
@@ -7844,7 +7844,7 @@ ${FJ1}`;import{jsxDEV as Ef,Fragment as NJ1}from"preact/jsx-dev-runtime";functio
7844
7844
  }
7845
7845
  });
7846
7846
  })();`;function UzQ({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=WzQ(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,D=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,Y=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,X=new Date;return DB("html",{lang:"en","data-theme":"dark",children:[DB("head",{children:[DB("meta",{charSet:"utf-8"},void 0,!1,void 0,this),DB("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),DB("title",{children:A.title},void 0,!1,void 0,this),DB("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),DB("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),DB("link",{href:XzQ,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&DB("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),DB("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:ZJ1}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),DB("body",{children:[DB("main",{class:"console","data-component":"dashboard:dashboard",children:[DB(zJ1,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),DB("section",{class:I,children:[$&&DB("div",{class:"identity-column",children:[DB(LJ1,{character:A.character},void 0,!1,void 0,this),DB(ovA,{interactions:D,baseUrl:A.baseUrl},void 0,!1,void 0,this),Y&&A.operatorAccess&&DB(RJ1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),DB("div",{class:"main-column",children:[DB(qJ1,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&Y&&A.operatorAccess&&DB(RJ1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((W)=>DB(i8A,{widget:W},`${W.widget.pluginId}:${W.widget.id}`,!1,void 0,this)),w.secondary.map((W)=>DB(i8A,{widget:W},`${W.widget.pluginId}:${W.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),DB("div",{class:"sidebar-column",children:[!$&&DB(ovA,{interactions:D,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((W)=>DB(i8A,{widget:W},`${W.widget.pluginId}:${W.widget.id}`,!1,void 0,this)),DB(EJ1,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),DB(CJ1,{appInfo:A.appInfo,now:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),DB(bJ1,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),DB("script",{dangerouslySetInnerHTML:{__html:fzQ}},void 0,!1,void 0,this),DB("script",{dangerouslySetInnerHTML:{__html:HzQ}},void 0,!1,void 0,this),A.widgetScripts.map((W,H)=>DB("script",{dangerouslySetInnerHTML:{__html:W}},`widget-script:${H}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function PJ1(A){return`<!doctype html>
7847
- ${YzQ(DB(UzQ,{input:A},void 0,!1,void 0,this))}`}function kJ1(A,Q){let B={},w=new Set;for(let[$,D]of Object.entries(A)){let I=Q?.get(D.widget.pluginId,D.widget.id);if(B[$]={...D,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var jJ1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.108",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 GzQ=J.object({version:J.string().default("1.0.0"),routePath:J.string().default("/dashboard"),themeCSS:J.string().optional()}),FzQ=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number().default(50),section:J.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:J.string(),visibility:g7.default("public"),component:J.custom().optional(),clientScript:J.string().optional(),dataProvider:J.function().returns(J.promise(J.unknown()))}).superRefine((A,Q)=>{if(!nvA(A.rendererName)&&!A.component)Q.addIssue({code:J.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),KzQ=J.object({pluginId:J.string(),widgetId:J.string().optional()});function ZzQ(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 avA extends QB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",jJ1,A??{},GzQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new p8A(this.logger),this.datasource=new l8A(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=FzQ.parse(Q.payload),w=ZzQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:c8A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:x0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=KzQ.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 pY()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",D=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=D.filter((m)=>Q9.hasPermission($,m.visibility)),Y=D.length-I.length,[X,W]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),H=Q.identity.get(),F=Q.identity.getProfile(),K=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...W,endpoints:W.endpoints.filter((m)=>Q9.hasPermission($,m.visibility)),interactions:W.interactions.filter((m)=>Q9.hasPermission($,m.visibility))},q=F.name||W.model||"Brain Dashboard",L=new URL(A.url),E=`${L.pathname}${L.search}`,R=encodeURIComponent(E),j=kJ1(X.widgets,this.widgetRegistry),C={title:q,baseUrl:K,widgets:j.widgets,widgetScripts:j.widgetScripts,character:H,profile:F,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:Y,loginUrl:`/login?return_to=${R}`,logoutUrl:`/logout?return_to=${R}`}};return new Response(PJ1(C),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function dN(A){return new avA(A)}sA();HA();var NzQ=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number(),section:J.enum(["primary","secondary","sidebar"]),rendererName:J.string(),visibility:g7,component:J.custom().optional()}),zzQ=J.object({widget:NzQ,data:J.unknown()}),qzQ=J.object({widgets:J.record(zzQ)});HA();sA();HA();import{h as xzQ}from"preact";HA();LY();sA();var U_=J.enum(["generating","draft","queued","published","failed"]),ap=J.object({subject:J.string(),status:U_,entityIds:J.array(J.string()).optional(),scheduledFor:J.string().datetime().optional(),sentAt:J.string().datetime().optional(),buttondownId:J.string().optional(),sourceEntityType:J.string().optional()}),_J1=ap.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:J.string().optional()}),tp=e1.extend({entityType:J.literal("newsletter"),metadata:_J1});sA();class yJ1 extends N2{constructor(){super({entityType:"newsletter",schema:tp,frontmatterSchema:ap})}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 xJ1=new yJ1;sA();sA();HA();var LzQ=GH.extend({status:J.enum(["generating","draft","queued","published","failed"]).optional()}),EzQ=FH.extend({query:LzQ.optional()});function vJ1(A){try{let{content:Q}=O2(A.content,ap);return Q}catch{return A.content}}class tvA extends L5{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=EzQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=vJ1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:u9(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 D=w.status,I=D?{filter:{metadata:{status:D}}}:void 0,{items:Y,pagination:X}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(Y,X,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),D=[];if(w.metadata.entityIds?.length){let X=w.metadata.sourceEntityType??"post";D=(await Promise.all(w.metadata.entityIds.map(async(H)=>{let F=await B.getEntity({entityType:X,id:H});if(F){let K=F.metadata;return{id:H,title:K.title??H,url:`/${X}s/${K.slug??H}`}}return null}))).filter((H)=>H!==null)}let I=vJ1(w),Y={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:D.length>0?D:void 0};return Q.parse(Y)}}sA();HA();var VzQ=J.object({prompt:J.string().optional().describe("AI generation prompt"),sourceEntityIds:J.array(J.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:J.enum(["post"]).optional().describe("Type of source entities"),content:J.string().optional().describe("Direct content (skip AI)"),subject:J.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:J.boolean().optional().describe("Create as queued (true) or draft (false)")});class evA extends r9{constructor(A,Q){super(A,Q,{schema:VzQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:D}=A,{content:I,subject:Y}=A;if(I){if(!Y)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let K=D??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let q=(await Promise.all($.map((C)=>this.context.entityService.getEntity({entityType:K,id:C})))).filter((C)=>C!=null);if(q.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${q.length} posts`});let E=`Create an engaging newsletter that highlights these blog posts:
7847
+ ${YzQ(DB(UzQ,{input:A},void 0,!1,void 0,this))}`}function kJ1(A,Q){let B={},w=new Set;for(let[$,D]of Object.entries(A)){let I=Q?.get(D.widget.pluginId,D.widget.id);if(B[$]={...D,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var jJ1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.109",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 GzQ=J.object({version:J.string().default("1.0.0"),routePath:J.string().default("/dashboard"),themeCSS:J.string().optional()}),FzQ=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number().default(50),section:J.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:J.string(),visibility:g7.default("public"),component:J.custom().optional(),clientScript:J.string().optional(),dataProvider:J.function().returns(J.promise(J.unknown()))}).superRefine((A,Q)=>{if(!nvA(A.rendererName)&&!A.component)Q.addIssue({code:J.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),KzQ=J.object({pluginId:J.string(),widgetId:J.string().optional()});function ZzQ(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 avA extends QB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",jJ1,A??{},GzQ)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new p8A(this.logger),this.datasource=new l8A(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=FzQ.parse(Q.payload),w=ZzQ(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:c8A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:x0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=KzQ.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 pY()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",D=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=D.filter((m)=>Q9.hasPermission($,m.visibility)),Y=D.length-I.length,[X,W]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),H=Q.identity.get(),F=Q.identity.getProfile(),K=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...W,endpoints:W.endpoints.filter((m)=>Q9.hasPermission($,m.visibility)),interactions:W.interactions.filter((m)=>Q9.hasPermission($,m.visibility))},q=F.name||W.model||"Brain Dashboard",L=new URL(A.url),E=`${L.pathname}${L.search}`,R=encodeURIComponent(E),j=kJ1(X.widgets,this.widgetRegistry),C={title:q,baseUrl:K,widgets:j.widgets,widgetScripts:j.widgetScripts,character:H,profile:F,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:Y,loginUrl:`/login?return_to=${R}`,logoutUrl:`/logout?return_to=${R}`}};return new Response(PJ1(C),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function dN(A){return new avA(A)}sA();HA();var NzQ=J.object({id:J.string(),pluginId:J.string(),title:J.string(),description:J.string().optional(),priority:J.number(),section:J.enum(["primary","secondary","sidebar"]),rendererName:J.string(),visibility:g7,component:J.custom().optional()}),zzQ=J.object({widget:NzQ,data:J.unknown()}),qzQ=J.object({widgets:J.record(zzQ)});HA();sA();HA();import{h as xzQ}from"preact";HA();LY();sA();var U_=J.enum(["generating","draft","queued","published","failed"]),ap=J.object({subject:J.string(),status:U_,entityIds:J.array(J.string()).optional(),scheduledFor:J.string().datetime().optional(),sentAt:J.string().datetime().optional(),buttondownId:J.string().optional(),sourceEntityType:J.string().optional()}),_J1=ap.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}).extend({error:J.string().optional()}),tp=e1.extend({entityType:J.literal("newsletter"),metadata:_J1});sA();class yJ1 extends N2{constructor(){super({entityType:"newsletter",schema:tp,frontmatterSchema:ap})}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 xJ1=new yJ1;sA();sA();HA();var LzQ=GH.extend({status:J.enum(["generating","draft","queued","published","failed"]).optional()}),EzQ=FH.extend({query:LzQ.optional()});function vJ1(A){try{let{content:Q}=O2(A.content,ap);return Q}catch{return A.content}}class tvA extends L5{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=EzQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=vJ1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:u9(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 D=w.status,I=D?{filter:{metadata:{status:D}}}:void 0,{items:Y,pagination:X}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(Y,X,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),D=[];if(w.metadata.entityIds?.length){let X=w.metadata.sourceEntityType??"post";D=(await Promise.all(w.metadata.entityIds.map(async(H)=>{let F=await B.getEntity({entityType:X,id:H});if(F){let K=F.metadata;return{id:H,title:K.title??H,url:`/${X}s/${K.slug??H}`}}return null}))).filter((H)=>H!==null)}let I=vJ1(w),Y={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:D.length>0?D:void 0};return Q.parse(Y)}}sA();HA();var VzQ=J.object({prompt:J.string().optional().describe("AI generation prompt"),sourceEntityIds:J.array(J.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:J.enum(["post"]).optional().describe("Type of source entities"),content:J.string().optional().describe("Direct content (skip AI)"),subject:J.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:J.boolean().optional().describe("Create as queued (true) or draft (false)")});class evA extends r9{constructor(A,Q){super(A,Q,{schema:VzQ,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:D}=A,{content:I,subject:Y}=A;if(I){if(!Y)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let K=D??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let q=(await Promise.all($.map((C)=>this.context.entityService.getEntity({entityType:K,id:C})))).filter((C)=>C!=null);if(q.length===0)this.failEarly(`No source entities found for IDs: ${$.join(", ")}`);await this.reportProgress(Q,{progress:30,message:`Generating newsletter from ${q.length} posts`});let E=`Create an engaging newsletter that highlights these blog posts:
7848
7848
 
7849
7849
  ${q.map((C)=>`## ${C.metadata.title}
7850
7850
 
@@ -7913,14 +7913,14 @@ Newsletter-specific guidelines:
7913
7913
  - "Reply and let me know..."
7914
7914
  - "Until next time..."
7915
7915
 
7916
- The goal is to build a relationship with readers through valuable, authentic content.`});HA();sA();import{jsxDEV as Z4,Fragment as RzQ}from"preact/jsx-dev-runtime";var OzQ=J.object({id:J.string(),subject:J.string(),status:U_,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),CzQ=J.object({newsletters:J.array(OzQ),totalCount:J.number(),pagination:i9.nullable()}),bzQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let D=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return Z4(RzQ,{children:[Z4(fQ,{title:D,description:I},void 0,!1,void 0,this),Z4("div",{className:"newsletter-list bg-theme",children:Z4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[Z4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:D},void 0,!1,void 0,this),A.length===0?Z4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):Z4("div",{className:"space-y-4",children:A.map((Y)=>Z4(qB,{href:Y.url,children:[Z4(u$,{className:"text-lg",children:Y.subject},void 0,!1,void 0,this),Z4(Z9,{children:Z4("div",{className:"flex items-center gap-3",children:[Z4(HD,{status:Y.status},void 0,!1,void 0,this),Z4("span",{className:"text-sm text-theme-muted",children:R6(Y.sentAt??Y.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y.excerpt&&Z4("p",{className:"text-theme-muted line-clamp-2",children:Y.excerpt},void 0,!1,void 0,this)]},Y.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&Z4(bF,{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)},gJ1=R1({name:"newsletter-list",description:"Newsletter list page template",schema:CzQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:bzQ}});HA();sA();import{jsxDEV as X8,Fragment as _zQ}from"preact/jsx-dev-runtime";var PzQ=J.object({id:J.string(),title:J.string(),url:J.string()}),SJ1=J.object({id:J.string(),subject:J.string(),url:J.string()}),kzQ=J.object({id:J.string(),subject:J.string(),status:U_,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(PzQ).optional(),prevNewsletter:SJ1.nullable().optional(),nextNewsletter:SJ1.nullable().optional()}),jzQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:D,sourceEntities:I,prevNewsletter:Y,nextNewsletter:X})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],H=$??w,F=$?"Sent":"Created";return X8(_zQ,{children:[X8(fQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),X8("section",{className:"newsletter-detail-section",children:X8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:X8("div",{className:"max-w-3xl mx-auto",children:[X8(VU,{items:W},void 0,!1,void 0,this),X8("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),X8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[X8(HD,{status:Q},void 0,!1,void 0,this),X8("span",{children:[F,": ",R6(H,{style:"long"})]},void 0,!0,void 0,this),D&&Q==="queued"&&X8("span",{children:["Scheduled for: ",R6(D,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&X8(qB,{variant:"compact",className:"mb-8",children:[X8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),X8("ul",{className:"space-y-1",children:I.map((K)=>X8("li",{children:X8("a",{href:K.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:K.title},void 0,!1,void 0,this)},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X8(B$,{markdown:B},void 0,!1,void 0,this),(Y??X)&&X8("nav",{className:"mt-12 pt-8 border-t border-theme",children:X8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Y?X8(qB,{href:Y.url,variant:"compact",children:[X8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),X8("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):X8("div",{},void 0,!1,void 0,this),X&&X8(qB,{href:X.url,variant:"compact",className:"md:text-right",children:[X8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),X8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.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)},hJ1=R1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:kzQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:jzQ}});var mJ1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.108",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 vzQ=J.object({});class ATA extends MQ{entityType="newsletter";schema=tp;adapter=xJ1;constructor(A={}){super("newsletter",mJ1,A,vzQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new evA(this.logger,A)}getTemplates(){return{generation:TJ1,"newsletter-list":gJ1,"newsletter-detail":hJ1}}getDataSources(){return[new tvA(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(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:()=>xzQ(qjA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}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:"newsletter",provider:Q}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w,authContext:$}=Q.payload;if(B!=="newsletter")return{success:!0};try{A.permissions.assertEntityActionAllowed(B,"publish",$??{userPermissionLevel:"anchor"});let D=await A.entityService.getEntity({entityType:"newsletter",id:w});if(!D)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Newsletter not found: ${w}`}}),{success:!0};if(D.metadata.status==="published")return{success:!0};let I=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:D.metadata.subject,content:D.content}}),Y=new Date().toISOString(),X=!("noop"in I)&&I.data?I.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...D,metadata:{...D.metadata,status:"published",sentAt:Y,buttondownId:X}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,sentAt:Y}}),this.logger.info(`Published newsletter: ${w}`),{success:!0}}catch(D){let I=x0(D);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:I}}),{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:x0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=J.object({prompt:J.string().optional(),content:J.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
7916
+ The goal is to build a relationship with readers through valuable, authentic content.`});HA();sA();import{jsxDEV as Z4,Fragment as RzQ}from"preact/jsx-dev-runtime";var OzQ=J.object({id:J.string(),subject:J.string(),status:U_,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),CzQ=J.object({newsletters:J.array(OzQ),totalCount:J.number(),pagination:i9.nullable()}),bzQ=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let D=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return Z4(RzQ,{children:[Z4(fQ,{title:D,description:I},void 0,!1,void 0,this),Z4("div",{className:"newsletter-list bg-theme",children:Z4("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[Z4("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:D},void 0,!1,void 0,this),A.length===0?Z4("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):Z4("div",{className:"space-y-4",children:A.map((Y)=>Z4(qB,{href:Y.url,children:[Z4(u$,{className:"text-lg",children:Y.subject},void 0,!1,void 0,this),Z4(Z9,{children:Z4("div",{className:"flex items-center gap-3",children:[Z4(HD,{status:Y.status},void 0,!1,void 0,this),Z4("span",{className:"text-sm text-theme-muted",children:R6(Y.sentAt??Y.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y.excerpt&&Z4("p",{className:"text-theme-muted line-clamp-2",children:Y.excerpt},void 0,!1,void 0,this)]},Y.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&Z4(bF,{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)},gJ1=R1({name:"newsletter-list",description:"Newsletter list page template",schema:CzQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:bzQ}});HA();sA();import{jsxDEV as X8,Fragment as _zQ}from"preact/jsx-dev-runtime";var PzQ=J.object({id:J.string(),title:J.string(),url:J.string()}),SJ1=J.object({id:J.string(),subject:J.string(),url:J.string()}),kzQ=J.object({id:J.string(),subject:J.string(),status:U_,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(PzQ).optional(),prevNewsletter:SJ1.nullable().optional(),nextNewsletter:SJ1.nullable().optional()}),jzQ=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:D,sourceEntities:I,prevNewsletter:Y,nextNewsletter:X})=>{let W=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],H=$??w,F=$?"Sent":"Created";return X8(_zQ,{children:[X8(fQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),X8("section",{className:"newsletter-detail-section",children:X8("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:X8("div",{className:"max-w-3xl mx-auto",children:[X8(VU,{items:W},void 0,!1,void 0,this),X8("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),X8("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[X8(HD,{status:Q},void 0,!1,void 0,this),X8("span",{children:[F,": ",R6(H,{style:"long"})]},void 0,!0,void 0,this),D&&Q==="queued"&&X8("span",{children:["Scheduled for: ",R6(D,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&X8(qB,{variant:"compact",className:"mb-8",children:[X8("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),X8("ul",{className:"space-y-1",children:I.map((K)=>X8("li",{children:X8("a",{href:K.url,className:"text-sm text-brand hover:text-brand-dark transition-colors",children:K.title},void 0,!1,void 0,this)},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X8(B$,{markdown:B},void 0,!1,void 0,this),(Y??X)&&X8("nav",{className:"mt-12 pt-8 border-t border-theme",children:X8("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[Y?X8(qB,{href:Y.url,variant:"compact",children:[X8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),X8("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):X8("div",{},void 0,!1,void 0,this),X&&X8(qB,{href:X.url,variant:"compact",className:"md:text-right",children:[X8("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),X8("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:X.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)},hJ1=R1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:kzQ,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:jzQ}});var mJ1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.109",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 vzQ=J.object({});class ATA extends MQ{entityType="newsletter";schema=tp;adapter=xJ1;constructor(A={}){super("newsletter",mJ1,A,vzQ)}getEntityTypeConfig(){return{publish:{publishStatuses:["queued","published","failed"]}}}createGenerationHandler(A){return new evA(this.logger,A)}getTemplates(){return{generation:TJ1,"newsletter-list":gJ1,"newsletter-detail":hJ1}}getDataSources(){return[new tvA(this.logger.child("NewsletterDataSource"))]}async onRegister(A){this.deferPublishRegistration(A),this.subscribeToPublishExecute(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:()=>xzQ(qjA,{variant:"inline"})}});return{success:!0}}),this.logger.debug("Newsletter plugin registered")}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:"newsletter",provider:Q}}),{success:!0}})}subscribeToPublishExecute(A){A.messaging.subscribe("publish:execute",async(Q)=>{let{entityType:B,entityId:w,authContext:$}=Q.payload;if(B!=="newsletter")return{success:!0};try{A.permissions.assertEntityActionAllowed(B,"publish",$??{userPermissionLevel:"anchor"});let D=await A.entityService.getEntity({entityType:"newsletter",id:w});if(!D)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Newsletter not found: ${w}`}}),{success:!0};if(D.metadata.status==="published")return{success:!0};let I=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:D.metadata.subject,content:D.content}}),Y=new Date().toISOString(),X=!("noop"in I)&&I.data?I.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...D,metadata:{...D.metadata,status:"published",sentAt:Y,buttondownId:X}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,sentAt:Y}}),this.logger.info(`Published newsletter: ${w}`),{success:!0}}catch(D){let I=x0(D);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:I}}),{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:x0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=J.object({prompt:J.string().optional(),content:J.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
7917
7917
 
7918
- ${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function QTA(A={}){return new ATA(A)}sA();HA();class J_{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(()=>({})),D=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:D}),Error(`Buttondown API error: ${D}`)}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}}}sA();HA();var TzQ=J.object({email:J.string().email().describe("Email address to subscribe"),name:J.string().optional().describe("Subscriber name (optional)"),tags:J.array(J.string()).optional().describe("Tags to apply to subscriber (optional)")}),gzQ=J.object({email:J.string().email().describe("Email address to unsubscribe")}),SzQ=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function uJ1(A,Q,B){let w=new J_(Q,B);return[uQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",TzQ,async($)=>{try{let D=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=D.subscriber_type==="already_subscribed";return K8({subscriberId:D.id,email:D.email,status:D.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(D){return i5(x0(D))}}),uQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",gzQ,async($)=>{try{return await w.unsubscribe($.email),K8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(D){return i5(x0(D))}}),uQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",SzQ,async($)=>{try{let D=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return K8({subscribers:D.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:D.count},`Found ${D.count} subscribers`)}catch(D){return i5(x0(D))}})]}HA();async function cJ1(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 D=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:D.id}),{success:!0,emailId:D.id}}catch(D){let I=x0(D);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var pJ1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.108",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 mzQ=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class BTA extends QB{constructor(A={}){super("buttondown",pJ1,A,mzQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new J_({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:x0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await cJ1(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 uJ1(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 wTA(A={}){return new BTA(A)}var uzQ=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function lJ1(A={}){let Q=uzQ.parse(A);return[QTA({}),wTA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}sA();HA();import{existsSync as ezQ,mkdirSync as AqQ,writeFileSync as QqQ}from"fs";import{join as nF}from"path";HA();var $TA=J.object({baseFolder:J.string().default("_obsidian")});HA();function czQ(A){let Q=A,B=!0,w=void 0,$=!1,D=!0;while(D){if(D=!1,Q instanceof J.ZodOptional)B=!1,Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodNullable)B=!1,Q=Q._def.innerType,D=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function pzQ(A){if(A instanceof J.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof J.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof J.ZodString)return{type:"string"};if(A instanceof J.ZodNumber)return{type:"number"};if(A instanceof J.ZodBoolean)return{type:"boolean"};if(A instanceof J.ZodArray)return{type:"array"};if(A instanceof J.ZodDate)return{type:"date"};if(A instanceof J.ZodPipeline){if(A._def.out instanceof J.ZodDate)return{type:"date"}}return{type:"unknown"}}function iJ1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:D,required:I,defaultValue:Y}=czQ($),X=pzQ(D),W={name:w,type:X.type,required:I},H=Y!==void 0?Y:X.defaultValue;if(H!==void 0)W.defaultValue=H;if(X.enumValues)W.enumValues=X.enumValues;B.push(W)}return B}function lzQ(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 dJ1(A,Q,B=""){let w=["---"];for(let $ of Q){let D=lzQ($,A);if(D==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${D}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
7918
+ ${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function QTA(A={}){return new ATA(A)}sA();HA();class J_{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(()=>({})),D=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:D}),Error(`Buttondown API error: ${D}`)}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}}}sA();HA();var TzQ=J.object({email:J.string().email().describe("Email address to subscribe"),name:J.string().optional().describe("Subscriber name (optional)"),tags:J.array(J.string()).optional().describe("Tags to apply to subscriber (optional)")}),gzQ=J.object({email:J.string().email().describe("Email address to unsubscribe")}),SzQ=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function uJ1(A,Q,B){let w=new J_(Q,B);return[uQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",TzQ,async($)=>{try{let D=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=D.subscriber_type==="already_subscribed";return K8({subscriberId:D.id,email:D.email,status:D.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(D){return i5(x0(D))}}),uQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",gzQ,async($)=>{try{return await w.unsubscribe($.email),K8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(D){return i5(x0(D))}}),uQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",SzQ,async($)=>{try{let D=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return K8({subscribers:D.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:D.count},`Found ${D.count} subscribers`)}catch(D){return i5(x0(D))}})]}HA();async function cJ1(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 D=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:D.id}),{success:!0,emailId:D.id}}catch(D){let I=x0(D);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var pJ1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.109",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 mzQ=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class BTA extends QB{constructor(A={}){super("buttondown",pJ1,A,mzQ)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new J_({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:x0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await cJ1(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 uJ1(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 wTA(A={}){return new BTA(A)}var uzQ=J.object({apiKey:J.string().optional().describe("Buttondown API key"),doubleOptIn:J.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:J.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function lJ1(A={}){let Q=uzQ.parse(A);return[QTA({}),wTA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}sA();HA();import{existsSync as ezQ,mkdirSync as AqQ,writeFileSync as QqQ}from"fs";import{join as nF}from"path";HA();var $TA=J.object({baseFolder:J.string().default("_obsidian")});HA();function czQ(A){let Q=A,B=!0,w=void 0,$=!1,D=!0;while(D){if(D=!1,Q instanceof J.ZodOptional)B=!1,Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,D=!0;if(Q instanceof J.ZodNullable)B=!1,Q=Q._def.innerType,D=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function pzQ(A){if(A instanceof J.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof J.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof J.ZodString)return{type:"string"};if(A instanceof J.ZodNumber)return{type:"number"};if(A instanceof J.ZodBoolean)return{type:"boolean"};if(A instanceof J.ZodArray)return{type:"array"};if(A instanceof J.ZodDate)return{type:"date"};if(A instanceof J.ZodPipeline){if(A._def.out instanceof J.ZodDate)return{type:"date"}}return{type:"unknown"}}function iJ1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:D,required:I,defaultValue:Y}=czQ($),X=pzQ(D),W={name:w,type:X.type,required:I},H=Y!==void 0?Y:X.defaultValue;if(H!==void 0)W.defaultValue=H;if(X.enumValues)W.enumValues=X.enumValues;B.push(W)}return B}function lzQ(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 dJ1(A,Q,B=""){let w=["---"];for(let $ of Q){let D=lzQ($,A);if(D==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${D}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
7919
7919
  `)}HA();var izQ={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function dzQ(A){let Q={name:A.name,id:A.name,type:izQ[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function rJ1(A,Q){let B={filesPaths:A,fields:Q.map(dzQ)};return`---
7920
7920
  ${BH(B)}---
7921
- `}HA();var rzQ=new Set(["entityType"]),nzQ={base:"Notes"},ozQ=new Set(["base"]);function szQ(A){let Q=["file.name"];for(let B of A)if(!rzQ.has(B.name))Q.push(B.name);return Q}function azQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function nJ1(A,Q){let B=nzQ[A]??nd(A),w=azQ(Q),$=szQ(Q),D=[{type:"table",name:`All ${B}`,order:$}];if(w)D.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let Y={filters:{and:[ozQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:D};return{filename:`${B}.base`,content:BH(Y),hasStatus:w}}function oJ1(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 BH(B)}function sJ1(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 BH(B)}var aJ1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.108",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 BqQ={mkdir:AqQ,writeFile:QqQ,existsFile:ezQ},wqQ=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class DTA extends QB{deps;constructor(A={},Q={}){super("obsidian-vault",aJ1,A,$TA);this.deps={...BqQ,...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[uQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",wqQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((E)=>Q.includes(E)):B,$=nF(A.dataDir,this.config.baseFolder),D=nF($,"templates"),I=nF($,"fileClasses"),Y=nF($,"bases");this.deps.mkdir(D,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0});let X=[],W=[],H=[],F=[],K=[],Z=[];for(let E of w){let R=A.entities.getEffectiveFrontmatterSchema(E);if(!R){this.logger.debug(`Skipping ${E}: no frontmatter schema`),W.push(E);continue}let j=iJ1(R),C=A.entities.getAdapter(E),m=C?.isSingleton===!0,i=rJ1(E,j);if(this.deps.writeFile(nF(I,`${E}.md`),i),H.push(E),m){K.push(E),this.logger.debug(`Generated fileClass (singleton): ${E}`);continue}let g=C?.getBodyTemplate()??"",x=dJ1(E,j,g);this.deps.writeFile(nF(D,`${E}.md`),x),X.push(E);let T=nJ1(E,j),S=nF(Y,T.filename);if(!this.deps.existsFile(S))this.deps.writeFile(S,T.content),F.push(E),this.logger.debug(`Generated base: ${T.filename}`);if(T.hasStatus)Z.push({entityType:E,fields:j});this.logger.debug(`Generated template + fileClass: ${E}`)}let q=oJ1(K);if(q){let E=nF(Y,"Settings.base");if(!this.deps.existsFile(E))this.deps.writeFile(E,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let L=sJ1(Z);if(L){let E=nF(Y,"Pipeline.base");if(!this.deps.existsFile(E))this.deps.writeFile(E,L),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${X.length} templates, ${H.length} fileClasses, ${F.length} bases (${W.length} skipped)`),K8({generated:X,skipped:W,fileClasses:H,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),i5(B instanceof Error?B.message:"Unknown error")}}}function ITA(A,Q){return new DTA(A,Q)}sA();HA();sA();var YTA=J.enum(["new","planned","in-progress","done","declined"]),XTA=J.enum(["low","medium","high","critical"]),ep=J.object({title:J.string(),status:YTA,priority:XTA.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),tJ1=J.object({title:J.string(),status:YTA,priority:XTA,requested:J.number().int(),slug:J.string()}),Al=e1.extend({entityType:J.literal("wish"),metadata:tJ1}),WTA=J.object({});sA();HA();class Ql extends N2{constructor(){super({entityType:"wish",schema:Al,frontmatterSchema:ep})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,ep);return{frontmatter:ep.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=b1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var fTA=new Ql;HA();HA();async function eJ1(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 D=b1(Q.title);return A.getEntity({entityType:"wish",id:D})}class d8A{logger;context;adapter=new Ql;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??"",D=await eJ1({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:w,description:$});if(D){let{frontmatter:W,description:H}=this.adapter.parseWishContent(D.content),F=W.requested+1,K=this.adapter.createWishContent({...W,requested:F},H);return await this.context.entityService.updateEntity({entity:{...D,content:K,metadata:{...D.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:D.id,requested:F}),{success:!0,entityId:D.id,existed:!0,requested:F}}let I=b1(w),Y=A.options?.priority??"medium",X=this.adapter.createWishContent({title:w,status:"new",priority:Y,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:X,metadata:{title:w,status:"new",priority:Y,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var AG1={critical:0,high:1,medium:2,low:3};function QG1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return AG1[Q.metadata.priority]-AG1[B.metadata.priority]})}var BG1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.108",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 wG1 extends MQ{entityType=fTA.entityType;schema=Al;adapter=fTA;constructor(A={}){super("wishlist",BG1,A,WTA)}async interceptCreate(A,Q,B){let w=await new d8A(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 QG1(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 d8A(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 DqQ(A={}){return new wG1(A)}var r8A=DqQ;sA();HA();sA();var Bl=J.object({title:J.string(),target:J.string()}),$G1=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),wl=e1.extend({entityType:J.literal("prompt"),metadata:$G1});sA();HA();class HTA extends N2{constructor(){super({entityType:"prompt",schema:wl,frontmatterSchema:Bl})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Bl);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Bl),B=b1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var n8A=new HTA;var DG1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.108",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 UTA extends MQ{entityType=n8A.entityType;schema=wl;adapter=n8A;constructor(){super("prompt",DG1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function HM(){return new UTA}sA();HA();class o8A{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(YqQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function YqQ(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}}HA();d7();var IG1={query:J.string().describe("Search terms for stock photos"),perPage:J.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:J.number().min(1).default(1).describe("Page number")},YG1={photoId:J.string().describe("Photo ID from search results"),downloadLocation:J.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:J.string().describe("Photographer name for attribution"),photographerUrl:J.string().url().describe("Photographer profile URL for attribution"),sourceUrl:J.string().url().describe("Photo page URL on provider"),imageUrl:J.string().url().describe("Image URL to download"),title:J.string().optional().describe("Image entity title"),alt:J.string().optional().describe("Alt text for the image"),targetEntityType:J.string().optional().describe("Entity type to set cover image on"),targetEntityId:J.string().optional().describe("Entity ID to set cover image on")};function WG1(A,Q){return[XqQ(A,Q),WqQ(A,Q)]}function XqQ(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:IG1,handler:async(B)=>{let w=J.object(IG1).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 WqQ(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:YG1,handler:async(B)=>{let w=J.object(YG1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:D,photographerName:I,photographerUrl:Y,sourceUrl:X,imageUrl:W,title:H,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:Y,sourceUrl:X},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(L[0]){let g={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await XG1(Q.entityService,K,Z,L[0].id),g.coverSet=!0;return{success:!0,data:g}}Q.provider.triggerDownload(D).catch(()=>{});let E;try{E=await Q.fetchImage(W)}catch(g){return{success:!1,error:g instanceof Error?g.message:"Image download failed"}}let R=H??`Stock photo ${$}`,j=CH.createImageEntity({dataUrl:E,title:R,alt:F??R}),C={id:$,...j,metadata:{...j.metadata,sourceUrl:W}},{entityId:m}=await Q.entityService.createEntity({entity:C}),i={imageEntityId:m,alreadyExisted:!1,attribution:q};if(K&&Z)await XG1(Q.entityService,K,Z,m),i.coverSet=!0;return{success:!0,data:i}}}}async function XG1(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}d7();var fG1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.108",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 HqQ=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class JTA extends QB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",fG1,A,HqQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new o8A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=WG1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??zW}),this.cachedTools}}function GTA(A={},Q={}){return new JTA(A,Q)}sA();HA();sA();sA();HA();var HG1=J.enum(["ai","foundation","work"]),UG1=J.object({suffix:HG1,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),$l=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(UG1).min(1)}),s8A=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),Dl=e1.extend({entityType:J.literal("ecosystem-section"),metadata:s8A});class JG1 extends N2{constructor(){super({entityType:"ecosystem-section",schema:Dl,frontmatterSchema:s8A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var FTA=new JG1;HA();function UqQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function KTA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Il(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function a8A(A){let Q=UqQ(A),w=KTA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return $l.parse({eyebrow:KTA(Q,"Eyebrow"),headline:KTA(Q,"Headline"),cards:w.map(($)=>({suffix:Il($,"Suffix"),title:Il($,"Title"),body:Il($,"Body"),linkLabel:Il($,"Link Label"),linkHref:Il($,"Link Href")}))})}function GG1(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(`
7921
+ `}HA();var rzQ=new Set(["entityType"]),nzQ={base:"Notes"},ozQ=new Set(["base"]);function szQ(A){let Q=["file.name"];for(let B of A)if(!rzQ.has(B.name))Q.push(B.name);return Q}function azQ(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function nJ1(A,Q){let B=nzQ[A]??nd(A),w=azQ(Q),$=szQ(Q),D=[{type:"table",name:`All ${B}`,order:$}];if(w)D.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let Y={filters:{and:[ozQ.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:D};return{filename:`${B}.base`,content:BH(Y),hasStatus:w}}function oJ1(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 BH(B)}function sJ1(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 BH(B)}var aJ1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.109",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 BqQ={mkdir:AqQ,writeFile:QqQ,existsFile:ezQ},wqQ=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class DTA extends QB{deps;constructor(A={},Q={}){super("obsidian-vault",aJ1,A,$TA);this.deps={...BqQ,...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[uQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",wqQ,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((E)=>Q.includes(E)):B,$=nF(A.dataDir,this.config.baseFolder),D=nF($,"templates"),I=nF($,"fileClasses"),Y=nF($,"bases");this.deps.mkdir(D,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(Y,{recursive:!0});let X=[],W=[],H=[],F=[],K=[],Z=[];for(let E of w){let R=A.entities.getEffectiveFrontmatterSchema(E);if(!R){this.logger.debug(`Skipping ${E}: no frontmatter schema`),W.push(E);continue}let j=iJ1(R),C=A.entities.getAdapter(E),m=C?.isSingleton===!0,i=rJ1(E,j);if(this.deps.writeFile(nF(I,`${E}.md`),i),H.push(E),m){K.push(E),this.logger.debug(`Generated fileClass (singleton): ${E}`);continue}let g=C?.getBodyTemplate()??"",x=dJ1(E,j,g);this.deps.writeFile(nF(D,`${E}.md`),x),X.push(E);let T=nJ1(E,j),S=nF(Y,T.filename);if(!this.deps.existsFile(S))this.deps.writeFile(S,T.content),F.push(E),this.logger.debug(`Generated base: ${T.filename}`);if(T.hasStatus)Z.push({entityType:E,fields:j});this.logger.debug(`Generated template + fileClass: ${E}`)}let q=oJ1(K);if(q){let E=nF(Y,"Settings.base");if(!this.deps.existsFile(E))this.deps.writeFile(E,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let L=sJ1(Z);if(L){let E=nF(Y,"Pipeline.base");if(!this.deps.existsFile(E))this.deps.writeFile(E,L),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${X.length} templates, ${H.length} fileClasses, ${F.length} bases (${W.length} skipped)`),K8({generated:X,skipped:W,fileClasses:H,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),i5(B instanceof Error?B.message:"Unknown error")}}}function ITA(A,Q){return new DTA(A,Q)}sA();HA();sA();var YTA=J.enum(["new","planned","in-progress","done","declined"]),XTA=J.enum(["low","medium","high","critical"]),ep=J.object({title:J.string(),status:YTA,priority:XTA.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),tJ1=J.object({title:J.string(),status:YTA,priority:XTA,requested:J.number().int(),slug:J.string()}),Al=e1.extend({entityType:J.literal("wish"),metadata:tJ1}),WTA=J.object({});sA();HA();class Ql extends N2{constructor(){super({entityType:"wish",schema:Al,frontmatterSchema:ep})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,ep);return{frontmatter:ep.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=b1(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var fTA=new Ql;HA();HA();async function eJ1(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 D=b1(Q.title);return A.getEntity({entityType:"wish",id:D})}class d8A{logger;context;adapter=new Ql;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??"",D=await eJ1({search:(W)=>this.context.entityService.search(W),getEntity:(W)=>this.context.entityService.getEntity(W),similarityThreshold:0.85},{title:w,description:$});if(D){let{frontmatter:W,description:H}=this.adapter.parseWishContent(D.content),F=W.requested+1,K=this.adapter.createWishContent({...W,requested:F},H);return await this.context.entityService.updateEntity({entity:{...D,content:K,metadata:{...D.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:D.id,requested:F}),{success:!0,entityId:D.id,existed:!0,requested:F}}let I=b1(w),Y=A.options?.priority??"medium",X=this.adapter.createWishContent({title:w,status:"new",priority:Y,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:X,metadata:{title:w,status:"new",priority:Y,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var AG1={critical:0,high:1,medium:2,low:3};function QG1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return AG1[Q.metadata.priority]-AG1[B.metadata.priority]})}var BG1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.109",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 wG1 extends MQ{entityType=fTA.entityType;schema=Al;adapter=fTA;constructor(A={}){super("wishlist",BG1,A,WTA)}async interceptCreate(A,Q,B){let w=await new d8A(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 QG1(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 d8A(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 DqQ(A={}){return new wG1(A)}var r8A=DqQ;sA();HA();sA();var Bl=J.object({title:J.string(),target:J.string()}),$G1=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),wl=e1.extend({entityType:J.literal("prompt"),metadata:$G1});sA();HA();class HTA extends N2{constructor(){super({entityType:"prompt",schema:wl,frontmatterSchema:Bl})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,Bl);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,Bl),B=b1(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var n8A=new HTA;var DG1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.109",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 UTA extends MQ{entityType=n8A.entityType;schema=wl;adapter=n8A;constructor(){super("prompt",DG1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function HM(){return new UTA}sA();HA();class o8A{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(YqQ),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function YqQ(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}}HA();d7();var IG1={query:J.string().describe("Search terms for stock photos"),perPage:J.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:J.number().min(1).default(1).describe("Page number")},YG1={photoId:J.string().describe("Photo ID from search results"),downloadLocation:J.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:J.string().describe("Photographer name for attribution"),photographerUrl:J.string().url().describe("Photographer profile URL for attribution"),sourceUrl:J.string().url().describe("Photo page URL on provider"),imageUrl:J.string().url().describe("Image URL to download"),title:J.string().optional().describe("Image entity title"),alt:J.string().optional().describe("Alt text for the image"),targetEntityType:J.string().optional().describe("Entity type to set cover image on"),targetEntityId:J.string().optional().describe("Entity ID to set cover image on")};function WG1(A,Q){return[XqQ(A,Q),WqQ(A,Q)]}function XqQ(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:IG1,handler:async(B)=>{let w=J.object(IG1).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 WqQ(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:YG1,handler:async(B)=>{let w=J.object(YG1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:D,photographerName:I,photographerUrl:Y,sourceUrl:X,imageUrl:W,title:H,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:Y,sourceUrl:X},L=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:W}}}});if(L[0]){let g={imageEntityId:L[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await XG1(Q.entityService,K,Z,L[0].id),g.coverSet=!0;return{success:!0,data:g}}Q.provider.triggerDownload(D).catch(()=>{});let E;try{E=await Q.fetchImage(W)}catch(g){return{success:!1,error:g instanceof Error?g.message:"Image download failed"}}let R=H??`Stock photo ${$}`,j=CH.createImageEntity({dataUrl:E,title:R,alt:F??R}),C={id:$,...j,metadata:{...j.metadata,sourceUrl:W}},{entityId:m}=await Q.entityService.createEntity({entity:C}),i={imageEntityId:m,alreadyExisted:!1,attribution:q};if(K&&Z)await XG1(Q.entityService,K,Z,m),i.coverSet=!0;return{success:!0,data:i}}}}async function XG1(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}d7();var fG1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.109",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 HqQ=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class JTA extends QB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",fG1,A,HqQ);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new o8A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=WG1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??zW}),this.cachedTools}}function GTA(A={},Q={}){return new JTA(A,Q)}sA();HA();sA();sA();HA();var HG1=J.enum(["ai","foundation","work"]),UG1=J.object({suffix:HG1,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),$l=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(UG1).min(1)}),s8A=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),Dl=e1.extend({entityType:J.literal("ecosystem-section"),metadata:s8A});class JG1 extends N2{constructor(){super({entityType:"ecosystem-section",schema:Dl,frontmatterSchema:s8A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var FTA=new JG1;HA();function UqQ(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function KTA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Il(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function a8A(A){let Q=UqQ(A),w=KTA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return $l.parse({eyebrow:KTA(Q,"Eyebrow"),headline:KTA(Q,"Headline"),cards:w.map(($)=>({suffix:Il($,"Suffix"),title:Il($,"Title"),body:Il($,"Body"),linkLabel:Il($,"Link Label"),linkHref:Il($,"Link Href")}))})}function GG1(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(`
7922
7922
  `)}var JqQ=J.object({query:J.object({id:J.string().optional()}).optional()}).passthrough();class t8A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=JqQ.parse(A??{}).query?.id??"rizom-ecosystem",D=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!D)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(a8A(D.content))}}sA();var GqQ=JQA({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 pU(...A){return GqQ(ek(A))}import{jsxDEV as jsw}from"preact/jsx-dev-runtime";import{jsxDEV as vsw}from"preact/jsx-dev-runtime";import{jsxDEV as hsw}from"preact/jsx-dev-runtime";import{jsxDEV as KqQ}from"preact/jsx-dev-runtime";var ZTA="px-6 md:px-10 xl:px-20",FqQ=`${ZTA} relative z-[1]`,NTA=({id:A,className:Q,children:B})=>KqQ("section",{id:A,className:pU(FqQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as e8A}from"preact/jsx-dev-runtime";var ZqQ=new Map([["work","text-accent"],["foundation","text-secondary"],["ai","text-accent-bright"]]),Yl=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let D=ZqQ.get(Q);return e8A("span",{className:pU("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[e8A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),e8A("span",{className:pU(D??"text-accent",w),children:"."},void 0,!1,void 0,this),e8A("span",{className:pU("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as asw}from"preact/jsx-dev-runtime";import{jsxDEV as Qaw}from"preact/jsx-dev-runtime";import{jsxDEV as Daw,Fragment as $aw}from"preact/jsx-dev-runtime";import{jsxDEV as Xaw}from"preact/jsx-dev-runtime";import{Fragment as zTA}from"preact";import{jsxDEV as Xl}from"preact/jsx-dev-runtime";var NqQ=/(\*[^*]+\*)/;function qTA(A,Q){let B=A.split(`
7923
- `);return Xl(zTA,{children:B.map((w,$)=>Xl(zTA,{children:[$>0&&Xl("br",{},void 0,!1,void 0,this),w.split(NqQ).map((D,I)=>{if(D.length>=3&&D.startsWith("*")&&D.endsWith("*"))return Xl("span",{className:Q,children:D.slice(1,-1)},I,!1,void 0,this);return Xl(zTA,{children:D},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as FD,Fragment as PqQ}from"preact/jsx-dev-runtime";var zqQ="italic text-accent font-normal",qqQ="You are here",LqQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},EqQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},VqQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},MqQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",OqQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",CqQ="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",bqQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",RqQ=({card:A})=>{let Q=A.linkLabel===qqQ,B=A.linkHref.trim().length===0,w=FD(PqQ,{children:[FD(Yl,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),FD("span",{className:`${MqQ} ${LqQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),FD("p",{className:OqQ,children:A.body},void 0,!1,void 0,this),Q?FD("span",{className:bqQ,children:A.linkLabel},void 0,!1,void 0,this):FD("span",{className:CqQ,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?EqQ[A.suffix]:"border-white/10"}`;return Q||B?FD("div",{className:$,children:w},void 0,!1,void 0,this):FD("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${VqQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},LTA=({eyebrow:A,headline:Q,cards:B})=>FD(NTA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[FD("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[FD("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),FD("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:qTA(Q,zqQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FD("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)=>FD(RqQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var kqQ=[{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 FG1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:kqQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var jqQ=FG1();var ETA=R1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:$l,formatter:{parse:a8A,format:GG1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:LTA}});var KG1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.108",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 VTA extends MQ{entityType="ecosystem-section";schema=Dl;adapter=FTA;constructor(A={}){super("rizom-ecosystem",KG1,A,J.object({}).default({}))}getTemplates(){return{ecosystem:ETA}}getDataSources(){return[new t8A]}}function UM(A={}){return new VTA(A)}HA();sA();sA();HA();b$();HA();sA();var O9="agent",ZG1="agent-discovery",NG1="agent:generation",zG1="agent-network",qG1="AgentNetworkWidget",Wl="agent-discovery:entities",MTA="agent-list",OTA="agent-detail",j6="skill",LG1="skill",A6A="skill-derivation",EG1="skill:project",VG1="skill-derivation",MG1="skill:skill-derivation",OG1="skills";var G_=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),fX=J.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),Vf=wW.pick({name:!0,kind:!0,organization:!0}).extend({brainName:J.string().describe("Name of the brain instance"),url:J.string().url().describe("Brain endpoint URL"),did:J.string().optional().describe("Decentralized identifier (public)"),repoDid:J.string().optional().describe("ATProto repo DID"),brainDid:J.string().optional().describe("ATProto brain DID"),anchorDid:J.string().optional().describe("ATProto anchor DID"),cardUri:J.string().optional().describe("ATProto brain card URI"),cardCid:J.string().optional().describe("ATProto brain card CID"),a2aEndpoint:J.string().url().optional().describe("A2A endpoint URL"),status:fX,discoveredAt:J.string().datetime().describe("When this agent was first discovered")}),CG1=Vf.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:J.string().datetime().optional(),slug:J.string(),repoDid:J.string().optional(),brainDid:J.string().optional(),anchorDid:J.string().optional(),cardUri:J.string().optional(),cardCid:J.string().optional(),a2aEndpoint:J.string().url().optional()}),F_=e1.extend({entityType:J.literal(O9),metadata:CG1}),fl=F_.extend({frontmatter:Vf,about:J.string(),skills:J.array(G_),notes:J.string()}),K_=fl.extend({url:J.string().optional(),typeLabel:J.string().optional()}),yqQ=fl.extend({url:J.string(),typeLabel:J.string()});HA();var xqQ=J.array(G_);function bG1(A){let Q=xqQ.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(`
7923
+ `);return Xl(zTA,{children:B.map((w,$)=>Xl(zTA,{children:[$>0&&Xl("br",{},void 0,!1,void 0,this),w.split(NqQ).map((D,I)=>{if(D.length>=3&&D.startsWith("*")&&D.endsWith("*"))return Xl("span",{className:Q,children:D.slice(1,-1)},I,!1,void 0,this);return Xl(zTA,{children:D},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as FD,Fragment as PqQ}from"preact/jsx-dev-runtime";var zqQ="italic text-accent font-normal",qqQ="You are here",LqQ={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},EqQ={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},VqQ={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},MqQ="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",OqQ="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",CqQ="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",bqQ="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",RqQ=({card:A})=>{let Q=A.linkLabel===qqQ,B=A.linkHref.trim().length===0,w=FD(PqQ,{children:[FD(Yl,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),FD("span",{className:`${MqQ} ${LqQ[A.suffix]}`,children:A.title},void 0,!1,void 0,this),FD("p",{className:OqQ,children:A.body},void 0,!1,void 0,this),Q?FD("span",{className:bqQ,children:A.linkLabel},void 0,!1,void 0,this):FD("span",{className:CqQ,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?EqQ[A.suffix]:"border-white/10"}`;return Q||B?FD("div",{className:$,children:w},void 0,!1,void 0,this):FD("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${VqQ[A.suffix]}`,children:w},void 0,!1,void 0,this)},LTA=({eyebrow:A,headline:Q,cards:B})=>FD(NTA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[FD("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[FD("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),FD("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:qTA(Q,zqQ)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),FD("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)=>FD(RqQ,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var kqQ=[{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 FG1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:kqQ.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var jqQ=FG1();var ETA=R1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:$l,formatter:{parse:a8A,format:GG1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:LTA}});var KG1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.109",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 VTA extends MQ{entityType="ecosystem-section";schema=Dl;adapter=FTA;constructor(A={}){super("rizom-ecosystem",KG1,A,J.object({}).default({}))}getTemplates(){return{ecosystem:ETA}}getDataSources(){return[new t8A]}}function UM(A={}){return new VTA(A)}HA();sA();sA();HA();b$();HA();sA();var O9="agent",ZG1="agent-discovery",NG1="agent:generation",zG1="agent-network",qG1="AgentNetworkWidget",Wl="agent-discovery:entities",MTA="agent-list",OTA="agent-detail",j6="skill",LG1="skill",A6A="skill-derivation",EG1="skill:project",VG1="skill-derivation",MG1="skill:skill-derivation",OG1="skills";var G_=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),fX=J.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),Vf=wW.pick({name:!0,kind:!0,organization:!0}).extend({brainName:J.string().describe("Name of the brain instance"),url:J.string().url().describe("Brain endpoint URL"),did:J.string().optional().describe("Decentralized identifier (public)"),repoDid:J.string().optional().describe("ATProto repo DID"),brainDid:J.string().optional().describe("ATProto brain DID"),anchorDid:J.string().optional().describe("ATProto anchor DID"),cardUri:J.string().optional().describe("ATProto brain card URI"),cardCid:J.string().optional().describe("ATProto brain card CID"),a2aEndpoint:J.string().url().optional().describe("A2A endpoint URL"),status:fX,discoveredAt:J.string().datetime().describe("When this agent was first discovered")}),CG1=Vf.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:J.string().datetime().optional(),slug:J.string(),repoDid:J.string().optional(),brainDid:J.string().optional(),anchorDid:J.string().optional(),cardUri:J.string().optional(),cardCid:J.string().optional(),a2aEndpoint:J.string().url().optional()}),F_=e1.extend({entityType:J.literal(O9),metadata:CG1}),fl=F_.extend({frontmatter:Vf,about:J.string(),skills:J.array(G_),notes:J.string()}),K_=fl.extend({url:J.string().optional(),typeLabel:J.string().optional()}),yqQ=fl.extend({url:J.string(),typeLabel:J.string()});HA();var xqQ=J.array(G_);function bG1(A){let Q=xqQ.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(`
7924
7924
  `)}function RG1(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
7925
7925
  `)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",D=w[2]??"",I=w[3],Y=I?I.split(",").map((X)=>X.trim()).filter(Boolean):[];Q.push({name:$,description:D,tags:Y})}return Q}var vqQ=J.object({about:J.string(),skills:J.array(G_),notes:J.string()}),PG1=new xB(vqQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:bG1,parser:RG1},{key:"notes",label:"Notes",type:"string"}]});class KD extends N2{constructor(){super({entityType:O9,schema:F_,frontmatterSchema:Vf})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Vf),B=eK(Q.url);return{content:A,entityType:O9,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:fX.parse(A.status),discoveredAt:A.discoveredAt},B=PG1.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=PG1.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,Vf),body:this.parseAgentContent(A.content)}}}sA();var TqQ=new KD,gqQ=GH.extend({status:fX.optional()}),SqQ=FH.extend({query:gqQ.optional()});function hqQ(A){let Q=O2(A.content,Vf),B=TqQ.parseAgentContent(A.content);return fl.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class Q6A extends L5{id=Wl;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:O9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return hqQ(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=SqQ.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=fX.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:D}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,D,w))}}sA();HA();e8();sA();async function kG1(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 D=await $.json();return Hv(D)}catch{return null}}function B6A(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""}HA();var mqQ=new KD;function jG1(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function rN(A){let Q=new Set,B=[];for(let w of A){let $=jG1(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function uqQ(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function _G1(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=Q.visibilityScope??"public",D=new Map,[I,Y]=await Promise.all([A.entityService.listEntities({entityType:j6,options:{filter:{visibilityScope:$}}}),A.entityService.listEntities({entityType:O9,options:{filter:{visibilityScope:$}}})]),X=(W)=>{for(let H of rN(W))D.set(H,(D.get(H)??0)+1)};for(let W of I)X(W.metadata.tags);for(let W of Y){let H=mqQ.parseAgentContent(W.content);X(H.skills.flatMap((F)=>F.tags))}return Array.from(D.entries()).map(([W,H])=>({tag:W,count:H})).filter((W)=>W.count>=B).sort(uqQ).slice(0,w)}function yG1(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(`
7926
7926
  `)}var cqQ=new KD;function xG1(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 D=Q.status??"discovered",I=new Date().toISOString();return{content:cqQ.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:D,discoveredAt:I,about:$.join(`
@@ -8021,7 +8021,7 @@ ${BH(B)}---
8021
8021
  setTagFilter("all");
8022
8022
  });
8023
8023
  })();`;import{jsxDEV as mQ}from"preact/jsx-dev-runtime";function aqQ({item:A}){return mQ("li",{class:"list-item",children:[mQ("div",{class:"list-main",children:[mQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),mQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&mQ("div",{class:"list-tags",children:A.tags.map((Q)=>mQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),mQ("div",{class:"list-meta",children:A.status==="discovered"&&mQ("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 tqQ({item:A}){return mQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[mQ("div",{class:"list-main",children:mQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),mQ("div",{class:"list-meta",children:mQ("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 eqQ({kind:A,items:Q,active:B}){return mQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?mQ("ul",{class:"list agent-network-list",children:Q.map((w)=>mQ(aqQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):mQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function ALQ({skills:A,count:Q,filters:B}){return mQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[mQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[mQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[mQ("span",{class:"count",children:Q},void 0,!1,void 0,this),mQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>mQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[mQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),mQ("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?mQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>mQ(tqQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):mQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function RTA({data:A}){let Q=mG1.safeParse(A);if(!Q.success)return mQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return mQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[mQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[mQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",mQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),mQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",mQ("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),mQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:bTA.map((w)=>{let $=w==="all";return mQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[mQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),mQ("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),bTA.map((w)=>mQ(eqQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),mQ(ALQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cG1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:zG1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:qG1,component:RTA,clientScript:$6A,dataProvider:async()=>uG1(A)}}),{success:!0}})}HA();var pG1=new KD;function QLQ(A){return A.skills.map((Q)=>({name:Q.name,description:Q.description,tags:Q.tags??[]}))}function BLQ(A){return new URL(A).hostname}function wLQ(A){return[`ATProto card: ${A.uri}`,`ATProto card CID: ${A.cid}`,`ATProto repo DID: ${A.repoDid}`].join(`
8024
- `)}function $LQ(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 DLQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function ILQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=BLQ(w.siteUrl),D=await A.entityService.getEntity({entityType:"agent",id:$}),I=D?pG1.parseEntity(D):void 0,Y=w.brain.did,X=w.anchor.did,W=QLQ(w),H=D?.metadata.status??"discovered",F=D?.metadata.url??w.siteUrl,K=D?.metadata.slug??eK(F),Z=D?.metadata.name??w.anchor.name,q=I?.frontmatter.kind??w.anchor.kind,L=D?.metadata.discoveredAt??B,E=w.brain.purpose||I?.body.about||"",R=W.length>0?W:I?.body.skills??[],j={...D?.metadata??{},name:Z,url:F,status:H,discoveredAt:L,slug:K,repoDid:Q.repoDid,...Y&&{brainDid:Y},...X&&{anchorDid:X},cardUri:Q.uri,cardCid:Q.cid},C=pG1.createAgentContent({name:Z,kind:q,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:F,...Y&&{did:Y,brainDid:Y},...X&&{anchorDid:X},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:H,discoveredAt:L,about:E,skills:R,notes:wLQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(D){let i={...D,content:C,metadata:j,updated:B};return await A.entityService.updateEntity({entity:i}),{agent:i,created:!1}}let m={id:$,entityType:"agent",content:C,metadata:j,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:m}),{agent:m,created:!0}}function lG1(A){A.messaging.subscribe(nwA,async(Q)=>{let B=Gf1.parse(Q.payload),w=await ILQ(A,B),$=$LQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await DLQ(A,w.created?Uf1:Jf1,$),{success:!0,data:$}})}function iG1(){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`, 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- Do **not** repeat the save-first instruction 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`.'}sA();Hw();HA();import{jsxDEV as dG1}from"preact/jsx-dev-runtime";function D6A(A){try{return new URL(A).hostname}catch{return A}}var I6A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let D=0;D<A.length;D++)w=A.charCodeAt(D)+((w<<5)-w);let $=Math.abs(w)%360;return dG1("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)},Y6A=({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 dG1("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 z2,Fragment as WLQ}from"preact/jsx-dev-runtime";var YLQ=({skills:A})=>{if(A.length===0)return null;return z2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>z2("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 XLQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function rG1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var PTA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,D=Q.status==="approved";return z2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${D?"":"opacity-70"}`,children:[z2(I6A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),z2("div",{className:"flex-1 min-w-0",children:[z2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[z2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),z2(Y6A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&z2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&z2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),D&&z2(YLQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[z2("span",{className:"text-xs text-theme-muted",children:D6A(Q.url)},void 0,!1,void 0,this),z2("span",{className:"text-[11px] text-theme-muted opacity-60",children:D?`Discovered ${XLQ(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)},nG1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let D=Q??"Agent Directory",I=B?.totalItems??A.length,Y=A.filter((K)=>K.frontmatter.status==="approved"),X=A.filter((K)=>K.frontmatter.status==="discovered"),W=Y.length,H=X.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return z2(WLQ,{children:[z2(fQ,{title:D,description:F},void 0,!1,void 0,this),z2("div",{className:"agent-list bg-theme",children:z2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[z2("div",{className:"mb-8 pb-6 border-b border-theme",children:[z2("h1",{className:"text-4xl font-bold text-heading mb-2",children:D},void 0,!1,void 0,this),z2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),z2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[H," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-wrap gap-2 text-sm",children:[z2("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),z2("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),z2("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"&&Y.length>0&&z2("section",{className:"mb-10",children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),z2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&z2("section",{children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("div",{children:[z2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),z2("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),z2("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:X.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&z2("section",{children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),z2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:A.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&z2("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"&&z2("div",{className:"mt-12",children:z2(bF,{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"&&z2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?z2("a",{href:rG1(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):z2("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),z2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?z2("a",{href:rG1(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):z2("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 W2,Fragment as JLQ}from"preact/jsx-dev-runtime";function fLQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Hl=({children:A})=>W2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),HLQ=({skill:A})=>W2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[W2("div",{className:"flex-1",children:[W2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),W2("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&&W2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>W2("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),ULQ=({label:A,value:Q,valueClassName:B})=>W2("div",{className:"flex justify-between text-[13px]",children:[W2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),W2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oG1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:D,notes:I}=A,Y=D6A(w.url),X=w.status==="approved";return W2(JLQ,{children:[W2(fQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),W2("article",{className:"agent-detail",children:W2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[W2("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),W2("div",{className:"flex items-start gap-6 mb-8",children:[W2(I6A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),W2("div",{children:[W2("div",{className:"flex items-center gap-3 mb-1",children:[W2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),W2(Y6A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),W2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&W2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&W2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),W2("span",{className:"text-sm",children:["Discovered ",fLQ(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),W2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!X&&W2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[W2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),W2("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),W2("div",{className:"flex flex-col md:flex-row gap-12",children:[W2("div",{className:"flex-[2] min-w-0",children:[$&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"About"},void 0,!1,void 0,this),W2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D.length>0&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"Skills"},void 0,!1,void 0,this),W2("div",{className:"flex flex-col gap-2.5",children:D.map((W)=>W2(HLQ,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"Notes"},void 0,!1,void 0,this),W2("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),W2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[W2("section",{className:"mb-8",children:[W2(Hl,{children:"Brain"},void 0,!1,void 0,this),W2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[W2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&W2("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),W2("section",{className:"mb-8",children:[W2(Hl,{children:"Connection"},void 0,!1,void 0,this),W2("div",{className:"flex flex-col gap-3",children:[W2("div",{children:[W2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),W2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2(ULQ,{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),W2("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 ",Y," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&W2("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:[W2("div",{className:"min-h-[1px]",children:Q&&W2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[W2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),W2("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),W2("div",{className:"min-h-[1px] md:text-right",children:B&&W2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[W2("span",{children:"Next \u2192"},void 0,!1,void 0,this),W2("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 GLQ=J.object({agents:J.array(K_),pageTitle:J.string().optional(),pagination:i9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),fX])});function sG1(){return{[MTA]:R1({name:MTA,description:"Agent directory list page template",schema:GLQ,dataSourceId:Wl,requiredPermission:"public",layout:{component:nG1}}),[OTA]:R1({name:OTA,description:"Individual agent profile template",schema:J.object({agent:K_,prevAgent:K_.nullable(),nextAgent:K_.nullable()}),dataSourceId:Wl,requiredPermission:"public",layout:{component:oG1}})}}var X6A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.108",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 KLQ=new KD;class kTA extends MQ{entityType=O9;schema=F_;adapter=KLQ;constructor(){super(ZG1,X6A)}interceptCreate(A,Q,B){return vG1(A,Q,B,this.id)}createGenerationHandler(A){return new CTA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return sG1()}getDataSources(){return[new Q6A(this.logger.child("AgentDataSource"))]}async onRegister(A){lG1(A),cG1(A,this.id)}async getInstructions(){return iG1()}}function jTA(){return new kTA}sA();HA();sA();var Z_=aD,aG1=aD,Ul=e1.extend({entityType:J.literal(j6),metadata:aG1});sA();class N_ extends N2{constructor(){super({entityType:j6,schema:Ul,frontmatterSchema:Z_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Z_);return{content:A,entityType:j6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}sA();HA();var ZLQ=J.object({skills:J.array(Z_).max(8)}),tG1=R1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:ZLQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
8024
+ `)}function $LQ(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 DLQ(A,Q,B){await A.messaging.send({type:Q,payload:B,broadcast:!0})}async function ILQ(A,Q,B=new Date().toISOString()){let{record:w}=Q,$=BLQ(w.siteUrl),D=await A.entityService.getEntity({entityType:"agent",id:$}),I=D?pG1.parseEntity(D):void 0,Y=w.brain.did,X=w.anchor.did,W=QLQ(w),H=D?.metadata.status??"discovered",F=D?.metadata.url??w.siteUrl,K=D?.metadata.slug??eK(F),Z=D?.metadata.name??w.anchor.name,q=I?.frontmatter.kind??w.anchor.kind,L=D?.metadata.discoveredAt??B,E=w.brain.purpose||I?.body.about||"",R=W.length>0?W:I?.body.skills??[],j={...D?.metadata??{},name:Z,url:F,status:H,discoveredAt:L,slug:K,repoDid:Q.repoDid,...Y&&{brainDid:Y},...X&&{anchorDid:X},cardUri:Q.uri,cardCid:Q.cid},C=pG1.createAgentContent({name:Z,kind:q,...I?.frontmatter.organization&&{organization:I.frontmatter.organization},brainName:w.brain.name,url:F,...Y&&{did:Y,brainDid:Y},...X&&{anchorDid:X},repoDid:Q.repoDid,cardUri:Q.uri,cardCid:Q.cid,...I?.frontmatter.a2aEndpoint&&{a2aEndpoint:I.frontmatter.a2aEndpoint},status:H,discoveredAt:L,about:E,skills:R,notes:wLQ({repoDid:Q.repoDid,uri:Q.uri,cid:Q.cid})});if(D){let i={...D,content:C,metadata:j,updated:B};return await A.entityService.updateEntity({entity:i}),{agent:i,created:!1}}let m={id:$,entityType:"agent",content:C,metadata:j,contentHash:"",visibility:"public",created:B,updated:B};return await A.entityService.createEntity({entity:m}),{agent:m,created:!0}}function lG1(A){A.messaging.subscribe(nwA,async(Q)=>{let B=Gf1.parse(Q.payload),w=await ILQ(A,B),$=$LQ({agent:w.agent,repoDid:B.repoDid,uri:B.uri,cid:B.cid,record:B.record});return await DLQ(A,w.created?Uf1:Jf1,$),{success:!0,data:$}})}function iG1(){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`, 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- Do **not** repeat the save-first instruction 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`.'}sA();Hw();HA();import{jsxDEV as dG1}from"preact/jsx-dev-runtime";function D6A(A){try{return new URL(A).hostname}catch{return A}}var I6A=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let D=0;D<A.length;D++)w=A.charCodeAt(D)+((w<<5)-w);let $=Math.abs(w)%360;return dG1("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)},Y6A=({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 dG1("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 z2,Fragment as WLQ}from"preact/jsx-dev-runtime";var YLQ=({skills:A})=>{if(A.length===0)return null;return z2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>z2("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 XLQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function rG1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var PTA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,D=Q.status==="approved";return z2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${D?"":"opacity-70"}`,children:[z2(I6A,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),z2("div",{className:"flex-1 min-w-0",children:[z2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[z2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),z2(Y6A,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&z2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&z2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),D&&z2(YLQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[z2("span",{className:"text-xs text-theme-muted",children:D6A(Q.url)},void 0,!1,void 0,this),z2("span",{className:"text-[11px] text-theme-muted opacity-60",children:D?`Discovered ${XLQ(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)},nG1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let D=Q??"Agent Directory",I=B?.totalItems??A.length,Y=A.filter((K)=>K.frontmatter.status==="approved"),X=A.filter((K)=>K.frontmatter.status==="discovered"),W=Y.length,H=X.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return z2(WLQ,{children:[z2(fQ,{title:D,description:F},void 0,!1,void 0,this),z2("div",{className:"agent-list bg-theme",children:z2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[z2("div",{className:"mb-8 pb-6 border-b border-theme",children:[z2("h1",{className:"text-4xl font-bold text-heading mb-2",children:D},void 0,!1,void 0,this),z2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),z2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[W," approved"]},void 0,!0,void 0,this),z2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[H," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-wrap gap-2 text-sm",children:[z2("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),z2("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),z2("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"&&Y.length>0&&z2("section",{className:"mb-10",children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),z2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&X.length>0&&z2("section",{children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("div",{children:[z2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),z2("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),z2("span",{className:"text-sm text-theme-muted",children:X.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:X.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&z2("section",{children:[z2("div",{className:"flex items-center justify-between mb-4",children:[z2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),z2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z2("div",{className:"flex flex-col gap-4",children:A.map((K)=>z2(PTA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&z2("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"&&z2("div",{className:"mt-12",children:z2(bF,{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"&&z2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?z2("a",{href:rG1(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):z2("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),z2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?z2("a",{href:rG1(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):z2("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 W2,Fragment as JLQ}from"preact/jsx-dev-runtime";function fLQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var Hl=({children:A})=>W2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),HLQ=({skill:A})=>W2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[W2("div",{className:"flex-1",children:[W2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),W2("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&&W2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>W2("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),ULQ=({label:A,value:Q,valueClassName:B})=>W2("div",{className:"flex justify-between text-[13px]",children:[W2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),W2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oG1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:D,notes:I}=A,Y=D6A(w.url),X=w.status==="approved";return W2(JLQ,{children:[W2(fQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),W2("article",{className:"agent-detail",children:W2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[W2("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),W2("div",{className:"flex items-start gap-6 mb-8",children:[W2(I6A,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),W2("div",{children:[W2("div",{className:"flex items-center gap-3 mb-1",children:[W2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),W2(Y6A,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),W2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&W2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&W2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),W2("span",{className:"text-sm",children:["Discovered ",fLQ(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),W2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!X&&W2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[W2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),W2("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),W2("div",{className:"flex flex-col md:flex-row gap-12",children:[W2("div",{className:"flex-[2] min-w-0",children:[$&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"About"},void 0,!1,void 0,this),W2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D.length>0&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"Skills"},void 0,!1,void 0,this),W2("div",{className:"flex flex-col gap-2.5",children:D.map((W)=>W2(HLQ,{skill:W},W.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&W2("section",{className:"mb-8",children:[W2(Hl,{children:"Notes"},void 0,!1,void 0,this),W2("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),W2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[W2("section",{className:"mb-8",children:[W2(Hl,{children:"Brain"},void 0,!1,void 0,this),W2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[W2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&W2("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),W2("section",{className:"mb-8",children:[W2(Hl,{children:"Connection"},void 0,!1,void 0,this),W2("div",{className:"flex flex-col gap-3",children:[W2("div",{children:[W2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),W2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2(ULQ,{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),W2("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 ",Y," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&W2("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:[W2("div",{className:"min-h-[1px]",children:Q&&W2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[W2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),W2("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),W2("div",{className:"min-h-[1px] md:text-right",children:B&&W2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[W2("span",{children:"Next \u2192"},void 0,!1,void 0,this),W2("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 GLQ=J.object({agents:J.array(K_),pageTitle:J.string().optional(),pagination:i9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),fX])});function sG1(){return{[MTA]:R1({name:MTA,description:"Agent directory list page template",schema:GLQ,dataSourceId:Wl,requiredPermission:"public",layout:{component:nG1}}),[OTA]:R1({name:OTA,description:"Individual agent profile template",schema:J.object({agent:K_,prevAgent:K_.nullable(),nextAgent:K_.nullable()}),dataSourceId:Wl,requiredPermission:"public",layout:{component:oG1}})}}var X6A={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.109",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 KLQ=new KD;class kTA extends MQ{entityType=O9;schema=F_;adapter=KLQ;constructor(){super(ZG1,X6A)}interceptCreate(A,Q,B){return vG1(A,Q,B,this.id)}createGenerationHandler(A){return new CTA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return sG1()}getDataSources(){return[new Q6A(this.logger.child("AgentDataSource"))]}async onRegister(A){lG1(A),cG1(A,this.id)}async getInstructions(){return iG1()}}function jTA(){return new kTA}sA();HA();sA();var Z_=aD,aG1=aD,Ul=e1.extend({entityType:J.literal(j6),metadata:aG1});sA();class N_ extends N2{constructor(){super({entityType:j6,schema:Ul,frontmatterSchema:Z_})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Z_);return{content:A,entityType:j6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}sA();HA();var ZLQ=J.object({skills:J.array(Z_).max(8)}),tG1=R1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:ZLQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
8025
8025
 
8026
8026
  Given knowledge domains, CONSOLIDATE related topics into broader skills.
8027
8027
  There should be FEWER skills than topics \u2014 combine related domains.
@@ -8171,9 +8171,9 @@ Context:
8171
8171
  ${JSON.stringify(w,null,2)}
8172
8172
 
8173
8173
  Draft SWOT:
8174
- ${JSON.stringify(B,null,2)}`}function K6A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function hLQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((D)=>D.theme.trim().toLowerCase()));for(let D of Q[w]){let I=D.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${D.sourceTheme}" in ${w}`)}}}class Z6A{logger;context;adapter=new oF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=xTA.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 hTA(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:W}=await this.context.ai.generateObject(await TLQ(this.context,w),vTA),H=vTA.parse(W);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await SLQ(this.context,w,H),J6A);$=J6A.parse(F.object),hLQ(H,$)}let I=new Date().toISOString(),Y=this.adapter.createSwotContent({strengths:K6A($.strengths),weaknesses:K6A($.weaknesses),opportunities:K6A($.opportunities),threats:K6A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let X=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(X)await this.context.entityService.updateEntity({entity:{...X,content:Y,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Y,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"}}}HA();import{jsxDEV as K7}from"preact/jsx-dev-runtime";var N6A=J.object({title:J.string(),detail:J.string().optional()}),mLQ=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(N6A).default([]),weaknesses:J.array(N6A).default([]),opportunities:J.array(N6A).default([]),threats:J.array(N6A).default([]),derivedAt:J.string()})]);function uLQ({items:A}){if(A.length===0)return K7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return K7("ul",{class:"swot-list",children:A.map((Q)=>K7("li",{class:"swot-item",children:[K7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?K7("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 z6A({title:A,tone:Q,items:B}){return K7("section",{class:`swot-cell is-${Q}`,children:[K7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),K7(uLQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cTA({data:A}){let Q=mLQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return K7("div",{"data-swot-widget":!0,children:K7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return K7("div",{"data-swot-widget":!0,children:K7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[K7(z6A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),K7(z6A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),K7(z6A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),K7(z6A,{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)}HA();var pTA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.108",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 lTA=new oF;class iTA extends MQ{entityType="swot";schema=z_;adapter=lTA;initialSyncComplete=!1;constructor(){super("swot",pTA)}async onRegister(A){let Q=new Z6A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let D=e$.from(async()=>{});if(!D)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",D);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return lTA.parseSwotContent(I.content).frontmatter});let B=async(D)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:D},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${D}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:D}),null}},w=async(D)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(D)};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:cTA,dataProvider:async()=>{let D=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!D)return{status:"generating"};let{frontmatter:I}=lTA.parseSwotContent(D.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(D)=>{let{entityType:I}=D.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 dTA(){return new iTA}sA();b$();HA();var P08=new oF,UF1=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),rTA=J.enum(["discovered","approved"]),pLQ=J.object({name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:rTA,discoveredAt:J.string().datetime()}),lLQ=e1.extend({entityType:J.literal("agent"),metadata:J.object({name:J.string(),url:J.string().url(),status:rTA,slug:J.string()})}),iLQ=e1.extend({entityType:J.literal("skill"),metadata:aD}),dLQ=J.object({about:J.string(),skills:J.array(UF1),notes:J.string()});function rLQ(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(`
8174
+ ${JSON.stringify(B,null,2)}`}function K6A(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function hLQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((D)=>D.theme.trim().toLowerCase()));for(let D of Q[w]){let I=D.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${D.sourceTheme}" in ${w}`)}}}class Z6A{logger;context;adapter=new oF;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=xTA.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 hTA(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:W}=await this.context.ai.generateObject(await TLQ(this.context,w),vTA),H=vTA.parse(W);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await SLQ(this.context,w,H),J6A);$=J6A.parse(F.object),hLQ(H,$)}let I=new Date().toISOString(),Y=this.adapter.createSwotContent({strengths:K6A($.strengths),weaknesses:K6A($.weaknesses),opportunities:K6A($.opportunities),threats:K6A($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let X=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(X)await this.context.entityService.updateEntity({entity:{...X,content:Y,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:Y,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"}}}HA();import{jsxDEV as K7}from"preact/jsx-dev-runtime";var N6A=J.object({title:J.string(),detail:J.string().optional()}),mLQ=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(N6A).default([]),weaknesses:J.array(N6A).default([]),opportunities:J.array(N6A).default([]),threats:J.array(N6A).default([]),derivedAt:J.string()})]);function uLQ({items:A}){if(A.length===0)return K7("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return K7("ul",{class:"swot-list",children:A.map((Q)=>K7("li",{class:"swot-item",children:[K7("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?K7("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 z6A({title:A,tone:Q,items:B}){return K7("section",{class:`swot-cell is-${Q}`,children:[K7("div",{class:"swot-head",children:A},void 0,!1,void 0,this),K7(uLQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function cTA({data:A}){let Q=mLQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return K7("div",{"data-swot-widget":!0,children:K7("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return K7("div",{"data-swot-widget":!0,children:K7("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[K7(z6A,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),K7(z6A,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),K7(z6A,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),K7(z6A,{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)}HA();var pTA={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.109",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 lTA=new oF;class iTA extends MQ{entityType="swot";schema=z_;adapter=lTA;initialSyncComplete=!1;constructor(){super("swot",pTA)}async onRegister(A){let Q=new Z6A(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let D=e$.from(async()=>{});if(!D)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",D);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return lTA.parseSwotContent(I.content).frontmatter});let B=async(D)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:D},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${D}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:D}),null}},w=async(D)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(D)};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:cTA,dataProvider:async()=>{let D=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!D)return{status:"generating"};let{frontmatter:I}=lTA.parseSwotContent(D.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(D)=>{let{entityType:I}=D.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 dTA(){return new iTA}sA();b$();HA();var P08=new oF,UF1=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),rTA=J.enum(["discovered","approved"]),pLQ=J.object({name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:rTA,discoveredAt:J.string().datetime()}),lLQ=e1.extend({entityType:J.literal("agent"),metadata:J.object({name:J.string(),url:J.string().url(),status:rTA,slug:J.string()})}),iLQ=e1.extend({entityType:J.literal("skill"),metadata:aD}),dLQ=J.object({about:J.string(),skills:J.array(UF1),notes:J.string()});function rLQ(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(`
8175
8175
  `)}function nLQ(A){if(!A.trim())return[];return A.split(`
8176
- `).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 oLQ=new xB(dLQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:rLQ,parser:nLQ},{key:"notes",label:"Notes",type:"string"}]});class JF1 extends N2{constructor(){super({entityType:"agent",schema:lLQ,frontmatterSchema:pLQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=oLQ.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 GF1 extends N2{constructor(){super({entityType:"skill",schema:iLQ,frontmatterSchema:aD})}fromMarkdown(A){let Q=this.parseFrontMatter(A,aD);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var k08=new JF1,j08=new GF1,_08=J.object({skills:J.array(aD),agents:J.array(J.object({id:J.string().optional(),name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:rTA,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(UF1),notes:J.string().default("")}))});var sLQ=J.object({}).strict();function q6A(A={}){return sLQ.parse(A),[dTA()]}sA();HA();HA();var nTA=J.object({enabled:J.boolean().default(!0),pdsEndpoint:J.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:J.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:J.string().optional().describe("DID of the PDS repo that owns records"),appPassword:J.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:J.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:J.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function aLQ(A){return A.replace(/\/+$/,"")}var tLQ=(A,Q)=>fetch(A,Q);async function Gl(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 Fl{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=aLQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??tLQ}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 Gl(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 Gl(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 Gl(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 Gl(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 Gl(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function GM(A){return A?.startsWith("did:web:")??!1}function L6A(A){if(!GM(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 KF1(A){if(!GM(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 ZF1(A){return A.replace(/\/+$/,"")}function Kl(A){return`did:web:${encodeURIComponent(A)}`}function E6A(A){return`${Kl(A)}:anchor`}function oTA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function NF1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...oTA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:ZF1(A.pdsEndpoint)}]}}function zF1(A){if(!GM(A.brainDid))return null;return NF1(A,A.brainDid)}function FF1(A,Q){if(!A||!Q)return;let B=L6A(A),w=KF1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function V6A(A){let Q=[],B=FF1(A.brainDid,zF1(A));if(B)Q.push(B);if(GM(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=FF1(A.anchorDid,oTA(A.anchorDid));if(w)Q.push(w)}return Q}function sTA(A,Q){let B=[];if(!A.brainDid){let w=Kl(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:NF1(A,w)})}if(!A.anchorDid){let w=E6A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:oTA(w)})}return B}function eLQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function AEQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function qF1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function LF1(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 QEQ(A){let Q=A.metadata,B=qF1(Q,"name"),w=qF1(Q,"description");if(!B||!w)return;let $=LF1(Q,"tags"),D=LF1(Q,"examples");return{id:AEQ(B),name:B,description:w,...$&&{tags:$},...D&&{examples:D}}}async function BEQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>QEQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function aTA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),D=await A.identity.getAppInfo(),I=eLQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let Y=new URL(I).hostname,X=Q.brainDid??Kl(Y),W=Q.anchorDid??E6A(Y);if(GM(X)){if(L6A(X)!==Y)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let H=await BEQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:X,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:W,name:$.name,kind:$.kind},skills:H,model:D.model,version:D.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}HA();var EF1={dryRun:J.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},wEQ={},VF1={entityType:J.string().describe("Local entity type with a registered AT Protocol projection"),entityId:J.string().optional().describe("Local entity ID to publish"),slug:J.string().optional().describe("Local entity slug to publish"),dryRun:J.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:J.array(J.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},MF1={repos:J.array(J.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},OF1={entityId:J.string().optional().describe("Local blog post entity ID to publish"),slug:J.string().optional().describe("Local blog post slug to publish"),dryRun:J.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:J.array(J.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function CF1(A,Q,B){return[$EQ(A,Q),DEQ(A,Q,B),IEQ(A,Q,B),XEQ(A,Q,B),YEQ(A,Q,B)]}function $EQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:wEQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function DEQ(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:EF1,handler:async(w)=>{let $=J.object(EF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}function IEQ(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:VF1,handler:async(w)=>{let $=J.object(VF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}function YEQ(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:MF1,handler:async(w)=>{let $=J.object(MF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Discovery failed"}}}}}function XEQ(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:OF1,handler:async(w)=>{let $=J.object(OF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}var bF1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.108",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 RF1=ww["ai.rizom.brain.card"],fEQ="ai.rizom.brain.card",HEQ="self",PF1=50;class tTA extends QB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",bF1,A,nTA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??k6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=V6A(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 D=new URL($.url).hostname,I=[...V6A(this.config),...sTA(this.config,D)].filter((X)=>X.path===w),Y=I.find((X)=>X.hostname===D)??I[0];if(!Y)return new Response("Not found",{status:404});return new Response(JSON.stringify(Y.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await aTA(A,this.config);TN(RF1,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 D=this.createPdsClient($),I=await D.createSession(),Y=w??I.did;if(!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:Y,uri:X.uri,cid:X.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((D)=>D.trim()))].filter((D)=>D.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>PF1)throw Error(`AT Protocol discovery accepts at most ${PF1} repos per batch`);let w=new Set,$=[];for(let D of B)try{let I=await this.resolveRepoPdsEndpoint(D),Y=this.createPublicPdsClient(I.pdsEndpoint);if(!Y.getRecord)throw Error("AT Protocol PDS client does not support record reads");let X=await Y.getRecord({repo:I.repoDid,collection:fEQ,rkey:HEQ});TN(RF1,X.value);let W=JEQ(X.uri)??I.repoDid,H=`${W}:${X.uri}:${X.cid}`;if(w.has(H)){$.push({repo:D,status:"skipped",repoDid:W,uri:X.uri,cid:X.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(H),await A.messaging.send({type:nwA,payload:{repoDid:W,uri:X.uri,cid:X.cid,record:X.value},broadcast:!0}),$.push({repo:D,status:"discovered",repoDid:W,uri:X.uri,cid:X.cid})}catch(I){$.push({repo:D,status:"skipped",error:x0(I)})}return{discovered:$.filter((D)=>D.status==="discovered").length,skipped:$.filter((D)=>D.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:x0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return CF1(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 D=this.config.repoDid;if(Q.dryRun){let K=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return TN(B.lexicon,K),{record:K,dryRun:!0,...D&&{repo:D}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let Y=this.createPdsClient(I),X=await Y.createSession(),W=D??X.did,H=await B.buildRecord({entity:w,context:A,config:this.config,client:Y,...Q.topics&&{topics:Q.topics}});if(TN(B.lexicon,H),!Y.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let F=await Y.putRecord({repo:W,collection:B.collection,rkey:UEQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:H});return await B.onPublished?.({entity:w,context:A,record:H,uri:F.uri,cid:F.cid}),{record:H,repo:W,uri:F.uri,cid:F.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 Fl({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(GEQ(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 Fl({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function UEQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function JEQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function GEQ(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 M6A(A,Q){return new tTA(A,Q)}sA();HA();Hw();u6();HA();sA();var O6A=In.extend({expertise:J.array(J.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:J.string().optional().describe("What you're currently working on"),availability:J.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),nN=wW.extend(O6A.shape);sA();tJ();HA();var FEQ=new KH;class C6A{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,[$,D,I,Y]=await Promise.all([RC(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Vp(w)]),X=FEQ.parseProfileBody($,nN),W=D.sort(Kx).slice(0,3).map(Cp),H=I.sort(Kx).slice(0,3).map(jp);if(!Y.cta)throw Error("CTA not configured in site-info");let F={profile:X,posts:W,decks:H,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Y.cta,sections:Y.sections??{}};return Q.parse(F)}}sA();tJ();var KEQ=new KH;class b6A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await RC(B.entityService),D={profile:KEQ.parseProfileBody(w,nN)};return Q.parse(D)}}import{jsxDEV as dw,Fragment as zEQ}from"preact/jsx-dev-runtime";var ZEQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",NEQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",eTA=({number:A,title:Q,blurb:B,children:w})=>dw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:dw("div",{className:"max-w-6xl mx-auto",children:dw("div",{className:ZEQ,children:[dw(FjA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),dw("div",{className:NEQ,"aria-hidden":"true"},void 0,!1,void 0,this),dw("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),AgA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:D,sections:I})=>{let Y=A.tagline||A.description,X=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})),W=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})),H=A.name||"Home",F=A.intro||A.description||Y||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return dw(zEQ,{children:[dw(fQ,{title:H,description:F,ogType:"website"},void 0,!1,void 0,this),dw("div",{className:"homepage-list bg-theme",children:[dw("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:dw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&dw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[dw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),dw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&dw("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:XBA(Y,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&dw("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:XBA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),dw(eTA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:dw(YBA,{items:X,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&dw(eTA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:dw(YBA,{items:W,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&dw(eTA,{number:"03",title:"About",blurb:I.about?.blurb,children:dw("div",{className:"flex flex-col gap-8",children:[A.description&&dw("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&&dw(KjA,{subjects:A.expertise},void 0,!1,void 0,this),dw("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",dw("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),dw(AjA,{cta:D,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 $w,Fragment as qEQ}from"preact/jsx-dev-runtime";var QgA=({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 $w(qEQ,{children:[$w(fQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),$w("div",{className:"about-page bg-theme",children:[$w("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:$w("div",{className:"relative z-10 max-w-4xl mx-auto",children:[$w("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&&$w("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),$w("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&$w("section",{className:"content-section-reveal mb-20 md:mb-28",children:$w(B$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&$w("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),$w("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,D)=>$w("li",{className:Oc({variant:"accent",size:"lg"}),children:$},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),$w("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&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),$w("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)&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),$w("div",{className:"space-y-4",children:[A.email&&$w("p",{className:"text-lg",children:$w("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&&$w("p",{className:"text-lg",children:$w("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&&$w("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,D)=>$w(Q$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},D,!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 Z7,Fragment as kF1}from"preact/jsx-dev-runtime";var BgA=()=>{return Z7(kF1,{children:[Z7(fQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),Z7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:Z7("div",{className:"text-center max-w-md",children:[Z7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),Z7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),Z7("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),Z7(Q$,{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)},wgA=()=>{return Z7(kF1,{children:[Z7(fQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),Z7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:Z7("div",{className:"text-center max-w-md",children:[Z7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),Z7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),Z7("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),Z7(Q$,{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)};HA();var jF1=J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),_F1=J.object({entityDisplay:J.object({post:jF1,deck:jF1}).describe("Display metadata for post and deck entity types (required for homepage)")});var yF1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.108",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 $gA extends QB{dependencies=["blog","decks"];constructor(A){super("professional-site",yF1,A,_F1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",O6A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,D=new C6A(w,$);A.entities.registerDataSource(D);let I=new b6A;A.entities.registerDataSource(I);let Y=J.object({profile:nN,posts:J.array(cF),decks:J.array(eV),postsListUrl:J.string(),decksListUrl:J.string(),cta:TyA,sections:J.record(J.string(),Kr)}),X=J.object({profile:nN}),W=J.object({});A.templates.register({"homepage-list":R1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Y,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:AgA}}),about:R1({name:"about",description:"About page with full profile information",schema:X,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:QgA}}),"subscribe-thanks":R1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:BgA}}),"subscribe-error":R1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:wgA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function xF1(A){return new $gA(A??{})}var vF1=[{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 R6A}from"preact/jsx-dev-runtime";function TF1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return R6A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[R6A($jA,{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),R6A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),R6A(BjA,{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 EEQ={layouts:{default:TF1},routes:vF1,plugin:xF1,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"}}}},Zl=EEQ;var gF1=`/*
8176
+ `).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 oLQ=new xB(dLQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:rLQ,parser:nLQ},{key:"notes",label:"Notes",type:"string"}]});class JF1 extends N2{constructor(){super({entityType:"agent",schema:lLQ,frontmatterSchema:pLQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=oLQ.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 GF1 extends N2{constructor(){super({entityType:"skill",schema:iLQ,frontmatterSchema:aD})}fromMarkdown(A){let Q=this.parseFrontMatter(A,aD);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var k08=new JF1,j08=new GF1,_08=J.object({skills:J.array(aD),agents:J.array(J.object({id:J.string().optional(),name:J.string(),kind:J.enum(["professional","team","collective"]),organization:J.string().optional(),brainName:J.string(),url:J.string().url(),did:J.string().optional(),status:rTA,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(UF1),notes:J.string().default("")}))});var sLQ=J.object({}).strict();function q6A(A={}){return sLQ.parse(A),[dTA()]}sA();HA();HA();var nTA=J.object({enabled:J.boolean().default(!0),pdsEndpoint:J.string().url().default("https://bsky.social").describe("AT Protocol PDS service endpoint"),identifier:J.string().optional().describe("PDS login identifier, usually a handle or account DID"),repoDid:J.string().optional().describe("DID of the PDS repo that owns records"),appPassword:J.string().optional().describe("App password for prototype authentication; supply via ${ENV_VAR} interpolation, never a committed literal"),anchorDid:J.string().optional().describe("Optional human/operator DID referenced from records; defaults to did:web:<site-host>:anchor when omitted"),brainDid:J.string().optional().describe("Optional public brain DID referenced from records; defaults to did:web:<site-host> when omitted")});function aLQ(A){return A.replace(/\/+$/,"")}var tLQ=(A,Q)=>fetch(A,Q);async function Gl(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 Fl{pdsEndpoint;identifier;appPassword;fetchFn;session;constructor(A){this.pdsEndpoint=aLQ(A.pdsEndpoint),this.identifier=A.identifier,this.appPassword=A.appPassword,this.fetchFn=A.fetch??tLQ}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 Gl(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 Gl(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 Gl(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 Gl(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 Gl(B)}async getSession(){return this.session??=await this.createSession(),this.session}}function GM(A){return A?.startsWith("did:web:")??!1}function L6A(A){if(!GM(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 KF1(A){if(!GM(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 ZF1(A){return A.replace(/\/+$/,"")}function Kl(A){return`did:web:${encodeURIComponent(A)}`}function E6A(A){return`${Kl(A)}:anchor`}function oTA(A){return{"@context":["https://www.w3.org/ns/did/v1"],id:A}}function NF1(A,Q){let B=A.identifier?.startsWith("did:")?void 0:A.identifier?[`at://${A.identifier}`]:void 0;return{...oTA(Q),...B&&{alsoKnownAs:B},service:[{id:"#atproto_pds",type:"AtprotoPersonalDataServer",serviceEndpoint:ZF1(A.pdsEndpoint)}]}}function zF1(A){if(!GM(A.brainDid))return null;return NF1(A,A.brainDid)}function FF1(A,Q){if(!A||!Q)return;let B=L6A(A),w=KF1(A);if(!B||!w)return;return{path:w,hostname:B,document:Q}}function V6A(A){let Q=[],B=FF1(A.brainDid,zF1(A));if(B)Q.push(B);if(GM(A.anchorDid)&&A.anchorDid!==A.brainDid){let w=FF1(A.anchorDid,oTA(A.anchorDid));if(w)Q.push(w)}return Q}function sTA(A,Q){let B=[];if(!A.brainDid){let w=Kl(Q);B.push({path:"/.well-known/did.json",hostname:Q,document:NF1(A,w)})}if(!A.anchorDid){let w=E6A(Q);B.push({path:"/anchor/did.json",hostname:Q,document:oTA(w)})}return B}function eLQ(A,Q){if(!A)return;try{return new URL(A,Q).toString()}catch{return}}function AEQ(A){let Q=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,200);return Q.length>0?Q:"skill"}function qF1(A,Q){let B=A[Q];return typeof B==="string"&&B.length>0?B:void 0}function LF1(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 QEQ(A){let Q=A.metadata,B=qF1(Q,"name"),w=qF1(Q,"description");if(!B||!w)return;let $=LF1(Q,"tags"),D=LF1(Q,"examples");return{id:AEQ(B),name:B,description:w,...$&&{tags:$},...D&&{examples:D}}}async function BEQ(A){if(!A.entityService.hasEntityType("skill"))return[];return(await A.entityService.listEntities({entityType:"skill",options:{filter:{visibilityScope:"public"}}})).map((B)=>QEQ(B)).filter((B)=>B!==void 0).slice(0,100)}async function aTA(A,Q,B=new Date){let w=A.identity.get(),$=A.identity.getProfile(),D=await A.identity.getAppInfo(),I=eLQ(A.siteUrl??$.website,void 0);if(!I)throw Error("AT Protocol brain card publishing requires siteUrl");let Y=new URL(I).hostname,X=Q.brainDid??Kl(Y),W=Q.anchorDid??E6A(Y);if(GM(X)){if(L6A(X)!==Y)throw Error("AT Protocol brain card did:web host must match siteUrl host")}let H=await BEQ(A);return{$type:"ai.rizom.brain.card",siteUrl:I,brain:{did:X,name:w.name,role:w.role,purpose:w.purpose,values:w.values},anchor:{did:W,name:$.name,kind:$.kind},skills:H,model:D.model,version:D.version,createdAt:B.toISOString(),updatedAt:B.toISOString()}}HA();var EF1={dryRun:J.boolean().default(!1).describe("Build and return the card record without writing to the PDS")},wEQ={},VF1={entityType:J.string().describe("Local entity type with a registered AT Protocol projection"),entityId:J.string().optional().describe("Local entity ID to publish"),slug:J.string().optional().describe("Local entity slug to publish"),dryRun:J.boolean().default(!1).describe("Build and return the record without writing to the PDS"),topics:J.array(J.string()).optional().describe("Optional topic labels to include in the AT Protocol record")},MF1={repos:J.array(J.string().min(1)).min(1).max(50).describe("Candidate AT Protocol repo DIDs or handles to inspect")},OF1={entityId:J.string().optional().describe("Local blog post entity ID to publish"),slug:J.string().optional().describe("Local blog post slug to publish"),dryRun:J.boolean().default(!1).describe("Build and return the post record without writing to the PDS"),topics:J.array(J.string()).optional().describe("Optional topic labels to include in the AT Protocol record")};function CF1(A,Q,B){return[$EQ(A,Q),DEQ(A,Q,B),IEQ(A,Q,B),XEQ(A,Q,B),YEQ(A,Q,B)]}function $EQ(A,Q){return{name:`${A}_validate_credentials`,description:"Validate AT Protocol PDS credentials without publishing records.",inputSchema:wEQ,handler:async()=>{return{success:!0,data:{valid:await Q.validatePdsCredentials()}}}}}function DEQ(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:EF1,handler:async(w)=>{let $=J.object(EF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}function IEQ(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:VF1,handler:async(w)=>{let $=J.object(VF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}function YEQ(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:MF1,handler:async(w)=>{let $=J.object(MF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Discovery failed"}}}}}function XEQ(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:OF1,handler:async(w)=>{let $=J.object(OF1).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(D){return{success:!1,error:D instanceof Error?D.message:"Publish failed"}}}}}var bF1={name:"@brains/atproto",private:!0,version:"0.2.0-alpha.109",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 RF1=ww["ai.rizom.brain.card"],fEQ="ai.rizom.brain.card",HEQ="self",PF1=50;class tTA extends QB{deps;projectionRegistry;constructor(A={},Q={}){super("atproto",bF1,A,nTA);this.deps=Q,this.projectionRegistry=Q.projectionRegistry??k6.getInstance()}getWebRoutes(){if(!this.config.enabled)return[];let A=V6A(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 D=new URL($.url).hostname,I=[...V6A(this.config),...sTA(this.config,D)].filter((X)=>X.path===w),Y=I.find((X)=>X.hostname===D)??I[0];if(!Y)return new Response("Not found",{status:404});return new Response(JSON.stringify(Y.document),{headers:{"Content-Type":"application/did+json"}})}}))}async publishBrainCard(A,Q={}){let B=await aTA(A,this.config);TN(RF1,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 D=this.createPdsClient($),I=await D.createSession(),Y=w??I.did;if(!D.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let X=await D.putRecord({repo:Y,collection:"ai.rizom.brain.card",rkey:"self",validate:!1,record:B});return{record:B,repo:Y,uri:X.uri,cid:X.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((D)=>D.trim()))].filter((D)=>D.length>0);if(B.length===0)throw Error("AT Protocol discovery requires at least one repo DID or handle");if(B.length>PF1)throw Error(`AT Protocol discovery accepts at most ${PF1} repos per batch`);let w=new Set,$=[];for(let D of B)try{let I=await this.resolveRepoPdsEndpoint(D),Y=this.createPublicPdsClient(I.pdsEndpoint);if(!Y.getRecord)throw Error("AT Protocol PDS client does not support record reads");let X=await Y.getRecord({repo:I.repoDid,collection:fEQ,rkey:HEQ});TN(RF1,X.value);let W=JEQ(X.uri)??I.repoDid,H=`${W}:${X.uri}:${X.cid}`;if(w.has(H)){$.push({repo:D,status:"skipped",repoDid:W,uri:X.uri,cid:X.cid,error:"Duplicate brain card in discovery batch"});continue}w.add(H),await A.messaging.send({type:nwA,payload:{repoDid:W,uri:X.uri,cid:X.cid,record:X.value},broadcast:!0}),$.push({repo:D,status:"discovered",repoDid:W,uri:X.uri,cid:X.cid})}catch(I){$.push({repo:D,status:"skipped",error:x0(I)})}return{discovered:$.filter((D)=>D.status==="discovered").length,skipped:$.filter((D)=>D.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:x0(Q)}),!1}}async getTools(){if(!this.config.enabled)return[];return CF1(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 D=this.config.repoDid;if(Q.dryRun){let K=await B.buildRecord({entity:w,context:A,config:this.config,...Q.topics&&{topics:Q.topics},dryRun:!0});return TN(B.lexicon,K),{record:K,dryRun:!0,...D&&{repo:D}}}let I=this.resolveAppPassword();if(!this.config.identifier||!I)throw Error("AT Protocol publishing requires identifier and app password configuration");let Y=this.createPdsClient(I),X=await Y.createSession(),W=D??X.did,H=await B.buildRecord({entity:w,context:A,config:this.config,client:Y,...Q.topics&&{topics:Q.topics}});if(TN(B.lexicon,H),!Y.putRecord)throw Error("AT Protocol PDS client does not support record upserts");let F=await Y.putRecord({repo:W,collection:B.collection,rkey:UEQ(w.id),...B.validate!==void 0&&{validate:B.validate},record:H});return await B.onPublished?.({entity:w,context:A,record:H,uri:F.uri,cid:F.cid}),{record:H,repo:W,uri:F.uri,cid:F.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 Fl({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(GEQ(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 Fl({pdsEndpoint:this.config.pdsEndpoint,identifier:this.config.identifier??"",appPassword:A})}resolveAppPassword(){return this.config.appPassword}}function UEQ(A){let Q=A.replace(/[^A-Za-z0-9._~:-]/g,"_").slice(0,512);return Q.length>0?Q:"self"}function JEQ(A){return/^at:\/\/([^/]+)/.exec(A)?.[1]}function GEQ(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 M6A(A,Q){return new tTA(A,Q)}sA();HA();Hw();u6();HA();sA();var O6A=In.extend({expertise:J.array(J.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:J.string().optional().describe("What you're currently working on"),availability:J.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),nN=wW.extend(O6A.shape);sA();tJ();HA();var FEQ=new KH;class C6A{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,[$,D,I,Y]=await Promise.all([RC(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Vp(w)]),X=FEQ.parseProfileBody($,nN),W=D.sort(Kx).slice(0,3).map(Cp),H=I.sort(Kx).slice(0,3).map(jp);if(!Y.cta)throw Error("CTA not configured in site-info");let F={profile:X,posts:W,decks:H,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:Y.cta,sections:Y.sections??{}};return Q.parse(F)}}sA();tJ();var KEQ=new KH;class b6A{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await RC(B.entityService),D={profile:KEQ.parseProfileBody(w,nN)};return Q.parse(D)}}import{jsxDEV as dw,Fragment as zEQ}from"preact/jsx-dev-runtime";var ZEQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",NEQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",eTA=({number:A,title:Q,blurb:B,children:w})=>dw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:dw("div",{className:"max-w-6xl mx-auto",children:dw("div",{className:ZEQ,children:[dw(FjA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),dw("div",{className:NEQ,"aria-hidden":"true"},void 0,!1,void 0,this),dw("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),AgA=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:D,sections:I})=>{let Y=A.tagline||A.description,X=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})),W=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})),H=A.name||"Home",F=A.intro||A.description||Y||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return dw(zEQ,{children:[dw(fQ,{title:H,description:F,ogType:"website"},void 0,!1,void 0,this),dw("div",{className:"homepage-list bg-theme",children:[dw("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:dw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&dw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[dw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),dw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y&&dw("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:XBA(Y,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&dw("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:XBA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),dw(eTA,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:dw(YBA,{items:X,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),W.length>0&&dw(eTA,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:dw(YBA,{items:W,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&dw(eTA,{number:"03",title:"About",blurb:I.about?.blurb,children:dw("div",{className:"flex flex-col gap-8",children:[A.description&&dw("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&&dw(KjA,{subjects:A.expertise},void 0,!1,void 0,this),dw("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",dw("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),dw(AjA,{cta:D,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 $w,Fragment as qEQ}from"preact/jsx-dev-runtime";var QgA=({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 $w(qEQ,{children:[$w(fQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),$w("div",{className:"about-page bg-theme",children:[$w("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:$w("div",{className:"relative z-10 max-w-4xl mx-auto",children:[$w("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&&$w("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),$w("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&$w("section",{className:"content-section-reveal mb-20 md:mb-28",children:$w(B$,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&$w("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),$w("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,D)=>$w("li",{className:Oc({variant:"accent",size:"lg"}),children:$},D,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),$w("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&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),$w("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)&&$w("section",{children:[$w("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),$w("div",{className:"space-y-4",children:[A.email&&$w("p",{className:"text-lg",children:$w("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&&$w("p",{className:"text-lg",children:$w("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&&$w("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,D)=>$w(Q$,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},D,!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 Z7,Fragment as kF1}from"preact/jsx-dev-runtime";var BgA=()=>{return Z7(kF1,{children:[Z7(fQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),Z7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:Z7("div",{className:"text-center max-w-md",children:[Z7("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),Z7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),Z7("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),Z7(Q$,{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)},wgA=()=>{return Z7(kF1,{children:[Z7(fQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),Z7("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:Z7("div",{className:"text-center max-w-md",children:[Z7("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),Z7("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),Z7("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),Z7(Q$,{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)};HA();var jF1=J.object({label:J.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:J.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),_F1=J.object({entityDisplay:J.object({post:jF1,deck:jF1}).describe("Display metadata for post and deck entity types (required for homepage)")});var yF1={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.109",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 $gA extends QB{dependencies=["blog","decks"];constructor(A){super("professional-site",yF1,A,_F1)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",O6A);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,D=new C6A(w,$);A.entities.registerDataSource(D);let I=new b6A;A.entities.registerDataSource(I);let Y=J.object({profile:nN,posts:J.array(cF),decks:J.array(eV),postsListUrl:J.string(),decksListUrl:J.string(),cta:TyA,sections:J.record(J.string(),Kr)}),X=J.object({profile:nN}),W=J.object({});A.templates.register({"homepage-list":R1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:Y,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:AgA}}),about:R1({name:"about",description:"About page with full profile information",schema:X,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:QgA}}),"subscribe-thanks":R1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:W,requiredPermission:"public",layout:{component:BgA}}),"subscribe-error":R1({name:"subscribe-error",description:"Newsletter subscription error page",schema:W,requiredPermission:"public",layout:{component:wgA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function xF1(A){return new $gA(A??{})}var vF1=[{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 R6A}from"preact/jsx-dev-runtime";function TF1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return R6A("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[R6A($jA,{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),R6A("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),R6A(BjA,{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 EEQ={layouts:{default:TF1},routes:vF1,plugin:xF1,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"}}}},Zl=EEQ;var gF1=`/*
8177
8177
  * Default theme \u2014 simplified editorial base inspired by the Rizom family.
8178
8178
  *
8179
8179
  * This theme is intentionally less branded than @brains/theme-rizom. It
@@ -8561,8 +8561,8 @@ ${JSON.stringify(B,null,2)}`}function K6A(A){return A.map((Q)=>Q.detail===null?{
8561
8561
 
8562
8562
  .btn-primary:disabled { opacity: 0.5; }
8563
8563
  }
8564
- `;var L_=gF1;import{join as OEQ}from"path";var SF1={name:"@brains/rover",version:"0.2.0-alpha.108",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 hF1=["prompt","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],mF1=[...hF1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],CEQ=[...mF1,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo"],bEQ=["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."],uF1=uZ({name:"rover",version:SF1.version,model:"gpt-5.4-mini",site:Zl,theme:L_,presets:{core:hF1,default:mF1,full:CEQ},evalDisable:["discord","webserver","web-chat","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:bEQ,capabilities:[["prompt",HM,void 0],["image",mg,void 0],["cms",fM,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Ph,void 0],["notifications",Te,void 0],["email-resend",UQA,void 0],["dashboard",dN,void 0],["dashboard-root",dN,{routePath:"/"}],["blog",wxA,{}],["series",WxA,void 0],["decks",_p,void 0],["document",PxA,void 0],["note",QM,{}],["link",$M,{}],["portfolio",QvA,{}],["topics",b8A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",gvA,{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",lp,{autoGenerateOnBlogPublish:!0}],["newsletter",lJ1,{doubleOptIn:!0}],["obsidian-vault",ITA,{autoSync:!0}],["wishlist",r8A,{}],["stock-photo",GTA,{}],["agents",f6A,void 0],["assessment",q6A,void 0],["atproto",M6A,void 0],["directory-sync",XV,{seedContent:!0,seedContentPath:OEQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h8A,{}],["rizom-ecosystem",UM,void 0],["site-info",rV,void 0],["site-builder",dV,{cms:{}}]],interfaces:[["mcp",L3,()=>({})],["discord",BN,()=>({})],["webserver",wN,()=>({})],["web-chat",Sk,()=>({})],["a2a",hk,()=>({})]],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"}}});lZ();sA();HA();var cF1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.108",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 lF1=J.object({enabled:J.boolean().default(!0)}),DgA="/atproto/lexicons";function pF1(A){return new Response(`${JSON.stringify(A,null,2)}
8565
- `,{headers:{"Content-Type":"application/json"}})}class IgA extends QB{constructor(A={}){super("atproto-registry",cF1,A,lF1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${DgA}/index.json`,method:"GET",public:!0,handler:()=>pF1(this.getIndex())},...nV().map((A)=>({path:`${DgA}/${A.id}.json`,method:"GET",public:!0,handler:()=>pF1(A)}))]}getIndex(){return{lexicons:uyA().map((A)=>({...A,path:`${DgA}/${A.id}.json`}))}}getLexicon(A){return myA(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:J.string().describe("Canonical lexicon NSID"),record:J.record(J.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=J.object({nsid:J.string(),record:J.record(J.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 TN(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:nV().length,nsids:nV().map((A)=>A.id),metadata:uyA()}})}}}function YgA(A={}){return new IgA(A)}sA();HA();HA();sA();var P6A=J.object({routeId:J.string(),sectionId:J.string()}),Nl=e1.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:P6A});sA();class iF1 extends N2{constructor(){super({entityType:"site-content",schema:Nl,frontmatterSchema:P6A})}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 XgA=new iF1;HA();var k6A=J.object({routeId:J.string().optional().describe("Optional: specific route filter"),sectionId:J.string().optional().describe("Optional: specific section filter"),dryRun:J.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:J.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),kQ8=J.object({jobs:J.array(J.object({jobId:J.string(),routeId:J.string(),sectionId:J.string()})),totalSections:J.number(),queuedSections:J.number(),skippedSections:J.number().optional(),batchId:J.string().optional()});class WgA{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(),D=$;if(A.routeId){if(D=$.filter((H)=>H.id===A.routeId),D.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let H of D)for(let F of H.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:H.id,sectionId:F.id});continue}if(F.template){let K=this.context.templates.getCapabilities(F.template);if(!K){w.warn("Template not found, skipping section",{routeId:H.id,sectionId:F.id,templateName:F.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:H.id,sectionId:F.id,templateName:F.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:H.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let K=`${H.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:H.id,sectionId:F.id});continue}}I.push({route:H,section:F})}let Y=I.length;if(A.dryRun)return{jobs:[],totalSections:Y,queuedSections:Y,batchId:`dry-run-${Date.now()}`};let X=[],W=[];for(let{route:H,section:F}of I){let K=`${H.id}:${F.id}`,Z=F.template,q={routeId:H.id,sectionId:F.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:H.id,sectionId:F.id,routeTitle:H.title??Q?.title??"",routeDescription:H.description??Q?.description??"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};W.push({type:"shell:content-generation",data:q})}if(W.length>0){let H=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(W,H);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)X.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:X,totalSections:Y,queuedSections:X.length,batchId:F}}return{jobs:[],totalSections:Y,queuedSections:0,batchId:`empty-${Date.now()}`}}}class fgA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new WgA(A)}async generateContent(A,Q){let B=k6A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}b$();HA();function zl(A,Q){return Q?A.optional():A}function UgA(A){switch(A.type){case"string":return zl(J.string(),A.optional);case"number":return zl(J.number(),A.optional);case"enum":{let Q=[...A.options];return zl(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=UgA(w);return zl(J.object(Q),A.optional)}case"array":{let Q=J.array(PEQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return zl(Q,A.optional)}}}function PEQ(A){let{items:Q}=A;switch(Q.type){case"string":return J.string();case"number":return J.number();case"enum":{let B=[...Q.options];return J.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=UgA($);return J.object(B)}}}function HgA(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])=>HgA(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,$])=>HgA(w,$)),B}}}}function kEQ(A,Q){let B={};for(let[D,I]of Object.entries(Q.fields))B[D]=UgA(I);let w=J.object(B),$=new xB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([D,I])=>HgA(D,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 JgA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,kEQ(Q,B)]))}HA();var dF1=J.object({namespace:J.string(),sections:J.record(J.any())}),rF1=J.object({definitions:J.union([dF1,J.array(dF1)]).optional()});sA();function nF1(A,Q){return[uQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",k6A,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 D={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,D);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 oF1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.108",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 GgA extends QB{siteContentService;constructor(A={}){super("site-content",oF1,A,rF1)}async onRegister(A){A.entities.register("site-content",Nl,XgA);for(let Q of DH(this.config.definitions))A.templates.register(JgA(Q),Q.namespace);this.siteContentService=new fgA(A)}async getTools(){return nF1(()=>this.siteContentService,this.id)}}function ql(A={}){return new GgA(A)}sA();HA();Hw();HA();sA();var sF1=J.enum(["available","early access","coming soon","planned"]),aF1=J.object({title:J.string(),description:J.string()}),pI=J.object({name:J.string(),availability:sF1,order:J.number(),ogImageId:J.string().optional()}),j6A=J.object({tagline:J.string(),promise:J.string(),role:J.string(),purpose:J.string(),audience:J.string(),values:J.array(J.string()).min(1),features:J.array(aF1).min(1).max(6),story:J.string()}),_EQ=pI.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),E_=e1.extend({entityType:J.literal("product"),metadata:_EQ}),_6A=E_.extend({frontmatter:pI,body:j6A,labels:J.record(J.string(),J.string()),ogImageUrl:J.string().optional()}),y6A=_6A.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),ogImageUrl:J.string().optional()});sA();HA();b$();class V_ extends xB{constructor(){super(j6A,{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 FgA extends N2{constructor(){super({entityType:"product",schema:E_,frontmatterSchema:pI,bodyFormatter:new V_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,pI);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,pI),B=b1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var x6A=new FgA;HA();sA();var tF1=J.object({title:J.string(),description:J.string()}),eF1=J.object({title:J.string(),description:J.string()}),yEQ=J.object({title:J.string(),description:J.string()}),AK1=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),sF=J.object({headline:J.string(),tagline:J.string()}),xEQ=J.object({title:J.string(),description:J.string()}),v6A=J.object({vision:J.string(),pillars:J.array(tF1).min(1).max(6),approach:J.array(xEQ).min(1).max(6),productsIntro:J.string(),technologies:J.array(yEQ).min(1).max(6),benefits:J.array(eF1).min(1).max(6),cta:AK1}),QK1=sF.pick({headline:!0}).extend({slug:J.string()}),M_=e1.extend({entityType:J.literal("products-overview"),metadata:QK1}),Ll=M_.extend({frontmatter:sF,body:v6A,labels:J.record(J.string(),J.string())});sA();HA();b$();class O_ extends xB{constructor(){super(v6A,{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 KgA extends N2{constructor(){super({entityType:"products-overview",schema:M_,frontmatterSchema:sF,bodyFormatter:new O_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=b1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var ZgA=new KgA;sA();HA();var vEQ=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function BK1(A,Q){let B=O2(A.content,pI),w=Q.parse(B.content),$=Q.getLabels();return _6A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function wK1(A,Q){let B=O2(A.content,sF),w=Q.parse(B.content),$=Q.getLabels();return Ll.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class T6A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new O_;productFormatter=new V_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=vEQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let W=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!W)throw Error("Products overview entity not found");let H=wK1(W,this.overviewFormatter);return Q.parse(H)}if(w.query?.id){let W=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!W)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:BK1(W,this.productFormatter)})}let[D,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),Y=D[0];if(!Y)throw Error("Products overview entity not found");return Q.parse({overview:wK1(Y,this.overviewFormatter),products:I.map((X)=>BK1(X,this.productFormatter))})}}import{jsxDEV as A1,Fragment as SEQ}from"preact/jsx-dev-runtime";var $K1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(SEQ,{children:[A1(fQ,{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:`
8564
+ `;var L_=gF1;import{join as OEQ}from"path";var SF1={name:"@brains/rover",version:"0.2.0-alpha.109",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 hF1=["prompt","note","link","wishlist","topics","directory-sync","atproto","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","web-chat","discord","a2a"],mF1=[...hF1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],CEQ=[...mF1,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo"],bEQ=["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."],uF1=uZ({name:"rover",version:SF1.version,model:"gpt-5.4-mini",site:Zl,theme:L_,presets:{core:hF1,default:mF1,full:CEQ},evalDisable:["discord","webserver","web-chat","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:bEQ,capabilities:[["prompt",HM,void 0],["image",mg,void 0],["cms",fM,(A)=>({...A.CMS_CONTENT_REPO_PAT?{passkeyLogin:{contentRepoToken:A.CMS_CONTENT_REPO_PAT}}:{}})],["auth-service",Ph,void 0],["notifications",Te,void 0],["email-resend",UQA,void 0],["dashboard",dN,void 0],["dashboard-root",dN,{routePath:"/"}],["blog",wxA,{}],["series",WxA,void 0],["decks",_p,void 0],["document",PxA,void 0],["note",QM,{}],["link",$M,{}],["portfolio",QvA,{}],["topics",b8A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",gvA,{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",lp,{autoGenerateOnBlogPublish:!0}],["newsletter",lJ1,{doubleOptIn:!0}],["obsidian-vault",ITA,{autoSync:!0}],["wishlist",r8A,{}],["stock-photo",GTA,{}],["agents",f6A,void 0],["assessment",q6A,void 0],["atproto",M6A,(A)=>({...A.ATPROTO_APP_PASSWORD?{appPassword:A.ATPROTO_APP_PASSWORD}:{}})],["directory-sync",XV,{seedContent:!0,seedContentPath:OEQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",h8A,{}],["rizom-ecosystem",UM,void 0],["site-info",rV,void 0],["site-builder",dV,{cms:{}}]],interfaces:[["mcp",L3,()=>({})],["discord",BN,()=>({})],["webserver",wN,()=>({})],["web-chat",Sk,()=>({})],["a2a",hk,()=>({})]],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"}}});lZ();sA();HA();var cF1={name:"@brains/atproto-registry",private:!0,version:"0.2.0-alpha.109",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 lF1=J.object({enabled:J.boolean().default(!0)}),DgA="/atproto/lexicons";function pF1(A){return new Response(`${JSON.stringify(A,null,2)}
8565
+ `,{headers:{"Content-Type":"application/json"}})}class IgA extends QB{constructor(A={}){super("atproto-registry",cF1,A,lF1)}getWebRoutes(){if(!this.config.enabled)return[];return[{path:`${DgA}/index.json`,method:"GET",public:!0,handler:()=>pF1(this.getIndex())},...nV().map((A)=>({path:`${DgA}/${A.id}.json`,method:"GET",public:!0,handler:()=>pF1(A)}))]}getIndex(){return{lexicons:uyA().map((A)=>({...A,path:`${DgA}/${A.id}.json`}))}}getLexicon(A){return myA(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:J.string().describe("Canonical lexicon NSID"),record:J.record(J.unknown()).describe("Record payload to validate")},handler:async(A)=>{let Q=J.object({nsid:J.string(),record:J.record(J.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 TN(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:nV().length,nsids:nV().map((A)=>A.id),metadata:uyA()}})}}}function YgA(A={}){return new IgA(A)}sA();HA();HA();sA();var P6A=J.object({routeId:J.string(),sectionId:J.string()}),Nl=e1.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:P6A});sA();class iF1 extends N2{constructor(){super({entityType:"site-content",schema:Nl,frontmatterSchema:P6A})}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 XgA=new iF1;HA();var k6A=J.object({routeId:J.string().optional().describe("Optional: specific route filter"),sectionId:J.string().optional().describe("Optional: specific section filter"),dryRun:J.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:J.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),kQ8=J.object({jobs:J.array(J.object({jobId:J.string(),routeId:J.string(),sectionId:J.string()})),totalSections:J.number(),queuedSections:J.number(),skippedSections:J.number().optional(),batchId:J.string().optional()});class WgA{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(),D=$;if(A.routeId){if(D=$.filter((H)=>H.id===A.routeId),D.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let H of D)for(let F of H.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:H.id,sectionId:F.id});continue}if(F.template){let K=this.context.templates.getCapabilities(F.template);if(!K){w.warn("Template not found, skipping section",{routeId:H.id,sectionId:F.id,templateName:F.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:H.id,sectionId:F.id,templateName:F.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:H.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let K=`${H.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:H.id,sectionId:F.id});continue}}I.push({route:H,section:F})}let Y=I.length;if(A.dryRun)return{jobs:[],totalSections:Y,queuedSections:Y,batchId:`dry-run-${Date.now()}`};let X=[],W=[];for(let{route:H,section:F}of I){let K=`${H.id}:${F.id}`,Z=F.template,q={routeId:H.id,sectionId:F.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:H.id,sectionId:F.id,routeTitle:H.title??Q?.title??"",routeDescription:H.description??Q?.description??"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};W.push({type:"shell:content-generation",data:q})}if(W.length>0){let H=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(W,H);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)X.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:X,totalSections:Y,queuedSections:X.length,batchId:F}}return{jobs:[],totalSections:Y,queuedSections:0,batchId:`empty-${Date.now()}`}}}class fgA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new WgA(A)}async generateContent(A,Q){let B=k6A.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}b$();HA();function zl(A,Q){return Q?A.optional():A}function UgA(A){switch(A.type){case"string":return zl(J.string(),A.optional);case"number":return zl(J.number(),A.optional);case"enum":{let Q=[...A.options];return zl(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=UgA(w);return zl(J.object(Q),A.optional)}case"array":{let Q=J.array(PEQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return zl(Q,A.optional)}}}function PEQ(A){let{items:Q}=A;switch(Q.type){case"string":return J.string();case"number":return J.number();case"enum":{let B=[...Q.options];return J.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=UgA($);return J.object(B)}}}function HgA(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])=>HgA(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,$])=>HgA(w,$)),B}}}}function kEQ(A,Q){let B={};for(let[D,I]of Object.entries(Q.fields))B[D]=UgA(I);let w=J.object(B),$=new xB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([D,I])=>HgA(D,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 JgA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,kEQ(Q,B)]))}HA();var dF1=J.object({namespace:J.string(),sections:J.record(J.any())}),rF1=J.object({definitions:J.union([dF1,J.array(dF1)]).optional()});sA();function nF1(A,Q){return[uQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",k6A,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 D={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,D);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 oF1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.109",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 GgA extends QB{siteContentService;constructor(A={}){super("site-content",oF1,A,rF1)}async onRegister(A){A.entities.register("site-content",Nl,XgA);for(let Q of DH(this.config.definitions))A.templates.register(JgA(Q),Q.namespace);this.siteContentService=new fgA(A)}async getTools(){return nF1(()=>this.siteContentService,this.id)}}function ql(A={}){return new GgA(A)}sA();HA();Hw();HA();sA();var sF1=J.enum(["available","early access","coming soon","planned"]),aF1=J.object({title:J.string(),description:J.string()}),pI=J.object({name:J.string(),availability:sF1,order:J.number(),ogImageId:J.string().optional()}),j6A=J.object({tagline:J.string(),promise:J.string(),role:J.string(),purpose:J.string(),audience:J.string(),values:J.array(J.string()).min(1),features:J.array(aF1).min(1).max(6),story:J.string()}),_EQ=pI.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),E_=e1.extend({entityType:J.literal("product"),metadata:_EQ}),_6A=E_.extend({frontmatter:pI,body:j6A,labels:J.record(J.string(),J.string()),ogImageUrl:J.string().optional()}),y6A=_6A.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),ogImageUrl:J.string().optional()});sA();HA();b$();class V_ extends xB{constructor(){super(j6A,{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 FgA extends N2{constructor(){super({entityType:"product",schema:E_,frontmatterSchema:pI,bodyFormatter:new V_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,pI);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,pI),B=b1(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var x6A=new FgA;HA();sA();var tF1=J.object({title:J.string(),description:J.string()}),eF1=J.object({title:J.string(),description:J.string()}),yEQ=J.object({title:J.string(),description:J.string()}),AK1=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),sF=J.object({headline:J.string(),tagline:J.string()}),xEQ=J.object({title:J.string(),description:J.string()}),v6A=J.object({vision:J.string(),pillars:J.array(tF1).min(1).max(6),approach:J.array(xEQ).min(1).max(6),productsIntro:J.string(),technologies:J.array(yEQ).min(1).max(6),benefits:J.array(eF1).min(1).max(6),cta:AK1}),QK1=sF.pick({headline:!0}).extend({slug:J.string()}),M_=e1.extend({entityType:J.literal("products-overview"),metadata:QK1}),Ll=M_.extend({frontmatter:sF,body:v6A,labels:J.record(J.string(),J.string())});sA();HA();b$();class O_ extends xB{constructor(){super(v6A,{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 KgA extends N2{constructor(){super({entityType:"products-overview",schema:M_,frontmatterSchema:sF,bodyFormatter:new O_})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,sF);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,sF),B=b1(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var ZgA=new KgA;sA();HA();var vEQ=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function BK1(A,Q){let B=O2(A.content,pI),w=Q.parse(B.content),$=Q.getLabels();return _6A.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function wK1(A,Q){let B=O2(A.content,sF),w=Q.parse(B.content),$=Q.getLabels();return Ll.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class T6A{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new O_;productFormatter=new V_;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=vEQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let W=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!W)throw Error("Products overview entity not found");let H=wK1(W,this.overviewFormatter);return Q.parse(H)}if(w.query?.id){let W=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!W)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:BK1(W,this.productFormatter)})}let[D,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),Y=D[0];if(!Y)throw Error("Products overview entity not found");return Q.parse({overview:wK1(Y,this.overviewFormatter),products:I.map((X)=>BK1(X,this.productFormatter))})}}import{jsxDEV as A1,Fragment as SEQ}from"preact/jsx-dev-runtime";var $K1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return A1(SEQ,{children:[A1(fQ,{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:`
8566
8566
  @keyframes wave-drift {
8567
8567
  from { transform: translateX(0); }
8568
8568
  to { transform: translateX(-50%); }
@@ -8757,7 +8757,7 @@ ${JSON.stringify(B,null,2)}`}function K6A(A){return A.map((Q)=>Q.detail===null?{
8757
8757
  font: 10px/1.45 var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
8758
8758
  }
8759
8759
  `}},void 0,!1,void 0,this),lI("section",{className:"product-shell",children:[lI("header",{className:"product-hero",children:[Q.brandLabel&&lI("p",{className:"printable-kicker",children:Q.brandLabel},void 0,!1,void 0,this),lI("h1",{className:"printable-title",children:Q.name},void 0,!1,void 0,this),Q.availability&&lI("div",{className:"printable-meta",children:lI("span",{children:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),lI("div",{className:"product-body-wrap",children:[lI("aside",{className:"product-rail","aria-hidden":"true",children:lI("p",{className:"product-rail-label",children:"Product brief / capabilities"},void 0,!1,void 0,this)},void 0,!1,void 0,this),lI(B$,{markdown:Q.body,className:"printable-body"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.brandLabel&&lI("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 dEQ=26214400,rEQ=60000;class zgA{context;renderPdf;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Nf}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==g6A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let B=nEQ(Q,{brandLabel:this.resolveBrandLabel()}),w=await cEQ(iEQ(lEQ(),"brain-product-printable-"));try{let $=await mI({outputDir:w,mediaPath:`/_media/printable/product/${Q.id}`,template:YK1,format:"pdf",content:B,siteConfig:{title:B.name,themeMode:"light"},themeCSS:this.context.themeCSS}),D=await uI({rootDir:w});try{return{type:"document",data:await this.renderPdf(D.urlFor($.urlPath),{maxBytes:dEQ,timeoutMs:rEQ,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${oEQ(Q)}-printable.pdf`}}finally{await D.close()}}finally{await pEQ(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 nEQ(A,Q={}){let{frontmatter:B,content:w}=yB(A.content),$=pI.parse(B);return{name:$.name,body:w,availability:$.availability,...Q.brandLabel?{brandLabel:Q.brandLabel}:{}}}function oEQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.name)}HA();HA();import{jsxDEV as tEQ}from"preact/jsx-dev-runtime";var S6A="og-image",sEQ="products:og-image",XK1=J.object({name:J.string().min(1),tagline:J.string().optional(),availability:J.string().optional(),brandLabel:J.string().optional()}),WK1={name:sEQ,pluginId:"products",schema:XK1,renderers:{image:aEQ}};function aEQ(A){let Q=XK1.parse(A);return tEQ(MF,{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 qgA{context;deps;constructor(A,Q={}){this.context=A;this.deps=Q}async resolve(A){if(A.sourceEntityType!=="product"||A.attachmentType!==S6A)return;let Q=await this.context.entityService.getEntity({entityType:"product",id:A.sourceEntityId});if(!Q)return;let{frontmatter:B,content:w}=yB(Q.content),$=pI.parse(B),D=eEQ(w,"Tagline"),I=this.resolveBrandLabel(),Y={name:$.name,availability:$.availability,...D?{tagline:D}:{},...I?{brandLabel:I}:{}};return{type:"image",data:await sV({mediaPath:`/_media/og/product/${Q.id}`,template:WK1,content:Y,title:Y.name,themeMode:"light",themeCSS:this.context.themeCSS,tmpPrefix:"brain-product-og-image-",...this.deps.screenshotPng&&{screenshotPng:this.deps.screenshotPng}}),mimeType:"image/png",filename:`${AVQ(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 eEQ(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 D=$.join(`
8760
- `).trim();return D.length>0?D:void 0}function AVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.name)}var fK1={name:"@brains/products",private:!0,version:"0.2.0-alpha.108",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 BVQ=J.object({overview:Ll,products:J.array(y6A)}),wVQ=J.object({product:y6A});class LgA extends MQ{entityType=x6A.entityType;schema=E_;adapter=x6A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",fK1,A,NgA)}getTemplates(){return{"product-list":R1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:BVQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:$K1}}),"product-detail":R1({name:"product-detail",description:"Individual product detail page",schema:wVQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:DK1}})}}getDataSources(){return[new T6A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",g6A,new zgA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",S6A,new qgA(A)),A.entities.register("products-overview",M_,ZgA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function EgA(A={}){return new LgA(A)}import{join as jVQ}from"path";import{jsxDEV as h6A,Fragment as $VQ}from"preact/jsx-dev-runtime";var C_=({children:A})=>h6A($VQ,{children:[h6A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:h6A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h6A("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 cw8}from"preact/jsx-dev-runtime";import{jsxDEV as IVQ}from"preact/jsx-dev-runtime";var m6A="px-6 md:px-10 xl:px-20",DVQ=`${m6A} relative z-[1]`,oN=({id:A,className:Q,children:B})=>IVQ("section",{id:A,className:Q2(DVQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as sw8}from"preact/jsx-dev-runtime";import{jsxDEV as ew8}from"preact/jsx-dev-runtime";import{jsxDEV as HVQ}from"preact/jsx-dev-runtime";var YVQ="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)]",XVQ={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)]"},WVQ={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)]"},fVQ="w-full md:w-auto",FM=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:D})=>HVQ("a",{href:A,className:Q2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",YVQ,XVQ[Q],WVQ[B],w&&fVQ,$),children:D},void 0,!1,void 0,this);import{jsxDEV as I88}from"preact/jsx-dev-runtime";import{jsxDEV as f88}from"preact/jsx-dev-runtime";import{Fragment as J88}from"preact";import{jsxDEV as F88}from"preact/jsx-dev-runtime";import{jsxDEV as HK1}from"preact/jsx-dev-runtime";var u6A=({sections:A})=>HK1(C_,{children:HK1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);sA();HA();var UK1=`/*
8760
+ `).trim();return D.length>0?D:void 0}function AVQ(A){let Q=A.metadata.slug;return Q.length>0?Q:b1(A.metadata.name)}var fK1={name:"@brains/products",private:!0,version:"0.2.0-alpha.109",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 BVQ=J.object({overview:Ll,products:J.array(y6A)}),wVQ=J.object({product:y6A});class LgA extends MQ{entityType=x6A.entityType;schema=E_;adapter=x6A;unregisterPrintableAttachmentProvider;unregisterOgImageAttachmentProvider;constructor(A={}){super("products",fK1,A,NgA)}getTemplates(){return{"product-list":R1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:BVQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:$K1}}),"product-detail":R1({name:"product-detail",description:"Individual product detail page",schema:wVQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:DK1}})}}getDataSources(){return[new T6A(this.logger.child("ProductsDataSource"))]}async onRegister(A){this.unregisterPrintableAttachmentProvider=A.attachments.register("product",g6A,new zgA(A)),this.unregisterOgImageAttachmentProvider=A.attachments.register("product",S6A,new qgA(A)),A.entities.register("products-overview",M_,ZgA)}async onShutdown(){this.unregisterPrintableAttachmentProvider?.(),this.unregisterPrintableAttachmentProvider=void 0,this.unregisterOgImageAttachmentProvider?.(),this.unregisterOgImageAttachmentProvider=void 0}}function EgA(A={}){return new LgA(A)}import{join as jVQ}from"path";import{jsxDEV as h6A,Fragment as $VQ}from"preact/jsx-dev-runtime";var C_=({children:A})=>h6A($VQ,{children:[h6A("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:h6A("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h6A("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 cw8}from"preact/jsx-dev-runtime";import{jsxDEV as IVQ}from"preact/jsx-dev-runtime";var m6A="px-6 md:px-10 xl:px-20",DVQ=`${m6A} relative z-[1]`,oN=({id:A,className:Q,children:B})=>IVQ("section",{id:A,className:Q2(DVQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as sw8}from"preact/jsx-dev-runtime";import{jsxDEV as ew8}from"preact/jsx-dev-runtime";import{jsxDEV as HVQ}from"preact/jsx-dev-runtime";var YVQ="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)]",XVQ={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)]"},WVQ={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)]"},fVQ="w-full md:w-auto",FM=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:D})=>HVQ("a",{href:A,className:Q2("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",YVQ,XVQ[Q],WVQ[B],w&&fVQ,$),children:D},void 0,!1,void 0,this);import{jsxDEV as I88}from"preact/jsx-dev-runtime";import{jsxDEV as f88}from"preact/jsx-dev-runtime";import{Fragment as J88}from"preact";import{jsxDEV as F88}from"preact/jsx-dev-runtime";import{jsxDEV as HK1}from"preact/jsx-dev-runtime";var u6A=({sections:A})=>HK1(C_,{children:HK1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);sA();HA();var UK1=`/*
8761
8761
  * Shared globals + helpers used by tree / constellation / roots canvas
8762
8762
  * scripts. Loaded as a shared static asset by the Rizom runtime package
8763
8763
  * so the variant canvases
@@ -11247,7 +11247,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});HA();var p
11247
11247
  `);return this.truncateContent(w||Q||v_(A))}truncateContent(A){if(A.length<=oK1)return A;let Q=A.slice(0,oK1-1),B=Q.search(/\s\S*$/);return`${(B>0?Q.slice(0,B):Q).trimEnd()}\u2026`}isSummaryEntity(A){return A.entityType===_6}isDecisionEntity(A){return A.entityType===iI}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return Mf(Q)}}var GMQ=5,FMQ=3;function _gA(A){A.messaging.subscribe(bx,async(Q)=>{let B=X4A.parse(Q.payload);return{success:!0,data:await A5A(A,B)}})}async function A5A(A,Q){let B=B9(Q.userPermissionLevel);if(!Q.channelId)return sK1(A,Q,{visibilityScope:B,reason:"no-channel-context",items:[]}),{items:[]};let w=new T_(A),$=await w.retrieve({query:Q.message,conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:GMQ,visibilityScope:B}),D=$.results.length===0?await w.retrieve({conversationId:Q.conversationId,interfaceType:Q.interfaceType,channelId:Q.channelId,limit:FMQ,visibilityScope:B}):void 0,I=$.results.length>0,Y=I?$.results:D?.results??[];return sK1(A,Q,{visibilityScope:B,spaceId:$.spaceId??D?.spaceId,reason:Y.length>0?"memory-injected":"no-same-space-memory",items:Y.map((X)=>KMQ(X,I))}),{items:Y.map(ZMQ)}}function sK1(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 KMQ(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 ZMQ(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}}}sA();e8();HA();LY();var xgA=J.object({role:pJ,content:J.string(),timestamp:J.string().datetime().optional(),actor:Mq.optional(),source:Oq.optional()}),NMQ=J.object({conversationId:J.string().default("eval-conversation"),messages:J.array(xgA)}),zMQ=J.object({conversationId:J.string()}),qMQ=J.object({conversationId:J.string().default("eval-conversation"),interfaceType:J.string().default("eval"),channelId:J.string().default("eval-channel"),channelName:J.string().optional(),projectionDecision:J.enum(["update","append"]).default("update"),existingSummary:J.string().optional(),existingMessageCount:J.number().int().min(0).default(0),messages:J.array(xgA)}),Q5A=J.object({actorId:J.string(),canonicalId:J.string().optional(),displayName:J.string().optional()}),LMQ=Q5A.extend({roles:J.array(J.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:J.array(J.string()).optional()}),EMQ=J.object({actorId:J.string().optional(),canonicalId:J.string().optional(),displayName:J.string()}),eK1=J.object({id:J.string(),entityType:J.enum(["summary","decision","action-item"]),content:J.string(),excerpt:J.string().optional(),score:J.number().optional(),conversationId:J.string(),interfaceType:J.string(),channelId:J.string(),channelName:J.string().optional(),updated:J.string().datetime().optional(),visibility:m7,status:J.string().optional(),participants:J.array(LMQ).optional(),decidedBy:J.array(Q5A).optional(),mentionedBy:J.array(Q5A).optional(),assignedTo:J.array(EMQ).optional(),requestedBy:J.array(Q5A).optional()}),VMQ=J.object({query:J.string().optional(),conversationId:J.string().optional(),interfaceType:J.string().optional(),channelId:J.string().optional(),limit:J.number().int().min(1).optional(),includeOtherSpaces:J.boolean().optional(),actorId:J.string().optional(),canonicalId:J.string().optional(),visibilityScope:m7.optional(),memory:J.array(eK1).optional()}),MMQ=J.object({conversationId:J.string().default("eval-conversation"),message:J.string(),interfaceType:J.string().default("eval"),channelId:J.string().optional(),channelName:J.string().optional(),userPermissionLevel:J.enum(["anchor","trusted","public"]).default("trusted"),memory:J.array(eK1).optional()}),OMQ=J.object({conversationId:J.string().default("eval-conversation"),existingSummary:J.string().optional(),existingMessageCount:J.number().int().min(0).default(0),messages:J.array(xgA)});function AZ1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let D=NMQ.parse($),I=ygA(D.messages,D.conversationId),X=await new __(Q,B,w).extract(I);return X.entries.map((W)=>{let H=X.decisions.filter((K)=>K.timeRange.start>=W.timeRange.start).filter((K)=>K.timeRange.end<=W.timeRange.end).map((K)=>K.text),F=X.actionItems.filter((K)=>K.timeRange.start>=W.timeRange.start).filter((K)=>K.timeRange.end<=W.timeRange.end).map((K)=>K.text);return{...W,decisions:H,actionItems:F,keyPointsText:W.keyPoints.join(`
11248
11248
  `),decisionsText:H.join(`
11249
11249
  `),actionItemsText:F.join(`
11250
- `)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let D=OMQ.parse($),I=ygA(D.messages,D.conversationId),Y=D.existingSummary?aK1({conversationId:D.conversationId,content:D.existingSummary,messageCount:D.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new aN(Q,B,w).decideProjection(I,Y)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let D=VMQ.parse($),I=D.memory?tK1(Q,D.memory):Q;return new T_(I).retrieve(D)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let D=MMQ.parse($),I=D.memory?tK1(Q,D.memory):Q;return A5A(I,D)}),Q.eval.registerHandler("projectMessages",async($)=>{let D=qMQ.parse($),I=ygA(D.messages,D.conversationId),Y=CMQ({conversationId:D.conversationId,interfaceType:D.interfaceType,channelId:D.channelId,channelName:D.channelName,messages:I}),X=D.existingSummary?aK1({conversationId:D.conversationId,content:D.existingSummary,messageCount:D.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,W=[],H=[],F=bMQ({context:Q,conversation:Y,messages:I,existing:X,upserted:W,deleted:H,projectionDecision:D.projectionDecision});return{result:await new aN(F,B,w).projectConversation(D.conversationId),summaries:W.filter((q)=>q.entityType==="summary"),decisions:W.filter((q)=>q.entityType==="decision"),actionItems:W.filter((q)=>q.entityType==="action-item"),deleted:H}}),Q.eval.registerHandler("projectConversation",async($)=>{let D=zMQ.parse($);return new aN(Q,B,w).projectConversation(D.conversationId)})}function aK1(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 ygA(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 CMQ(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 bMQ(A){let Q=Mf(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 tK1(A,Q){let B=Q.map(RMQ),w=B.map(($,D)=>({entity:$,score:Q[D]?.score??1,excerpt:Q[D]?.excerpt??v_($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((D)=>D.entityType===$)}}}function RMQ(A){if(A.entityType==="summary")return PMQ(A);if(A.entityType==="decision")return kMQ(A);return jMQ(A)}function vgA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:bB(A.content),visibility:A.visibility,created:Q,updated:Q}}function PMQ(A){return{...vgA(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 kMQ(A){return{...vgA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:Mf(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 jMQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...vgA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:Mf(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 QZ1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.108",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 yMQ=new UX,xMQ=new P_,vMQ=new k_,TMQ=J.object({conversationId:J.string()});class TgA extends MQ{entityType=_6;schema=Vl;adapter=yMQ;constructor(A={}){super(p6A,QZ1,A,CgA)}getConfig(){return this.config}getTemplates(){return{"summary-list":bK1,"summary-detail":RK1,"ai-response":PK1}}getDataSources(){return[new jgA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:_6,job:{type:qK1,handler:new o6A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await Lq(A,_6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:OgA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:p6A}}},sourceChange:{sourceKind:Xv,sourceTypes:[Xv],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[VC],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:OgA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:p6A}}}}}]}parseConversationMessagePayload(A){return TMQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return NM({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(iI,Ml,xMQ),A.entities.register(HX,Ol,vMQ),_K1({context:A,pluginId:this.id}),xK1({context:A,pluginId:this.id}),lK1({context:A,pluginId:this.id}),rK1({context:A,pluginId:this.id,config:this.config}),_gA(A),AZ1({context:A,logger:this.logger,config:this.config})}}function ggA(A){return new TgA(A)}sA();HA();sA();var aF=J.object({title:J.string(),section:J.string(),order:J.number().int(),sourcePath:J.string(),description:J.string().optional(),slug:J.string().optional()}),BZ1=aF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:J.string()}),g_=e1.extend({entityType:J.literal("doc"),metadata:BZ1}),tF=g_.extend({frontmatter:aF,body:J.string()});sA();HA();class SgA extends N2{constructor(){super({entityType:"doc",schema:g_,frontmatterSchema:aF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,aF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,aF),B=Q.slug??b1(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 B5A=new SgA;sA();function wZ1(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 $Z1(A){let Q=O2(A.content,aF);return tF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class w5A extends L5{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 $Z1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let H=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(H.items,null,w.query))}let[$,D]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=wZ1(D.items),Y=I.findIndex((H)=>H.id===$.item.id),X=Y>0?I[Y-1]:null,W=Y>=0&&Y<I.length-1?I[Y+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:X,nextDoc:W})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:wZ1(A),pagination:Q,baseUrl:B.baseUrl}}}sA();Hw();HA();import{jsxDEV as g5}from"preact/jsx-dev-runtime";var gMQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function Rl(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 $5A(A){let Q=new Map;for(let B of Rl(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function S_(A){return`/docs/${A.metadata.slug}`}function D5A(A){return`section-${A+1}`}function h_(A){return gMQ[A]??String(A+1)}var YZ1="text-[var(--docs-text)] font-bold",XZ1="text-[var(--docs-accent)] font-bold",WZ1="text-[var(--docs-text-muted)]",SMQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",hMQ="docs-font-display text-[var(--docs-heading)]",DZ1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",IZ1="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",hgA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",lU={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:SMQ,display:hMQ,button:`${DZ1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${DZ1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},fZ1=()=>g5("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:[g5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[g5("span",{className:YZ1,children:"brains"},void 0,!1,void 0,this),g5("span",{className:XZ1,children:"."},void 0,!1,void 0,this),g5("span",{className:WZ1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[g5("a",{className:IZ1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),g5("a",{className:IZ1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),g5("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),HZ1=()=>g5("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:[g5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[g5("span",{className:YZ1,children:"rizom"},void 0,!1,void 0,this),g5("span",{className:XZ1,children:"."},void 0,!1,void 0,this),g5("span",{className:WZ1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[g5("a",{className:hgA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),g5("a",{className:hgA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),g5("a",{className:hgA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),g5("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),mMQ=`
11250
+ `)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let D=OMQ.parse($),I=ygA(D.messages,D.conversationId),Y=D.existingSummary?aK1({conversationId:D.conversationId,content:D.existingSummary,messageCount:D.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null;return new aN(Q,B,w).decideProjection(I,Y)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let D=VMQ.parse($),I=D.memory?tK1(Q,D.memory):Q;return new T_(I).retrieve(D)}),Q.eval.registerHandler("buildAgentContext",async($)=>{let D=MMQ.parse($),I=D.memory?tK1(Q,D.memory):Q;return A5A(I,D)}),Q.eval.registerHandler("projectMessages",async($)=>{let D=qMQ.parse($),I=ygA(D.messages,D.conversationId),Y=CMQ({conversationId:D.conversationId,interfaceType:D.interfaceType,channelId:D.channelId,channelName:D.channelName,messages:I}),X=D.existingSummary?aK1({conversationId:D.conversationId,content:D.existingSummary,messageCount:D.existingMessageCount,projectionVersion:w.projectionVersion,visibility:w.memoryVisibility}):null,W=[],H=[],F=bMQ({context:Q,conversation:Y,messages:I,existing:X,upserted:W,deleted:H,projectionDecision:D.projectionDecision});return{result:await new aN(F,B,w).projectConversation(D.conversationId),summaries:W.filter((q)=>q.entityType==="summary"),decisions:W.filter((q)=>q.entityType==="decision"),actionItems:W.filter((q)=>q.entityType==="action-item"),deleted:H}}),Q.eval.registerHandler("projectConversation",async($)=>{let D=zMQ.parse($);return new aN(Q,B,w).projectConversation(D.conversationId)})}function aK1(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 ygA(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 CMQ(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 bMQ(A){let Q=Mf(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 tK1(A,Q){let B=Q.map(RMQ),w=B.map(($,D)=>({entity:$,score:Q[D]?.score??1,excerpt:Q[D]?.excerpt??v_($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((D)=>D.entityType===$)}}}function RMQ(A){if(A.entityType==="summary")return PMQ(A);if(A.entityType==="decision")return kMQ(A);return jMQ(A)}function vgA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:bB(A.content),visibility:A.visibility,created:Q,updated:Q}}function PMQ(A){return{...vgA(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 kMQ(A){return{...vgA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:Mf(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 jMQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...vgA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:Mf(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 QZ1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.109",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 yMQ=new UX,xMQ=new P_,vMQ=new k_,TMQ=J.object({conversationId:J.string()});class TgA extends MQ{entityType=_6;schema=Vl;adapter=yMQ;constructor(A={}){super(p6A,QZ1,A,CgA)}getConfig(){return this.config}getTemplates(){return{"summary-list":bK1,"summary-detail":RK1,"ai-response":PK1}}getDataSources(){return[new jgA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:_6,job:{type:qK1,handler:new o6A(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await Lq(A,_6,{outputVisibility:this.config.memoryVisibility}),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:OgA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:p6A}}},sourceChange:{sourceKind:Xv,sourceTypes:[Xv],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[VC],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:OgA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:p6A}}}}}]}parseConversationMessagePayload(A){return TMQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return NM({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(iI,Ml,xMQ),A.entities.register(HX,Ol,vMQ),_K1({context:A,pluginId:this.id}),xK1({context:A,pluginId:this.id}),lK1({context:A,pluginId:this.id}),rK1({context:A,pluginId:this.id,config:this.config}),_gA(A),AZ1({context:A,logger:this.logger,config:this.config})}}function ggA(A){return new TgA(A)}sA();HA();sA();var aF=J.object({title:J.string(),section:J.string(),order:J.number().int(),sourcePath:J.string(),description:J.string().optional(),slug:J.string().optional()}),BZ1=aF.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:J.string()}),g_=e1.extend({entityType:J.literal("doc"),metadata:BZ1}),tF=g_.extend({frontmatter:aF,body:J.string()});sA();HA();class SgA extends N2{constructor(){super({entityType:"doc",schema:g_,frontmatterSchema:aF})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,aF);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,aF),B=Q.slug??b1(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 B5A=new SgA;sA();function wZ1(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 $Z1(A){let Q=O2(A.content,aF);return tF.parse({...A,frontmatter:Q.metadata,body:Q.content})}class w5A extends L5{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 $Z1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let H=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(H.items,null,w.query))}let[$,D]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=wZ1(D.items),Y=I.findIndex((H)=>H.id===$.item.id),X=Y>0?I[Y-1]:null,W=Y>=0&&Y<I.length-1?I[Y+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:X,nextDoc:W})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:wZ1(A),pagination:Q,baseUrl:B.baseUrl}}}sA();Hw();HA();import{jsxDEV as g5}from"preact/jsx-dev-runtime";var gMQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function Rl(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 $5A(A){let Q=new Map;for(let B of Rl(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function S_(A){return`/docs/${A.metadata.slug}`}function D5A(A){return`section-${A+1}`}function h_(A){return gMQ[A]??String(A+1)}var YZ1="text-[var(--docs-text)] font-bold",XZ1="text-[var(--docs-accent)] font-bold",WZ1="text-[var(--docs-text-muted)]",SMQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",hMQ="docs-font-display text-[var(--docs-heading)]",DZ1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",IZ1="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",hgA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",lU={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:SMQ,display:hMQ,button:`${DZ1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${DZ1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},fZ1=()=>g5("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:[g5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[g5("span",{className:YZ1,children:"brains"},void 0,!1,void 0,this),g5("span",{className:XZ1,children:"."},void 0,!1,void 0,this),g5("span",{className:WZ1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[g5("a",{className:IZ1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),g5("a",{className:IZ1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),g5("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),HZ1=()=>g5("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:[g5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[g5("span",{className:YZ1,children:"rizom"},void 0,!1,void 0,this),g5("span",{className:XZ1,children:"."},void 0,!1,void 0,this),g5("span",{className:WZ1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[g5("a",{className:hgA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),g5("a",{className:hgA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),g5("a",{className:hgA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),g5("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),mMQ=`
11251
11251
  .docs-handbook {
11252
11252
  --docs-bg: var(--color-bg, #0d0a1a);
11253
11253
  --docs-bg-card: var(--color-bg-card, #1a0a3e);
@@ -11399,7 +11399,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});HA();var p
11399
11399
  background: transparent;
11400
11400
  }
11401
11401
 
11402
- `,UZ1=()=>g5("style",{children:mMQ},void 0,!1,void 0,this);import{jsxDEV as J2,Fragment as uMQ}from"preact/jsx-dev-runtime";var I5A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:D=""})=>J2(uMQ,{children:[J2(fQ,{title:A,description:Q},void 0,!1,void 0,this),J2(UZ1,{},void 0,!1,void 0,this),J2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[J2(fZ1,{},void 0,!1,void 0,this),J2("div",{className:`${lU.wrap} ${D}`.trim(),children:[B,$&&J2(HZ1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),JZ1=({docsCount:A,sectionsCount:Q,startDoc:B})=>J2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[J2("p",{className:`${lU.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),J2("h1",{className:`${lU.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",J2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J2("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),J2("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:[J2("div",{children:[J2("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),J2("div",{children:[J2("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),J2("div",{children:[J2("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),J2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&J2("a",{className:lU.primaryButton,href:S_(B),children:"Start reading"},void 0,!1,void 0,this),J2("a",{className:lU.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),GZ1=({groups:A})=>J2("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:[J2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),J2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>J2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[J2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[h_(B),"."]},void 0,!0,void 0,this),J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${D5A(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),FZ1=({group:A,index:Q})=>J2("article",{className:"mb-16 last:mb-0",id:D5A(Q),children:[J2("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:[J2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[h_(Q),"."]},void 0,!0,void 0,this),J2("h2",{className:`${lU.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),J2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>J2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:J2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:S_(B),children:[J2("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&&J2("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),KZ1=({title:A})=>J2("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:[J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),J2("span",{children:"/"},void 0,!1,void 0,this),J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),J2("span",{children:"/"},void 0,!1,void 0,this),J2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),ZZ1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>J2("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:J2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[J2("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),J2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let D=$===Q;return J2("li",{className:D?"mb-[22px]":"mb-3.5",children:[J2("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)] ${D?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${D5A($)}`,children:[J2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[h_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),D&&J2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let Y=I.metadata.slug===B;return J2("li",{children:J2("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)] ${Y?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:S_(I),"aria-current":Y?"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),NZ1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return J2("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?J2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:S_(A),children:[J2("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),J2("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):J2("span",{},void 0,!1,void 0,this),Q&&J2("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:S_(Q),children:[J2("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),J2("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 m_}from"preact/jsx-dev-runtime";var mgA=({docs:A})=>{let Q=Rl(A),B=$5A(Q),$=Q.filter((D)=>D.metadata.slug!=="index")[0]??Q[0];return m_(I5A,{title:"Documentation",description:"Brains documentation",children:[m_(JZ1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),m_("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:[m_(GZ1,{groups:B},void 0,!1,void 0,this),m_("div",{children:B.map((D,I)=>m_(FZ1,{group:D,index:I},D.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 dI}from"preact/jsx-dev-runtime";var ugA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=$5A(Q.length>0?Q:[A]),D=Rl(Q.length>0?Q:[A]),I=D.findIndex((X)=>X.metadata.slug===A.metadata.slug),Y=Math.max($.findIndex((X)=>X.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return dI(I5A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(KZ1,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(ZZ1,{groups:$,activeGroupIndex:Y,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${lU.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[h_(Y),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${D.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${lU.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&&dI("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),dI("div",{className:"docs-article__body",children:dI(B$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(NZ1,{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 cMQ=J.object({docs:J.array(tF),pagination:i9.nullable(),baseUrl:J.string().optional()}),pMQ=J.object({doc:tF,docs:J.array(tF),prevDoc:tF.nullable(),nextDoc:tF.nullable()});function zZ1(){return{"doc-list":R1({name:"doc-list",description:"Documentation index template",schema:cMQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:mgA}}),"doc-detail":R1({name:"doc-detail",description:"Documentation page template",schema:pMQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:ugA}})}}var qZ1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.108",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 cgA extends MQ{entityType=B5A.entityType;schema=g_;adapter=B5A;constructor(){super("docs",qZ1,{},void 0)}getTemplates(){return zZ1()}getDataSources(){return[new w5A(this.logger.child("DocDataSource"))]}}function pgA(){return new cgA}sA();HA();HA();b$();var LZ1=J.object({label:J.string(),href:J.string()}),EZ1=J.object({label:J.string(),title:J.string(),detail:J.string()}),iMQ=J.object({eyebrow:J.string(),name:J.string(),sub:J.string()}),dMQ=J.object({tone:J.enum(["capture","synthesis","share"]),title:J.string(),text:J.string()}),lgA=J.object({captures:J.number(),links:J.number(),topics:J.number(),summaries:J.number(),peers:J.number()}),u_=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:LZ1,secondaryCta:LZ1,inputs:J.array(EZ1).min(1),outputs:J.array(EZ1).min(1),core:iMQ,legend:J.array(dMQ).min(1)}),igA=u_.extend({counts:lgA}),VZ1={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."}]},MZ1=new xB(u_,{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 Y5A(A){return MZ1.parse(A)}function OZ1(A){return MZ1.format(A)}HA();var rMQ=J.object({query:J.object({routeId:J.string().default("home"),sectionId:J.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),nMQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class dgA{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=rMQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),D=await this.fetchCounts(B);return Q.parse({...$,counts:D})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return VZ1;return u_.parse(Y5A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(nMQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return lgA.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 CZ1=J.object({label:J.string(),href:J.string()}),oMQ=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:CZ1,secondaryCta:CZ1,signals:J.array(J.object({label:J.string(),value:J.string(),note:J.string()}))}),sMQ=J.object({eyebrow:J.string(),title:J.string(),intro:J.string(),steps:J.array(J.object({phase:J.string(),title:J.string(),text:J.string()}))}),aMQ=J.object({title:J.string(),intro:J.string(),cards:J.array(J.object({label:J.string(),title:J.string(),text:J.string()}))}),tMQ=J.object({title:J.string(),intro:J.string(),points:J.array(J.string())}),eMQ={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."]},AOQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function bZ1({href:A,label:Q}){return Q1("a",{href:A,className:AOQ,children:Q},void 0,!1,void 0,this)}function QOQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(C_,{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(bZ1,{...$},`${$.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(bZ1,{...$},`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 BOQ=({sections:A,siteInfo:Q})=>Q1(QOQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function wOQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:D}){return Q1(oN,{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(FM,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(FM,{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:D.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 $OQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(oN,{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 DOQ({title:A,intro:Q,cards:B}){return Q1(oN,{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 IOQ({title:A,intro:Q,points:B}){return Q1(oN,{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 YOQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},XOQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Pl=(A,Q,B=`${Q}s`)=>`${XOQ(A)} ${A===1?Q:B}`;function WOQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:D,outputs:I,core:Y,legend:X,counts:W}){let H=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Pl(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Pl(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Pl(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Pl(W.summaries,"summary","summaries")}];return Q1(oN,{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(FM,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(FM,{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:D.map((F)=>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:F.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:F.detail},void 0,!1,void 0,this)]},`${F.label}-${F.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),H.map((F)=>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 ${F.className}`,children:F.label},F.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:Y.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:Y.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:Y.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Pl(W.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((F)=>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:F.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:F.detail},void 0,!1,void 0,this)]},`${F.label}-${F.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:X.map((F)=>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 ${YOQ(F.tone)}`},void 0,!1,void 0,this),F.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:F.text},void 0,!1,void 0,this)]},F.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var fOQ=R1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:igA,formatter:{parse:(A)=>igA.parse({...Y5A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>OZ1(u_.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:WOQ}}),HOQ=(A)=>wOQ(oMQ.parse(A)),UOQ=(A)=>$OQ(sMQ.parse(A)),JOQ=(A)=>DOQ(aMQ.parse(A)),GOQ=(A)=>IOQ(tMQ.parse(A)),RZ1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},PZ1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:HOQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...RZ1,label:"Primary CTA"},secondaryCta:{...RZ1,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:UOQ,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:JOQ,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:GOQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},FOQ=[{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:eMQ}]}],kZ1=MgA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:BOQ,routes:FOQ,templates:{"home-diagram":fOQ},dataSources:[new dgA]});var jZ1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.108",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:*",typescript:"^5.3.3"}};var _Z1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],yZ1=[..._Z1,"image","site-info","site-content","site-builder"],NOQ=[...yZ1,"docs","decks"],zOQ=["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.'],xZ1=uZ({name:"relay",version:jZ1.version,model:"gpt-5.4-mini",site:kZ1,theme:b_,presets:{core:_Z1,default:yZ1,full:NOQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:zOQ,capabilities:[["prompt",HM,void 0],["note",QM,{}],["link",$M,{}],["image",mg,void 0],["topics",b8A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",ggA,{memoryVisibility:"shared"}],["docs",pgA,void 0],["decks",_p,void 0],["agents",f6A,void 0],["assessment",q6A,void 0],["auth-service",Ph,void 0],["notifications",Te,void 0],["email-resend",UQA,void 0],["cms",fM,{}],["dashboard",dN,void 0],["directory-sync",XV,{seedContent:!0,seedContentPath:ZOQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",ql,{definitions:PZ1}],["rizom-ecosystem",UM,void 0],["site-info",rV,void 0],["site-builder",dV,{}]],interfaces:[["mcp",L3,()=>({})],["discord",BN,()=>({captureUrls:!0})],["a2a",hk,()=>({})],["webserver",wN,()=>({})],["web-chat",Sk,()=>({})]],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 tRQ}from"fs";import{join as eRQ}from"path";import{execSync as APQ}from"child_process";import{parseArgs as EOQ}from"util";var VOQ={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 Of(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function tN(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function vZ1(A){let{values:Q,positionals:B}=EOQ({args:A,options:VOQ,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:Of(Q,"model"),domain:Of(Q,"domain"),"content-repo":Of(Q,"content-repo"),backend:Of(Q,"backend"),"push-to":Of(Q,"push-to"),"ai-api-key":Of(Q,"ai-api-key"),"no-interactive":tN(Q,"no-interactive"),preview:tN(Q,"preview"),deploy:tN(Q,"deploy"),regen:tN(Q,"regen"),all:tN(Q,"all"),only:Of(Q,"only"),"dry-run":tN(Q,"dry-run"),"startup-check":tN(Q,"startup-check"),"storage-dir":Of(Q,"storage-dir"),yes:tN(Q,"yes"),remote:Of(Q,"remote"),token:Of(Q,"token"),outputDir:Of(Q,"outputDir")}}}kl();import{mkdirSync as cRQ}from"fs";import{join as pRQ}from"path";import{execSync as lRQ}from"child_process";var W5A={name:"@rizom/brain",version:"0.2.0-alpha.108",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 sZ1,writeFileSync as _l,chmodSync as yl,existsSync as BSA,readFileSync as wSA}from"fs";import{basename as $SA,dirname as DSA,join as i8,resolve as wCQ}from"path";import{fileURLToPath as $CQ}from"url";var TZ1=`ARG BUN_VERSION=1.3.10
11402
+ `,UZ1=()=>g5("style",{children:mMQ},void 0,!1,void 0,this);import{jsxDEV as J2,Fragment as uMQ}from"preact/jsx-dev-runtime";var I5A=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:D=""})=>J2(uMQ,{children:[J2(fQ,{title:A,description:Q},void 0,!1,void 0,this),J2(UZ1,{},void 0,!1,void 0,this),J2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[J2(fZ1,{},void 0,!1,void 0,this),J2("div",{className:`${lU.wrap} ${D}`.trim(),children:[B,$&&J2(HZ1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),JZ1=({docsCount:A,sectionsCount:Q,startDoc:B})=>J2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[J2("p",{className:`${lU.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),J2("h1",{className:`${lU.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",J2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J2("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),J2("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:[J2("div",{children:[J2("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),J2("div",{children:[J2("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),J2("div",{children:[J2("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),J2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&J2("a",{className:lU.primaryButton,href:S_(B),children:"Start reading"},void 0,!1,void 0,this),J2("a",{className:lU.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),GZ1=({groups:A})=>J2("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:[J2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),J2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>J2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[J2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[h_(B),"."]},void 0,!0,void 0,this),J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${D5A(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),FZ1=({group:A,index:Q})=>J2("article",{className:"mb-16 last:mb-0",id:D5A(Q),children:[J2("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:[J2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[h_(Q),"."]},void 0,!0,void 0,this),J2("h2",{className:`${lU.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),J2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>J2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:J2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:S_(B),children:[J2("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&&J2("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),KZ1=({title:A})=>J2("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:[J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),J2("span",{children:"/"},void 0,!1,void 0,this),J2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),J2("span",{children:"/"},void 0,!1,void 0,this),J2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),ZZ1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>J2("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:J2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[J2("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),J2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let D=$===Q;return J2("li",{className:D?"mb-[22px]":"mb-3.5",children:[J2("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)] ${D?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${D5A($)}`,children:[J2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[h_($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),D&&J2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let Y=I.metadata.slug===B;return J2("li",{children:J2("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)] ${Y?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:S_(I),"aria-current":Y?"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),NZ1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return J2("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?J2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:S_(A),children:[J2("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),J2("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):J2("span",{},void 0,!1,void 0,this),Q&&J2("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:S_(Q),children:[J2("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),J2("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 m_}from"preact/jsx-dev-runtime";var mgA=({docs:A})=>{let Q=Rl(A),B=$5A(Q),$=Q.filter((D)=>D.metadata.slug!=="index")[0]??Q[0];return m_(I5A,{title:"Documentation",description:"Brains documentation",children:[m_(JZ1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),m_("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:[m_(GZ1,{groups:B},void 0,!1,void 0,this),m_("div",{children:B.map((D,I)=>m_(FZ1,{group:D,index:I},D.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 dI}from"preact/jsx-dev-runtime";var ugA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=$5A(Q.length>0?Q:[A]),D=Rl(Q.length>0?Q:[A]),I=D.findIndex((X)=>X.metadata.slug===A.metadata.slug),Y=Math.max($.findIndex((X)=>X.docs.some((W)=>W.metadata.slug===A.metadata.slug)),0);return dI(I5A,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(KZ1,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(ZZ1,{groups:$,activeGroupIndex:Y,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${lU.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[h_(Y),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${D.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${lU.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&&dI("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),dI("div",{className:"docs-article__body",children:dI(B$,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(NZ1,{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 cMQ=J.object({docs:J.array(tF),pagination:i9.nullable(),baseUrl:J.string().optional()}),pMQ=J.object({doc:tF,docs:J.array(tF),prevDoc:tF.nullable(),nextDoc:tF.nullable()});function zZ1(){return{"doc-list":R1({name:"doc-list",description:"Documentation index template",schema:cMQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:mgA}}),"doc-detail":R1({name:"doc-detail",description:"Documentation page template",schema:pMQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:ugA}})}}var qZ1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.109",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 cgA extends MQ{entityType=B5A.entityType;schema=g_;adapter=B5A;constructor(){super("docs",qZ1,{},void 0)}getTemplates(){return zZ1()}getDataSources(){return[new w5A(this.logger.child("DocDataSource"))]}}function pgA(){return new cgA}sA();HA();HA();b$();var LZ1=J.object({label:J.string(),href:J.string()}),EZ1=J.object({label:J.string(),title:J.string(),detail:J.string()}),iMQ=J.object({eyebrow:J.string(),name:J.string(),sub:J.string()}),dMQ=J.object({tone:J.enum(["capture","synthesis","share"]),title:J.string(),text:J.string()}),lgA=J.object({captures:J.number(),links:J.number(),topics:J.number(),summaries:J.number(),peers:J.number()}),u_=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:LZ1,secondaryCta:LZ1,inputs:J.array(EZ1).min(1),outputs:J.array(EZ1).min(1),core:iMQ,legend:J.array(dMQ).min(1)}),igA=u_.extend({counts:lgA}),VZ1={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."}]},MZ1=new xB(u_,{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 Y5A(A){return MZ1.parse(A)}function OZ1(A){return MZ1.format(A)}HA();var rMQ=J.object({query:J.object({routeId:J.string().default("home"),sectionId:J.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),nMQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class dgA{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=rMQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),D=await this.fetchCounts(B);return Q.parse({...$,counts:D})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return VZ1;return u_.parse(Y5A(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(nMQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return lgA.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 CZ1=J.object({label:J.string(),href:J.string()}),oMQ=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:CZ1,secondaryCta:CZ1,signals:J.array(J.object({label:J.string(),value:J.string(),note:J.string()}))}),sMQ=J.object({eyebrow:J.string(),title:J.string(),intro:J.string(),steps:J.array(J.object({phase:J.string(),title:J.string(),text:J.string()}))}),aMQ=J.object({title:J.string(),intro:J.string(),cards:J.array(J.object({label:J.string(),title:J.string(),text:J.string()}))}),tMQ=J.object({title:J.string(),intro:J.string(),points:J.array(J.string())}),eMQ={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."]},AOQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function bZ1({href:A,label:Q}){return Q1("a",{href:A,className:AOQ,children:Q},void 0,!1,void 0,this)}function QOQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return Q1(C_,{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(bZ1,{...$},`${$.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(bZ1,{...$},`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 BOQ=({sections:A,siteInfo:Q})=>Q1(QOQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function wOQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:D}){return Q1(oN,{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(FM,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(FM,{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:D.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 $OQ({eyebrow:A,title:Q,intro:B,steps:w}){return Q1(oN,{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 DOQ({title:A,intro:Q,cards:B}){return Q1(oN,{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 IOQ({title:A,intro:Q,points:B}){return Q1(oN,{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 YOQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},XOQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Pl=(A,Q,B=`${Q}s`)=>`${XOQ(A)} ${A===1?Q:B}`;function WOQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:D,outputs:I,core:Y,legend:X,counts:W}){let H=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Pl(W.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Pl(W.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Pl(W.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Pl(W.summaries,"summary","summaries")}];return Q1(oN,{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(FM,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),Q1(FM,{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:D.map((F)=>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:F.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:F.detail},void 0,!1,void 0,this)]},`${F.label}-${F.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),H.map((F)=>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 ${F.className}`,children:F.label},F.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:Y.eyebrow},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:Y.name},void 0,!1,void 0,this),Q1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:Y.sub},void 0,!1,void 0,this),Q1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Pl(W.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((F)=>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:F.label},void 0,!1,void 0,this),Q1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),Q1("p",{className:"mt-1 font-body text-[13px] leading-[1.5] text-theme-muted",children:F.detail},void 0,!1,void 0,this)]},`${F.label}-${F.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:X.map((F)=>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 ${YOQ(F.tone)}`},void 0,!1,void 0,this),F.title]},void 0,!0,void 0,this),Q1("p",{className:"mt-1.5 font-body text-[13px] leading-[1.6] text-theme-muted",children:F.text},void 0,!1,void 0,this)]},F.title,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}var fOQ=R1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:igA,formatter:{parse:(A)=>igA.parse({...Y5A(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>OZ1(u_.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:WOQ}}),HOQ=(A)=>wOQ(oMQ.parse(A)),UOQ=(A)=>$OQ(sMQ.parse(A)),JOQ=(A)=>DOQ(aMQ.parse(A)),GOQ=(A)=>IOQ(tMQ.parse(A)),RZ1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},PZ1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:HOQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...RZ1,label:"Primary CTA"},secondaryCta:{...RZ1,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:UOQ,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:JOQ,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:GOQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},FOQ=[{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:eMQ}]}],kZ1=MgA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:BOQ,routes:FOQ,templates:{"home-diagram":fOQ},dataSources:[new dgA]});var jZ1={name:"@brains/relay",private:!0,version:"0.2.0-alpha.109",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:*",typescript:"^5.3.3"}};var _Z1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","notifications","email-resend","cms","dashboard","mcp","webserver","web-chat","discord","a2a"],yZ1=[..._Z1,"image","site-info","site-content","site-builder"],NOQ=[...yZ1,"docs","decks"],zOQ=["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.'],xZ1=uZ({name:"relay",version:jZ1.version,model:"gpt-5.4-mini",site:kZ1,theme:b_,presets:{core:_Z1,default:yZ1,full:NOQ},evalDisable:["webserver","web-chat","mcp","discord"],agentInstructions:zOQ,capabilities:[["prompt",HM,void 0],["note",QM,{}],["link",$M,{}],["image",mg,void 0],["topics",b8A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",ggA,{memoryVisibility:"shared"}],["docs",pgA,void 0],["decks",_p,void 0],["agents",f6A,void 0],["assessment",q6A,void 0],["auth-service",Ph,void 0],["notifications",Te,void 0],["email-resend",UQA,void 0],["cms",fM,{}],["dashboard",dN,void 0],["directory-sync",XV,{seedContent:!0,seedContentPath:ZOQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",ql,{definitions:PZ1}],["rizom-ecosystem",UM,void 0],["site-info",rV,void 0],["site-builder",dV,{}]],interfaces:[["mcp",L3,()=>({})],["discord",BN,()=>({captureUrls:!0})],["a2a",hk,()=>({})],["webserver",wN,()=>({})],["web-chat",Sk,()=>({})]],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 tRQ}from"fs";import{join as eRQ}from"path";import{execSync as APQ}from"child_process";import{parseArgs as EOQ}from"util";var VOQ={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 Of(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function tN(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function vZ1(A){let{values:Q,positionals:B}=EOQ({args:A,options:VOQ,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:Of(Q,"model"),domain:Of(Q,"domain"),"content-repo":Of(Q,"content-repo"),backend:Of(Q,"backend"),"push-to":Of(Q,"push-to"),"ai-api-key":Of(Q,"ai-api-key"),"no-interactive":tN(Q,"no-interactive"),preview:tN(Q,"preview"),deploy:tN(Q,"deploy"),regen:tN(Q,"regen"),all:tN(Q,"all"),only:Of(Q,"only"),"dry-run":tN(Q,"dry-run"),"startup-check":tN(Q,"startup-check"),"storage-dir":Of(Q,"storage-dir"),yes:tN(Q,"yes"),remote:Of(Q,"remote"),token:Of(Q,"token"),outputDir:Of(Q,"outputDir")}}}kl();import{mkdirSync as cRQ}from"fs";import{join as pRQ}from"path";import{execSync as lRQ}from"child_process";var W5A={name:"@rizom/brain",version:"0.2.0-alpha.109",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 sZ1,writeFileSync as _l,chmodSync as yl,existsSync as BSA,readFileSync as wSA}from"fs";import{basename as $SA,dirname as DSA,join as i8,resolve as wCQ}from"path";import{fileURLToPath as $CQ}from"url";var TZ1=`ARG BUN_VERSION=1.3.10
11403
11403
  FROM oven/bun:\${BUN_VERSION}-slim AS runtime
11404
11404
 
11405
11405
  WORKDIR /app
@@ -11476,6 +11476,7 @@ env:
11476
11476
  - AI_API_KEY
11477
11477
  - GIT_SYNC_TOKEN
11478
11478
  - DISCORD_BOT_TOKEN
11479
+ - ATPROTO_APP_PASSWORD
11479
11480
  - SETUP_EMAIL_TO
11480
11481
  - SETUP_EMAIL_API_KEY
11481
11482
  - SETUP_EMAIL_FROM
@@ -12006,6 +12007,10 @@ CMS_CONTENT_REPO_PAT=
12006
12007
  # @sensitive
12007
12008
  DISCORD_BOT_TOKEN=
12008
12009
 
12010
+ # AT Protocol publishing/discovery (optional)
12011
+ # @sensitive
12012
+ ATPROTO_APP_PASSWORD=
12013
+
12009
12014
  # LinkedIn
12010
12015
  # @sensitive
12011
12016
  LINKEDIN_ACCESS_TOKEN=