@rizom/brain 0.2.0-alpha.80 → 0.2.0-alpha.81
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 +68 -41
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/site.js +4 -4
- package/dist/site.js.map +1 -1
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -495,7 +495,7 @@ ${F}`,args:{...$,...D,id:I.id,confirmed:!0,contentHash:I.contentHash}}},{visibil
|
|
|
495
495
|
hash text NOT NULL,
|
|
496
496
|
created_at numeric
|
|
497
497
|
)
|
|
498
|
-
`;await A.session.run($);let I=(await A.values(xA`SELECT id, hash, created_at FROM ${xA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let Y of B)if(!I||Number(I[2])<Y.folderMillis){for(let H of Y.sql)D.push(A.run(xA.raw(H)));D.push(A.run(xA`INSERT INTO ${xA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var Wn=i(()=>{y50();j5()});async function x50(A,Q){let B=Q?.child("entity-migrate")??fQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=gi(A);B.debug("Running entity database migrations...");try{await Ti($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),await Si($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var h50=i(()=>{Wn();t9A();GA()});async function g50(A,Q){let B=Q?.child("job-queue-migrate")??fQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=yi(A);B.debug("Running job queue migrations...");try{await xi($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var T50=i(()=>{Wn();u9A();GA()});async function S50(A,Q){let B=Q?.child("conversation-migrate")??fQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=oi(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var m50=i(()=>{Wn();v7A();GA()});class py{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Kv,migrateEntities:x50,migrateJobQueue:g50,migrateConversations:S50}}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 hWA=i(()=>{Hn();h50();T50();m50()});function ac1(){return process.env[sc1]}function u50(){return ac1()!=="production"}var sc1="NODE_ENV";var Un;var gWA=i(()=>{GA();Un=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 p50;var c50=i(()=>{p50={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.80",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.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var lQ=v((ec1,Jn)=>{(function(){function A(wA,KA){Object.defineProperty(w.prototype,wA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",KA[0],KA[1])}})}function Q(wA){if(wA===null||typeof wA!=="object")return null;return wA=rA&&wA[rA]||wA["@@iterator"],typeof wA==="function"?wA:null}function B(wA,KA){wA=(wA=wA.constructor)&&(wA.displayName||wA.name)||"ReactClass";var cA=wA+"."+KA;ZA[cA]||(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.",KA,wA),ZA[cA]=!0)}function w(wA,KA,cA){this.props=wA,this.context=KA,this.refs=uA,this.updater=cA||CA}function $(){}function f(wA,KA,cA){this.props=wA,this.context=KA,this.refs=uA,this.updater=cA||CA}function I(){}function D(wA){return""+wA}function Y(wA){try{D(wA);var KA=!1}catch(H0){KA=!0}if(KA){KA=console;var cA=KA.error,f0=typeof Symbol==="function"&&Symbol.toStringTag&&wA[Symbol.toStringTag]||wA.constructor.name||"Object";return cA.call(KA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",f0),D(wA)}}function H(wA){if(wA==null)return null;if(typeof wA==="function")return wA.$$typeof===U0?null:wA.displayName||wA.name||null;if(typeof wA==="string")return wA;switch(wA){case e:return"Fragment";case UA:return"Profiler";case d:return"StrictMode";case J0:return"Suspense";case FA:return"SuspenseList";case NA: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 c:return"Portal";case fA:return wA.displayName||"Context";case VA:return(wA._context.displayName||"Context")+".Consumer";case tA:var KA=wA.render;return wA=wA.displayName,wA||(wA=KA.displayName||KA.name||"",wA=wA!==""?"ForwardRef("+wA+")":"ForwardRef"),wA;case z0:return KA=wA.displayName||null,KA!==null?KA:H(wA.type)||"Memo";case Y0:KA=wA._payload,wA=wA._init;try{return H(wA(KA))}catch(cA){}}return null}function W(wA){if(wA===e)return"<>";if(typeof wA==="object"&&wA!==null&&wA.$$typeof===Y0)return"<...>";try{var KA=H(wA);return KA?"<"+KA+">":"<...>"}catch(cA){return"<...>"}}function F(){var wA=$0.A;return wA===null?null:wA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(wA){if(RA.call(wA,"key")){var KA=Object.getOwnPropertyDescriptor(wA,"key").get;if(KA&&KA.isReactWarning)return!1}return wA.key!==void 0}function q(wA,KA){function cA(){$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)",KA))}cA.isReactWarning=!0,Object.defineProperty(wA,"key",{get:cA,configurable:!0})}function E(){var wA=H(this.type);return A1[wA]||(A1[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 L(wA,KA,cA,f0,H0,R0){var A0=cA.ref;return wA={$$typeof:l,type:wA,key:KA,props:cA,_owner:f0},(A0!==void 0?A0:null)!==null?Object.defineProperty(wA,"ref",{enumerable:!1,get:E}):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:H0}),Object.defineProperty(wA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:R0}),Object.freeze&&(Object.freeze(wA.props),Object.freeze(wA)),wA}function b(wA,KA){return KA=L(wA.type,KA,wA.props,wA._owner,wA._debugStack,wA._debugTask),wA._store&&(KA._store.validated=wA._store.validated),KA}function _(wA){j(wA)?wA._store&&(wA._store.validated=1):typeof wA==="object"&&wA!==null&&wA.$$typeof===Y0&&(wA._payload.status==="fulfilled"?j(wA._payload.value)&&wA._payload.value._store&&(wA._payload.value._store.validated=1):wA._store&&(wA._store.validated=1))}function j(wA){return typeof wA==="object"&&wA!==null&&wA.$$typeof===l}function s(wA){var KA={"=":"=0",":":"=2"};return"$"+wA.replace(/[=:]/g,function(cA){return KA[cA]})}function n(wA,KA){return typeof wA==="object"&&wA!==null&&wA.key!=null?(Y(wA.key),s(""+wA.key)):KA.toString(36)}function T(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(KA){wA.status==="pending"&&(wA.status="fulfilled",wA.value=KA)},function(KA){wA.status==="pending"&&(wA.status="rejected",wA.reason=KA)})),wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason}}throw wA}function y(wA,KA,cA,f0,H0){var R0=typeof wA;if(R0==="undefined"||R0==="boolean")wA=null;var A0=!1;if(wA===null)A0=!0;else switch(R0){case"bigint":case"string":case"number":A0=!0;break;case"object":switch(wA.$$typeof){case l:case c:A0=!0;break;case Y0:return A0=wA._init,y(A0(wA._payload),KA,cA,f0,H0)}}if(A0){A0=wA,H0=H0(A0);var t0=f0===""?"."+n(A0,0):f0;return L0(H0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),y(H0,KA,cA,"",function(m1){return m1})):H0!=null&&(j(H0)&&(H0.key!=null&&(A0&&A0.key===H0.key||Y(H0.key)),cA=b(H0,cA+(H0.key==null||A0&&A0.key===H0.key?"":(""+H0.key).replace(gA,"$&/")+"/")+t0),f0!==""&&A0!=null&&j(A0)&&A0.key==null&&A0._store&&!A0._store.validated&&(cA._store.validated=2),H0=cA),KA.push(H0)),1}if(A0=0,t0=f0===""?".":f0+":",L0(wA))for(var Q1=0;Q1<wA.length;Q1++)f0=wA[Q1],R0=t0+n(f0,Q1),A0+=y(f0,KA,cA,R0,H0);else if(Q1=Q(wA),typeof Q1==="function")for(Q1===wA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),wA=Q1.call(wA),Q1=0;!(f0=wA.next()).done;)f0=f0.value,R0=t0+n(f0,Q1++),A0+=y(f0,KA,cA,R0,H0);else if(R0==="object"){if(typeof wA.then==="function")return y(T(wA),KA,cA,f0,H0);throw KA=String(wA),Error("Objects are not valid as a React child (found: "+(KA==="[object Object]"?"object with keys {"+Object.keys(wA).join(", ")+"}":KA)+"). If you meant to render a collection of children, use an array instead.")}return A0}function h(wA,KA,cA){if(wA==null)return wA;var f0=[],H0=0;return y(wA,f0,"","",function(R0){return KA.call(cA,R0,H0++)}),f0}function g(wA){if(wA._status===-1){var KA=wA._ioInfo;KA!=null&&(KA.start=KA.end=performance.now()),KA=wA._result;var cA=KA();if(cA.then(function(H0){if(wA._status===0||wA._status===-1){wA._status=1,wA._result=H0;var R0=wA._ioInfo;R0!=null&&(R0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=H0)}},function(H0){if(wA._status===0||wA._status===-1){wA._status=2,wA._result=H0;var R0=wA._ioInfo;R0!=null&&(R0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=H0)}}),KA=wA._ioInfo,KA!=null){KA.value=cA;var f0=cA.displayName;typeof f0==="string"&&(KA.name=f0)}wA._status===-1&&(wA._status=0,wA._result=cA)}if(wA._status===1)return KA=wA._result,KA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
498
|
+
`;await A.session.run($);let I=(await A.values(xA`SELECT id, hash, created_at FROM ${xA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let Y of B)if(!I||Number(I[2])<Y.folderMillis){for(let H of Y.sql)D.push(A.run(xA.raw(H)));D.push(A.run(xA`INSERT INTO ${xA.identifier(w)} ("hash", "created_at") VALUES(${Y.hash}, ${Y.folderMillis})`))}await A.session.migrate(D)}var Wn=i(()=>{y50();j5()});async function x50(A,Q){let B=Q?.child("entity-migrate")??fQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=gi(A);B.debug("Running entity database migrations...");try{await Ti($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/entity-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),await Si($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var h50=i(()=>{Wn();t9A();GA()});async function g50(A,Q){let B=Q?.child("job-queue-migrate")??fQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=yi(A);B.debug("Running job queue migrations...");try{await xi($,f);let D=import.meta.url.includes("/dist/")?new URL("./migrations/job-queue",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var T50=i(()=>{Wn();u9A();GA()});async function S50(A,Q){let B=Q?.child("conversation-migrate")??fQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=oi(A);B.debug("Running conversation database migrations...");try{if(f.startsWith("file:"))await $.execute("PRAGMA journal_mode = WAL");let D=import.meta.url.includes("/dist/")?new URL("./migrations/conversation-service",import.meta.url).pathname:new URL("../drizzle",import.meta.url).pathname;await TC(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var m50=i(()=>{Wn();v7A();GA()});class py{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Kv,migrateEntities:x50,migrateJobQueue:g50,migrateConversations:S50}}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 hWA=i(()=>{Hn();h50();T50();m50()});function ac1(){return process.env[sc1]}function u50(){return ac1()!=="production"}var sc1="NODE_ENV";var Un;var gWA=i(()=>{GA();Un=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 p50;var c50=i(()=>{p50={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.81",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.1.0"},devDependencies:{"@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"^1.1.14","@types/react":"^19.0.3",typescript:"^5.3.3"}}});var lQ=v((ec1,Jn)=>{(function(){function A(wA,KA){Object.defineProperty(w.prototype,wA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",KA[0],KA[1])}})}function Q(wA){if(wA===null||typeof wA!=="object")return null;return wA=rA&&wA[rA]||wA["@@iterator"],typeof wA==="function"?wA:null}function B(wA,KA){wA=(wA=wA.constructor)&&(wA.displayName||wA.name)||"ReactClass";var cA=wA+"."+KA;ZA[cA]||(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.",KA,wA),ZA[cA]=!0)}function w(wA,KA,cA){this.props=wA,this.context=KA,this.refs=uA,this.updater=cA||CA}function $(){}function f(wA,KA,cA){this.props=wA,this.context=KA,this.refs=uA,this.updater=cA||CA}function I(){}function D(wA){return""+wA}function Y(wA){try{D(wA);var KA=!1}catch(H0){KA=!0}if(KA){KA=console;var cA=KA.error,f0=typeof Symbol==="function"&&Symbol.toStringTag&&wA[Symbol.toStringTag]||wA.constructor.name||"Object";return cA.call(KA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",f0),D(wA)}}function H(wA){if(wA==null)return null;if(typeof wA==="function")return wA.$$typeof===U0?null:wA.displayName||wA.name||null;if(typeof wA==="string")return wA;switch(wA){case e:return"Fragment";case UA:return"Profiler";case d:return"StrictMode";case J0:return"Suspense";case FA:return"SuspenseList";case NA: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 c:return"Portal";case fA:return wA.displayName||"Context";case VA:return(wA._context.displayName||"Context")+".Consumer";case tA:var KA=wA.render;return wA=wA.displayName,wA||(wA=KA.displayName||KA.name||"",wA=wA!==""?"ForwardRef("+wA+")":"ForwardRef"),wA;case z0:return KA=wA.displayName||null,KA!==null?KA:H(wA.type)||"Memo";case Y0:KA=wA._payload,wA=wA._init;try{return H(wA(KA))}catch(cA){}}return null}function W(wA){if(wA===e)return"<>";if(typeof wA==="object"&&wA!==null&&wA.$$typeof===Y0)return"<...>";try{var KA=H(wA);return KA?"<"+KA+">":"<...>"}catch(cA){return"<...>"}}function F(){var wA=$0.A;return wA===null?null:wA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(wA){if(RA.call(wA,"key")){var KA=Object.getOwnPropertyDescriptor(wA,"key").get;if(KA&&KA.isReactWarning)return!1}return wA.key!==void 0}function q(wA,KA){function cA(){$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)",KA))}cA.isReactWarning=!0,Object.defineProperty(wA,"key",{get:cA,configurable:!0})}function E(){var wA=H(this.type);return A1[wA]||(A1[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 L(wA,KA,cA,f0,H0,R0){var A0=cA.ref;return wA={$$typeof:l,type:wA,key:KA,props:cA,_owner:f0},(A0!==void 0?A0:null)!==null?Object.defineProperty(wA,"ref",{enumerable:!1,get:E}):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:H0}),Object.defineProperty(wA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:R0}),Object.freeze&&(Object.freeze(wA.props),Object.freeze(wA)),wA}function b(wA,KA){return KA=L(wA.type,KA,wA.props,wA._owner,wA._debugStack,wA._debugTask),wA._store&&(KA._store.validated=wA._store.validated),KA}function _(wA){j(wA)?wA._store&&(wA._store.validated=1):typeof wA==="object"&&wA!==null&&wA.$$typeof===Y0&&(wA._payload.status==="fulfilled"?j(wA._payload.value)&&wA._payload.value._store&&(wA._payload.value._store.validated=1):wA._store&&(wA._store.validated=1))}function j(wA){return typeof wA==="object"&&wA!==null&&wA.$$typeof===l}function s(wA){var KA={"=":"=0",":":"=2"};return"$"+wA.replace(/[=:]/g,function(cA){return KA[cA]})}function n(wA,KA){return typeof wA==="object"&&wA!==null&&wA.key!=null?(Y(wA.key),s(""+wA.key)):KA.toString(36)}function T(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(KA){wA.status==="pending"&&(wA.status="fulfilled",wA.value=KA)},function(KA){wA.status==="pending"&&(wA.status="rejected",wA.reason=KA)})),wA.status){case"fulfilled":return wA.value;case"rejected":throw wA.reason}}throw wA}function y(wA,KA,cA,f0,H0){var R0=typeof wA;if(R0==="undefined"||R0==="boolean")wA=null;var A0=!1;if(wA===null)A0=!0;else switch(R0){case"bigint":case"string":case"number":A0=!0;break;case"object":switch(wA.$$typeof){case l:case c:A0=!0;break;case Y0:return A0=wA._init,y(A0(wA._payload),KA,cA,f0,H0)}}if(A0){A0=wA,H0=H0(A0);var t0=f0===""?"."+n(A0,0):f0;return L0(H0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),y(H0,KA,cA,"",function(m1){return m1})):H0!=null&&(j(H0)&&(H0.key!=null&&(A0&&A0.key===H0.key||Y(H0.key)),cA=b(H0,cA+(H0.key==null||A0&&A0.key===H0.key?"":(""+H0.key).replace(gA,"$&/")+"/")+t0),f0!==""&&A0!=null&&j(A0)&&A0.key==null&&A0._store&&!A0._store.validated&&(cA._store.validated=2),H0=cA),KA.push(H0)),1}if(A0=0,t0=f0===""?".":f0+":",L0(wA))for(var Q1=0;Q1<wA.length;Q1++)f0=wA[Q1],R0=t0+n(f0,Q1),A0+=y(f0,KA,cA,R0,H0);else if(Q1=Q(wA),typeof Q1==="function")for(Q1===wA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),wA=Q1.call(wA),Q1=0;!(f0=wA.next()).done;)f0=f0.value,R0=t0+n(f0,Q1++),A0+=y(f0,KA,cA,R0,H0);else if(R0==="object"){if(typeof wA.then==="function")return y(T(wA),KA,cA,f0,H0);throw KA=String(wA),Error("Objects are not valid as a React child (found: "+(KA==="[object Object]"?"object with keys {"+Object.keys(wA).join(", ")+"}":KA)+"). If you meant to render a collection of children, use an array instead.")}return A0}function h(wA,KA,cA){if(wA==null)return wA;var f0=[],H0=0;return y(wA,f0,"","",function(R0){return KA.call(cA,R0,H0++)}),f0}function g(wA){if(wA._status===-1){var KA=wA._ioInfo;KA!=null&&(KA.start=KA.end=performance.now()),KA=wA._result;var cA=KA();if(cA.then(function(H0){if(wA._status===0||wA._status===-1){wA._status=1,wA._result=H0;var R0=wA._ioInfo;R0!=null&&(R0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=H0)}},function(H0){if(wA._status===0||wA._status===-1){wA._status=2,wA._result=H0;var R0=wA._ioInfo;R0!=null&&(R0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=H0)}}),KA=wA._ioInfo,KA!=null){KA.value=cA;var f0=cA.displayName;typeof f0==="string"&&(KA.name=f0)}wA._status===-1&&(wA._status=0,wA._result=cA)}if(wA._status===1)return KA=wA._result,KA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
499
499
|
|
|
500
500
|
Your code should look like:
|
|
501
501
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1721,7 +1721,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1721
1721
|
Title: "${A.entityTitle??D}"
|
|
1722
1722
|
|
|
1723
1723
|
Content:
|
|
1724
|
-
${A.entityContent}`,Oo1);Y=`${w.trim()} ${b.imagePrompt}`}catch(b){this.logger.warn("AI prompt distillation failed, using fallback",{error:h0(b)})}}await this.reportProgress(B,{progress:hQ.PROCESS,message:"Generating image"});let H=this.context.identity.get(),W=this.context.identity.getProfile(),K=W40(H,W)+Y,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(b){return this.logger.error("Image generation failed",{jobId:Q,error:h0(b)}),y$.failure(b)}await this.reportProgress(B,{progress:hQ.GENERATE,message:"Creating image entity"});let q=D2(D),E=LK.createImageEntity({dataUrl:Z.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:q}))this.logger.debug("Deleting existing image for regeneration",{imageId:q}),await this.context.entityService.deleteEntity({entityType:"image",id:q});if(await this.context.entityService.createEntity({entity:{...E,id:q}}),this.logger.debug("Created image entity",{imageId:q}),f&&I){await this.reportProgress(B,{progress:hQ.SAVE,message:`Updating ${f} with cover image`});let b=await ii(this.context.entityService,f,I,this.logger);if(!b)return y$.failure(Error(`Target entity not found: ${f}/${I}`));let _=cy(b,q);await this.context.entities.update(_),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:q}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:h0(Y)}),y$.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var U40={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.80",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 Po1=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")});class tJA extends NQ{entityType=LK.entityType;schema=my;adapter=LK;constructor(A={}){super("image",U40,A,Po1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await p4(B.entityService,A.targetEntityType,A.targetEntityId,this.logger,"Target entity");if(!w.ok)return{kind:"handled",result:{success:!1,error:w.error}};return{kind:"continue",input:{...A,targetEntityId:w.entity.id}}}createGenerationHandler(A){return new vo(A,this.logger)}async onRegister(A){let Q=new vo(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function Sx(A){return new tJA(A)}B0();import{StdioServerTransport as ko1}from"@modelcontextprotocol/sdk/server/stdio.js";function J40(){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 eJA(){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 yo(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 eJA()}class SY{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return SY.instance??=new SY(A),SY.instance}static resetInstance(){if(SY.instance)SY.instance.stop(),SY.instance=null}static createFresh(A){return new SY(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?yo(this.config.logger):J40()}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 ko1,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 G40}from"crypto";import{WebStandardStreamableHTTPServerTransport as jo1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as _o1}from"@modelcontextprotocol/sdk/types.js";var vo1={"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 yo1(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 NJ{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?yo(this.config.logger):eJA(),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 NJ.instance??=new NJ(A),NJ.instance}static resetInstance(){NJ.instance=null}static createFresh(A){return new NJ(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(vo1))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:`${yo1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${xo1(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&_o1(B))w=new jo1({sessionIdGenerator:()=>G40(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??G40();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 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);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 xo1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as go1}from"crypto";import{mkdir as To1,readFile as So1,writeFile as mo1,chmod as uo1}from"fs/promises";import{dirname as co1,join as po1}from"path";function F40(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function K40(A){try{return new URL(A)}catch{return}}function AGA(A,Q){if(A===Q)return!0;let B=K40(A),w=K40(Q);if(!B||!w)return!1;if(!F40(B.hostname)||!F40(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ho1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ho1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function QGA(A,Q){return A.some((B)=>AGA(B,Q))}var lo1="oauth-auth-codes.json",io1=600;function Z40(){return Math.floor(Date.now()/1000)}function ro1(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 do1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(ro1)}}async function no1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class xo{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=po1(A.storageDir,A.storeFile??lo1)}async createCode(A){let Q=Z40(),B={code:`ocd_${go1()}`,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+io1};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=Z40(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new mY("Authorization code not found");if(f.consumed_at!==void 0)throw new mY("Authorization code already consumed");if(f.expires_at<=Q)throw new mY("Authorization code expired");if(f.client_id!==A.clientId)throw new mY("Authorization code client mismatch");if(!AGA(f.redirect_uri,A.redirectUri))throw new mY("Authorization code redirect URI mismatch");let I=await no1(A.codeVerifier);if(f.code_challenge!==I)throw new mY("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new mY("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return do1(JSON.parse(await So1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await To1(co1(this.storeFile),{recursive:!0,mode:448}),await mo1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1724
|
+
${A.entityContent}`,Oo1);Y=`${w.trim()} ${b.imagePrompt}`}catch(b){this.logger.warn("AI prompt distillation failed, using fallback",{error:h0(b)})}}await this.reportProgress(B,{progress:hQ.PROCESS,message:"Generating image"});let H=this.context.identity.get(),W=this.context.identity.getProfile(),K=W40(H,W)+Y,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(b){return this.logger.error("Image generation failed",{jobId:Q,error:h0(b)}),y$.failure(b)}await this.reportProgress(B,{progress:hQ.GENERATE,message:"Creating image entity"});let q=D2(D),E=LK.createImageEntity({dataUrl:Z.dataUrl,title:D});if(await this.context.entityService.getEntity({entityType:"image",id:q}))this.logger.debug("Deleting existing image for regeneration",{imageId:q}),await this.context.entityService.deleteEntity({entityType:"image",id:q});if(await this.context.entityService.createEntity({entity:{...E,id:q}}),this.logger.debug("Created image entity",{imageId:q}),f&&I){await this.reportProgress(B,{progress:hQ.SAVE,message:`Updating ${f} with cover image`});let b=await ii(this.context.entityService,f,I,this.logger);if(!b)return y$.failure(Error(`Target entity not found: ${f}/${I}`));let _=cy(b,q);await this.context.entities.update(_),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Image generation complete"}),this.logger.info("Image generation job complete",{jobId:Q,imageId:q,targetEntityType:f,targetEntityId:I}),{success:!0,imageId:q}}catch(Y){return this.logger.error("Image generation job failed",{jobId:Q,error:h0(Y)}),y$.failure(Y)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var U40={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.81",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 Po1=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")});class tJA extends NQ{entityType=LK.entityType;schema=my;adapter=LK;constructor(A={}){super("image",U40,A,Po1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await p4(B.entityService,A.targetEntityType,A.targetEntityId,this.logger,"Target entity");if(!w.ok)return{kind:"handled",result:{success:!1,error:w.error}};return{kind:"continue",input:{...A,targetEntityId:w.entity.id}}}createGenerationHandler(A){return new vo(A,this.logger)}async onRegister(A){let Q=new vo(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function Sx(A){return new tJA(A)}B0();import{StdioServerTransport as ko1}from"@modelcontextprotocol/sdk/server/stdio.js";function J40(){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 eJA(){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 yo(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 eJA()}class SY{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return SY.instance??=new SY(A),SY.instance}static resetInstance(){if(SY.instance)SY.instance.stop(),SY.instance=null}static createFresh(A){return new SY(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?yo(this.config.logger):J40()}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 ko1,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 G40}from"crypto";import{WebStandardStreamableHTTPServerTransport as jo1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as _o1}from"@modelcontextprotocol/sdk/types.js";var vo1={"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 yo1(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 NJ{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?yo(this.config.logger):eJA(),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 NJ.instance??=new NJ(A),NJ.instance}static resetInstance(){NJ.instance=null}static createFresh(A){return new NJ(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(vo1))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:`${yo1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${xo1(I)}"`).join(", ")}`}async authenticate(A){let Q=new URL(A.url).pathname;if(Q==="/health"||Q==="/status"||Q==="/mcp"&&A.method==="OPTIONS")return null;if(this.authConfig.disabled)return null;let B=A.headers.get("authorization");if(!B?.startsWith("Bearer "))return this.logger.warn("Authentication failed: Missing Bearer token"),this.getAuthErrorResponse("Unauthorized: Bearer token required",401,this.getBearerChallenge(A,{realm:"mcp"}));if(this.authConfig.token){if(B.substring(7)!==this.authConfig.token)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));return this.logger.debug("Authentication successful"),null}try{let w=await this.authConfig.verifyBearerToken?.(A);if(!w)return this.logger.warn("Authentication failed: Invalid token"),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}));let $=this.authConfig.requiredScopes??[],f=$.filter((I)=>!w.scope?.includes(I));if(f.length>0)return this.logger.warn(`Authentication failed: Missing required scope(s): ${f.join(", ")}`),this.getAuthErrorResponse("Forbidden: Missing required scope",403,this.getBearerChallenge(A,{error:"insufficient_scope",scope:$.join(" ")}));return this.logger.debug("Authentication successful"),null}catch(w){return this.logger.warn("Authentication failed: Invalid token",w),this.getAuthErrorResponse("Unauthorized: Invalid token",401,this.getBearerChallenge(A,{error:"invalid_token"}))}}async handleMcpRequest(A){let Q=A.headers.get("mcp-session-id")??void 0;if(A.method==="GET"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.debug(`GET /mcp - SSE stream for session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="DELETE"){if(!Q||!this.transports[Q])return this.createTextResponse("Invalid or missing session ID",400);return this.logger.info(`DELETE /mcp - Terminating session ${Q}`),this.withCors(await this.transports[Q].handleRequest(A))}if(A.method==="OPTIONS")return this.withCors(new Response(null,{status:204}));if(A.method!=="POST")return this.createTextResponse("Method Not Allowed",405);if(!this.mcpServer)return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Service Unavailable: MCP server not connected"},id:null},503);let B=await A.json();this.logger.debug(`POST /mcp - Session: ${Q??"new"}`);try{let w;if(Q&&this.transports[Q])w=this.transports[Q];else if(!Q&&_o1(B))w=new jo1({sessionIdGenerator:()=>G40(),onsessioninitialized:(f)=>{this.logger.info(`Session initialized: ${f}`),this.transports[f]=w},onsessionclosed:(f)=>{this.logger.info(`Session closed: ${f}`),delete this.transports[f]}}),await(this.mcpTransport?this.mcpTransport.createMcpServer():this.mcpServer).connect(w);else return this.createJsonResponse({jsonrpc:"2.0",error:{code:-32000,message:"Bad Request: Server not initialized"},id:null},400);return this.withCors(await w.handleRequest(A,{parsedBody:B}))}catch(w){return this.logger.error("MCP transport error:",w),this.createJsonResponse({jsonrpc:"2.0",error:{code:-32603,message:"Internal error"}},500)}}async handleAgentChatRequest(A){if(!this.agentService)return this.createJsonResponse({error:"Agent service not connected"},503);let{message:Q,conversationId:B}=await A.json();if(!Q||typeof Q!=="string")return this.createJsonResponse({error:"Missing or invalid 'message' field"},400);let w=B??G40();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 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);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 xo1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as go1}from"crypto";import{mkdir as To1,readFile as So1,writeFile as mo1,chmod as uo1}from"fs/promises";import{dirname as co1,join as po1}from"path";function F40(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function K40(A){try{return new URL(A)}catch{return}}function AGA(A,Q){if(A===Q)return!0;let B=K40(A),w=K40(Q);if(!B||!w)return!1;if(!F40(B.hostname)||!F40(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&ho1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function ho1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function QGA(A,Q){return A.some((B)=>AGA(B,Q))}var lo1="oauth-auth-codes.json",io1=600;function Z40(){return Math.floor(Date.now()/1000)}function ro1(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 do1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(ro1)}}async function no1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class xo{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=po1(A.storageDir,A.storeFile??lo1)}async createCode(A){let Q=Z40(),B={code:`ocd_${go1()}`,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+io1};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=Z40(),B;if(await this.enqueueWrite(async()=>{let w=await this.readStore(),$=w.codes.findIndex((D)=>D.code===A.code),f=$>=0?w.codes[$]:void 0;if(!f)throw new mY("Authorization code not found");if(f.consumed_at!==void 0)throw new mY("Authorization code already consumed");if(f.expires_at<=Q)throw new mY("Authorization code expired");if(f.client_id!==A.clientId)throw new mY("Authorization code client mismatch");if(!AGA(f.redirect_uri,A.redirectUri))throw new mY("Authorization code redirect URI mismatch");let I=await no1(A.codeVerifier);if(f.code_challenge!==I)throw new mY("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new mY("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return do1(JSON.parse(await So1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await To1(co1(this.storeFile),{recursive:!0,mode:448}),await mo1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1725
1725
|
`,{mode:384}),await uo1(this.storeFile,384)}}class mY extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as FU0}from"crypto";GA();import{randomUUID as z40}from"crypto";import{mkdir as oo1,readFile as so1,writeFile as ao1,chmod as to1}from"fs/promises";import{dirname as eo1,join as As1}from"path";var Qs1="oauth-clients.json",Bs1=J.enum(["none","client_secret_basic","client_secret_post"]),ws1=J.object({redirect_uris:J.array(J.string().url()).min(1),token_endpoint_auth_method:Bs1.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 $s1(){return Math.floor(Date.now()/1000)}function fs1(){return`ocs_${z40().replaceAll("-","")}`}function Is1(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(Ds1)}}function Ds1(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 ho{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=As1(A.storageDir,A.storeFile??Qs1)}async registerClient(A){let Q=ws1.safeParse(A);if(!Q.success)throw new mx(Q.error.message);let B=Q.data,w=$s1(),$=`oc_${z40()}`,f=B.token_endpoint_auth_method==="none",I={client_id:$,client_id_issued_at:w,redirect_uris:B.redirect_uris,token_endpoint_auth_method:B.token_endpoint_auth_method,grant_types:B.grant_types,response_types:B.response_types,...B.scope?{scope:B.scope}:{},...B.client_name?{client_name:B.client_name}:{},...B.client_uri?{client_uri:B.client_uri}:{},...B.logo_uri?{logo_uri:B.logo_uri}:{},...B.contacts?{contacts:B.contacts}:{},...!f?{client_secret:fs1(),client_secret_expires_at:0}:{}};return await this.enqueueWrite(async()=>{let D=await this.readStore();D.clients.push(I),await this.writeStore(D)}),I}async getClient(A){return(await this.readStore()).clients.find((B)=>B.client_id===A)}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Is1(JSON.parse(await so1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await oo1(eo1(this.storeFile),{recursive:!0,mode:448}),await ao1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1726
1726
|
`,{mode:384}),await to1(this.storeFile,384)}}class mx extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}function N40(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function Ys1(A){let Q=new Uint8Array(A);if(Q.length===64)return Q;if(Q[0]!==48)return Q;let B=2;if(Q[1]&&Q[1]>128)B+=Q[1]-128;if(Q[B]!==2)throw Error("Invalid DER ECDSA signature");let w=Q[B+1];if(w===void 0)throw Error("Invalid DER ECDSA signature");let $=B+2,f=Q.slice($,$+w);if(B=$+w,Q[B]!==2)throw Error("Invalid DER ECDSA signature");let I=Q[B+1];if(I===void 0)throw Error("Invalid DER ECDSA signature");let D=B+2,Y=Q.slice(D,D+I);return new Uint8Array([...q40(f),...q40(Y)])}function q40(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 BGA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${N40(B)}.${N40(Q)}`,$=await crypto.subtle.importKey("jwk",A,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),f=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},$,new TextEncoder().encode(w));return`${w}.${Buffer.from(Ys1(f)).toString("base64url")}`}import{createHash as Hs1}from"crypto";import{mkdir as Xs1,readFile as Ws1,writeFile as Us1,chmod as Js1}from"fs/promises";import{dirname as Gs1,join as Fs1}from"path";var Ks1="oauth-signing-key.jwk";function L40(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 E40(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return Hs1("sha256").update(Q).digest("base64url")}function Zs1(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function zs1(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!L40(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=E40(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class go{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=Fs1(A.storageDir,A.keyFile??Ks1)}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 zs1();return await Xs1(Gs1(this.keyFile),{recursive:!0,mode:448}),await Us1(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1727
1727
|
`,{mode:384}),await Js1(this.keyFile,384),Q}async getPublicJwk(){return Zs1(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await Ws1(this.keyFile,"utf8"));if(!L40(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:E40(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var u2={};vB(u2,{trimPadding:()=>V40,toUTF8String:()=>Rs1,toBuffer:()=>Ms1,toBase64:()=>Cs1,isBase64URL:()=>Ps1,isBase64:()=>bs1,fromUTF8String:()=>Os1,fromBuffer:()=>Vs1});var M40=(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},Ns1=M40("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),qs1=M40("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),Ls1=/^[-A-Za-z0-9\-_]*$/,Es1=/^[-A-Za-z0-9+/]*={0,3}$/,uX={};uX.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,Y,H;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let W=new ArrayBuffer(w),F=new Uint8Array(W),K=Q?qs1:Ns1;for($=0;$<B;$+=4)I=K[A.charCodeAt($)],D=K[A.charCodeAt($+1)],Y=K[A.charCodeAt($+2)],H=K[A.charCodeAt($+3)],F[f++]=I<<2|D>>4,F[f++]=(D&15)<<4|Y>>2,F[f++]=(Y&3)<<6|H&63;return W};uX.fromArrayBuffer=(A,Q)=>{let B=new Uint8Array(A),w,$="",f=B.length,I=Q?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(w=0;w<f;w+=3)$+=I[B[w]>>2],$+=I[(B[w]&3)<<4|B[w+1]>>4],$+=I[(B[w+1]&15)<<2|B[w+2]>>6],$+=I[B[w+2]&63];let D=f%3;if(D===2)$=$.substring(0,$.length-1)+(Q?"":"=");else if(D===1)$=$.substring(0,$.length-2)+(Q?"":"==");return $};uX.toString=(A,Q)=>{return new TextDecoder().decode(uX.toArrayBuffer(A,Q))};uX.fromString=(A,Q)=>{return uX.fromArrayBuffer(new TextEncoder().encode(A),Q)};uX.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?Ls1.test(A):Es1.test(A)}catch(B){return!1}};uX.base64=uX;var qJ=uX;function Ms1(A,Q="base64url"){let B=qJ.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function Vs1(A,Q="base64url"){let B=new Uint8Array(A);return qJ.fromArrayBuffer(B.buffer,Q==="base64url")}function Cs1(A){let Q=qJ.toArrayBuffer(A,!0);return qJ.fromArrayBuffer(Q)}function Os1(A){return qJ.fromString(A,!0)}function Rs1(A){return qJ.toString(A,!0)}function bs1(A){return qJ.validate(A,!1)}function Ps1(A){return A=V40(A),qJ.validate(A,!0)}function V40(A){return A.replace(/=/g,"")}var C7={};vB(C7,{encode:()=>ss1,decodeFirst:()=>os1});function ZO(A,Q,B){if(Q<24)return[Q,1];let w=A.byteLength-B-1,$=new DataView(A.buffer,B+1),f,I=0;switch(Q){case 24:{if(w>0)f=$.getUint8(0),I=2;break}case 25:{if(w>1)f=$.getUint16(0,!1),I=3;break}case 26:{if(w>3)f=$.getUint32(0,!1),I=5;break}case 27:{if(w>7){let D=$.getBigUint64(0,!1);if(D>=24n&&D<=Number.MAX_SAFE_INTEGER)return[Number(D),9]}break}}if(f&&f>=24)return[f,I];throw Error("Length not supported or not well formed")}var To=0,ux=1,wGA=2,$GA=3,fGA=4,IGA=5,DGA=6,C40=7;function cX(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==ux){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 mo{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 O40(A,Q,B){return ZO(A,Q,B)}function ks1(A,Q,B){let[w,$]=O40(A,Q,B);return[-w-1,$]}function R40(A,Q,B){let[w,$]=ZO(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var js1=new TextDecoder;function _s1(A,Q,B){let[w,$]=R40(A,Q,B);return[js1.decode(w),$]}function vs1(A,Q,B){if(Q===0)return[[],1];let[w,$]=ZO(A,Q,B),f=$,I=[];for(let D=0;D<w;D++){if(A.byteLength-B-f<=0)throw Error("array is not supported or well formed");let[H,W]=sN(A,B+f);I.push(H),f+=W}return[I,f]}var So="Map is not supported or well formed";function ys1(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=ZO(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let Y=A.byteLength-B-f;if(Y<=0)throw Error(So);let[H,W]=sN(A,B+f);if(f+=W,Y-=W,Y<=0)throw Error(So);if(typeof H!=="string"&&typeof H!=="number")throw Error(So);if(I.has(H))throw Error(So);let[F,K]=sN(A,B+f);f+=K,I.set(H,F)}return[I,f]}function xs1(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 hs1(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 gs1(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 Ts1(A,Q,B){let[w,$]=ZO(A,Q,B),[f,I]=sN(A,B+$);return[new mo(w,f),$+I]}function sN(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 To:return O40(A,$,Q);case ux:return ks1(A,$,Q);case wGA:return R40(A,$,Q);case $GA:return _s1(A,$,Q);case fGA:return vs1(A,$,Q);case IGA:return ys1(A,$,Q);case DGA:return Ts1(A,$,Q);case C40: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 xs1(A,Q);case 26:return hs1(A,Q);case 27:return gs1(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function Ss1(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function ms1(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 us1(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return cX(ux,Math.abs(A));else return cX(To,A);return[ms1(A)]}else if(A<0n)return cX(ux,A*-1n);else return cX(To,A)}var cs1=new TextEncoder;function ps1(A,Q){Q.push(...cX($GA,A.length)),Q.push(cs1.encode(A))}function ls1(A,Q){Q.push(...cX(wGA,A.length)),Q.push(A)}function is1(A,Q){Q.push(...cX(fGA,A.length));for(let B of A)cx(B,Q)}function rs1(A,Q){Q.push(new Uint8Array(cX(IGA,A.size)));for(let[B,w]of A.entries())cx(B,Q),cx(w,Q)}function ds1(A,Q){Q.push(...cX(DGA,A.tag)),cx(A.value,Q)}function cx(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(Ss1(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...us1(A));return}if(typeof A=="string"){ps1(A,Q);return}if(A instanceof Uint8Array){ls1(A,Q);return}if(Array.isArray(A)){is1(A,Q);return}if(A instanceof Map){rs1(A,Q);return}if(A instanceof mo){ds1(A,Q);return}throw Error("Not implemented")}function YGA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return sN(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return sN(new DataView(A),Q);return sN(A,Q)}function HGA(A){let Q=[];cx(A,Q);let B=0;for(let f of Q)if(typeof f=="number")B+=1;else B+=f.length;let w=new Uint8Array(B),$=0;for(let f of Q)if(typeof f=="number")w[$]=f,$+=1;else w.set(f,$),$+=f.length;return w}function os1(A){let Q=new Uint8Array(A),B=YGA(Q,0),[w]=B;return w}function ss1(A){return HGA(A)}var lX={};vB(lX,{verify:()=>YW0,getRandomValues:()=>_40,digest:()=>j40});function b40(A){let Q=A.get(S2.kty);return XGA(Q)&&Q===yI.OKP}function gK(A){let Q=A.get(S2.kty);return XGA(Q)&&Q===yI.EC2}function zO(A){let Q=A.get(S2.kty);return XGA(Q)&&Q===yI.RSA}var S2;(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"})(S2||(S2={}));var yI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(yI||(yI={}));function XGA(A){return Object.values(yI).indexOf(A)>=0}var b9;(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"})(b9||(b9={}));function P40(A){return Object.values(b9).indexOf(A)>=0}var HQ;(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"})(HQ||(HQ={}));function pX(A){return Object.values(HQ).indexOf(A)>=0}function TK(A){if([HQ.RS1].indexOf(A)>=0)return"SHA-1";else if([HQ.ES256,HQ.PS256,HQ.RS256].indexOf(A)>=0)return"SHA-256";else if([HQ.ES384,HQ.PS384,HQ.RS384].indexOf(A)>=0)return"SHA-384";else if([HQ.ES512,HQ.PS512,HQ.RS512,HQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var px=void 0;function Zf(){return new Promise((Q,B)=>{if(px)return Q(px);let w=ts1.stubThisGlobalThisCrypto();if(w)return px=w,Q(px);return B(new k40)})}class k40 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var ts1={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{px=A}};async function j40(A,Q){let B=await Zf(),w=TK(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function _40(A){return(await Zf()).getRandomValues(A),A}async function NO(A){let Q=await Zf(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function uo(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Zf(),I=Q.get(S2.alg),D=Q.get(S2.crv),Y=Q.get(S2.x),H=Q.get(S2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!Y)throw Error("Public key was missing x (EC2)");if(!H)throw Error("Public key was missing y (EC2)");let W;if(D===b9.P256)W="P-256";else if(D===b9.P384)W="P-384";else if(D===b9.P521)W="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let F={kty:"EC",crv:W,x:u2.fromBuffer(Y),y:u2.fromBuffer(H),ext:!1},Z=await NO({keyData:F,algorithm:{name:"ECDSA",namedCurve:W}}),q=TK(I);if($)q=TK($);let E={name:"ECDSA",hash:{name:q}};return f.subtle.verify(E,Z,B,w)}function WGA(A){if([HQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([HQ.ES256,HQ.ES384,HQ.ES512,HQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([HQ.RS256,HQ.RS384,HQ.RS512,HQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([HQ.PS256,HQ.PS384,HQ.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 co(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await Zf(),I=Q.get(S2.alg),D=Q.get(S2.n),Y=Q.get(S2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!pX(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!Y)throw Error("Public key was missing e (RSA)");let H={kty:"RSA",alg:"",n:u2.fromBuffer(D),e:u2.fromBuffer(Y),ext:!1},W={name:WGA(I),hash:{name:TK(I)}},F={name:WGA(I)};if($)W.hash.name=TK($);if(W.name==="RSASSA-PKCS1-v1_5"){if(W.hash.name==="SHA-256")H.alg="RS256";else if(W.hash.name==="SHA-384")H.alg="RS384";else if(W.hash.name==="SHA-512")H.alg="RS512";else if(W.hash.name==="SHA-1")H.alg="RS1"}else if(W.name==="RSA-PSS"){let Z=0;if(W.hash.name==="SHA-256")H.alg="PS256",Z=32;else if(W.hash.name==="SHA-384")H.alg="PS384",Z=48;else if(W.hash.name==="SHA-512")H.alg="PS512",Z=64;F.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${W.name})`);let K=await NO({keyData:H,algorithm:W});return f.subtle.verify(F,K,B,w)}function po(A){let Q=X2.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 Y5(A){let Q;if(typeof A==="string")if(u2.isBase64URL(A))Q=u2.toBase64(A);else if(u2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=u2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2300,8 +2300,8 @@ ${b}`)}if(w!==void 0&&f?.algorithms!==void 0){let L=f.algorithms.map((b)=>b.alg)
|
|
|
2300
2300
|
</form>
|
|
2301
2301
|
</main>
|
|
2302
2302
|
</body>
|
|
2303
|
-
</html>`}function LZA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function EZA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(EU0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Ma(A){let Q=za(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function fW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}GA();var Ca="email:send",VU0=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();B0();GA();var CU0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.
|
|
2304
|
-
`)}}return{to:A.to,subject:kU0(A.subject,Q),body:kU0(A.body,Q)}}function kU0(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 bg(A){return new CZA(A)}GA();var OZA=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 jU0(A,Q){return[]}B0();function RZA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=RV.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var _U0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.80",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 JZ extends LX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",_U0,Q,OZA)}async getTools(){return jU0(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"});RZA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=gR();return this.httpServer=NJ.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||gR()))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=SY.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(){SY.resetInstance(),NJ.resetInstance()}}B0();GA();var ND=Y1(Ec0(),1);GA();B0();var YMA=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),...Uv.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var Mc0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.80",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 HMA=2000,IR2=8000,DR2=100;function PAA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class nZ extends fN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",Mc0,A,YMA);this.fetchText=Q.fetchText??ll}async onRegister(A){await super.onRegister(A),this.client=new ND.Client({intents:[ND.GatewayIntentBits.Guilds,ND.GatewayIntentBits.GuildMessages,ND.GatewayIntentBits.MessageContent,ND.GatewayIntentBits.DirectMessages],partials:[ND.Partials.Channel]}),this.client.on(ND.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(ND.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(!PAA(B))return;let w=Z_(Q,HMA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!PAA(B))return;let w=Z_(Q,HMA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!PAA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,HMA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let Y=Q||$||!this.config.requireMention||w;if(I&&(!Y||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:f}));if(!Y){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",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let H=this.stripMention(A.content);if(A.attachments.size>0){let F=this.context.permissions.getUserLevel("discord",A.author.id,D);if(F==="anchor"||F==="trusted")for(let Z of A.attachments.values()){let q=Z.name,E=Z.contentType??void 0,L=Z.size;if(!this.isUploadableTextFile(q,E))continue;if(!this.isFileSizeAllowed(L))continue;try{let b=await this.fetchText(Z.url);H+=`
|
|
2303
|
+
</html>`}function LZA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function EZA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(EU0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Ma(A){let Q=za(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function fW(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}GA();var Ca="email:send",VU0=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();B0();GA();var CU0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.81",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 VZA="notifications:send",gA2=J.object({}),TA2=J.discriminatedUnion("type",[J.object({type:J.literal("email"),address:J.string().email()}).strict()]),SA2=J.object({recipient:TA2,title:J.string().min(1),body:J.string().min(1),html:J.string().min(1).optional(),sensitivity:J.enum(["normal","secret"]).default("normal")}).strict(),OU0=J.discriminatedUnion("status",[J.object({status:J.literal("sent"),deliveryId:J.string().optional()}).strict(),J.object({status:J.literal("failed")}).strict()]);class RU0 extends YB{constructor(A={}){super("notifications",CU0,A,gA2)}async onRegister(A){A.messaging.subscribe(VZA,async(Q)=>{let B=SA2.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:Ca,payload:w});if(!("success"in $)||!$.success||!$.data)return{success:!1,error:"Notification delivery failed"};let f=$.data;if(f.status!=="sent")return{success:!1,error:"Notification delivery failed"};return{success:!0,data:f.id?{status:"sent",deliveryId:f.id}:{status:"sent"}}})}}function bU0(A={}){return new RU0(A)}B0();GA();var PU0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.81",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 uA2=J.union([J.string().email(),J.object({to:J.string().email(),subject:J.string().min(1),body:J.string().min(1)}).strict()]),cA2=J.object({issuer:J.string().optional(),trustedIssuers:J.array(J.string()).default([]),allowLocalhostIssuers:J.boolean().optional(),storageDir:J.string().default("./data/auth"),setupEmail:uA2.optional()}),pA2=J.object({}),Oa;function gR(){return Oa}class CZA extends YB{service;constructor(A={}){super("auth-service",PU0,A,cA2)}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 Va({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(),Oa=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(Oa===this.service)Oa=void 0;this.service=void 0}async getTools(){return[YQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",pA2,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return bw({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return bw({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return bw({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=lA2(this.config.setupEmail,B);if(await Q.hasSetupEmailDelivery(B.setupTokenId,w.to))return;let $=await A.messaging.send({type:VZA,payload:{recipient:{type:"email",address:w.to},title:w.subject,body:w.body,sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=OU0.safeParse($.data);if(!f.success||f.data.status!=="sent"){A.logger.warn("Passkey setup email delivery was not confirmed");return}await Q.recordSetupEmailDelivery(B.setupTokenId,w.to,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function lA2(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(`
|
|
2304
|
+
`)}}return{to:A.to,subject:kU0(A.subject,Q),body:kU0(A.body,Q)}}function kU0(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 bg(A){return new CZA(A)}GA();var OZA=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 jU0(A,Q){return[]}B0();function RZA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=RV.safeParse(B.payload);if(!w.success)return Q.warn("Received invalid job-progress message",{error:w.error.message}),{success:!1};let $=w.data,f=$.type,I=$.status,D=$.id;if(Q.debug(`${f} ${D} - ${I}:`,{id:$.id,message:$.message,progress:$.progress,metadata:$.metadata}),$.batchDetails)Q.debug(`Batch details for ${D}:`,{totalOperations:$.batchDetails.totalOperations,completedOperations:$.batchDetails.completedOperations,failedOperations:$.batchDetails.failedOperations,currentOperation:$.batchDetails.currentOperation,errors:$.batchDetails.errors});if($.jobDetails)Q.debug(`Job details for ${D}:`,{jobType:$.jobDetails.jobType,priority:$.jobDetails.priority,retryCount:$.jobDetails.retryCount});return{success:!0}}),Q.debug("Subscribed to job progress events")}var _U0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.81",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 JZ extends LX{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",_U0,Q,OZA)}async getTools(){return jU0(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"});RZA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=gR();return this.httpServer=NJ.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||gR()))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=SY.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(){SY.resetInstance(),NJ.resetInstance()}}B0();GA();var ND=Y1(Ec0(),1);GA();B0();var YMA=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),...Uv.shape,captureUrlEmoji:J.string().default("\uD83D\uDD16")});var Mc0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.81",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 HMA=2000,IR2=8000,DR2=100;function PAA(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class nZ extends fN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",Mc0,A,YMA);this.fetchText=Q.fetchText??ll}async onRegister(A){await super.onRegister(A),this.client=new ND.Client({intents:[ND.GatewayIntentBits.Guilds,ND.GatewayIntentBits.GuildMessages,ND.GatewayIntentBits.MessageContent,ND.GatewayIntentBits.DirectMessages],partials:[ND.Partials.Channel]}),this.client.on(ND.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(ND.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(!PAA(B))return;let w=Z_(Q,HMA);for(let $ of w)B.send($).catch((f)=>this.logger.error("Failed to send message",{error:f}))}async sendMessageWithId({channelId:A,message:Q}){if(!A||!this.client)return;let B=this.client.channels.cache.get(A);if(!PAA(B))return;let w=Z_(Q,HMA),$;for(let f of w)$=(await B.send(f)).id;return $}async editMessage({channelId:A,messageId:Q,newMessage:B}){if(!A||!this.client)return!1;let w=this.client.channels.cache.get(A);if(!PAA(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,HMA)),!0}catch{return!1}}supportsMessageEditing(){return!0}async handleMessage(A){if(A.author.id===this.client?.user?.id)return;if(!this.context)return;let Q=!A.guild,B=A.channel.isThread();if(Q&&!this.config.allowDMs)return;let w=!!this.client?.user&&A.mentions.has(this.client.user,{ignoreEveryone:!0});if(A.author.bot&&!w)return;let $=B&&"ownerId"in A.channel&&A.channel.ownerId===this.client?.user?.id,f=this.getSpaceChannelId(A),I=!Q&&this.isConfiguredSpace(f),D={channelId:f,isBot:A.author.bot};if(this.config.allowedChannels.length>0&&!Q&&!this.isAllowedChannel(A.channel.id,f))return;let Y=Q||$||!this.config.requireMention||w;if(I&&(!Y||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:f}));if(!Y){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",D).catch((Z)=>this.logger.error("URL capture failed",{error:Z,url:K}))}}return}let H=this.stripMention(A.content);if(A.attachments.size>0){let F=this.context.permissions.getUserLevel("discord",A.author.id,D);if(F==="anchor"||F==="trusted")for(let Z of A.attachments.values()){let q=Z.name,E=Z.contentType??void 0,L=Z.size;if(!this.isUploadableTextFile(q,E))continue;if(!this.isFileSizeAllowed(L))continue;try{let b=await this.fetchText(Z.url);H+=`
|
|
2305
2305
|
|
|
2306
2306
|
`+this.formatFileUploadMessage(q,b)}catch(b){this.logger.error("Failed to download attachment",{error:b,filename:q})}}}if(H=H.trim(),!H)return;let W=A.channel.id;await this.routeToAgent(H,W,A,D)}async capturePassiveSpaceMessage(A,Q){if(!this.context)return;let B=this.stripMention(A.content).trim();if(!B)return;let w=`discord-${Q}`,$=this.getChannelName(A);await this.context.conversations.start({sessionId:w,interfaceType:"discord",channelId:Q,metadata:{channelName:$,interfaceType:"discord",channelId:Q}}),await this.context.conversations.addMessage({conversationId:w,role:"user",content:B,metadata:this.buildUserMessageMetadata(A,Q,$,{threadId:A.channel.isThread()?A.channel.id:void 0})})}async routeToAgent(A,Q,B,w){if(!this.context)return;let $=this.context.agent,f=Q;if(this.config.useThreads&&B.guild&&!B.channel.isThread())try{f=(await B.startThread({name:UX(A,DR2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(H){this.logger.error("Failed to create thread",{error:H})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),Y=this.getChannelName(B);this.startProcessingInput(f);try{let H=this.client?.channels.cache.get(f);if(PAA(H))this.startTypingIndicator(H);if(this.pendingConfirmations.has(I)){await this.handleConfirmationResponse(A,I,f);return}let W=await $.chat(A,I,{userPermissionLevel:D,interfaceType:"discord",channelId:f,channelName:Y,...this.buildUserMessageMetadata(B,Q,Y,{threadId:f!==Q||B.channel.isThread()?f:void 0})});if(W.pendingConfirmation)this.pendingConfirmations.set(I,!0);let F=await this.sendMessageWithId({channelId:f,message:W.text});if(F&&W.toolResults){for(let K of W.toolResults)if(K.jobId)this.trackAgentResponseForJob(K.jobId,F,f)}}catch(H){this.logger.error("Error handling message",{error:H,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${H instanceof Error?H.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}async handleConfirmationResponse(A,Q,B){let w=mV(A);if(!w){this.sendMessageToChannel({channelId:B,message:"_Please reply with **yes** to confirm or **no/cancel** to abort._"});return}this.pendingConfirmations.delete(Q);let $=await this.context?.agent.confirmPendingAction(Q,w.confirmed);if($)await this.sendMessageWithId({channelId:B,message:$.text})}startTypingIndicator(A){if(!this.config.showTypingIndicator)return;A.sendTyping().catch((B)=>this.logger.debug("Typing indicator failed",{error:B}));let Q=setInterval(()=>{A.sendTyping().catch((B)=>this.logger.debug("Typing indicator failed",{error:B}))},IR2);this.typingIntervals.set(A.id,Q)}stopTypingIndicator(A){let Q=this.typingIntervals.get(A);if(Q)clearInterval(Q),this.typingIntervals.delete(A)}getAuthorDisplayName(A){return A.member?.displayName??A.author.globalName??A.author.username}getChannelName(A){return A.guild?.name??"DM"}getSpaceChannelId(A){if(!A.channel.isThread())return A.channel.id;if("parentId"in A.channel&&typeof A.channel.parentId==="string")return A.channel.parentId;if("parent"in A.channel&&A.channel.parent&&typeof A.channel.parent==="object"&&"id"in A.channel.parent&&typeof A.channel.parent.id==="string")return A.channel.parent.id;return A.channel.id}isConfiguredSpace(A){let Q=`discord:${A}`;return this.context?.spaces.some((B)=>iU(B,Q))??!1}isAllowedChannel(A,Q){return this.config.allowedChannels.includes(A)||this.config.allowedChannels.includes(Q)}willRouteUseNonSpaceConversation(A){if(A.channel.isThread())return this.getSpaceChannelId(A)!==A.channel.id;return this.config.useThreads&&Boolean(A.guild)}buildUserMessageMetadata(A,Q,B,w={}){return{actor:{actorId:`discord:${A.author.id}`,interfaceType:"discord",role:"user",displayName:this.getAuthorDisplayName(A),username:A.author.username,isBot:Boolean(A.author.bot)},source:{messageId:A.id,channelId:Q,channelName:B,...w.threadId?{threadId:w.threadId}:{},metadata:{...A.guild?.id?{guildId:A.guild.id}:{},...A.guild?.name?{guildName:A.guild.name}:{}}}}}stripMention(A){if(!this.client?.user)return A;return A.replace(new RegExp(`<@!?${this.client.user.id}>`,"g"),"").trim()}}B0();import{resolve as cb,join as dR2}from"path";var XMA=(A,Q,B)=>{return(w,$)=>{let f=-1;return I(0);async function I(D){if(D<=f)throw Error("next() called multiple times");f=D;let Y,H=!1,W;if(A[D])W=A[D][0][0],w.req.routeIndex=D;else W=D===A.length&&$||void 0;if(W)try{Y=await W(w,()=>I(D+1))}catch(F){if(F instanceof Error&&Q)w.error=F,Y=await Q(F,w),H=!0;else throw F}else if(w.finalized===!1&&B)Y=await B(w);if(Y&&(w.finalized===!1||H))w.res=Y;return w}}};var Vc0=Symbol();var Cc0=async(A,Q=Object.create(null))=>{let{all:B=!1,dot:w=!1}=Q,f=(A instanceof kAA?A.raw.headers:A.headers).get("Content-Type");if(f?.startsWith("multipart/form-data")||f?.startsWith("application/x-www-form-urlencoded"))return YR2(A,{all:B,dot:w});return{}};async function YR2(A,Q){let B=await A.formData();if(B)return HR2(B,Q);return{}}function HR2(A,Q){let B=Object.create(null);if(A.forEach((w,$)=>{if(!(Q.all||$.endsWith("[]")))B[$]=w;else XR2(B,$,w)}),Q.dot)Object.entries(B).forEach(([w,$])=>{if(w.includes("."))WR2(B,w,$),delete B[w]});return B}var XR2=(A,Q,B)=>{if(A[Q]!==void 0)if(Array.isArray(A[Q]))A[Q].push(B);else A[Q]=[A[Q],B];else if(!Q.endsWith("[]"))A[Q]=B;else A[Q]=[B]},WR2=(A,Q,B)=>{let w=A,$=Q.split(".");$.forEach((f,I)=>{if(I===$.length-1)w[f]=B;else{if(!w[f]||typeof w[f]!=="object"||Array.isArray(w[f])||w[f]instanceof File)w[f]=Object.create(null);w=w[f]}})};var UMA=(A)=>{let Q=A.split("/");if(Q[0]==="")Q.shift();return Q},Oc0=(A)=>{let{groups:Q,path:B}=UR2(A),w=UMA(B);return JR2(w,Q)},UR2=(A)=>{let Q=[];return A=A.replace(/\{[^}]+\}/g,(B,w)=>{let $=`@${w}`;return Q.push([$,B]),$}),{groups:Q,path:A}},JR2=(A,Q)=>{for(let B=Q.length-1;B>=0;B--){let[w]=Q[B];for(let $=A.length-1;$>=0;$--)if(A[$].includes(w)){A[$]=A[$].replace(w,Q[B][1]);break}}return A},jAA={},Rc0=(A,Q)=>{if(A==="*")return"*";let B=A.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(B){let w=`${A}#${Q}`;if(!jAA[w])if(B[2])jAA[w]=Q&&Q[0]!==":"&&Q[0]!=="*"?[w,B[1],new RegExp(`^${B[2]}(?=/${Q})`)]:[A,B[1],new RegExp(`^${B[2]}$`)];else jAA[w]=[A,B[1],!0];return jAA[w]}return null},_AA=(A,Q)=>{try{return Q(A)}catch{return A.replace(/(?:%[0-9A-Fa-f]{2})+/g,(B)=>{try{return Q(B)}catch{return B}})}},JMA=(A)=>_AA(A,decodeURI),GMA=(A)=>{let Q=A.url,B=Q.indexOf("/",Q.indexOf(":")+4),w=B;for(;w<Q.length;w++){let $=Q.charCodeAt(w);if($===37){let f=Q.indexOf("?",w),I=Q.indexOf("#",w),D=f===-1?I===-1?void 0:I:I===-1?f:Math.min(f,I),Y=Q.slice(B,D);return JMA(Y.includes("%25")?Y.replace(/%25/g,"%2525"):Y)}else if($===63||$===35)break}return Q.slice(B,w)};var bc0=(A)=>{let Q=GMA(A);return Q.length>1&&Q.at(-1)==="/"?Q.slice(0,-1):Q},VL=(A,Q,...B)=>{if(B.length)Q=VL(Q,...B);return`${A?.[0]==="/"?"":"/"}${A}${Q==="/"?"":`${A?.at(-1)==="/"?"":"/"}${Q?.[0]==="/"?Q.slice(1):Q}`}`},vAA=(A)=>{if(A.charCodeAt(A.length-1)!==63||!A.includes(":"))return null;let Q=A.split("/"),B=[],w="";return Q.forEach(($)=>{if($!==""&&!/\:/.test($))w+="/"+$;else if(/\:/.test($))if(/\?/.test($)){if(B.length===0&&w==="")B.push("/");else B.push(w);let f=$.replace("?","");w+="/"+f,B.push(w)}else w+="/"+$}),B.filter(($,f,I)=>I.indexOf($)===f)},WMA=(A)=>{if(!/[%+]/.test(A))return A;if(A.indexOf("+")!==-1)A=A.replace(/\+/g," ");return A.indexOf("%")!==-1?_AA(A,FMA):A},Pc0=(A,Q,B)=>{let w;if(!B&&Q&&!/[%+]/.test(Q)){let I=A.indexOf("?",8);if(I===-1)return;if(!A.startsWith(Q,I+1))I=A.indexOf(`&${Q}`,I+1);while(I!==-1){let D=A.charCodeAt(I+Q.length+1);if(D===61){let Y=I+Q.length+2,H=A.indexOf("&",Y);return WMA(A.slice(Y,H===-1?void 0:H))}else if(D==38||isNaN(D))return"";I=A.indexOf(`&${Q}`,I+1)}if(w=/[%+]/.test(A),!w)return}let $={};w??=/[%+]/.test(A);let f=A.indexOf("?",8);while(f!==-1){let I=A.indexOf("&",f+1),D=A.indexOf("=",f);if(D>I&&I!==-1)D=-1;let Y=A.slice(f+1,D===-1?I===-1?void 0:I:D);if(w)Y=WMA(Y);if(f=I,Y==="")continue;let H;if(D===-1)H="";else if(H=A.slice(D+1,I===-1?void 0:I),w)H=WMA(H);if(B){if(!($[Y]&&Array.isArray($[Y])))$[Y]=[];$[Y].push(H)}else $[Y]??=H}return Q?$[Q]:$},kc0=Pc0,jc0=(A,Q)=>{return Pc0(A,Q,!0)},FMA=decodeURIComponent;var _c0=(A)=>_AA(A,FMA),kAA=class{raw;#A;#Q;routeIndex=0;path;bodyCache={};constructor(A,Q="/",B=[[]]){this.raw=A,this.path=Q,this.#Q=B,this.#A={}}param(A){return A?this.#B(A):this.#f()}#B(A){let Q=this.#Q[0][this.routeIndex][1][A],B=this.#$(Q);return B&&/\%/.test(B)?_c0(B):B}#f(){let A={},Q=Object.keys(this.#Q[0][this.routeIndex][1]);for(let B of Q){let w=this.#$(this.#Q[0][this.routeIndex][1][B]);if(w!==void 0)A[B]=/\%/.test(w)?_c0(w):w}return A}#$(A){return this.#Q[1]?this.#Q[1][A]:A}query(A){return kc0(this.url,A)}queries(A){return jc0(this.url,A)}header(A){if(A)return this.raw.headers.get(A)??void 0;let Q={};return this.raw.headers.forEach((B,w)=>{Q[w]=B}),Q}async parseBody(A){return this.bodyCache.parsedBody??=await Cc0(this,A)}#w=(A)=>{let{bodyCache:Q,raw:B}=this,w=Q[A];if(w)return w;let $=Object.keys(Q)[0];if($)return Q[$].then((f)=>{if($==="json")f=JSON.stringify(f);return new Response(f)[A]()});return Q[A]=B[A]()};json(){return this.#w("text").then((A)=>JSON.parse(A))}text(){return this.#w("text")}arrayBuffer(){return this.#w("arrayBuffer")}blob(){return this.#w("blob")}formData(){return this.#w("formData")}addValidatedData(A,Q){this.#A[A]=Q}valid(A){return this.#A[A]}get url(){return this.raw.url}get method(){return this.raw.method}get[Vc0](){return this.#Q}get matchedRoutes(){return this.#Q[0].map(([[,A]])=>A)}get routePath(){return this.#Q[0].map(([[,A]])=>A)[this.routeIndex].path}};var vc0={Stringify:1,BeforeStream:2,Stream:3},yc0=(A,Q)=>{let B=new String(A);return B.isEscaped=!0,B.callbacks=Q,B};var KMA=async(A,Q,B,w,$)=>{if(typeof A==="object"&&!(A instanceof String)){if(!(A instanceof Promise))A=A.toString();if(A instanceof Promise)A=await A}let f=A.callbacks;if(!f?.length)return Promise.resolve(A);if($)$[0]+=A;else $=[A];let I=Promise.all(f.map((D)=>D({phase:Q,buffer:$,context:w}))).then((D)=>Promise.all(D.filter(Boolean).map((Y)=>KMA(Y,Q,!1,w,$))).then(()=>$[0]));if(B)return yc0(await I,f);else return I};var GR2="text/plain; charset=UTF-8",ZMA=(A,Q)=>{return{"Content-Type":A,...Q}},US=(A,Q)=>new Response(A,Q),xc0=class{#A;#Q;env={};#B;finalized=!1;error;#f;#$;#w;#X;#Y;#H;#D;#W;#U;constructor(A,Q){if(this.#A=A,Q)this.#$=Q.executionCtx,this.env=Q.env,this.#H=Q.notFoundHandler,this.#U=Q.path,this.#W=Q.matchResult}get req(){return this.#Q??=new kAA(this.#A,this.#U,this.#W),this.#Q}get event(){if(this.#$&&"respondWith"in this.#$)return this.#$;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#$)return this.#$;else throw Error("This context has no ExecutionContext")}get res(){return this.#w||=US(null,{headers:this.#D??=new Headers})}set res(A){if(this.#w&&A){A=US(A.body,A);for(let[Q,B]of this.#w.headers.entries()){if(Q==="content-type")continue;if(Q==="set-cookie"){let w=this.#w.headers.getSetCookie();A.headers.delete("set-cookie");for(let $ of w)A.headers.append("set-cookie",$)}else A.headers.set(Q,B)}}this.#w=A,this.finalized=!0}render=(...A)=>{return this.#Y??=(Q)=>this.html(Q),this.#Y(...A)};setLayout=(A)=>this.#X=A;getLayout=()=>this.#X;setRenderer=(A)=>{this.#Y=A};header=(A,Q,B)=>{if(this.finalized)this.#w=US(this.#w.body,this.#w);let w=this.#w?this.#w.headers:this.#D??=new Headers;if(Q===void 0)w.delete(A);else if(B?.append)w.append(A,Q);else w.set(A,Q)};status=(A)=>{this.#f=A};set=(A,Q)=>{this.#B??=new Map,this.#B.set(A,Q)};get=(A)=>{return this.#B?this.#B.get(A):void 0};get var(){if(!this.#B)return{};return Object.fromEntries(this.#B)}#I(A,Q,B){let w=this.#w?new Headers(this.#w.headers):this.#D??new Headers;if(typeof Q==="object"&&"headers"in Q){let f=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);for(let[I,D]of f)if(I.toLowerCase()==="set-cookie")w.append(I,D);else w.set(I,D)}if(B)for(let[f,I]of Object.entries(B))if(typeof I==="string")w.set(f,I);else{w.delete(f);for(let D of I)w.append(f,D)}let $=typeof Q==="number"?Q:Q?.status??this.#f;return US(A,{status:$,headers:w})}newResponse=(...A)=>this.#I(...A);body=(A,Q,B)=>this.#I(A,Q,B);text=(A,Q,B)=>{return!this.#D&&!this.#f&&!Q&&!B&&!this.finalized?new Response(A):this.#I(A,Q,ZMA(GR2,B))};json=(A,Q,B)=>{return this.#I(JSON.stringify(A),Q,ZMA("application/json",B))};html=(A,Q,B)=>{let w=($)=>this.#I($,Q,ZMA("text/html; charset=UTF-8",B));return typeof A==="object"?KMA(A,vc0.Stringify,!1,{}).then(w):w(A)};redirect=(A,Q)=>{let B=String(A);return this.header("Location",!/[^\x00-\xFF]/.test(B)?B:encodeURI(B)),this.newResponse(null,Q??302)};notFound=()=>{return this.#H??=()=>US(),this.#H(this)}};var Lw="ALL",hc0="all",gc0=["get","post","put","delete","options","patch"],yAA="Can not add a route since the matcher is already built.",xAA=class extends Error{};var zMA="__COMPOSED_HANDLER";var FR2=(A)=>{return A.text("404 Not Found",404)},Tc0=(A,Q)=>{if("getResponse"in A){let B=A.getResponse();return Q.newResponse(B.body,B)}return console.error(A),Q.text("Internal Server Error",500)},Sc0=class A{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#A="/";routes=[];constructor(Q={}){[...gc0,hc0].forEach((f)=>{this[f]=(I,...D)=>{if(typeof I==="string")this.#A=I;else this.#f(f,this.#A,I);return D.forEach((Y)=>{this.#f(f,this.#A,Y)}),this}}),this.on=(f,I,...D)=>{for(let Y of[I].flat()){this.#A=Y;for(let H of[f].flat())D.map((W)=>{this.#f(H.toUpperCase(),this.#A,W)})}return this},this.use=(f,...I)=>{if(typeof f==="string")this.#A=f;else this.#A="*",I.unshift(f);return I.forEach((D)=>{this.#f(Lw,this.#A,D)}),this};let{strict:w,...$}=Q;Object.assign(this,$),this.getPath=w??!0?Q.getPath??GMA:bc0}#Q(){let Q=new A({router:this.router,getPath:this.getPath});return Q.errorHandler=this.errorHandler,Q.#B=this.#B,Q.routes=this.routes,Q}#B=FR2;errorHandler=Tc0;route(Q,B){let w=this.basePath(Q);return B.routes.map(($)=>{let f;if(B.errorHandler===Tc0)f=$.handler;else f=async(I,D)=>(await XMA([],B.errorHandler)(I,()=>$.handler(I,D))).res,f[zMA]=$.handler;w.#f($.method,$.path,f)}),this}basePath(Q){let B=this.#Q();return B._basePath=VL(this._basePath,Q),B}onError=(Q)=>{return this.errorHandler=Q,this};notFound=(Q)=>{return this.#B=Q,this};mount(Q,B,w){let $,f;if(w)if(typeof w==="function")f=w;else if(f=w.optionHandler,w.replaceRequest===!1)$=(Y)=>Y;else $=w.replaceRequest;let I=f?(Y)=>{let H=f(Y);return Array.isArray(H)?H:[H]}:(Y)=>{let H=void 0;try{H=Y.executionCtx}catch{}return[Y.env,H]};$||=(()=>{let Y=VL(this._basePath,Q),H=Y==="/"?0:Y.length;return(W)=>{let F=new URL(W.url);return F.pathname=F.pathname.slice(H)||"/",new Request(F,W)}})();let D=async(Y,H)=>{let W=await B($(Y.req.raw),...I(Y));if(W)return W;await H()};return this.#f(Lw,VL(Q,"*"),D),this}#f(Q,B,w){Q=Q.toUpperCase(),B=VL(this._basePath,B);let $={basePath:this._basePath,path:B,method:Q,handler:w};this.router.add(Q,B,[w,$]),this.routes.push($)}#$(Q,B){if(Q instanceof Error)return this.errorHandler(Q,B);throw Q}#w(Q,B,w,$){if($==="HEAD")return(async()=>new Response(null,await this.#w(Q,B,w,"GET")))();let f=this.getPath(Q,{env:w}),I=this.router.match($,f),D=new xc0(Q,{path:f,matchResult:I,env:w,executionCtx:B,notFoundHandler:this.#B});if(I[0].length===1){let H;try{H=I[0][0][0][0](D,async()=>{D.res=await this.#B(D)})}catch(W){return this.#$(W,D)}return H instanceof Promise?H.then((W)=>W||(D.finalized?D.res:this.#B(D))).catch((W)=>this.#$(W,D)):H??this.#B(D)}let Y=XMA(I[0],this.errorHandler,this.#B);return(async()=>{try{let H=await Y(D);if(!H.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return H.res}catch(H){return this.#$(H,D)}})()}fetch=(Q,...B)=>{return this.#w(Q,B[1],B[0],Q.method)};request=(Q,B,w,$)=>{if(Q instanceof Request)return this.fetch(B?new Request(Q,B):Q,w,$);return Q=Q.toString(),this.fetch(new Request(/^https?:\/\//.test(Q)?Q:`http://localhost${VL("/",Q)}`,B),w,$)};fire=()=>{addEventListener("fetch",(Q)=>{Q.respondWith(this.#w(Q.request,Q,void 0,Q.request.method))})}};var JS=[];function hAA(A,Q){let B=this.buildAllMatchers(),w=($,f)=>{let I=B[$]||B[Lw],D=I[2][f];if(D)return D;let Y=f.match(I[0]);if(!Y)return[[],JS];let H=Y.indexOf("",1);return[I[1][H],Y]};return this.match=w,w(A,Q)}var gAA="[^/]+",GS=".*",FS="(?:|/.*)",CL=Symbol(),KR2=new Set(".\\+*[^]$()");function ZR2(A,Q){if(A.length===1)return Q.length===1?A<Q?-1:1:-1;if(Q.length===1)return 1;if(A===GS||A===FS)return 1;else if(Q===GS||Q===FS)return-1;if(A===gAA)return 1;else if(Q===gAA)return-1;return A.length===Q.length?A<Q?-1:1:Q.length-A.length}var mc0=class A{#A;#Q;#B=Object.create(null);insert(Q,B,w,$,f){if(Q.length===0){if(this.#A!==void 0)throw CL;if(f)return;this.#A=B;return}let[I,...D]=Q,Y=I==="*"?D.length===0?["","",GS]:["","",gAA]:I==="/*"?["","",FS]:I.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),H;if(Y){let W=Y[1],F=Y[2]||gAA;if(W&&Y[2]){if(F===".*")throw CL;if(F=F.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(F))throw CL}if(H=this.#B[F],!H){if(Object.keys(this.#B).some((K)=>K!==GS&&K!==FS))throw CL;if(f)return;if(H=this.#B[F]=new A,W!=="")H.#Q=$.varIndex++}if(!f&&W!=="")w.push([W,H.#Q])}else if(H=this.#B[I],!H){if(Object.keys(this.#B).some((W)=>W.length>1&&W!==GS&&W!==FS))throw CL;if(f)return;H=this.#B[I]=new A}H.insert(D,B,w,$,f)}buildRegExpStr(){let B=Object.keys(this.#B).sort(ZR2).map((w)=>{let $=this.#B[w];return(typeof $.#Q==="number"?`(${w})@${$.#Q}`:KR2.has(w)?`\\${w}`:w)+$.buildRegExpStr()});if(typeof this.#A==="number")B.unshift(`#${this.#A}`);if(B.length===0)return"";if(B.length===1)return B[0];return"(?:"+B.join("|")+")"}};var uc0=class{#A={varIndex:0};#Q=new mc0;insert(A,Q,B){let w=[],$=[];for(let I=0;;){let D=!1;if(A=A.replace(/\{[^}]+\}/g,(Y)=>{let H=`@\\${I}`;return $[I]=[H,Y],I++,D=!0,H}),!D)break}let f=A.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let I=$.length-1;I>=0;I--){let[D]=$[I];for(let Y=f.length-1;Y>=0;Y--)if(f[Y].indexOf(D)!==-1){f[Y]=f[Y].replace(D,$[I][1]);break}}return this.#Q.insert(f,Q,w,this.#A,B),w}buildRegExp(){let A=this.#Q.buildRegExpStr();if(A==="")return[/^$/,[],[]];let Q=0,B=[],w=[];return A=A.replace(/#(\d+)|@(\d+)|\.\*\$/g,($,f,I)=>{if(f!==void 0)return B[++Q]=Number(f),"$()";if(I!==void 0)return w[Number(I)]=++Q,"";return""}),[new RegExp(`^${A}`),B,w]}};var zR2=[/^$/,[],Object.create(null)],cc0=Object.create(null);function pc0(A){return cc0[A]??=new RegExp(A==="*"?"":`^${A.replace(/\/\*$|([.\\+*[^\]$()])/g,(Q,B)=>B?`\\${B}`:"(?:|/.*)")}$`)}function NR2(){cc0=Object.create(null)}function qR2(A){let Q=new uc0,B=[];if(A.length===0)return zR2;let w=A.map((H)=>[!/\*|\/:/.test(H[0]),...H]).sort(([H,W],[F,K])=>H?1:F?-1:W.length-K.length),$=Object.create(null);for(let H=0,W=-1,F=w.length;H<F;H++){let[K,Z,q]=w[H];if(K)$[Z]=[q.map(([L])=>[L,Object.create(null)]),JS];else W++;let E;try{E=Q.insert(Z,W,K)}catch(L){throw L===CL?new xAA(Z):L}if(K)continue;B[W]=q.map(([L,b])=>{let _=Object.create(null);b-=1;for(;b>=0;b--){let[j,s]=E[b];_[j]=s}return[L,_]})}let[f,I,D]=Q.buildRegExp();for(let H=0,W=B.length;H<W;H++)for(let F=0,K=B[H].length;F<K;F++){let Z=B[H][F]?.[1];if(!Z)continue;let q=Object.keys(Z);for(let E=0,L=q.length;E<L;E++)Z[q[E]]=D[Z[q[E]]]}let Y=[];for(let H in I)Y[H]=B[I[H]];return[f,Y,$]}function Sb(A,Q){if(!A)return;for(let B of Object.keys(A).sort((w,$)=>$.length-w.length))if(pc0(B).test(Q))return[...A[B]];return}var TAA=class{name="RegExpRouter";#A;#Q;constructor(){this.#A={[Lw]:Object.create(null)},this.#Q={[Lw]:Object.create(null)}}add(A,Q,B){let w=this.#A,$=this.#Q;if(!w||!$)throw Error(yAA);if(!w[A])[w,$].forEach((D)=>{D[A]=Object.create(null),Object.keys(D[Lw]).forEach((Y)=>{D[A][Y]=[...D[Lw][Y]]})});if(Q==="/*")Q="*";let f=(Q.match(/\/:/g)||[]).length;if(/\*$/.test(Q)){let D=pc0(Q);if(A===Lw)Object.keys(w).forEach((Y)=>{w[Y][Q]||=Sb(w[Y],Q)||Sb(w[Lw],Q)||[]});else w[A][Q]||=Sb(w[A],Q)||Sb(w[Lw],Q)||[];Object.keys(w).forEach((Y)=>{if(A===Lw||A===Y)Object.keys(w[Y]).forEach((H)=>{D.test(H)&&w[Y][H].push([B,f])})}),Object.keys($).forEach((Y)=>{if(A===Lw||A===Y)Object.keys($[Y]).forEach((H)=>D.test(H)&&$[Y][H].push([B,f]))});return}let I=vAA(Q)||[Q];for(let D=0,Y=I.length;D<Y;D++){let H=I[D];Object.keys($).forEach((W)=>{if(A===Lw||A===W)$[W][H]||=[...Sb(w[W],H)||Sb(w[Lw],H)||[]],$[W][H].push([B,f-Y+D+1])})}}match=hAA;buildAllMatchers(){let A=Object.create(null);return Object.keys(this.#Q).concat(Object.keys(this.#A)).forEach((Q)=>{A[Q]||=this.#B(Q)}),this.#A=this.#Q=void 0,NR2(),A}#B(A){let Q=[],B=A===Lw;if([this.#A,this.#Q].forEach((w)=>{let $=w[A]?Object.keys(w[A]).map((f)=>[f,w[A][f]]):[];if($.length!==0)B||=!0,Q.push(...$);else if(A!==Lw)Q.push(...Object.keys(w[Lw]).map((f)=>[f,w[Lw][f]]))}),!B)return null;else return qR2(Q)}};var LR2=class{name="PreparedRegExpRouter";#A;#Q;constructor(A,Q){this.#A=A,this.#Q=Q}#B(A,Q){let B=this.#A[A];B[1].forEach((w)=>w&&w.push(Q)),Object.values(B[2]).forEach((w)=>w[0].push(Q))}#f(A,Q,B,w,$){let f=this.#A[A];if(!$)f[2][Q][0].push([B,{}]);else w.forEach((I)=>{if(typeof I==="number")f[1][I].push([B,$]);else f[2][I||Q][0].push([B,$])})}add(A,Q,B){if(!this.#A[A]){let $=this.#A[Lw],f={};for(let I in $[2])f[I]=[$[2][I][0].slice(),JS];this.#A[A]=[$[0],$[1].map((I)=>Array.isArray(I)?I.slice():0),f]}if(Q==="/*"||Q==="*"){let $=[B,{}];if(A===Lw)for(let f in this.#A)this.#B(f,$);else this.#B(A,$);return}let w=this.#Q[Q];if(!w)throw Error(`Path ${Q} is not registered`);for(let[$,f]of w)if(A===Lw)for(let I in this.#A)this.#f(I,Q,B,$,f);else this.#f(A,Q,B,$,f)}buildAllMatchers(){return this.#A}match=hAA};var NMA=class{name="SmartRouter";#A=[];#Q=[];constructor(A){this.#A=A.routers}add(A,Q,B){if(!this.#Q)throw Error(yAA);this.#Q.push([A,Q,B])}match(A,Q){if(!this.#Q)throw Error("Fatal error");let B=this.#A,w=this.#Q,$=B.length,f=0,I;for(;f<$;f++){let D=B[f];try{for(let Y=0,H=w.length;Y<H;Y++)D.add(...w[Y]);I=D.match(A,Q)}catch(Y){if(Y instanceof xAA)continue;throw Y}this.match=D.match.bind(D),this.#A=[D],this.#Q=void 0;break}if(f===$)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,I}get activeRouter(){if(this.#Q||this.#A.length!==1)throw Error("No active router has been determined yet.");return this.#A[0]}};var KS=Object.create(null),ER2=(A)=>{for(let Q in A)return!0;return!1},lc0=class A{#A;#Q;#B;#f=0;#$=KS;constructor(Q,B,w){if(this.#Q=w||Object.create(null),this.#A=[],Q&&B){let $=Object.create(null);$[Q]={handler:B,possibleKeys:[],score:0},this.#A=[$]}this.#B=[]}insert(Q,B,w){this.#f=++this.#f;let $=this,f=Oc0(B),I=[];for(let D=0,Y=f.length;D<Y;D++){let H=f[D],W=f[D+1],F=Rc0(H,W),K=Array.isArray(F)?F[0]:H;if(K in $.#Q){if($=$.#Q[K],F)I.push(F[1]);continue}if($.#Q[K]=new A,F)$.#B.push(F),I.push(F[1]);$=$.#Q[K]}return $.#A.push({[Q]:{handler:w,possibleKeys:I.filter((D,Y,H)=>H.indexOf(D)===Y),score:this.#f}}),$}#w(Q,B,w,$,f){for(let I=0,D=B.#A.length;I<D;I++){let Y=B.#A[I],H=Y[w]||Y[Lw],W={};if(H!==void 0){if(H.params=Object.create(null),Q.push(H),$!==KS||f&&f!==KS)for(let F=0,K=H.possibleKeys.length;F<K;F++){let Z=H.possibleKeys[F],q=W[H.score];H.params[Z]=f?.[Z]&&!q?f[Z]:$[Z]??f?.[Z],W[H.score]=!0}}}}search(Q,B){let w=[];this.#$=KS;let f=[this],I=UMA(B),D=[],Y=I.length,H=null;for(let W=0;W<Y;W++){let F=I[W],K=W===Y-1,Z=[];for(let E=0,L=f.length;E<L;E++){let b=f[E],_=b.#Q[F];if(_)if(_.#$=b.#$,K){if(_.#Q["*"])this.#w(w,_.#Q["*"],Q,b.#$);this.#w(w,_,Q,b.#$)}else Z.push(_);for(let j=0,s=b.#B.length;j<s;j++){let n=b.#B[j],T=b.#$===KS?{}:{...b.#$};if(n==="*"){let m=b.#Q["*"];if(m)this.#w(w,m,Q,b.#$),m.#$=T,Z.push(m);continue}let[y,h,g]=n;if(!F&&!(g instanceof RegExp))continue;let AA=b.#Q[y];if(g instanceof RegExp){if(H===null){H=Array(Y);let BA=B[0]==="/"?1:0;for(let P=0;P<Y;P++)H[P]=BA,BA+=I[P].length+1}let m=B.substring(H[W]),HA=g.exec(m);if(HA){if(T[h]=HA[0],this.#w(w,AA,Q,b.#$,T),ER2(AA.#Q)){AA.#$=T;let BA=HA[0].match(/\//)?.length??0;(D[BA]||=[]).push(AA)}continue}}if(g===!0||g.test(F))if(T[h]=F,K){if(this.#w(w,AA,Q,T,b.#$),AA.#Q["*"])this.#w(w,AA.#Q["*"],Q,T,b.#$)}else AA.#$=T,Z.push(AA)}}let q=D.shift();f=q?Z.concat(q):Z}if(w.length>1)w.sort((W,F)=>{return W.score-F.score});return[w.map(({handler:W,params:F})=>[W,F])]}};var qMA=class{name="TrieRouter";#A;constructor(){this.#A=new lc0}add(A,Q,B){let w=vAA(Q);if(w){for(let $=0,f=w.length;$<f;$++)this.#A.insert(A,w[$],B);return}this.#A.insert(A,Q,B)}match(A,Q){return this.#A.search(A,Q)}};var mb=class extends Sc0{constructor(A={}){super(A);this.router=A.router??new NMA({routers:[new TAA,new qMA]})}};import{stat as RR2}from"fs/promises";import{join as bR2}from"path";var ub=/^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;var LMA=(A,Q=VR2)=>{let B=/\.([a-zA-Z0-9]+?)$/,w=A.match(B);if(!w)return;let $=Q[w[1]];if($&&$.startsWith("text"))$+="; charset=utf-8";return $};var MR2={aac:"audio/aac",avi:"video/x-msvideo",avif:"image/avif",av1:"video/av1",bin:"application/octet-stream",bmp:"image/bmp",css:"text/css",csv:"text/csv",eot:"application/vnd.ms-fontobject",epub:"application/epub+zip",gif:"image/gif",gz:"application/gzip",htm:"text/html",html:"text/html",ico:"image/x-icon",ics:"text/calendar",jpeg:"image/jpeg",jpg:"image/jpeg",js:"text/javascript",json:"application/json",jsonld:"application/ld+json",map:"application/json",mid:"audio/x-midi",midi:"audio/x-midi",mjs:"text/javascript",mp3:"audio/mpeg",mp4:"video/mp4",mpeg:"video/mpeg",oga:"audio/ogg",ogv:"video/ogg",ogx:"application/ogg",opus:"audio/opus",otf:"font/otf",pdf:"application/pdf",png:"image/png",rtf:"application/rtf",svg:"image/svg+xml",tif:"image/tiff",tiff:"image/tiff",ts:"video/mp2t",ttf:"font/ttf",txt:"text/plain",wasm:"application/wasm",webm:"video/webm",weba:"audio/webm",webmanifest:"application/manifest+json",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",xhtml:"application/xhtml+xml",xml:"application/xml",zip:"application/zip","3gp":"video/3gpp","3g2":"video/3gpp2",gltf:"model/gltf+json",glb:"model/gltf-binary"},VR2=MR2;var ic0=(...A)=>{let Q=A.filter(($)=>$!=="").join("/");Q=Q.replace(/(?<=\/)\/+/g,"");let B=Q.split("/"),w=[];for(let $ of B)if($===".."&&w.length>0&&w.at(-1)!=="..")w.pop();else if($!==".")w.push($);return w.join("/")||"."};var rc0={br:".br",zstd:".zst",gzip:".gz"},CR2=Object.keys(rc0),OR2="index.html",dc0=(A)=>{let Q=A.root??"./",B=A.path,w=A.join??ic0;return async($,f)=>{if($.finalized)return f();let I;if(A.path)I=A.path;else try{if(I=JMA($.req.path),/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(I))throw Error()}catch{return await A.onNotFound?.($.req.path,$),f()}let D=w(Q,!B&&A.rewriteRequestPath?A.rewriteRequestPath(I):I);if(A.isDir&&await A.isDir(D))D=w(D,OR2);let Y=A.getContent,H=await Y(D,$);if(H instanceof Response)return $.newResponse(H.body,H);if(H){let W=A.mimes&&LMA(D,A.mimes)||LMA(D);if($.header("Content-Type",W||"application/octet-stream"),A.precompressed&&(!W||ub.test(W))){let F=new Set($.req.header("Accept-Encoding")?.split(",").map((K)=>K.trim()));for(let K of CR2){if(!F.has(K))continue;let Z=await Y(D+rc0[K],$);if(Z){H=Z,$.header("Content-Encoding",K),$.header("Vary","Accept-Encoding",{append:!0});break}}}return await A.onFound?.(D,$),$.body(H)}await A.onNotFound?.(D,$),await f();return}};var EMA=(A)=>{return async function(B,w){return dc0({...A,getContent:async(I)=>{let D=Bun.file(I);return await D.exists()?D:null},join:bR2,isDir:async(I)=>{let D;try{D=(await RR2(I)).isDirectory()}catch{}return D}})(B,w)}};var MMA="x-hono-disable-ssg",VdB=(()=>{try{return new Response("SSG is disabled",{status:404,headers:{[MMA]:"true"}})}catch{return null}})();var{write:fnB}=Bun;var jR2=class{#A;constructor(A){this.#A=A,this.raw=A.raw,this.url=A.url?new URL(A.url):null,this.protocol=A.protocol??null}send(A,Q){this.#A.send(A,Q??{})}raw;binaryType="arraybuffer";get readyState(){return this.#A.readyState}url;protocol;close(A,Q){this.#A.close(A,Q)}};var nc0=(A)=>{return(...Q)=>{if(typeof Q[0]==="function"){let[B,w]=Q;return async function(f,I){let D=await B(f),Y=await A(f,D,w);if(Y)return Y;await I()}}else{let[B,w,$]=Q;return(async()=>{let f=await A(B,w,$);if(!f)throw Error("Failed to upgrade WebSocket");return f})()}}};var SAA=(A)=>("server"in A.env)?A.env.server:A.env;var _R2=nc0((A,Q)=>{let B=SAA(A);if(!B)throw TypeError("env has to include the 2nd argument of fetch.");if(B.upgrade(A.req.raw,{data:{events:Q,url:new URL(A.req.url),protocol:A.req.url}}))return new Response(null);return});var vR2=["gzip","deflate"],yR2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,oc0=(A)=>{let Q=A?.threshold??1024;return async function(w,$){await $();let f=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||f&&Number(f)<Q||!xR2(w.res)||!hR2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??vR2.find((H)=>I?.includes(H));if(!D||!w.res.body)return;let Y=new CompressionStream(D);w.res=new Response(w.res.body.pipeThrough(Y),w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}},xR2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&ub.test(Q)},hR2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!yR2.test(Q)};import{Readable as sc0}from"stream";import{createDeflate as gR2,createGzip as TR2}from"zlib";var SR2=["gzip","deflate"],mR2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,ac0=(A)=>{if(typeof CompressionStream<"u")return oc0(A);let Q=A?.threshold??1024;return async function(w,$){await $();let f=w.res.headers.get("Content-Length");if(w.res.headers.has("Content-Encoding")||w.res.headers.has("Transfer-Encoding")||w.req.method==="HEAD"||f&&Number(f)<Q||!uR2(w.res)||!cR2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??SR2.find((Y)=>I?.includes(Y));if(!D||!w.res.body)return;try{let Y=D==="gzip"?TR2():gR2(),H=w.res.body,F=sc0.fromWeb(H).pipe(Y),K=sc0.toWeb(F);w.res=new Response(K,w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}catch(Y){console.error("Compression error:",Y)}}},uR2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&ub.test(Q)},cR2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!mR2.test(Q)};var pR2=(A,Q)=>{if(!A)return Q;let B=new Uint8Array(new ArrayBuffer(A.byteLength+Q.byteLength));return B.set(new Uint8Array(A),0),B.set(Q,A.byteLength),B},tc0=async(A,Q)=>{if(!A)return null;let B=void 0,w=A.getReader();for(;;){let{value:$,done:f}=await w.read();if(f)break;B=await Q(pR2(B,$))}if(!B)return null;return Array.prototype.map.call(new Uint8Array(B),($)=>$.toString(16).padStart(2,"0")).join("")};var lR2=["cache-control","content-location","date","etag","expires","vary"],ec0=(A)=>A.replace(/^W\//,"");function iR2(A,Q){return Q!=null&&Q.split(/,\s*/).some((B)=>ec0(B)===ec0(A))}function rR2(A){if(!A){if(crypto&&crypto.subtle)A=(Q)=>crypto.subtle.digest({name:"SHA-1"},Q)}return A}var Ap0=(A)=>{let Q=A?.retainedHeaders??lR2,B=A?.weak??!1,w=rR2(A?.generateDigest);return async function(f,I){let D=f.req.header("If-None-Match")??null;await I();let Y=f.res,H=Y.headers.get("ETag");if(!H){if(!w)return;let W=await tc0(Y.clone().body,w);if(W===null)return;H=B?`W/"${W}"`:`"${W}"`}if(iR2(H,D))f.res=new Response(null,{status:304,statusText:"Not Modified",headers:{ETag:H}}),f.res.headers.forEach((W,F)=>{if(Q.indexOf(F.toLowerCase())===-1)f.res.headers.delete(F)});else f.res.headers.set("ETag",H)}};B0();function mAA(A,Q){return async(B)=>{let w=B.req.raw,$=w.headers.get("content-type")??"",f=w.headers.get("accept")?.includes("application/json"),I={};if($.includes("application/json"))I=await w.json();else if($.includes("form")){let Z=await w.formData();for(let[q,E]of Z.entries())I[q]=E}let D=`${A.pluginId}_${A.definition.tool}`,Y=await Q.send({type:`plugin:${A.pluginId}:tool:execute`,payload:{toolName:D,args:I,interfaceType:"webserver",userId:"anonymous"},sender:"webserver"}),H=typeof Y==="object"&&"data"in Y?Y.data:Y,W=__.safeParse(H),F=W.success?W.data:H,K=W.success&&W.data.success===!0;if(f)return B.json(F,K?200:400);if(K&&A.definition.successRedirect)return B.redirect(A.definition.successRedirect);if(!K&&A.definition.errorRedirect)return B.redirect(A.definition.errorRedirect);return B.json(F,K?200:400)}}var Qp0="public, max-age=31536000, immutable";class uAA{logger;options;productionServer=null;isPreviewHost(A){if(!A)return!1;let Q=A.replace(/:\d+$/,"").toLowerCase();return/^(?:preview\..+|.+-preview\..+)$/.test(Q)}constructor(A){this.logger=A.logger,this.options={...A,productionDistDir:cb(process.cwd(),A.productionDistDir),sharedImagesDir:cb(process.cwd(),A.sharedImagesDir),...A.previewDistDir&&{previewDistDir:cb(process.cwd(),A.previewDistDir)}}}async start(){if(this.productionServer){this.logger.warn("Webserver already running");return}let A=this.createApp({distDir:this.options.productionDistDir,compress:!0,defaultCache:"public, max-age=3600",immutableExtensions:/\.(js|css|jpg|jpeg|png|gif|ico|woff|woff2)$/,healthEndpoint:!0}),Q=this.options.previewDistDir?this.createApp({distDir:this.options.previewDistDir,compress:!1,defaultCache:"no-cache",immutableExtensions:/\.(jpg|jpeg|png|gif|ico|webp|svg|woff|woff2)$/,healthEndpoint:!1}):void 0;try{this.productionServer=Bun.serve({port:this.options.productionPort,fetch:async(B)=>{let w=await this.serveImageFastPath(B);if(w)return w;if(Q&&this.isPreviewHost(B.headers.get("host")))return Q.fetch(B);return A.fetch(B)}})}catch(B){let w=String(B);if(w.includes("EADDRINUSE")||w.includes("address already in use"))throw Error(`Port ${this.options.productionPort} is already in use. Another brain may be running \u2014 stop it first or configure a different port.`);throw B}this.logger.info(`Production server listening on http://localhost:${this.productionServer.port}`)}async stop(){if(this.productionServer)await this.productionServer.stop(),this.productionServer=null;this.logger.debug("Webserver stopped")}getStatus(){return{running:this.productionServer!==null,productionUrl:this.productionServer?`http://localhost:${this.productionServer.port}`:void 0,previewUrl:this.productionServer&&this.options.previewDistDir?`http://localhost:${this.productionServer.port}`:void 0}}createApp(A){let Q=new mb;if(A.healthEndpoint)Q.get("/health",async(B)=>{if(this.options.getHealthData){let w=await this.options.getHealthData();return B.json({status:"healthy",...w},200)}return B.json({status:"healthy"},200)});if(Q.use("/*",async(B,w)=>{let $=await this.handleDynamicRoute(B,A);if($)return $;return w()}),A.compress)Q.use("/*",ac0());return Q.use("/*",Ap0()),Q.use("/*",async(B,w)=>{if(await w(),A.immutableExtensions.test(B.req.path))B.header("Cache-Control",Qp0);else B.header("Cache-Control",A.defaultCache)}),Q.use("/*",this.createCleanUrlMiddleware(A.distDir)),Q.use("/*",EMA({root:A.distDir})),Q.notFound(async(B)=>{let w=Bun.file(dR2(A.distDir,"404.html"));if(await w.exists())return B.html(await w.text(),404);return B.text("Not Found",404)}),Q}getCurrentWebRoutes(){return this.options.getWebRoutes?.()??this.options.webRoutes??[]}getCurrentApiRoutes(){return this.options.getApiRoutes?.()??this.options.apiRoutes??[]}async handleDynamicRoute(A,Q){if(!Q.healthEndpoint)return null;let B=A.req.method.toUpperCase(),w=A.req.path,$=this.getCurrentWebRoutes().find((I)=>{let D=I.definition.method??"GET";return I.fullPath===w&&D===B});if($)return $.definition.handler(A.req.raw);let f=this.getCurrentApiRoutes().find((I)=>{let D=I.definition.method;return I.fullPath===w&&D===B});if(f&&this.options.messageBus)return mAA(f,this.options.messageBus)(A);return null}async serveImageFastPath(A){let Q;try{Q=new URL(A.url)}catch{return null}if(!Q.pathname.startsWith("/images/"))return null;let B=Q.pathname.slice(8),w=cb(this.options.sharedImagesDir,B);if(!w.startsWith(this.options.sharedImagesDir))return null;let $=Bun.file(w);if(!await $.exists())return null;return new Response($,{headers:{"Cache-Control":Qp0}})}createCleanUrlMiddleware(A){return async(Q,B)=>{let w=Q.req.path;if(w.includes(".")||w==="/"){await B();return}let $=cb(A,`.${w}`,"index.html");if(!$.startsWith(A)){await B();return}let f=Bun.file($);if(await f.exists())return Q.html(await f.text());let I=cb(A,`.${w}.html`);if(I.startsWith(A)){let D=Bun.file(I);if(await D.exists())return Q.html(await D.text())}await B()}}}import{existsSync as wp0}from"fs";import{join as $p0}from"path";GA();var VMA=J.object({enablePreview:J.boolean().default(!0).describe("Enable the preview site server when preview assets are configured"),previewDistDir:J.string().default("./dist/site-preview").describe("Directory for preview site files"),productionDistDir:J.string().describe("Directory for production site files").default("./dist/site-production"),sharedImagesDir:J.string().default("./dist/images").describe("Shared directory for optimized images"),previewPort:J.number().default(4321).describe("Port for preview server"),productionPort:J.number().describe("Port for production server").default(8080),apiPort:J.number().describe("Port for API route server (plugin HTTP endpoints)").default(3335)});var CMA=`<!DOCTYPE html>
|
|
2307
2307
|
<html lang="en">
|
|
@@ -2370,7 +2370,7 @@ ${b}`)}if(w!==void 0&&f?.algorithms!==void 0){let L=f.algorithms.map((b)=>b.alg)
|
|
|
2370
2370
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2371
2371
|
</div>
|
|
2372
2372
|
</body>
|
|
2373
|
-
</html>`;var Bp0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2373
|
+
</html>`;var Bp0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.81",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 oZ extends LX{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Bp0,A,VMA)}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 uAA({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&&!wp0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q($p0(this.config.previewDistDir,"index.html"),CMA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!wp0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q($p0(this.config.productionDistDir,"index.html"),CMA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}B0();GA();var fp0=J.object({port:J.number().default(3334),organization:J.string().optional(),trustedTokens:J.record(J.string()).optional(),outboundTokens:J.record(J.string()).optional(),requestTimeoutMs:J.number().positive().default(30000),streamIdleTimeoutMs:J.number().positive().default(60000),maxNetworkAttempts:J.number().int().positive().default(2)});B0();function oR2(A,Q){return`${A.name} is ${Q.name}'s ${A.role}. Its purpose is: ${A.purpose}.`}function Ip0(A){let{character:Q,profile:B,version:w,domain:$,organization:f,tools:I}=A,Y=`${A.baseUrl??($?`https://${$}`:"http://localhost:8080")}/a2a`,H=A.skills&&A.skills.length>0?A.skills.map((K)=>({id:K.name.toLowerCase().replace(/\s+/g,"-"),name:K.name,description:K.description,tags:K.tags,examples:K.examples})):I.map((K)=>({id:K.name,name:K.name,description:K.description,tags:[],examples:[]})),W={name:B.name};if(A.kind)W.kind=A.kind;if(B.description)W.description=B.description;if(f)W.organization=f;let F=[{uri:ei,description:"Anchor (operator) identity for this brain",params:W}];return{name:Q.name,description:oR2(Q,B),url:Y,version:w,protocolVersion:"0.2.2",capabilities:{streaming:!0,pushNotifications:!1,extensions:F},skills:H,defaultInputModes:["text/plain"],defaultOutputModes:["text/plain"],...f&&{provider:{organization:f,url:Y}},...A.authEnabled&&{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer"}},security:[{bearerAuth:[]}]}}}B0();var OMA=new Set(["completed","failed","canceled","rejected"]);class RMA{tasks=new Map;ttlMs;processingTimeoutMs;constructor(A=3600000,Q=300000){this.ttlMs=A,this.processingTimeoutMs=Q}evictExpired(){let A=Date.now();for(let[Q,B]of this.tasks)if(OMA.has(B.task.status.state)&&A-new Date(B.updatedAt).getTime()>=this.ttlMs)this.tasks.delete(Q)}createTask(A,Q){this.evictExpired();let B=crypto.randomUUID(),w=Q??crypto.randomUUID(),$=new Date().toISOString(),f={kind:"message",messageId:crypto.randomUUID(),role:"user",parts:[{kind:"text",text:A}],contextId:w,taskId:B},D={task:{id:B,contextId:w,kind:"task",status:{state:"submitted",timestamp:$},history:[f]},conversationId:`a2a:${B}`,createdAt:$,updatedAt:$};return this.tasks.set(B,D),D}getTask(A){return this.tasks.get(A)}updateState(A,Q,B){let w=this.tasks.get(A);if(!w)return;let $=new Date().toISOString();if(w.task.status={state:Q,timestamp:$},w.updatedAt=$,Q==="working")w.workingStartedAt=$;if(B){let f={kind:"message",messageId:crypto.randomUUID(),role:"agent",parts:[{kind:"text",text:B}],contextId:w.task.contextId,taskId:A};w.task.status.message=f,w.task.history??=[],w.task.history.push(f)}return w}addArtifact(A,Q,B){let w=this.tasks.get(A);if(!w)return;return w.task.artifacts??=[],w.task.artifacts.push({artifactId:crypto.randomUUID(),name:Q,parts:B}),w.updatedAt=new Date().toISOString(),w}getTaskWithHistory(A,Q){let B=this.tasks.get(A);if(!B)return;if(B.task.status.state==="working"&&B.workingStartedAt&&Date.now()-new Date(B.workingStartedAt).getTime()>=this.processingTimeoutMs)this.updateState(A,"failed","Processing timed out");if(Q===void 0||!B.task.history)return B.task;return{...B.task,history:B.task.history.slice(-Q)}}deleteTask(A){return this.tasks.delete(A)}get size(){return this.tasks.size}}GA();var Dp0=J.array(J.object({kind:J.string(),text:J.string().optional(),data:J.record(J.unknown()).optional()})),sR2=J.object({message:J.object({kind:J.literal("message").optional(),messageId:J.string().optional(),role:J.enum(["user","agent"]).optional(),parts:Dp0,contextId:J.string().optional(),taskId:J.string().optional()}),configuration:J.object({historyLength:J.number().optional()}).optional()}),Yp0=J.object({id:J.string(),historyLength:J.number().optional()});function bMA(A,Q){return{jsonrpc:"2.0",id:A,result:Q}}function qW(A,Q,B){return{jsonrpc:"2.0",id:A,error:{code:Q,message:B}}}var Hp0=J.object({jsonrpc:J.string(),id:J.union([J.string(),J.number()]),method:J.string(),params:J.record(J.unknown()).optional()});async function Xp0(A,Q){let{id:B,method:w,params:$}=A;switch(w){case"message/send":return aR2(B,$??{},Q);case"tasks/get":return eR2(B,$??{},Q);case"tasks/cancel":return Ab2(B,$??{},Q);default:return qW(B,-32601,`Method not found: ${w}`)}}async function aR2(A,Q,B){let w=sR2.safeParse(Q);if(!w.success)return qW(A,-32602,`Invalid params: ${w.error.message}`);let $=w.data.message.parts.filter((W)=>W.kind==="text"&&typeof W.text==="string");if($.length===0)return qW(A,-32602,"Message must contain at least one text part");let f=$.map((W)=>W.text).join(`
|
|
2374
2374
|
`),I=w.data.message.contextId,D=B.taskManager.createTask(f,I),Y=D.task.id;B.taskManager.updateState(Y,"working"),tR2(Y,f,D.conversationId,B);let H=B.taskManager.getTask(Y);if(!H)return qW(A,-32603,"Internal error: task disappeared");return bMA(A,H.task)}function tR2(A,Q,B,w){w.agentService.chat(Q,B,{userPermissionLevel:w.callerPermissionLevel,interfaceType:"a2a"}).then(($)=>{w.taskManager.updateState(A,"completed",$.text)}).catch(($)=>{let f=$ instanceof Error?$.message:"Unknown error";w.taskManager.updateState(A,"failed",`Error: ${f}`)})}var Wp0=J.object({message:J.object({kind:J.string(),parts:Dp0,contextId:J.string().optional()})});function Up0(A,Q,B){let $=Q.parts.filter((H)=>H.kind==="text"&&typeof H.text==="string").map((H)=>H.text).join(`
|
|
2375
2375
|
`)||"No message text",f=B.taskManager.createTask($,Q.contextId),I=f.task.id;B.taskManager.updateState(I,"working");let D=new TextEncoder,Y=new ReadableStream({start(H){let W=!1;function F(E){if(W)return;try{H.enqueue(D.encode(`data: ${JSON.stringify(E)}
|
|
2376
2376
|
|
|
@@ -2378,7 +2378,7 @@ ${b}`)}if(w!==void 0&&f?.algorithms!==void 0){let L=f.algorithms.map((b)=>b.alg)
|
|
|
2378
2378
|
|
|
2379
2379
|
`);$=I.pop()??"";for(let D of I){let Y=D.split(`
|
|
2380
2380
|
`).find((L)=>L.startsWith("data: "));if(!Y)continue;let H;try{H=JSON.parse(Y.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let W=H.result;if(!W)continue;if(W.final!==!0)continue;B.cancel().catch(()=>{});let K=W.status,Z=K?.state??"unknown",E=(K?.message?.parts??[]).filter((L)=>L.kind==="text"&&typeof L.text==="string").map((L)=>L.text).join(`
|
|
2381
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:E}}}f=await Gp0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class ZS extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class zS extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function Yb2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new ZS(w))},w)})])}catch(I){if(I instanceof ZS)throw I;if($.signal.aborted)throw new ZS(w);throw I}finally{if(f)clearTimeout(f)}}async function Gp0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new zS(Q)),Q)})])}catch(w){if(w instanceof zS)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function Hb2(A){if(A instanceof ZS||A instanceof zS)return!0;return A instanceof Error}function Xb2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof zS)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Kp0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??Qb2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Bb2,maxNetworkAttempts:A.maxNetworkAttempts??wb2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. 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:Jp0,visibility:"anchor",handler:async(w)=>{let $=J.object(Jp0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=$b2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let H=`https://${D}`,W=await fb2(H,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${H}`};let F=W.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return Ib2(F,I,Q,K,B)}}}var PMA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.80",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 Ub2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class pb extends LX{agentCard;taskManager=new RMA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",PMA,A,fp0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)f=I.map((D)=>VI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=Ip0({character:Q,profile:B,version:PMA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Ub2))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 mb;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=Hp0.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=Wp0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=Up0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await Xp0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[Kp0({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, or contact a saved approved agent, 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, or searching general content locally.\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")}}}}B0();class kMA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),Y=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var yi0=Y1(ji0(),1);import{extname as Xv2}from"path";var D0A=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function PL(A){let Q=Xv2(A).toLowerCase();return D0A.includes(Q)}function _i0(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 PVA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Wv2,relative as Uv2,sep as vi0,join as Jv2}from"path";function qD(A,Q){return Wv2(Q)?Q:Jv2(A,Q)}function sb(A,Q){let B=qD(A,Q),w=Uv2(A,B);return vi0==="/"?w:w.split(vi0).join("/")}function Gv2(A,Q){if(!sb(Q,A).startsWith("image/"))return!1;return PL(A)}function Fv2(A,Q){if(sb(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return Gv2(A,Q)}class kVA{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=yi0.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(!Fv2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=sb(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=qD(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 xi0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Kv2(Q)}function hi0(A){if(A)A.stop();return}function gi0(A,Q){if(A)A.setCallback(Q)}async function Kv2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,Y=new kMA(Q,$,f,I,D),H=new kVA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,F)=>{await Y.handleFileChange(W,F)}});return await H.start(),H}async function Ti0(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:$}}B0();class jVA{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??P5(),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 _VA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new jVA({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 vVA{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 Ev2,dirname as Mv2,extname as Vv2}from"path";import{extname as Zv2}from"path";var Y0A=[".pdf"],Si0=".meta.json";function kL(A){let Q=Zv2(A).toLowerCase();return Y0A.includes(Q)}function mi0(A){return A.toLowerCase().endsWith(Si0)}function yVA(A){return`${A}${Si0}`}function ui0(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as zv2,join as H0A}from"path";function X0A(A,Q){let w=sb(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=ci0(D);I=f.join(":")}else I=ci0(f[0]??"");return{entityType:$,id:I}}function pi0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),f=B==="base";if($.length===1)return f?H0A(A,`${$[0]}${w}`):H0A(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],Y=I.slice(0,-1);if(f)return H0A(A,...Y,`${D}${w}`);return H0A(A,B,...Y,`${D}${w}`)}function li0(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return PVA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?PVA(B[1]):".md"}function ci0(A){let Q=zv2(A).toLowerCase();return Q===".md"||D0A.includes(Q)||Y0A.includes(Q)?A.slice(0,-Q.length):A}c4();import{mkdir as Cv2,readFile as ab,writeFile as hVA,stat as Ov2,utimes as Rv2}from"fs/promises";import{join as W0A}from"path";import{mkdir as ii0,readdir as qv2,stat as Lv2}from"fs/promises";import{access as Nv2}from"fs/promises";async function _6(A){try{return await Nv2(A),!0}catch{return!1}}async function xVA(A,Q){return oi0(A,Q,{includeDocuments:!1,includeImages:!1})}async function ri0(A,Q){return oi0(A,Q,{includeDocuments:!0,includeImages:!0})}async function di0(A,Q){if(!await _6(A))await ii0(A,{recursive:!0});for(let B of Q)if(B!=="base")await ii0(W0A(A,B),{recursive:!0})}async function ni0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await _6(A))return{files:B,stats:w};let $=await xVA(A,Q);for(let f of $)try{let I=W0A(A,f),D=await Lv2(I),{entityType:Y}=X0A(A,f);B.push({path:f,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function oi0(A,Q,B){let w=[];if(!await _6(A))return w;let $=async(f,I="",D=!1,Y=!1)=>{let H=await qv2(f,{withFileTypes:!0});for(let W of H){let F=I?W0A(I,W.name):W.name;if(W.isFile()&&!W.name.endsWith(".invalid")&&!mi0(W.name)){if(W.name.endsWith(".md"))w.push(F);else if(B.includeImages&&D&&PL(W.name))w.push(F);else if(B.includeDocuments&&Y&&kL(W.name))w.push(F)}else if(W.isDirectory()&&!W.name.startsWith(".")){if(I===""&&!Q.hasEntityType(W.name))continue;let K=W0A(f,W.name),Z=W.name==="image"&&I==="",q=W.name==="document"&&I==="";await $(K,F,D||Z,Y||q)}}};return await $(A),w}function bv2(A){return typeof A==="object"&&A!==null}class gVA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return X0A(this.syncPath,A)}async readEntity(A){let Q=qD(this.syncPath,A),B=await Ov2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,Y;if(PL(A)||kL(A)){let F=(await ab(Q)).toString("base64"),K=Vv2(A);if(D=`data:${kL(A)?ui0(K):_i0(K)};base64,${F}`,kL(A))Y=await this.readDocumentSidecar(Q,A)}else D=await ab(Q,"utf-8");let H={entityType:w,id:$,content:D,created:f,updated:I};if(Y)H.metadata=Y;return H}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:Ev2(Q)},w=yVA(A);if(!await _6(w))return B;try{let $=await ab(w,"utf-8"),f=JSON.parse($),I=bv2(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),Y=!1;if(await _6(Q)){let H=await ab(Q),W=RB(H.toString("base64")),F=RB(D.toString("base64"));if(W===F)Y=!0}if(!Y)await this.ensureEntityDirectory(A,Q),await hVA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(Y)return}else{let f=this.entityService.serializeEntity(A);if(await _6(Q)){let I=await ab(Q,"utf-8"),D=RB(I),Y=RB(f);if(D===Y)return}await this.ensureEntityDirectory(A,Q),await hVA(Q,f,"utf-8")}let $=new Date(A.updated);await Rv2(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await Cv2(Mv2(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=yVA(Q),f=`${JSON.stringify(w,null,2)}
|
|
2381
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:E}}}f=await Gp0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class ZS extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class zS extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function Yb2(A,Q,B,w){let $=new AbortController,f;try{return await Promise.race([A(Q,{...B,signal:$.signal}),new Promise((I,D)=>{f=setTimeout(()=>{$.abort(),D(new ZS(w))},w)})])}catch(I){if(I instanceof ZS)throw I;if($.signal.aborted)throw new ZS(w);throw I}finally{if(f)clearTimeout(f)}}async function Gp0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new zS(Q)),Q)})])}catch(w){if(w instanceof zS)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function Hb2(A){if(A instanceof ZS||A instanceof zS)return!0;return A instanceof Error}function Xb2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof zS)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function Kp0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??Qb2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??Bb2,maxNetworkAttempts:A.maxNetworkAttempts??wb2};return{name:"a2a_call",description:"Call a saved remote A2A agent by its local directory id. 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:Jp0,visibility:"anchor",handler:async(w)=>{let $=J.object(Jp0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=$b2(f);if(!D)return{success:!1,error:"Invalid agent id. Use a saved agent id from your directory, not a URL."};if(!A.entityService)return{success:!1,error:"Agent directory is unavailable. Add the agent first, then try again."};let Y=await A.entityService.getEntity({entityType:"agent",id:D});if(!Y)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(Y.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let H=`https://${D}`,W=await fb2(H,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${H}`};let F=W.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return Ib2(F,I,Q,K,B)}}}var PMA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.81",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 Ub2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class pb extends LX{agentCard;taskManager=new RMA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",PMA,A,fp0)}async onRegister(A){if(await super.onRegister(A),this.hasWebserver=A.plugins.has("webserver"),this.agentService=A.agent,this.permissionContext=A.permissions,this.hasWebserver)A.endpoints.register({label:"A2A",url:"/a2a",priority:25}),A.interactions.register({id:"a2a",label:"A2A",description:"Let other agents discover and talk to this brain.",href:"/a2a",kind:"agent",priority:25}),this.logger.info("A2A interface registered",{domain:A.domain});else this.logger.info("A2A interface registered in tool-only mode",{domain:A.domain})}async onReady(A){await this.rebuildAgentCard(A)}async rebuildAgentCard(A){let Q=A.identity.get(),B=A.identity.getProfile(),w=A.tools.listForPermissionLevel("public"),$=this.config.trustedTokens&&Object.keys(this.config.trustedTokens).length>0,f;if(A.entityService.hasEntityType("skill"))try{let I=await A.entityService.listEntities({entityType:"skill"});if(I.length>0)f=I.map((D)=>VI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=Ip0({character:Q,profile:B,version:PMA.version,domain:A.domain,organization:this.config.organization,tools:w,skills:f,authEnabled:$}),this.logger.debug("Agent Card rebuilt",{skills:this.agentCard.skills.length})}getAgentCard(){return this.agentCard}resolveCallerPermission(A){if(!A?.startsWith("Bearer ")||!this.config.trustedTokens)return"public";let Q=A.slice(7),B=this.config.trustedTokens[Q];if(!B||!this.permissionContext)return"public";return this.permissionContext.getUserLevel("a2a",B)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Ub2))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 mb;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=Hp0.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=Wp0.safeParse(w.data.params??{});if(!I.success)return this.withCors(Q.json({jsonrpc:"2.0",error:{code:-32602,message:`Invalid params: ${I.error.message}`},id:w.data.id}));let{stream:D}=Up0(w.data.id,I.data.message,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(new Response(D,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}}))}let f=await Xp0(w.data,{taskManager:this.taskManager,agentService:this.agentService,callerPermissionLevel:$});return this.withCors(Q.json(f))}),this.app=A,A}getWebRoutes(){if(!this.hasWebserver)return[];let A=(Q)=>Promise.resolve(this.getOrCreateApp().fetch(Q));return[{path:"/.well-known/agent-card.json",method:"GET",public:!0,handler:A},{path:"/a2a",method:"GET",public:!0,handler:A},{path:"/a2a",method:"POST",public:!0,handler:A},{path:"/a2a",method:"OPTIONS",public:!0,handler:A}]}async getTools(){return[Kp0({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, or contact a saved approved agent, 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, or searching general content locally.\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")}}}}B0();class kMA{logger;handleImport;handleDelete;deleteOnFileRemoval;fileOperations;constructor(A,Q,B,w,$=!0){if(this.logger=A,this.fileOperations=w,this.deleteOnFileRemoval=$,B)this.handleImport=async(f)=>{let I=await B({type:"directory-import",data:{paths:[f]}});this.logger.debug("Queued import job for file change",{jobId:I,path:f})},this.handleDelete=async(f)=>{if(!this.deleteOnFileRemoval){this.logger.warn("File deleted but deleteOnFileRemoval is disabled",{path:f});return}try{let{entityType:I,id:D}=this.fileOperations.parseEntityFromPath(f),Y=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:Y,path:f,entityId:D,entityType:I})}catch(I){this.logger.warn("Could not extract entity info from deleted file",{path:f,error:I})}};else this.handleImport=async(f)=>{await Q([f])},this.handleDelete=async(f)=>{this.logger.warn("File deleted but no job queue available",{path:f})}}async handleFileChange(A,Q){this.logger.debug("Processing file change",{event:A,path:Q});try{switch(A){case"add":case"change":await this.handleImport(Q);break;case"delete":case"unlink":await this.handleDelete(Q);break;default:this.logger.debug("Unhandled file event",{event:A,path:Q})}}catch(B){this.logger.error("Failed to handle file change",{event:A,path:Q,error:B})}}}var yi0=Y1(ji0(),1);import{extname as Xv2}from"path";var D0A=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function PL(A){let Q=Xv2(A).toLowerCase();return D0A.includes(Q)}function _i0(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 PVA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as Wv2,relative as Uv2,sep as vi0,join as Jv2}from"path";function qD(A,Q){return Wv2(Q)?Q:Jv2(A,Q)}function sb(A,Q){let B=qD(A,Q),w=Uv2(A,B);return vi0==="/"?w:w.split(vi0).join("/")}function Gv2(A,Q){if(!sb(Q,A).startsWith("image/"))return!1;return PL(A)}function Fv2(A,Q){if(sb(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return Gv2(A,Q)}class kVA{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=yi0.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(!Fv2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=sb(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=qD(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 xi0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return Kv2(Q)}function hi0(A){if(A)A.stop();return}function gi0(A,Q){if(A)A.setCallback(Q)}async function Kv2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,Y=new kMA(Q,$,f,I,D),H=new kVA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,F)=>{await Y.handleFileChange(W,F)}});return await H.start(),H}async function Ti0(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:$}}B0();class jVA{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??P5(),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 _VA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new jVA({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 vVA{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 Ev2,dirname as Mv2,extname as Vv2}from"path";import{extname as Zv2}from"path";var Y0A=[".pdf"],Si0=".meta.json";function kL(A){let Q=Zv2(A).toLowerCase();return Y0A.includes(Q)}function mi0(A){return A.toLowerCase().endsWith(Si0)}function yVA(A){return`${A}${Si0}`}function ui0(A){switch(A.toLowerCase().replace(".","")){case"pdf":default:return"application/pdf"}}import{extname as zv2,join as H0A}from"path";function X0A(A,Q){let w=sb(A,Q).split("/"),$,f;if(w.length===1)$="base",f=w;else if(w.length>1&&w[0])$=w[0],f=w.slice(1);else $="base",f=w;let I;if(f.length>1){let D=f[f.length-1];if(D)f[f.length-1]=ci0(D);I=f.join(":")}else I=ci0(f[0]??"");return{entityType:$,id:I}}function pi0(A,Q,B,w=".md"){let $=Q.split(":").filter((H)=>H.length>0),f=B==="base";if($.length===1)return f?H0A(A,`${$[0]}${w}`):H0A(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],Y=I.slice(0,-1);if(f)return H0A(A,...Y,`${D}${w}`);return H0A(A,B,...Y,`${D}${w}`)}function li0(A){if(A.entityType==="document")return".pdf";if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return PVA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?PVA(B[1]):".md"}function ci0(A){let Q=zv2(A).toLowerCase();return Q===".md"||D0A.includes(Q)||Y0A.includes(Q)?A.slice(0,-Q.length):A}c4();import{mkdir as Cv2,readFile as ab,writeFile as hVA,stat as Ov2,utimes as Rv2}from"fs/promises";import{join as W0A}from"path";import{mkdir as ii0,readdir as qv2,stat as Lv2}from"fs/promises";import{access as Nv2}from"fs/promises";async function _6(A){try{return await Nv2(A),!0}catch{return!1}}async function xVA(A,Q){return oi0(A,Q,{includeDocuments:!1,includeImages:!1})}async function ri0(A,Q){return oi0(A,Q,{includeDocuments:!0,includeImages:!0})}async function di0(A,Q){if(!await _6(A))await ii0(A,{recursive:!0});for(let B of Q)if(B!=="base")await ii0(W0A(A,B),{recursive:!0})}async function ni0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await _6(A))return{files:B,stats:w};let $=await xVA(A,Q);for(let f of $)try{let I=W0A(A,f),D=await Lv2(I),{entityType:Y}=X0A(A,f);B.push({path:f,entityType:Y,modified:D.mtime}),w.totalFiles++,w.byEntityType[Y]=(w.byEntityType[Y]??0)+1}catch{continue}return{files:B,stats:w}}async function oi0(A,Q,B){let w=[];if(!await _6(A))return w;let $=async(f,I="",D=!1,Y=!1)=>{let H=await qv2(f,{withFileTypes:!0});for(let W of H){let F=I?W0A(I,W.name):W.name;if(W.isFile()&&!W.name.endsWith(".invalid")&&!mi0(W.name)){if(W.name.endsWith(".md"))w.push(F);else if(B.includeImages&&D&&PL(W.name))w.push(F);else if(B.includeDocuments&&Y&&kL(W.name))w.push(F)}else if(W.isDirectory()&&!W.name.startsWith(".")){if(I===""&&!Q.hasEntityType(W.name))continue;let K=W0A(f,W.name),Z=W.name==="image"&&I==="",q=W.name==="document"&&I==="";await $(K,F,D||Z,Y||q)}}};return await $(A),w}function bv2(A){return typeof A==="object"&&A!==null}class gVA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return X0A(this.syncPath,A)}async readEntity(A){let Q=qD(this.syncPath,A),B=await Ov2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D,Y;if(PL(A)||kL(A)){let F=(await ab(Q)).toString("base64"),K=Vv2(A);if(D=`data:${kL(A)?ui0(K):_i0(K)};base64,${F}`,kL(A))Y=await this.readDocumentSidecar(Q,A)}else D=await ab(Q,"utf-8");let H={entityType:w,id:$,content:D,created:f,updated:I};if(Y)H.metadata=Y;return H}async readDocumentSidecar(A,Q){let B={mimeType:"application/pdf",filename:Ev2(Q)},w=yVA(A);if(!await _6(w))return B;try{let $=await ab(w,"utf-8"),f=JSON.parse($),I=bv2(f)?f:{};return{...B,...I}}catch{return B}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w=A.entityType==="document";if(B||w){let f=B?/^data:image\/[a-z+]+;base64,(.+)$/i:/^data:application\/pdf;base64,(.+)$/i,I=A.content.match(f),D=I?.[1]?Buffer.from(I[1],"base64"):Buffer.from(A.content,"base64"),Y=!1;if(await _6(Q)){let H=await ab(Q),W=RB(H.toString("base64")),F=RB(D.toString("base64"));if(W===F)Y=!0}if(!Y)await this.ensureEntityDirectory(A,Q),await hVA(Q,D);if(w)await this.writeDocumentSidecar(A,Q);if(Y)return}else{let f=this.entityService.serializeEntity(A);if(await _6(Q)){let I=await ab(Q,"utf-8"),D=RB(I),Y=RB(f);if(D===Y)return}await this.ensureEntityDirectory(A,Q),await hVA(Q,f,"utf-8")}let $=new Date(A.updated);await Rv2(Q,$,$)}async ensureEntityDirectory(A,Q){if(A.entityType!=="base")await Cv2(Mv2(Q),{recursive:!0})}async writeDocumentSidecar(A,Q){let B=A.metadata,w={};for(let[I,D]of Object.entries(B)){if(I==="mimeType")continue;if(D===void 0)continue;w[I]=D}let $=yVA(Q),f=`${JSON.stringify(w,null,2)}
|
|
2382
2382
|
`;if(await _6($)){if(await ab($,"utf-8")===f)return}await this.ensureEntityDirectory(A,$),await hVA($,f,"utf-8")}getFilePath(A,Q,B=".md"){return pi0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,li0(A))}async getAllMarkdownFiles(){return xVA(this.syncPath,this.entityService)}async getAllSyncFiles(){return ri0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await di0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=RB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return ni0(this.syncPath,this.entityService)}async syncDirectoryExists(){return _6(this.syncPath)}async fileExists(A){return _6(A)}}Kf();GA();Kf();async function U0A(A,Q,B,w){let{sourceUrl:$}=A,f=await Q.listEntities({entityType:"image",options:{filter:{metadata:{sourceUrl:$}},limit:1}});if(f[0])return w.debug("Reusing existing image entity",{sourceUrl:$,imageId:f[0].id}),f[0].id;let I=await B($),{base64:D}=NK(I),Y=jN(D),H=qK(D);if(!Y||!H)throw Error("Could not detect image format or dimensions");let W=await Q.createEntity({entity:{id:A.id,entityType:"image",content:I,metadata:{title:A.title,alt:A.alt,format:Y,width:H.width,height:H.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var si0=J.object({title:J.string(),slug:J.string().optional(),coverImageUrl:J.string().url(),coverImageId:J.string().optional(),coverImageAlt:J.string().optional()});class TVA{entityService;fetcher;logger;constructor(A,Q,B=_Y){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=y4(A)}catch{return null}let{frontmatter:B}=Q,w=si0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!uU(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??D2($),customAlt:D}}async convert(A){let Q;try{Q=y4(A)}catch(H){return this.logger.debug("Parse failed",{error:H}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=si0.safeParse(B);if(!w.success)return{content:A,converted:!1};if(w.data.coverImageId)return{content:A,converted:!1};let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!uU(I))return{content:A,converted:!1};let Y={postTitle:$,postSlug:f??D2($),sourceUrl:I,customAlt:D};try{let H=await this.createImageEntity(Y),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=H,{content:mz(W,Q.content),converted:!0,imageId:H}}catch(H){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:h0(H)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return U0A({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}Kf();GA();class _S{entityService;fetcher;logger;constructor(A,Q,B=_Y){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=_WA(A);for(let $ of w){if(!uU($.url))continue;if($.url.startsWith("entity://"))continue;let f=this.reconstructMarkdown($);B.push({sourceUrl:$.url,alt:$.alt,originalMarkdown:f,postSlug:Q})}return B}reconstructMarkdown(A){if(A.title)return``;return``}async convert(A,Q){let B=this.detectInlineImages(A,Q);if(B.length===0)return{content:A,converted:!1,convertedCount:0};let w=A,$=0,f=0;for(let I of B)try{let D=await this.createImageEntity(I,f++),Y=``;w=w.replace(I.originalMarkdown,Y),$++,this.logger.debug("Converted inline image",{sourceUrl:I.sourceUrl,imageId:D})}catch(D){this.logger.warn("Failed to convert inline image",{sourceUrl:I.sourceUrl,error:h0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return U0A({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class SVA{logger;entityService;fileOperations;constructor(A,Q,B){this.logger=A,this.entityService=Q,this.fileOperations=B}async importEntitiesWithProgress(A,Q,B,w){this.logger.debug("Importing entities with progress reporting");let $={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},f=A??await this.fileOperations.getAllSyncFiles(),I=f.length;await Q.report({progress:0,message:`Starting import of ${I} files`});for(let D=0;D<I;D+=B){let Y=f.slice(D,D+B),H=await w(Y);$.imported+=H.imported,$.skipped+=H.skipped,$.failed+=H.failed,$.quarantined+=H.quarantined,$.errors.push(...H.errors),$.quarantinedFiles.push(...H.quarantinedFiles),$.jobIds.push(...H.jobIds);let W=Math.min(D+B,I),F=Math.round(W/I*40);await Q.report({progress:F,message:`Imported ${W}/${I} files`})}return $}async exportEntitiesWithProgress(A,Q,B,w){this.logger.debug("Exporting entities with progress reporting");let $=A??this.entityService.getEntityTypes();await Q.report({progress:50,message:`Starting export of ${$.length} entity types`});let f=await w(A);return await Q.report({progress:100,message:`Exported ${f.exported} entities`}),this.logger.debug("Export completed",f),f}}GA();import{rename as Pv2,appendFile as kv2,readFile as jv2,writeFile as _v2,access as vv2}from"fs/promises";import{join as ai0}from"path";class mVA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof J.ZodError)return!0;let Q=h0(A);return Q.includes("invalid_type")||Q.includes("invalid_enum_value")||Q.includes("Required")||Q.includes("Invalid frontmatter")||Q.includes("Unknown entity type")}async quarantineInvalidFile(A,Q,B,w){let $=w(A),f=`${$}.invalid`;try{await Pv2($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=ai0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),Y=h0(Q),H=`${D} - ${A}: ${Y}
|
|
2383
2383
|
\u2192 ${A}.invalid
|
|
2384
2384
|
|
|
@@ -2406,7 +2406,7 @@ ${b}`)}if(w!==void 0&&f?.algorithms!==void 0){let L=f.algorithms.map((b)=>b.alg)
|
|
|
2406
2406
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
2407
2407
|
## Getting Started
|
|
2408
2408
|
`),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(`
|
|
2409
|
-
`)}}B0();class S0A extends Pw{directorySync;constructor(A,Q,B){super(A,{schema:SCA,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}}}B0();class m0A extends Pw{directorySync;constructor(A,Q,B){super(A,{schema:TCA,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}}}B0();class u0A extends Pw{directorySync;context;constructor(A,Q,B){super(A,{schema:gCA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let Y=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let H=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}B0();class c0A extends Pw{context;constructor(A,Q,B){super(A,{schema:g0A,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=g0A.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}}}B0();GA();var bg2=J.object({});class p0A extends Pw{directorySync;constructor(A,Q){super(A,{schema:bg2,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}}B0();Kf();GA();x$();Kf();import{readFile as Pg2,writeFile as kg2}from"fs/promises";var jg2=mCA;class l0A extends Pw{context;fetcher;constructor(A,Q,B=_Y){super(Q,{schema:jg2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:hQ.INIT,message:`Reading file: ${w}`});let Y;try{Y=await Pg2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:h0(E)}),y$.failure(E)}let H;try{H=y4(Y)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:h0(E)}),y$.failure(E)}let W=H.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:hQ.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:hQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:hQ.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(n){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:h0(n)}),y$.failure(n)}await this.reportProgress(B,{progress:hQ.GENERATE,message:"Creating image entity"});let{base64:L}=NK(E),b=jN(L),_=qK(L);if(!b||!_)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),y$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let j=`Cover image for ${f}`,s=D??j;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:E,metadata:{title:j,alt:s,format:b,width:_.width,height:_.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:hQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:hQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=mz(Z,H.content);try{await kg2(w,q,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:h0(E)}),y$.failure(E)}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:h0(Y)}),y$.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}B0();Kf();GA();x$();import{readFile as _g2,writeFile as vg2}from"fs/promises";class i0A extends Pw{converter;constructor(A,Q,B=_Y){super(Q,{schema:uCA,jobTypeName:"inline-image-convert"});this.converter=new _S(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:hQ.INIT,message:`Reading file: ${w}`});let f;try{f=await _g2(w,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:hQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:hQ.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:hQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:hQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:hQ.SAVE,message:"Writing updated file"});try{await vg2(w,D.content,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=h0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function bo0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new u0A(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new S0A(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new m0A(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new c0A(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new p0A(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new l0A(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new i0A(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}B0();import{unlink as yg2,access as xg2}from"fs/promises";function Po0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:Y}=I.payload;try{let H=await f.getEntity({entityType:D,id:Y});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:Y}=I.payload,H=Q.fileOps.getFilePath(D,Y);if(await xg2(H).then(()=>!0,()=>!1))await yg2(H),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function ko0(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:P5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();B0();import{readdir as vo0,mkdir as gg2,copyFile as Tg2}from"fs/promises";import{join as _o0,resolve as cCA}from"path";import{join as hg2}from"path";async function jo0(A){if(!await _6(hg2(A,".git")))return!1;try{return await WG(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function Sg2(A,Q){if(!await _6(A))return!0;if((await vo0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await jo0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function yo0(A,Q){let B=await vo0(A,{withFileTypes:!0});for(let w of B){let $=_o0(A,w.name),f=_o0(Q,w.name);if(w.isDirectory()){if(!await _6(f))await gg2(f,{recursive:!0});await yo0($,f)}else await Tg2($,f)}}async function xo0(A,Q,B){let w=cCA(process.cwd(),A);B=B?cCA(B):cCA(process.cwd(),"seed-content");let $=await Sg2(w,Q);if($&&await _6(B))Q.debug("Copying seed content to brain-data directory"),await yo0(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 ho0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await xo0(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:wN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:wN.initialSyncCompleted,payload:{success:!1,error:h0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(wN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function go0(A,Q,B,w){let $=new nz(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(Y)}return()=>{$.dispose();for(let D of I)D()}}function To0(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:H,result:W}=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(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{I=!1}},Y=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as mo0}from"child_process";import{cpSync as mg2,existsSync as So0,mkdirSync as ug2,mkdtempSync as cg2,rmSync as pg2}from"fs";import{tmpdir as lg2}from"os";import{fileURLToPath as ig2}from"url";import{join as rg2,resolve as dg2}from"path";function tZ(A,Q){let B=mo0("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 ng2(A){return A.startsWith("file://")}function og2(A){return ig2(A)}function sg2(A,Q){return mo0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function uo0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ng2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=og2(A.gitUrl),w=dg2(A.seedContentPath);if(!So0(w))throw Error(`Seed content path not found: ${w}`);if(!So0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),ug2(B,{recursive:!0}),tZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(sg2(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 $=cg2(rg2(lg2(),"directory-sync-seed-"));try{tZ($,["init",`--initial-branch=${Q}`]),tZ($,["config","user.name",A.authorName??"Brain"]),tZ($,["config","user.email",A.authorEmail??"brain@localhost"]),mg2(w,$,{recursive:!0}),tZ($,["add","."]),tZ($,["commit","-m","seed content remote"]),tZ($,["remote","add","origin",A.gitUrl]),tZ($,["push","-u","origin",Q])}finally{pg2($,{recursive:!0,force:!0})}}function co0(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),Y=I.payload.paths,H=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:H}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}B0();GA();B0();GA();function po0(A,Q){return YQ(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 f=await Q.show(B.sha,w);return bw({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return bw({commits:[]},`No history found for ${B.entityType}/${B.id}`);return bw({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return T8($ instanceof Error?$.message:"History lookup failed")}})}function lo0(A,Q,B,w){let $=[YQ(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(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,Y={interfaceType:I.interfaceType,channelId:I.channelId},H=w!==void 0,W=()=>A.queueSyncBatch(Q,D,Y),F=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!F)return bw({gitPulled:H},"No files to sync");return bw({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:H},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${H?" (pulled from git)":""}`)}catch(D){return T8(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),YQ(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 f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return bw(I)}catch(f){return T8(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(po0(B,w));return $}var io0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.80",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 pCA extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",io0,A,lS)}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:iS,basePrompt:"",formatter:new T0A,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new vS({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(Po0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)ko0(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await uo0({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 hCA({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(go0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(To0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)ho0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);co0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return lo0(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 vS({...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){bo0(A,this.requireDirectorySync(),this.logger)}}function yL(A={}){return new pCA(A)}B0();GA();var ro0={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.80",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 eg2=J.object({apiKey:J.string().min(1).optional(),from:J.string().min(1).optional()});class do0 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",ro0,A,eg2);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(Ca,async(B)=>{let w=VU0.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 no0(A={}){return new do0(A)}B0();import{render as I$1}from"preact-render-to-string";import{h as ZE}from"preact";function oo0(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=oo0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function wP(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=oo0(A))&&(w&&(w+=" "),w+=Q);return w}var AT2=(A)=>{let Q=BT2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return As0(D,Q)||QT2(I)},getConflictingClassGroupIds:(I,D)=>{let Y=B[I]||[];if(D&&w[I])return[...Y,...w[I]];return Y}}},As0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?As0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},so0=/^\[(.+)\]$/,QT2=(A)=>{if(so0.test(A)){let Q=so0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},BT2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return $T2(Object.entries(A.classGroups),B).forEach(([f,I])=>{iCA(I,w,f,Q)}),w},iCA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:ao0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(wT2($)){iCA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{iCA(I,ao0(Q,f),B,w)})})},ao0=(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},wT2=(A)=>A.isThemeGetter,$T2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},fT2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var IT2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let Y=[],H=0,W=0,F;for(let L=0;L<D.length;L++){let b=D[L];if(H===0){if(b===$&&(w||D.slice(L,L+f)===Q)){Y.push(D.slice(W,L)),W=L+f;continue}if(b==="/"){F=L;continue}}if(b==="[")H++;else if(b==="]")H--}let K=Y.length===0?D:D.substring(W),Z=K.startsWith("!"),q=Z?K.substring(1):K,E=F&&F>W?F-W:void 0;return{modifiers:Y,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:E}};if(B)return(D)=>B({className:D,parseClassName:I});return I},DT2=(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},YT2=(A)=>({cache:fT2(A.cacheSize),parseClassName:IT2(A),...AT2(A)}),HT2=/\s+/,XT2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(HT2),D="";for(let Y=I.length-1;Y>=0;Y-=1){let H=I[Y],{modifiers:W,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(H),q=Boolean(Z),E=w(q?K.substring(0,Z):K);if(!E){if(!q){D=H+(D.length>0?" "+D:D);continue}if(E=w(K),!E){D=H+(D.length>0?" "+D:D);continue}q=!1}let L=DT2(W).join(":"),b=F?L+"!":L,_=b+E;if(f.includes(_))continue;f.push(_);let j=$(E,q);for(let s=0;s<j.length;++s){let n=j[s];f.push(b+n)}D=H+(D.length>0?" "+D:D)}return D};function WT2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=Qs0(Q))w&&(w+=" "),w+=B}return w}var Qs0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=Qs0(A[w]))B&&(B+=" "),B+=Q}return B};function to0(A,...Q){let B,w,$,f=I;function I(Y){let H=Q.reduce((W,F)=>F(W),A());return B=YT2(H),w=B.cache.get,$=B.cache.set,f=D,D(Y)}function D(Y){let H=w(Y);if(H)return H;let W=XT2(Y,B);return $(Y,W),W}return function(){return f(WT2.apply(null,arguments))}}var H8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},Bs0=/^\[(?:([a-z-]+):)?(.+)\]$/i,UT2=/^\d+\/\d+$/,JT2=new Set(["px","full","screen"]),GT2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,FT2=/\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$/,KT2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,ZT2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,zT2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,UG=(A)=>$P(A)||JT2.has(A)||UT2.test(A),eZ=(A)=>fP(A,"length",OT2),$P=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),lCA=(A)=>fP(A,"number",$P),rS=(A)=>Boolean(A)&&Number.isInteger(Number(A)),NT2=(A)=>A.endsWith("%")&&$P(A.slice(0,-1)),vQ=(A)=>Bs0.test(A),A3=(A)=>GT2.test(A),qT2=new Set(["length","size","percentage"]),LT2=(A)=>fP(A,qT2,ws0),ET2=(A)=>fP(A,"position",ws0),MT2=new Set(["image","url"]),VT2=(A)=>fP(A,MT2,bT2),CT2=(A)=>fP(A,"",RT2),dS=()=>!0,fP=(A,Q,B)=>{let w=Bs0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},OT2=(A)=>FT2.test(A)&&!KT2.test(A),ws0=()=>!1,RT2=(A)=>ZT2.test(A),bT2=(A)=>zT2.test(A);var eo0=()=>{let A=H8("colors"),Q=H8("spacing"),B=H8("blur"),w=H8("brightness"),$=H8("borderColor"),f=H8("borderRadius"),I=H8("borderSpacing"),D=H8("borderWidth"),Y=H8("contrast"),H=H8("grayscale"),W=H8("hueRotate"),F=H8("invert"),K=H8("gap"),Z=H8("gradientColorStops"),q=H8("gradientColorStopPositions"),E=H8("inset"),L=H8("margin"),b=H8("opacity"),_=H8("padding"),j=H8("saturate"),s=H8("scale"),n=H8("sepia"),T=H8("skew"),y=H8("space"),h=H8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",vQ,Q],HA=()=>[vQ,Q],BA=()=>["",UG,eZ],P=()=>["auto",$P,vQ],C=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["solid","dashed","dotted","double","none"],l=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],c=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",vQ],d=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[$P,vQ];return{cacheSize:500,separator:":",theme:{colors:[dS],spacing:[UG,eZ],blur:["none","",A3,vQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",A3,vQ],borderSpacing:HA(),borderWidth:BA(),contrast:UA(),grayscale:e(),hueRotate:UA(),invert:e(),gap:HA(),gradientColorStops:[A],gradientColorStopPositions:[NT2,eZ],inset:m(),margin:m(),opacity:UA(),padding:HA(),saturate:UA(),scale:UA(),sepia:e(),skew:UA(),space:HA(),translate:HA()},classGroups:{aspect:[{aspect:["auto","square","video",vQ]}],container:["container"],columns:[{columns:[A3]}],"break-after":[{"break-after":d()}],"break-before":[{"break-before":d()}],"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:[...C(),vQ]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[E]}],"inset-x":[{"inset-x":[E]}],"inset-y":[{"inset-y":[E]}],start:[{start:[E]}],end:[{end:[E]}],top:[{top:[E]}],right:[{right:[E]}],bottom:[{bottom:[E]}],left:[{left:[E]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",rS,vQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",vQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",rS,vQ]}],"grid-cols":[{"grid-cols":[dS]}],"col-start-end":[{col:["auto",{span:["full",rS,vQ]},vQ]}],"col-start":[{"col-start":P()}],"col-end":[{"col-end":P()}],"grid-rows":[{"grid-rows":[dS]}],"row-start-end":[{row:["auto",{span:[rS,vQ]},vQ]}],"row-start":[{"row-start":P()}],"row-end":[{"row-end":P()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",vQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",vQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...c()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...c(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...c(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[_]}],px:[{px:[_]}],py:[{py:[_]}],ps:[{ps:[_]}],pe:[{pe:[_]}],pt:[{pt:[_]}],pr:[{pr:[_]}],pb:[{pb:[_]}],pl:[{pl:[_]}],m:[{m:[L]}],mx:[{mx:[L]}],my:[{my:[L]}],ms:[{ms:[L]}],me:[{me:[L]}],mt:[{mt:[L]}],mr:[{mr:[L]}],mb:[{mb:[L]}],ml:[{ml:[L]}],"space-x":[{"space-x":[y]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[y]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",vQ,Q]}],"min-w":[{"min-w":[vQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[vQ,Q,"none","full","min","max","fit","prose",{screen:[A3]},A3]}],h:[{h:[vQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[vQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[vQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[vQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",A3,eZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",lCA]}],"font-family":[{font:[dS]}],"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",vQ]}],"line-clamp":[{"line-clamp":["none",$P,lCA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",UG,vQ]}],"list-image":[{"list-image":["none",vQ]}],"list-style-type":[{list:["none","disc","decimal",vQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[b]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[b]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",UG,eZ]}],"underline-offset":[{"underline-offset":["auto",UG,vQ]}],"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:HA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",vQ]}],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",vQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[b]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...C(),ET2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",LT2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},VT2]}],"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:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[b]}],"border-style":[{border:[...k(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[b]}],"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":[UG,vQ]}],"outline-w":[{outline:[UG,eZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:BA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[b]}],"ring-offset-w":[{"ring-offset":[UG,eZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",A3,CT2]}],"shadow-color":[{shadow:[dS]}],opacity:[{opacity:[b]}],"mix-blend":[{"mix-blend":[...l(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":l()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[Y]}],"drop-shadow":[{"drop-shadow":["","none",A3,vQ]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[F]}],saturate:[{saturate:[j]}],sepia:[{sepia:[n]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[b]}],"backdrop-saturate":[{"backdrop-saturate":[j]}],"backdrop-sepia":[{"backdrop-sepia":[n]}],"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",vQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",vQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",vQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[s]}],"scale-x":[{"scale-x":[s]}],"scale-y":[{"scale-y":[s]}],rotate:[{rotate:[rS,vQ]}],"translate-x":[{"translate-x":[h]}],"translate-y":[{"translate-y":[h]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",vQ]}],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",vQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":HA()}],"scroll-mx":[{"scroll-mx":HA()}],"scroll-my":[{"scroll-my":HA()}],"scroll-ms":[{"scroll-ms":HA()}],"scroll-me":[{"scroll-me":HA()}],"scroll-mt":[{"scroll-mt":HA()}],"scroll-mr":[{"scroll-mr":HA()}],"scroll-mb":[{"scroll-mb":HA()}],"scroll-ml":[{"scroll-ml":HA()}],"scroll-p":[{"scroll-p":HA()}],"scroll-px":[{"scroll-px":HA()}],"scroll-py":[{"scroll-py":HA()}],"scroll-ps":[{"scroll-ps":HA()}],"scroll-pe":[{"scroll-pe":HA()}],"scroll-pt":[{"scroll-pt":HA()}],"scroll-pr":[{"scroll-pr":HA()}],"scroll-pb":[{"scroll-pb":HA()}],"scroll-pl":[{"scroll-pl":HA()}],"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",vQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[UG,eZ,lCA]}],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"]}}},PT2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{nS(A,"cacheSize",Q),nS(A,"prefix",B),nS(A,"separator",w),nS(A,"experimentalParseClassName",$);for(let D in I)kT2(A[D],I[D]);for(let D in f)jT2(A[D],f[D]);return A},nS=(A,Q,B)=>{if(B!==void 0)A[Q]=B},kT2=(A,Q)=>{if(Q)for(let B in Q)nS(A,B,Q[B])},jT2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},r0A=(A,...Q)=>typeof A==="function"?to0(eo0,A,...Q):to0(()=>PT2(eo0(),A),...Q);var _T2=r0A({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 a1(...A){return _T2(wP(A))}var $s0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,fs0=wP,Ew=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return fs0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((H)=>{let W=B===null||B===void 0?void 0:B[H],F=f===null||f===void 0?void 0:f[H];if(W===null)return null;let K=$s0(W)||$s0(F);return $[H][K]}),D=B&&Object.entries(B).reduce((H,W)=>{let[F,K]=W;if(K===void 0)return H;return H[F]=K,H},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,W)=>{let{class:F,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[E,L]=q;return Array.isArray(L)?L.includes({...f,...D}[E]):{...f,...D}[E]===L})?[...H,F,K]:H},[]);return fs0(A,I,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as rCA}from"preact/jsx-dev-runtime";var Is0=Ew("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 dCA({variant:A,title:Q,children:B,className:w}){return rCA("div",{className:a1(Is0({variant:A}),w),role:"alert",children:[Q&&rCA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),rCA("div",{className:a1(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 vT2}from"preact/jsx-dev-runtime";var Ds0=Ew("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 xL({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return vT2("button",{type:f,className:a1(Ds0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as yT2}from"preact/jsx-dev-runtime";var Ys0=Ew("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 T5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return yT2("a",{href:A,className:a1(Ys0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as d0A}from"preact/jsx-dev-runtime";var Hs0=Ew("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"}}),xT2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function IP({variant:A,size:Q,className:B}){let w=xT2[Q??"md"];return d0A("button",{onclick:"toggleTheme()",type:"button",className:a1(Hs0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:d0A("svg",{className:a1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[d0A("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),d0A("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 nCA}from"preact/jsx-dev-runtime";var Xs0=Ew("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function n0A({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return nCA("ul",{className:a1(Xs0({orientation:w}),Q),children:[f.map((I)=>nCA("li",{children:nCA("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 j1w}from"preact/jsx-dev-runtime";import{jsxDEV as y1w}from"preact/jsx-dev-runtime";import{createContext as Xi2,h as Wi2}from"preact";import{useContext as Ui2}from"preact/hooks";_JA();var qA1=Y1(NA1(),1),Yi2=new vx({gfm:!0,breaks:!0}),Hi2={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 ZRA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new vx({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):Yi2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2409
|
+
`)}}B0();class S0A extends Pw{directorySync;constructor(A,Q,B){super(A,{schema:SCA,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}}}B0();class m0A extends Pw{directorySync;constructor(A,Q,B){super(A,{schema:TCA,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}}}B0();class u0A extends Pw{directorySync;context;constructor(A,Q,B){super(A,{schema:gCA,jobTypeName:"directory-sync"});this.context=Q,this.directorySync=B}async process(A,Q,B){let w=Date.now(),$=A.syncDirection??"both";this.logger.info("Starting directory sync job",{jobId:Q,operation:A.operation,syncDirection:$});let f={imported:0,skipped:0,failed:0,quarantined:0,quarantinedFiles:[],errors:[],jobIds:[]},I={exported:0,failed:0,errors:[]};if($!=="export")if(await B.report({progress:10,message:"Scanning directory for changes"}),f=await this.importWithProgress(A.paths,B),$==="import")await this.waitForImportJobs(f.jobIds,B),await B.report({progress:100,message:`Import complete: ${f.imported} imported`});else await B.report({progress:50,message:`Imported ${f.imported} entities`}),await this.waitForImportJobs(f.jobIds,B),await B.report({progress:56,message:"Processing complete, starting export"});if($!=="import"){let Y=$==="export"?10:60;await B.report({progress:Y,message:"Exporting entities to directory"}),I=await this.exportWithProgress(A.entityTypes,B),await B.report({progress:100,message:$==="export"?`Export complete: ${I.exported} exported`:`Sync complete: ${f.imported} imported, ${I.exported} exported`})}let D=Date.now()-w;return this.logger.info("Directory sync job completed",{jobId:Q,duration:D,imported:f.imported,exported:I.exported}),{import:f,export:I,duration:D}}async importWithProgress(A,Q){try{return await this.directorySync.importEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Import phase failed",{error:B}),B}}async exportWithProgress(A,Q){try{return await this.directorySync.exportEntitiesWithProgress(A,Q,10)}catch(B){throw this.logger.error("Export phase failed",{error:B}),B}}async waitForImportJobs(A,Q){if(A.length===0)return;this.logger.debug(`Waiting for ${A.length} import jobs to complete`);let{entityService:B}=this.context,w=300000,$=500,f=Date.now(),I=async()=>{let Y=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(Y===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${Y}/${A.length} completed)`);return}let H=Math.round(Y/A.length*100);return await Q.report({progress:50+Math.round(H*0.05),message:`Processing ${Y}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}B0();class c0A extends Pw{context;constructor(A,Q,B){super(A,{schema:g0A,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=g0A.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}}}B0();GA();var bg2=J.object({});class p0A extends Pw{directorySync;constructor(A,Q){super(A,{schema:bg2,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}}B0();Kf();GA();x$();Kf();import{readFile as Pg2,writeFile as kg2}from"fs/promises";var jg2=mCA;class l0A extends Pw{context;fetcher;constructor(A,Q,B=_Y){super(Q,{schema:jg2,jobTypeName:"cover-image-convert"});this.context=A,this.fetcher=B}async process(A,Q,B){let{filePath:w,sourceUrl:$,postTitle:f,postSlug:I,customAlt:D}=A;this.logger.debug("Starting image conversion job",{jobId:Q,filePath:w,sourceUrl:$,postSlug:I});try{await this.reportProgress(B,{progress:hQ.INIT,message:`Reading file: ${w}`});let Y;try{Y=await Pg2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:h0(E)}),y$.failure(E)}let H;try{H=y4(Y)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:h0(E)}),y$.failure(E)}let W=H.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:hQ.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:hQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:hQ.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(n){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:h0(n)}),y$.failure(n)}await this.reportProgress(B,{progress:hQ.GENERATE,message:"Creating image entity"});let{base64:L}=NK(E),b=jN(L),_=qK(L);if(!b||!_)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),y$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let j=`Cover image for ${f}`,s=D??j;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:E,metadata:{title:j,alt:s,format:b,width:_.width,height:_.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:hQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:hQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=mz(Z,H.content);try{await kg2(w,q,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:h0(E)}),y$.failure(E)}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(Y){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:h0(Y)}),y$.failure(Y)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}B0();Kf();GA();x$();import{readFile as _g2,writeFile as vg2}from"fs/promises";class i0A extends Pw{converter;constructor(A,Q,B=_Y){super(Q,{schema:uCA,jobTypeName:"inline-image-convert"});this.converter=new _S(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:hQ.INIT,message:`Reading file: ${w}`});let f;try{f=await _g2(w,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to read file",{filePath:w,error:H}),{success:!1,error:H}}await this.reportProgress(B,{progress:hQ.FETCH,message:"Detecting inline images"});let I=this.converter.detectInlineImages(f,$);if(I.length===0)return this.logger.debug("No inline images to convert",{filePath:w}),await this.reportProgress(B,{progress:hQ.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:hQ.PROCESS,message:`Converting ${I.length} images`});let D=await this.converter.convert(f,$);if(!D.converted)return this.logger.debug("No images were converted",{filePath:w}),await this.reportProgress(B,{progress:hQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:hQ.SAVE,message:"Writing updated file"});try{await vg2(w,D.content,"utf-8")}catch(Y){let H=h0(Y);return this.logger.error("Failed to write file",{filePath:w,error:H}),{success:!1,error:H}}return await this.reportProgress(B,{progress:hQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Inline image conversion complete",{filePath:w,convertedCount:D.convertedCount}),{success:!0,convertedCount:D.convertedCount}}catch(f){let I=h0(f);return this.logger.error("Inline image conversion job failed",{jobId:Q,filePath:w,error:I}),{success:!1,error:I}}}summarizeDataForLog(A){return{filePath:A.filePath,postSlug:A.postSlug}}}function bo0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new u0A(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new S0A(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new m0A(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new c0A(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new p0A(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new l0A(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new i0A(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}B0();import{unlink as yg2,access as xg2}from"fs/promises";function Po0(A,Q,B,w){let{subscribe:$}=A.messaging,{entityService:f}=A;$("entity:created",async(I)=>{let{entity:D}=I.payload;try{await Q.fileOps.writeEntity(D),B.debug("Auto-exported created entity",{id:D.id,entityType:D.entityType})}catch(Y){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:Y}=I.payload;try{let H=await f.getEntity({entityType:D,id:Y});if(!H)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:Y}),{success:!1};await Q.fileOps.writeEntity(H),B.debug("Auto-exported updated entity",{id:H.id,entityType:H.entityType})}catch(H){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:Y,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:Y}=I.payload,H=Q.fileOps.getFilePath(D,Y);if(await xg2(H).then(()=>!0,()=>!1))await yg2(H),B.debug("Auto-deleted entity file",{id:D,entityType:Y,path:H});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function ko0(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:P5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();B0();import{readdir as vo0,mkdir as gg2,copyFile as Tg2}from"fs/promises";import{join as _o0,resolve as cCA}from"path";import{join as hg2}from"path";async function jo0(A){if(!await _6(hg2(A,".git")))return!1;try{return await WG(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function Sg2(A,Q){if(!await _6(A))return!0;if((await vo0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await jo0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function yo0(A,Q){let B=await vo0(A,{withFileTypes:!0});for(let w of B){let $=_o0(A,w.name),f=_o0(Q,w.name);if(w.isDirectory()){if(!await _6(f))await gg2(f,{recursive:!0});await yo0($,f)}else await Tg2($,f)}}async function xo0(A,Q,B){let w=cCA(process.cwd(),A);B=B?cCA(B):cCA(process.cwd(),"seed-content");let $=await Sg2(w,Q);if($&&await _6(B))Q.debug("Copying seed content to brain-data directory"),await yo0(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 ho0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let Y=B.syncPath??A.dataDir;await xo0(Y,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let H=await $.pull();if(H.files.length>0)w.info("Pulled changes from remote",{filesChanged:H.files.length})}w.debug("Starting initial sync");let Y=await D.sync();w.debug("Initial sync completed",{imported:Y.import.imported,failed:Y.import.failed,duration:Y.duration}),await A.messaging.send({type:wN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(Y){w.error("Initial sync failed",Y),await A.messaging.send({type:wN.initialSyncCompleted,payload:{success:!1,error:h0(Y)},...{broadcast:!0}})}};A.messaging.subscribe(wN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function go0(A,Q,B,w){let $=new nz(()=>{Q.withLock(async()=>{try{await Q.commit(),await Q.push()}catch(D){w.error("Git auto-commit failed",{error:D})}})},B),f=["entity:created","entity:updated","entity:deleted"],I=[];for(let D of f){let Y=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(Y)}return()=>{$.dispose();for(let D of I)D()}}function To0(A,Q,B,w,$){if(w<=0)return()=>{};let f=w*60*1000,I=!1,D=async()=>{if(I)return;I=!0;try{let{files:H,result:W}=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(H.length>0)$.info("Periodic sync: pulled changes",{filesChanged:H.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(H){$.error("Periodic git sync failed",{error:H})}finally{I=!1}},Y=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(Y)}}import{spawnSync as mo0}from"child_process";import{cpSync as mg2,existsSync as So0,mkdirSync as ug2,mkdtempSync as cg2,rmSync as pg2}from"fs";import{tmpdir as lg2}from"os";import{fileURLToPath as ig2}from"url";import{join as rg2,resolve as dg2}from"path";function tZ(A,Q){let B=mo0("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 ng2(A){return A.startsWith("file://")}function og2(A){return ig2(A)}function sg2(A,Q){return mo0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function uo0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!ng2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=og2(A.gitUrl),w=dg2(A.seedContentPath);if(!So0(w))throw Error(`Seed content path not found: ${w}`);if(!So0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),ug2(B,{recursive:!0}),tZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(sg2(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 $=cg2(rg2(lg2(),"directory-sync-seed-"));try{tZ($,["init",`--initial-branch=${Q}`]),tZ($,["config","user.name",A.authorName??"Brain"]),tZ($,["config","user.email",A.authorEmail??"brain@localhost"]),mg2(w,$,{recursive:!0}),tZ($,["add","."]),tZ($,["commit","-m","seed content remote"]),tZ($,["remote","add","origin",A.gitUrl]),tZ($,["push","-u","origin",Q])}finally{pg2($,{recursive:!0,force:!0})}}function co0(A,Q,B,w,$){let{subscribe:f}=A.messaging;f("entity:export:request",async(I)=>{try{return{success:!0,data:await Q().exportEntities(I.payload.entityTypes)}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Export failed"}}}),f("entity:import:request",async(I)=>{try{let D=Q(),Y=I.payload.paths,H=await D.importEntities(Y);if(Y&&Y.length>0)await D.removeOrphanedEntities();return{success:!0,data:H}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Import failed"}}}),f("sync:status:request",async()=>{try{let D=await Q().getStatus();return{success:!0,data:{syncPath:D.syncPath,isInitialized:D.exists,watchEnabled:D.watching}}}catch(I){return{success:!1,error:I instanceof Error?I.message:"Status check failed"}}}),f("sync:configure:request",async(I)=>{try{return await B({syncPath:I.payload.syncPath}),{success:!0,data:{syncPath:I.payload.syncPath,configured:!0}}}catch(D){return{success:!1,error:D instanceof Error?D.message:"Configuration failed"}}}),f("git-sync:get-repo-info",async()=>{if(!$?.repo)return{success:!1,error:"Git not configured"};return{success:!0,data:{repo:$.repo,branch:$.branch??"main"}}}),w.debug("Registered message handlers")}B0();GA();B0();GA();function po0(A,Q){return YQ(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 f=await Q.show(B.sha,w);return bw({sha:B.sha,entityType:B.entityType,id:B.id,content:f},`Content at ${B.sha.slice(0,7)}`)}let $=await Q.log(w,B.limit);if($.length===0)return bw({commits:[]},`No history found for ${B.entityType}/${B.id}`);return bw({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return T8($ instanceof Error?$.message:"History lookup failed")}})}function lo0(A,Q,B,w){let $=[YQ(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(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,Y={interfaceType:I.interfaceType,channelId:I.channelId},H=w!==void 0,W=()=>A.queueSyncBatch(Q,D,Y),F=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!F)return bw({gitPulled:H},"No files to sync");return bw({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:H},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${H?" (pulled from git)":""}`)}catch(D){return T8(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),YQ(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 f=await A.getStatus(),I={syncPath:f.syncPath,lastSync:f.lastSync?.toISOString(),watching:f.watching};if(w){let D=await w.getStatus();I.git={isRepo:D.isRepo,branch:D.branch,hasChanges:D.hasChanges,ahead:D.ahead,behind:D.behind,remote:D.remote}}return bw(I)}catch(f){return T8(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(po0(B,w));return $}var io0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.81",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 pCA extends YB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",io0,A,lS)}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:iS,basePrompt:"",formatter:new T0A,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new vS({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(Po0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)ko0(A,$,this.config.syncPath??A.dataDir);let f=this.config.git!==void 0&&(this.config.git.repo!==void 0||this.config.git.gitUrl!==void 0);if(this.config.git&&!f)this.logger.debug("Git block present but no repo/gitUrl configured \u2014 git sync disabled");if(f&&this.config.git){await uo0({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 hCA({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(go0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(To0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)ho0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);co0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return lo0(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 vS({...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){bo0(A,this.requireDirectorySync(),this.logger)}}function yL(A={}){return new pCA(A)}B0();GA();var ro0={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.81",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 eg2=J.object({apiKey:J.string().min(1).optional(),from:J.string().min(1).optional()});class do0 extends YB{fetchImpl;constructor(A={},Q={}){super("email-resend",ro0,A,eg2);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(Ca,async(B)=>{let w=VU0.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 no0(A={}){return new do0(A)}B0();import{render as I$1}from"preact-render-to-string";import{h as ZE}from"preact";function oo0(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=oo0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function wP(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=oo0(A))&&(w&&(w+=" "),w+=Q);return w}var AT2=(A)=>{let Q=BT2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return As0(D,Q)||QT2(I)},getConflictingClassGroupIds:(I,D)=>{let Y=B[I]||[];if(D&&w[I])return[...Y,...w[I]];return Y}}},As0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?As0(A.slice(1),w):void 0;if($)return $;if(Q.validators.length===0)return;let f=A.join("-");return Q.validators.find(({validator:I})=>I(f))?.classGroupId},so0=/^\[(.+)\]$/,QT2=(A)=>{if(so0.test(A)){let Q=so0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},BT2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return $T2(Object.entries(A.classGroups),B).forEach(([f,I])=>{iCA(I,w,f,Q)}),w},iCA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:ao0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(wT2($)){iCA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{iCA(I,ao0(Q,f),B,w)})})},ao0=(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},wT2=(A)=>A.isThemeGetter,$T2=(A,Q)=>{if(!Q)return A;return A.map(([B,w])=>{let $=w.map((f)=>{if(typeof f==="string")return Q+f;if(typeof f==="object")return Object.fromEntries(Object.entries(f).map(([I,D])=>[Q+I,D]));return f});return[B,$]})},fT2=(A)=>{if(A<1)return{get:()=>{return},set:()=>{}};let Q=0,B=new Map,w=new Map,$=(f,I)=>{if(B.set(f,I),Q++,Q>A)Q=0,w=B,B=new Map};return{get(f){let I=B.get(f);if(I!==void 0)return I;if((I=w.get(f))!==void 0)return $(f,I),I},set(f,I){if(B.has(f))B.set(f,I);else $(f,I)}}};var IT2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let Y=[],H=0,W=0,F;for(let L=0;L<D.length;L++){let b=D[L];if(H===0){if(b===$&&(w||D.slice(L,L+f)===Q)){Y.push(D.slice(W,L)),W=L+f;continue}if(b==="/"){F=L;continue}}if(b==="[")H++;else if(b==="]")H--}let K=Y.length===0?D:D.substring(W),Z=K.startsWith("!"),q=Z?K.substring(1):K,E=F&&F>W?F-W:void 0;return{modifiers:Y,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:E}};if(B)return(D)=>B({className:D,parseClassName:I});return I},DT2=(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},YT2=(A)=>({cache:fT2(A.cacheSize),parseClassName:IT2(A),...AT2(A)}),HT2=/\s+/,XT2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(HT2),D="";for(let Y=I.length-1;Y>=0;Y-=1){let H=I[Y],{modifiers:W,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(H),q=Boolean(Z),E=w(q?K.substring(0,Z):K);if(!E){if(!q){D=H+(D.length>0?" "+D:D);continue}if(E=w(K),!E){D=H+(D.length>0?" "+D:D);continue}q=!1}let L=DT2(W).join(":"),b=F?L+"!":L,_=b+E;if(f.includes(_))continue;f.push(_);let j=$(E,q);for(let s=0;s<j.length;++s){let n=j[s];f.push(b+n)}D=H+(D.length>0?" "+D:D)}return D};function WT2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=Qs0(Q))w&&(w+=" "),w+=B}return w}var Qs0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=Qs0(A[w]))B&&(B+=" "),B+=Q}return B};function to0(A,...Q){let B,w,$,f=I;function I(Y){let H=Q.reduce((W,F)=>F(W),A());return B=YT2(H),w=B.cache.get,$=B.cache.set,f=D,D(Y)}function D(Y){let H=w(Y);if(H)return H;let W=XT2(Y,B);return $(Y,W),W}return function(){return f(WT2.apply(null,arguments))}}var H8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},Bs0=/^\[(?:([a-z-]+):)?(.+)\]$/i,UT2=/^\d+\/\d+$/,JT2=new Set(["px","full","screen"]),GT2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,FT2=/\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$/,KT2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,ZT2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,zT2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,UG=(A)=>$P(A)||JT2.has(A)||UT2.test(A),eZ=(A)=>fP(A,"length",OT2),$P=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),lCA=(A)=>fP(A,"number",$P),rS=(A)=>Boolean(A)&&Number.isInteger(Number(A)),NT2=(A)=>A.endsWith("%")&&$P(A.slice(0,-1)),vQ=(A)=>Bs0.test(A),A3=(A)=>GT2.test(A),qT2=new Set(["length","size","percentage"]),LT2=(A)=>fP(A,qT2,ws0),ET2=(A)=>fP(A,"position",ws0),MT2=new Set(["image","url"]),VT2=(A)=>fP(A,MT2,bT2),CT2=(A)=>fP(A,"",RT2),dS=()=>!0,fP=(A,Q,B)=>{let w=Bs0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},OT2=(A)=>FT2.test(A)&&!KT2.test(A),ws0=()=>!1,RT2=(A)=>ZT2.test(A),bT2=(A)=>zT2.test(A);var eo0=()=>{let A=H8("colors"),Q=H8("spacing"),B=H8("blur"),w=H8("brightness"),$=H8("borderColor"),f=H8("borderRadius"),I=H8("borderSpacing"),D=H8("borderWidth"),Y=H8("contrast"),H=H8("grayscale"),W=H8("hueRotate"),F=H8("invert"),K=H8("gap"),Z=H8("gradientColorStops"),q=H8("gradientColorStopPositions"),E=H8("inset"),L=H8("margin"),b=H8("opacity"),_=H8("padding"),j=H8("saturate"),s=H8("scale"),n=H8("sepia"),T=H8("skew"),y=H8("space"),h=H8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],m=()=>["auto",vQ,Q],HA=()=>[vQ,Q],BA=()=>["",UG,eZ],P=()=>["auto",$P,vQ],C=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],k=()=>["solid","dashed","dotted","double","none"],l=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],c=()=>["start","end","center","between","around","evenly","stretch"],e=()=>["","0",vQ],d=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[$P,vQ];return{cacheSize:500,separator:":",theme:{colors:[dS],spacing:[UG,eZ],blur:["none","",A3,vQ],brightness:UA(),borderColor:[A],borderRadius:["none","","full",A3,vQ],borderSpacing:HA(),borderWidth:BA(),contrast:UA(),grayscale:e(),hueRotate:UA(),invert:e(),gap:HA(),gradientColorStops:[A],gradientColorStopPositions:[NT2,eZ],inset:m(),margin:m(),opacity:UA(),padding:HA(),saturate:UA(),scale:UA(),sepia:e(),skew:UA(),space:HA(),translate:HA()},classGroups:{aspect:[{aspect:["auto","square","video",vQ]}],container:["container"],columns:[{columns:[A3]}],"break-after":[{"break-after":d()}],"break-before":[{"break-before":d()}],"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:[...C(),vQ]}],overflow:[{overflow:AA()}],"overflow-x":[{"overflow-x":AA()}],"overflow-y":[{"overflow-y":AA()}],overscroll:[{overscroll:g()}],"overscroll-x":[{"overscroll-x":g()}],"overscroll-y":[{"overscroll-y":g()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[E]}],"inset-x":[{"inset-x":[E]}],"inset-y":[{"inset-y":[E]}],start:[{start:[E]}],end:[{end:[E]}],top:[{top:[E]}],right:[{right:[E]}],bottom:[{bottom:[E]}],left:[{left:[E]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",rS,vQ]}],basis:[{basis:m()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",vQ]}],grow:[{grow:e()}],shrink:[{shrink:e()}],order:[{order:["first","last","none",rS,vQ]}],"grid-cols":[{"grid-cols":[dS]}],"col-start-end":[{col:["auto",{span:["full",rS,vQ]},vQ]}],"col-start":[{"col-start":P()}],"col-end":[{"col-end":P()}],"grid-rows":[{"grid-rows":[dS]}],"row-start-end":[{row:["auto",{span:[rS,vQ]},vQ]}],"row-start":[{"row-start":P()}],"row-end":[{"row-end":P()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",vQ]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",vQ]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...c()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...c(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...c(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[_]}],px:[{px:[_]}],py:[{py:[_]}],ps:[{ps:[_]}],pe:[{pe:[_]}],pt:[{pt:[_]}],pr:[{pr:[_]}],pb:[{pb:[_]}],pl:[{pl:[_]}],m:[{m:[L]}],mx:[{mx:[L]}],my:[{my:[L]}],ms:[{ms:[L]}],me:[{me:[L]}],mt:[{mt:[L]}],mr:[{mr:[L]}],mb:[{mb:[L]}],ml:[{ml:[L]}],"space-x":[{"space-x":[y]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[y]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",vQ,Q]}],"min-w":[{"min-w":[vQ,Q,"min","max","fit"]}],"max-w":[{"max-w":[vQ,Q,"none","full","min","max","fit","prose",{screen:[A3]},A3]}],h:[{h:[vQ,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[vQ,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[vQ,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[vQ,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",A3,eZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",lCA]}],"font-family":[{font:[dS]}],"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",vQ]}],"line-clamp":[{"line-clamp":["none",$P,lCA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",UG,vQ]}],"list-image":[{"list-image":["none",vQ]}],"list-style-type":[{list:["none","disc","decimal",vQ]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[b]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[b]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...k(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",UG,eZ]}],"underline-offset":[{"underline-offset":["auto",UG,vQ]}],"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:HA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",vQ]}],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",vQ]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[b]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...C(),ET2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",LT2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},VT2]}],"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:[f]}],"rounded-s":[{"rounded-s":[f]}],"rounded-e":[{"rounded-e":[f]}],"rounded-t":[{"rounded-t":[f]}],"rounded-r":[{"rounded-r":[f]}],"rounded-b":[{"rounded-b":[f]}],"rounded-l":[{"rounded-l":[f]}],"rounded-ss":[{"rounded-ss":[f]}],"rounded-se":[{"rounded-se":[f]}],"rounded-ee":[{"rounded-ee":[f]}],"rounded-es":[{"rounded-es":[f]}],"rounded-tl":[{"rounded-tl":[f]}],"rounded-tr":[{"rounded-tr":[f]}],"rounded-br":[{"rounded-br":[f]}],"rounded-bl":[{"rounded-bl":[f]}],"border-w":[{border:[D]}],"border-w-x":[{"border-x":[D]}],"border-w-y":[{"border-y":[D]}],"border-w-s":[{"border-s":[D]}],"border-w-e":[{"border-e":[D]}],"border-w-t":[{"border-t":[D]}],"border-w-r":[{"border-r":[D]}],"border-w-b":[{"border-b":[D]}],"border-w-l":[{"border-l":[D]}],"border-opacity":[{"border-opacity":[b]}],"border-style":[{border:[...k(),"hidden"]}],"divide-x":[{"divide-x":[D]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[D]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[b]}],"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":[UG,vQ]}],"outline-w":[{outline:[UG,eZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:BA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[b]}],"ring-offset-w":[{"ring-offset":[UG,eZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",A3,CT2]}],"shadow-color":[{shadow:[dS]}],opacity:[{opacity:[b]}],"mix-blend":[{"mix-blend":[...l(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":l()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[Y]}],"drop-shadow":[{"drop-shadow":["","none",A3,vQ]}],grayscale:[{grayscale:[H]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[F]}],saturate:[{saturate:[j]}],sepia:[{sepia:[n]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[Y]}],"backdrop-grayscale":[{"backdrop-grayscale":[H]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[b]}],"backdrop-saturate":[{"backdrop-saturate":[j]}],"backdrop-sepia":[{"backdrop-sepia":[n]}],"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",vQ]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",vQ]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",vQ]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[s]}],"scale-x":[{"scale-x":[s]}],"scale-y":[{"scale-y":[s]}],rotate:[{rotate:[rS,vQ]}],"translate-x":[{"translate-x":[h]}],"translate-y":[{"translate-y":[h]}],"skew-x":[{"skew-x":[T]}],"skew-y":[{"skew-y":[T]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",vQ]}],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",vQ]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":HA()}],"scroll-mx":[{"scroll-mx":HA()}],"scroll-my":[{"scroll-my":HA()}],"scroll-ms":[{"scroll-ms":HA()}],"scroll-me":[{"scroll-me":HA()}],"scroll-mt":[{"scroll-mt":HA()}],"scroll-mr":[{"scroll-mr":HA()}],"scroll-mb":[{"scroll-mb":HA()}],"scroll-ml":[{"scroll-ml":HA()}],"scroll-p":[{"scroll-p":HA()}],"scroll-px":[{"scroll-px":HA()}],"scroll-py":[{"scroll-py":HA()}],"scroll-ps":[{"scroll-ps":HA()}],"scroll-pe":[{"scroll-pe":HA()}],"scroll-pt":[{"scroll-pt":HA()}],"scroll-pr":[{"scroll-pr":HA()}],"scroll-pb":[{"scroll-pb":HA()}],"scroll-pl":[{"scroll-pl":HA()}],"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",vQ]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[UG,eZ,lCA]}],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"]}}},PT2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{nS(A,"cacheSize",Q),nS(A,"prefix",B),nS(A,"separator",w),nS(A,"experimentalParseClassName",$);for(let D in I)kT2(A[D],I[D]);for(let D in f)jT2(A[D],f[D]);return A},nS=(A,Q,B)=>{if(B!==void 0)A[Q]=B},kT2=(A,Q)=>{if(Q)for(let B in Q)nS(A,B,Q[B])},jT2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},r0A=(A,...Q)=>typeof A==="function"?to0(eo0,A,...Q):to0(()=>PT2(eo0(),A),...Q);var _T2=r0A({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 a1(...A){return _T2(wP(A))}var $s0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,fs0=wP,Ew=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return fs0(A,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className);let{variants:$,defaultVariants:f}=Q,I=Object.keys($).map((H)=>{let W=B===null||B===void 0?void 0:B[H],F=f===null||f===void 0?void 0:f[H];if(W===null)return null;let K=$s0(W)||$s0(F);return $[H][K]}),D=B&&Object.entries(B).reduce((H,W)=>{let[F,K]=W;if(K===void 0)return H;return H[F]=K,H},{}),Y=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((H,W)=>{let{class:F,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[E,L]=q;return Array.isArray(L)?L.includes({...f,...D}[E]):{...f,...D}[E]===L})?[...H,F,K]:H},[]);return fs0(A,I,Y,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as rCA}from"preact/jsx-dev-runtime";var Is0=Ew("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 dCA({variant:A,title:Q,children:B,className:w}){return rCA("div",{className:a1(Is0({variant:A}),w),role:"alert",children:[Q&&rCA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),rCA("div",{className:a1(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 vT2}from"preact/jsx-dev-runtime";var Ds0=Ew("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 xL({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return vT2("button",{type:f,className:a1(Ds0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as yT2}from"preact/jsx-dev-runtime";var Ys0=Ew("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 T5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return yT2("a",{href:A,className:a1(Ys0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as d0A}from"preact/jsx-dev-runtime";var Hs0=Ew("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"}}),xT2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function IP({variant:A,size:Q,className:B}){let w=xT2[Q??"md"];return d0A("button",{onclick:"toggleTheme()",type:"button",className:a1(Hs0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:d0A("svg",{className:a1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[d0A("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),d0A("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 nCA}from"preact/jsx-dev-runtime";var Xs0=Ew("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function n0A({items:A,className:Q,linkClassName:B="hover:text-accent transition-colors",orientation:w,children:$}){if(A.length===0&&!$)return null;let f=[...A].sort((I,D)=>I.priority-D.priority);return nCA("ul",{className:a1(Xs0({orientation:w}),Q),children:[f.map((I)=>nCA("li",{children:nCA("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 j1w}from"preact/jsx-dev-runtime";import{jsxDEV as y1w}from"preact/jsx-dev-runtime";import{createContext as Xi2,h as Wi2}from"preact";import{useContext as Ui2}from"preact/hooks";_JA();var qA1=Y1(NA1(),1),Yi2=new vx({gfm:!0,breaks:!0}),Hi2={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 ZRA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new vx({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):Yi2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2410
2410
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),qA1.default($,Hi2)}var LA1=Xi2(null);function MP({imageRenderer:A,children:Q}){return Wi2(LA1.Provider,{value:A??null},Q)}function EA1(){return Ui2(LA1)}function LG(){let A=EA1();return(Q)=>ZRA(Q,A?{imageRenderer:A}:void 0)}var Ji2=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,Gi2={"&":"&","<":"<",">":">",""":'"',"'":"'"},Fi2=/&(?:amp|lt|gt|quot|#39);/g;function Ki2(A){return A.replace(Fi2,(Q)=>Gi2[Q]??Q)}function zRA(A){return A.replace(Ji2,(Q,B)=>{return`<div class="mermaid">${Ki2(B)}</div>`})}var MA1=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function VA1(A){let Q={};for(let w of A.matchAll(MA1)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],Y=I[2];if(D&&Y!==void 0)Q[D]=Y}let f=$.replace(/([\w-]+)=["']([^"']*?)["']/g,"").trim();if(f)for(let I of f.matchAll(/(?:^|\s)([\w-]+)(?=\s|$)/g)){let D=I[1];if(D)Q[D]="true"}}let B=A.replace(MA1,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
2411
2411
|
|
|
2412
2412
|
`).trim();return{attributes:Q,markdown:B}}var Zi2=/<!--\s*\.break\s*-->/;function CA1(A){let Q=A.split(Zi2);return Q.length>1?Q:null}import{jsxDEV as EG}from"preact/jsx-dev-runtime";var NRA=({markdown:A})=>{let Q=LG(),w=A.split(/^---$/gm).map((I)=>I.trim()).map((I)=>{let{attributes:D,markdown:Y}=VA1(I),H=CA1(Y),W;if(H)W=`<div class="slide-columns">${H.map((K)=>`<div class="slide-column">${zRA(Q(K.trim()))}</div>`).join("")}</div>`;else W=zRA(Q(Y));return{attributes:D,htmlContent:W}}),$=w.some((I)=>I.htmlContent.includes('class="mermaid"')),f=w.map(({attributes:I,htmlContent:D},Y)=>EG("section",{...I,dangerouslySetInnerHTML:{__html:D}},Y,!1,void 0,this));return EG("section",{className:"presentation-section",children:[EG("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),EG("div",{className:"reveal",children:EG("div",{className:"slides",children:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),EG("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&EG("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),EG("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -3250,13 +3250,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
|
|
|
3250
3250
|
`+$:B,I=TW(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await e$.readFile(I,"utf-8"),Y=w.length>0?w:Q;if(Y.length>0){let H=Y.join(`
|
|
3251
3251
|
`)+`
|
|
3252
3252
|
|
|
3253
|
-
`+D;await e$.writeFile(I,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=TW(process.cwd(),"public");try{await e$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await e$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=TW(A,B.name),$=TW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await e$.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=TW(this.outputDir,$);await e$.mkdir(MwQ(f),{recursive:!0}),await e$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await e$.mkdir(Q,{recursive:!0});let B=await e$.readdir(A,{withFileTypes:!0});for(let w of B){let $=TW(A,w.name),f=TW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await e$.copyFile($,f)}}}function ePA(A){return new D$1(A)}V6();GA();GA();V6();var Y$1=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:zI,layouts:J.record(J.any()),themeCSS:J.string().optional()}),kIw=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 H$1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function X$1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}V6();Kf();V6();GA();var VwQ=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),CwQ=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function MQA(A,Q){let B=Q.urlGenerator??z9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((j)=>MQA(j,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,j])=>MQA(j,{...Q,urlGenerator:B})));for(let j=0;j<$.length;j++){let s=$[j];if(s)w[s[0]]=f[j]}let I=VwQ.safeParse(A);if(!I.success)return w;let D=I.data,Y=D.entityType,H=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[Y],F=W?W.label:Y.charAt(0).toUpperCase()+Y.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":FI(Y),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),E=uy(D),L=E?Q.imageBuildService?.get(E):void 0,b={};if(L)b={coverImageUrl:L.src,coverImageWidth:L.width,coverImageHeight:L.height,...L.srcset&&{coverImageSrcset:L.srcset,coverImageSizes:L.sizes}};else{let j=await OwQ(E,Q.pipelineContext.services.entityService);if(j)b={coverImageUrl:j.url,...j.width&&{coverImageWidth:j.width},...j.height&&{coverImageHeight:j.height}}}return{...w,...D,url:B.generateUrl(Y,H),typeLabel:F,listUrl:Z,listLabel:q,...b}}async function OwQ(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=CwQ.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 W$1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=uy(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:h0(w)})}return[...B]}async function U$1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,f=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},I=await w.pipelineContext.services.resolveTemplateContent($,f);if(!I)return null;return MQA(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:z9.getInstance()})}function J$1(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 U$1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return X$1(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 RwQ}from"path";async function G$1(A){let Q=A.parsedOptions.workingDir??RwQ(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 F$1(A){await new LQA({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay).generateEntityRoutes()}async function K$1(A){let Q=new qQA(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await W$1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function Z$1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function z$1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function N$1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function q$1(A){let Q=Y$1.parse(A.buildOptions),B=_$.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 F$1({pipelineContext:A.pipelineContext});let $=await G$1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=H$1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await K$1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=J$1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await Z$1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),z$1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),N$1({outputDir:Q.outputDir,errorMessage:f.message})}}class Y4{static instance=null;static defaultStaticSiteBuilderFactory=ePA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){Y4.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return Y4.instance??=new Y4(A,Y4.defaultStaticSiteBuilderFactory,Q,B,w,$),Y4.instance}static resetInstance(){Y4.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new Y4(A,$??Y4.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,z9.getInstance().configure(f)}async build(A,Q){return q$1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class AkA{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 nz(()=>{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})}}}V6();function bwQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function VQA(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?bwQ(w.sections,Q):[]})}function L$1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Qi.parse(w.payload),{routes:f,pluginId:I}=$;return VQA(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Bi.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=wi.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 $=$i.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 E$1}from"fs";import{join as M$1}from"path";async function PwQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=aPA(w,A.environment);await E$1.writeFile(M$1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=tPA($,w);await E$1.writeFile(M$1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function V$1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await PwQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}B0();GA();V6();var C$1=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:zI.optional()});V6();V6();async function Zu(A,Q){try{let B=await A({type:y_,payload:void 0});if("success"in B&&B.success&&B.data){let w=zI.safeParse(B.data);if(w.success)return zI.parse({...Q,...w.data})}}catch{}return Q}class QkA extends Pw{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:C$1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await Zu(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:Y},generateEntityUrl:(H,W)=>z9.getInstance().generateUrl(H,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}GA();V6();var kwQ=J.object({slot:J.enum(sz).optional().default("primary"),limit:J.number().optional()});class BkA{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=kwQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}V6();B0();GA();var jwQ=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function O$1(A,Q){return[YQ(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'.",jwQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();V6();var R$1=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:zI.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(az).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(sz).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 b$1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.80",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 wkA extends YB{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",b$1,{...A,layouts:Q},R$1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new EQA(A.logger),this._slotRegistry=new QQA,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new BkA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=z7.getInstance(A.entityService,A.logger),L$1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)VQA(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=Y4.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new QkA(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 AkA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(x_,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),V$1({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 O$1(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 Zu(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 Zu(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3253
|
+
`+D;await e$.writeFile(I,H,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=TW(process.cwd(),"public");try{await e$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await e$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=TW(A,B.name),$=TW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await e$.copyFile(w,$),this.logger.debug(`Copied static asset: ${B.name}`)}this.logger.debug("Static assets copied successfully")}async writeInlineStaticAssets(A){if(!A)return;let Q=Object.entries(A);if(Q.length===0)return;this.logger.debug(`Writing ${Q.length} inline static asset(s) from SitePackage`),await Promise.all(Q.map(async([B,w])=>{let $=B.startsWith("/")?B.slice(1):B,f=TW(this.outputDir,$);await e$.mkdir(MwQ(f),{recursive:!0}),await e$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await e$.mkdir(Q,{recursive:!0});let B=await e$.readdir(A,{withFileTypes:!0});for(let w of B){let $=TW(A,w.name),f=TW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await e$.copyFile($,f)}}}function ePA(A){return new D$1(A)}V6();GA();GA();V6();var Y$1=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:zI,layouts:J.record(J.any()),themeCSS:J.string().optional()}),kIw=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 H$1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function X$1(A,Q,B){let w=Q.getProfile(),$=B.getNavigationItems("primary"),f=B.getNavigationItems("secondary");return{...A,...w.socialLinks!==void 0&&{socialLinks:w.socialLinks},navigation:{primary:$,secondary:f},copyright:A.copyright??"Powered by Rizom"}}V6();Kf();V6();GA();var VwQ=J.object({id:J.string(),entityType:J.string(),content:J.string(),metadata:J.object({slug:J.string()}).passthrough()}).passthrough(),CwQ=J.object({content:J.string(),metadata:J.object({width:J.number().optional(),height:J.number().optional()}).passthrough()});async function MQA(A,Q){let B=Q.urlGenerator??z9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((j)=>MQA(j,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,j])=>MQA(j,{...Q,urlGenerator:B})));for(let j=0;j<$.length;j++){let s=$[j];if(s)w[s[0]]=f[j]}let I=VwQ.safeParse(A);if(!I.success)return w;let D=I.data,Y=D.entityType,H=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[Y],F=W?W.label:Y.charAt(0).toUpperCase()+Y.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":FI(Y),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),E=uy(D),L=E?Q.imageBuildService?.get(E):void 0,b={};if(L)b={coverImageUrl:L.src,coverImageWidth:L.width,coverImageHeight:L.height,...L.srcset&&{coverImageSrcset:L.srcset,coverImageSizes:L.sizes}};else{let j=await OwQ(E,Q.pipelineContext.services.entityService);if(j)b={coverImageUrl:j.url,...j.width&&{coverImageWidth:j.width},...j.height&&{coverImageHeight:j.height}}}return{...w,...D,url:B.generateUrl(Y,H),typeLabel:F,listUrl:Z,listLabel:q,...b}}async function OwQ(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=CwQ.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 W$1(A,Q){let B=new Set;try{let w=A.getEntityTypes();for(let $ of w){if($==="image")continue;let f=await A.listEntities({entityType:$});for(let I of f){let D=uy(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:h0(w)})}return[...B]}async function U$1(A,Q,B,w){if(!A.template)return A.content??null;let $=A.template,f=A.dataQuery?{dataParams:A.dataQuery,fallback:A.content,publishedOnly:B}:{savedContent:{entityType:"site-content",entityId:`${Q.id}:${A.id}`},fallback:A.content},I=await w.pipelineContext.services.resolveTemplateContent($,f);if(!I)return null;return MQA(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:z9.getInstance()})}function J$1(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 U$1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return X$1(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 RwQ}from"path";async function G$1(A){let Q=A.parsedOptions.workingDir??RwQ(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 F$1(A){await new LQA({logger:A.pipelineContext.logger.child("DynamicRouteGenerator"),entityService:A.pipelineContext.services.entityService,listViewTemplateNames:()=>A.pipelineContext.services.listViewTemplateNames()},A.pipelineContext.routeRegistry,A.pipelineContext.entityDisplay).generateEntityRoutes()}async function K$1(A){let Q=new qQA(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await W$1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function Z$1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function z$1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function N$1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function q$1(A){let Q=Y$1.parse(A.buildOptions),B=_$.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 F$1({pipelineContext:A.pipelineContext});let $=await G$1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=H$1(A.pipelineContext.routeRegistry);w.push(...f.warnings);let{routes:I}=f;await B?.report({message:`Building ${I.length} routes`,progress:20,total:100}),await B?.report({message:"Resolving images",progress:25,total:100});let D=await K$1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),Y=J$1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await Z$1({staticSiteBuilder:$,buildContext:Y,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),z$1({outputDir:Q.outputDir,routesBuilt:I.length,warnings:w})}catch($){let f=Error("Site build process failed");return A.pipelineContext.logger.error("Site build failed",{error:f,originalError:$}),N$1({outputDir:Q.outputDir,errorMessage:f.message})}}class Y4{static instance=null;static defaultStaticSiteBuilderFactory=ePA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){Y4.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return Y4.instance??=new Y4(A,Y4.defaultStaticSiteBuilderFactory,Q,B,w,$),Y4.instance}static resetInstance(){Y4.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new Y4(A,$??Y4.defaultStaticSiteBuilderFactory,Q,B,w,f)}constructor(A,Q,B,w,$,f){this.pipelineContext={logger:A,services:B,routeRegistry:w,profileService:$,entityDisplay:f},this.staticSiteBuilderFactory=Q,z9.getInstance().configure(f)}async build(A,Q){return q$1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class AkA{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 nz(()=>{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})}}}V6();function bwQ(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function VQA(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?bwQ(w.sections,Q):[]})}function L$1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=Qi.parse(w.payload),{routes:f,pluginId:I}=$;return VQA(f,I,Q),{success:!0}}catch($){return B.error("Failed to register routes",{error:$}),{success:!1,error:"Failed to register routes"}}}),A.messaging.subscribe("plugin:site-builder:route:unregister",async(w)=>{try{let $=Bi.parse(w.payload),{paths:f,pluginId:I}=$;if(f)for(let D of f)Q.unregister(D);else if(I)Q.unregisterByPlugin(I);return{success:!0}}catch($){return B.error("Failed to unregister routes",{error:$}),{success:!1,error:"Failed to unregister routes"}}}),A.messaging.subscribe("plugin:site-builder:route:list",async(w)=>{try{let $=wi.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 $=$i.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 E$1}from"fs";import{join as M$1}from"path";async function PwQ(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=aPA(w,A.environment);await E$1.writeFile(M$1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=tPA($,w);await E$1.writeFile(M$1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function V$1(A){let{context:Q,routeRegistry:B,logger:w}=A;Q.messaging.subscribe("site:build:completed",async($)=>{try{let f=$.payload;return w.info(`Received site:build:completed event for ${f.environment} environment - generating SEO files`),await PwQ(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}B0();GA();V6();var C$1=J.object({environment:J.enum(["preview","production"]).optional(),outputDir:J.string(),workingDir:J.string().optional(),enableContentGeneration:J.boolean().optional(),siteConfig:zI.optional()});V6();V6();async function Zu(A,Q){try{let B=await A({type:y_,payload:void 0});if("success"in B&&B.success&&B.data){let w=zI.safeParse(B.data);if(w.success)return zI.parse({...Q,...w.data})}}catch{}return Q}class QkA extends Pw{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:C$1,jobTypeName:"site-build"});this.sendMessage=Q;this.cfg=B}async process(A,Q,B){let w=A.environment??"preview",$=A.enableContentGeneration??!1;try{this.logger.debug("Starting site build job",{jobId:Q,environment:w,outputDir:A.outputDir}),await B.report({progress:0,total:100,message:`Starting site build for ${w} environment`});let f=B.createSub({scale:{start:10,end:90}}),I=await Zu(this.sendMessage,A.siteConfig??this.cfg.defaultSiteConfig),D=await this.cfg.siteBuilder.build({outputDir:A.outputDir,workingDir:A.workingDir,sharedImagesDir:this.cfg.sharedImagesDir,enableContentGeneration:$,environment:w,cleanBeforeBuild:!0,siteConfig:I,layouts:this.cfg.layouts,themeCSS:this.cfg.themeCSS,slots:this.cfg.slots,headScripts:this.cfg.getHeadScripts?.(),...this.cfg.staticAssets&&{staticAssets:this.cfg.staticAssets}},f.toCallback());if(await B.report({progress:100,total:100,message:`Site build completed: ${D.routesBuilt} routes built`}),this.logger.debug("Site build job completed",{jobId:Q,environment:w,routesBuilt:D.routesBuilt,success:D.success}),D.success){this.logger.info(`Emitting site:build:completed event for ${w} environment`);let Y=w==="preview"?this.cfg.previewUrl??this.cfg.siteUrl:this.cfg.siteUrl;await this.sendMessage({type:"site:build:completed",payload:{outputDir:A.outputDir,environment:w,routesBuilt:D.routesBuilt,siteConfig:{...I,url:Y},generateEntityUrl:(H,W)=>z9.getInstance().generateUrl(H,W)},broadcast:!0})}return{success:D.success,routesBuilt:D.routesBuilt,outputDir:A.outputDir,environment:w,...D.errors&&{errors:D.errors},...D.warnings&&{warnings:D.warnings}}}catch(f){throw this.logger.error("Site build job failed",f),f}}summarizeDataForLog(A){return{environment:A.environment,outputDir:A.outputDir}}}GA();V6();var kwQ=J.object({slot:J.enum(sz).optional().default("primary"),limit:J.number().optional()});class BkA{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=kwQ.parse(A??{});this.logger.debug("NavigationDataSource fetch called",{params:w});let $=this.routeRegistry.getNavigationItems(w.slot),f=w.limit?$.slice(0,w.limit):$,I=f.map((Y)=>({label:Y.label,href:Y.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}V6();B0();GA();var jwQ=J.object({environment:J.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function O$1(A,Q){return[YQ(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'.",jwQ,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();V6();var R$1=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:zI.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(az).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(sz).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 b$1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.81",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 wkA extends YB{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",b$1,{...A,layouts:Q},R$1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new EQA(A.logger),this._slotRegistry=new QQA,A.messaging.subscribe("plugin:site-builder:slot:register",async(B)=>{let{slotName:w,pluginId:$,render:f,priority:I}=B.payload;return this._slotRegistry?.register(w,{pluginId:$,render:f,...I!==void 0&&{priority:I}}),{success:!0}}),A.messaging.subscribe("plugin:site-builder:head-script:register",async(B)=>{let{pluginId:w,script:$}=B.payload;return this.headScripts.set(w,$),{success:!0}}),A.entities.registerDataSource(new BkA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=z7.getInstance(A.entityService,A.logger),L$1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)VQA(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=Y4.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new QkA(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 AkA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(x_,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),V$1({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 O$1(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 Zu(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 Zu(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3254
3254
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
3255
3255
|
`)}
|
|
3256
3256
|
|
|
3257
3257
|
## Site Builder Actions
|
|
3258
3258
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
3259
|
-
- 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(),Y4.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zE(A={}){return new wkA(A)}B0();V6();GA();B0();V6();var P$1=J.object({}),zu=w2.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:P$1}),$kA=Ii,Ak=zI.omit({url:!0,analyticsScript:!0});B0();class SW extends F2{constructor(){super({entityType:"site-info",schema:zu,frontmatterSchema:Ak,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Ak.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 mW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return mW.instance??=new mW(A,Q,B),mW.instance}static resetInstance(){mW.instance=null}static createFresh(A,Q,B){return new mW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new SW;let w=mW.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 vwQ=new SW;class CQA{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?vwQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var k$1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.
|
|
3259
|
+
- 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(),Y4.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function zE(A={}){return new wkA(A)}B0();V6();GA();B0();V6();var P$1=J.object({}),zu=w2.extend({id:J.literal("site-info"),entityType:J.literal("site-info"),metadata:P$1}),$kA=Ii,Ak=zI.omit({url:!0,analyticsScript:!0});B0();class SW extends F2{constructor(){super({entityType:"site-info",schema:zu,frontmatterSchema:Ak,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=Ak.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 mW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return mW.instance??=new mW(A,Q,B),mW.instance}static resetInstance(){mW.instance=null}static createFresh(A,Q,B){return new mW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new SW;let w=mW.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 vwQ=new SW;class CQA{logger;id="site-info:entities";name="Site Info DataSource";description="Provides site metadata (title, description, CTA) and profile social links";constructor(A){this.logger=A}async fetch(A,Q,B){let{entityService:w}=B,$;try{let D=await w.getEntity({entityType:"site-info",id:"site-info"});$=D?vwQ.parseSiteInfoBody(D.content):{title:"Brain",description:"A knowledge management system"}}catch{$={title:"Brain",description:"A knowledge management system"}}let f;try{let D=await w.getEntity({entityType:"anchor-profile",id:"anchor-profile"});if(D)f=D.metadata.socialLinks}catch{}let I={...$,socialLinks:f,copyright:$.copyright??"Powered by Rizom"};return this.logger.debug("SiteInfoDataSource returning",{title:I.title,hasSocialLinks:!!I.socialLinks}),Q.parse(I)}}var k$1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.81",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 xwQ=new SW;class fkA extends NQ{entityType="site-info";schema=zu;adapter=xwQ;defaultSiteInfo;constructor(A){super("site-info",k$1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new CQA(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=mW.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(y_,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:x_,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function NE(A){return new fkA(A)}var hwQ=new SW;async function Nu(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 hwQ.parseSiteInfoBody(B.content)}GA();var gwQ=Ak.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")});B0();uW();Eu();GA();var IkA=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)});B0();GA();x$();var mwQ=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()}),tDw=KI.extend({title:J.string().optional(),slug:J.string().optional()});class DkA extends E9{constructor(A,Q){super(A,Q,{schema:mwQ,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:Y,excerpt:H}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");Y=Y??`## Introduction
|
|
3260
3260
|
|
|
3261
3261
|
Add your introduction here.
|
|
3262
3262
|
|
|
@@ -3301,7 +3301,7 @@ The excerpt should be clear, concise, and compelling.`});GA();xw();uW();import{j
|
|
|
3301
3301
|
Note: This is part of a series called "${B.seriesName}".`:""}`;return A.ai.generate({prompt:w,templateName:"blog:generation"})}),A.eval.registerHandler("generateExcerpt",async(Q)=>{let B=Y8Q.parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3302
3302
|
|
|
3303
3303
|
Content:
|
|
3304
|
-
${B.content}`,templateName:"blog:excerpt"})})}var u$1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.
|
|
3304
|
+
${B.content}`,templateName:"blog:excerpt"})})}var u$1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.81",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/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 UkA extends NQ{entityType=qE.entityType;schema=Qk;adapter=qE;constructor(A={}){super("blog",u$1,A,IkA)}getEntityTypeConfig(){return{weight:2}}createGenerationHandler(A){return new DkA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return x$1()}getDataSources(){return[new HkA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (l$1(),p$1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await h$1(A,this.logger),g$1(A,this.logger),S$1(A,this.logger),m$1(A),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}}function JkA(A={}){return new UkA(A)}uW();Eu();B0();GA();GA();$$();hw();var OD=J.object({title:J.string(),slug:J.string(),coverImageId:J.string().optional()}),i$1=OD.pick({title:!0,slug:!0}),wk=w2.extend({metadata:i$1}),bQA=wk.extend({frontmatter:OD}),PQA=bQA.extend({description:J.string().optional(),postCount:J.number(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),r$1=J.object({description:J.string().optional()});function LE(A){return new yB(r$1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}hw();class GkA extends F2{constructor(){super({entityType:"series",schema:wk,frontmatterSchema:OD,supportsCoverImage:!0,bodyFormatter:LE("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,OD).coverImageId,B=LE(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=LE(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,OD);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,OD);return LE(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var $k=new GkA;B0();GA();c4();class FkA{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",options:{limit:1000}}),B=new Map(Q.map(($)=>[$.id,$])),w=new Set;for(let $ of A){let f=D2($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),Y=RB(D);if(I?.contentHash===Y)continue;let H={id:f,entityType:"series",content:D,contentHash:Y,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:$,slug:D2($)}};await this.entityService.upsertEntity({entity:H}),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=this.getSeriesName(A);if(B)await this.ensureSeriesExists(B);if(Q&&Q!==B)await this.cleanupOrphanedSeries(Q)}async handleEntityDeleted(){await this.syncAllSeries()}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}async ensureSeriesExists(A){let Q=D2(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:RB(w),created:new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:A,slug:D2(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=D2(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,options:{limit:1000}});for(let $ of w){let f=this.getSeriesName($);if(f)A.add(f)}}return A}createSeriesContent(A){let Q={title:A,slug:D2(A)};return q9("",Q)}}B0();GA();var W8Q=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()}),U8Q=J.object({type:J.enum(["list","detail"]),seriesName:J.string().optional()});function J8Q(A){let Q=U8Q.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=W8Q.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 d$1(A){let Q=AQ(A.content,OD);return bQA.parse({...A,frontmatter:Q.metadata})}class KkA{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=J8Q(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",options:{limit:1000}}),w=await this.countEntitiesPerSeries(Q),$=B.map((f)=>{let I=d$1(f),D=$k.parseBody(f.content);return{...I,description:D.description,postCount:w.get(f.metadata.title)??0}});return this.logger.debug(`Found ${$.length} series entities`),A.parse({series:$})}async fetchSeriesDetail(A,Q,B,w){if(!w)w=(await B.listEntities({entityType:"series",options:{filter:{metadata:{title:A}}}}))[0];if(!w)throw Error(`Series not found: ${A}`);let $=d$1(w),f=$k.parseBody(w.content),I=await this.getSeriesMembers(A,B);return this.logger.debug(`Found ${I.length} entities in series "${A}"`),Q.parse({seriesName:A,posts:I,series:{...$,description:f.description,postCount:I.length},description:f.description})}async fetchSeriesDetailBySlug(A,Q,B){let $=(await B.listEntities({entityType:"series",options:{filter:{metadata:{slug:A}}}}))[0];if(!$)return this.logger.warn(`Series not found with slug: ${A}`),Q.parse({seriesName:A,posts:[]});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,options:{limit:1000}});for(let f of $){let I=this.getSeriesName(f);if(I)Q.set(I,(Q.get(I)??0)+1)}}return Q}async getSeriesMembers(A,Q){let B=[],w=Q.getEntityTypes();for(let $ of w){if($==="series")continue;let f=await Q.listEntities({entityType:$,options:{filter:{metadata:{seriesName:A}}}});B.push(...f)}return B.sort(($,f)=>{let I=$.metadata.seriesIndex,D=f.metadata.seriesIndex;return(typeof I==="number"?I:999)-(typeof D==="number"?D:999)}),B}getSeriesName(A){let B=A.metadata.seriesName;return typeof B==="string"?B:void 0}}B0();GA();c4();var G8Q=J.object({prompt:J.string().optional(),title:J.string().optional(),seriesId:J.string().optional()});class kQA{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}
|
|
3305
3305
|
|
|
3306
3306
|
Content in this series:
|
|
3307
3307
|
${w.join(`
|
|
@@ -3313,7 +3313,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
3313
3313
|
3. Is engaging and makes readers want to explore the content
|
|
3314
3314
|
4. Works well as a series overview on a website
|
|
3315
3315
|
|
|
3316
|
-
Be concise and focus on what makes this series unique and valuable.`});var A91={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
3316
|
+
Be concise and focus on what makes this series unique and valuable.`});var A91={name:"@brains/series",private:!0,version:"0.2.0-alpha.81",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/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 Q91=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()})]);class ZkA extends NQ{entityType="series";schema=wk;adapter=$k;manager;constructor(){super("series",A91)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new kQA(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...t$1(),description:e$1}}getDataSources(){return[new KkA(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||!this.hasSeriesName(Q.entity))return null;let B=Q.entity.metadata.seriesName;return{mode:"source",entityId:Q.entity.id,entityType:Q.entity.entityType,seriesName:B}},jobOptions:(Q)=>{if(!Q.entity||!this.hasSeriesName(Q.entity))return;return this.getSourceProjectionJobOptions(Q.entity)}}}]}async onRegister(A){this.manager=new FkA(A.entityService,this.logger.child("SeriesManager"))}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=Q91.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);else await this.requireManager().cleanupOrphanedSeries(B.seriesName);return{success:!0}},validateAndParse:(Q)=>{let B=Q91.safeParse(Q??{});return B.success?B.data:null}}}requireManager(){if(!this.manager)throw Error("SeriesPlugin not registered");return this.manager}hasSeriesName(A){return typeof A.metadata.seriesName==="string"}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){await this.requireManager().handleEntityChange(A)}async projectAll(A){await this.requireManager().syncAllSeries();let Q=new kQA(this.logger.child("SeriesGenerationHandler"),A),B=await A.entityService.listEntities({entityType:"series",options:{limit:1000}});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 zkA(){return new ZkA}B0();GA();B0();GA();GA();B0();var N8Q=J.enum(["draft","queued","published"]),B91="publishedAt is required when deck status is published",w91=(A)=>A.status==="published"&&!A.publishedAt,NkA=(A)=>{if(w91(A))throw Error(B91)},V3=J.object({title:J.string(),slug:J.string().optional(),description:J.string().optional(),author:J.string().optional(),status:N8Q,publishedAt:J.string().datetime().optional(),event:J.string().optional(),coverImageId:J.string().optional()}),q8Q=V3.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:J.string()}).superRefine((A,Q)=>{if(!w91(A))return;Q.addIssue({code:J.ZodIssueCode.custom,path:["publishedAt"],message:B91})}),jQA=w2.extend({entityType:J.literal("deck"),metadata:q8Q}),_QA=jQA.extend({frontmatter:V3,body:J.string()}),Ou=_QA.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});class qkA extends F2{constructor(){super({entityType:"deck",schema:jQA,frontmatterSchema:V3,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,V3);NkA(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);NkA(Q),this.validateSlideStructure(B);let w=Q.slug??D2(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)}}var Ru=new qkA;GA();xw();var L8Q=J.object({markdown:J.string().describe("Markdown content with slide separators (---)")}),LkA=b1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:L8Q,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:NRA,fullscreen:!0}});xw();GA();var EkA=J.object({decks:J.array(_QA)}),MkA=J.object({decks:J.array(Ou),pageTitle:J.string().optional(),pageLabel:J.string().optional()});import{jsxDEV as VkA}from"preact/jsx-dev-runtime";var E8Q="Presentations",CkA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return VkA("div",{className:"deck-list bg-theme",children:VkA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:VkA(Em,{label:Q&&Q!=="Decks"?Q:E8Q,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};$$();class vQA extends yB{constructor(){super(EkA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var OkA=b1({name:"deck-list",description:"List view of all presentation decks",schema:MkA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new vQA,layout:{component:CkA}});GA();B0();var M8Q=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")}),$91=b1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:M8Q,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
3317
3317
|
|
|
3318
3318
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
3319
3319
|
|
|
@@ -3608,12 +3608,12 @@ ${D}`,templateName:"decks:description"})).description,await this.reportProgress(
|
|
|
3608
3608
|
font-weight: 600;
|
|
3609
3609
|
}
|
|
3610
3610
|
`}},void 0,!1,void 0,this),$.map((H,W)=>p9("section",{className:`deck-carousel-slide${W===0?" is-cover":""}`,children:[p9("header",{className:"deck-carousel-header",children:p9("span",{className:"deck-carousel-wordmark","aria-label":B??Q,children:[p9("span",{className:"wm-primary",children:f.primary},void 0,!1,void 0,this),f.secondary!==void 0&&p9(k8Q,{children:[p9("span",{className:"wm-dot",children:"."},void 0,!1,void 0,this),p9("span",{className:"wm-secondary",children:f.secondary},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p9("div",{className:"deck-carousel-body",children:p9("div",{className:"deck-carousel-content",dangerouslySetInnerHTML:{__html:Y(H.markdown)}},void 0,!1,void 0,this)},void 0,!1,void 0,this),p9("footer",{className:"deck-carousel-footer",children:[p9("span",{className:"deck-carousel-footer-meta",children:w??Q},void 0,!1,void 0,this),p9("span",{className:"deck-carousel-counter","aria-label":`Slide ${W+1} of ${I}`,children:[p9("span",{className:"deck-carousel-counter-current",children:String(W+1).padStart(2,"0")},void 0,!1,void 0,this)," / ",p9("span",{children:D},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},W,!0,void 0,this))]},void 0,!0,void 0,this)}import{mkdtemp as e8Q,rm as A6Q}from"fs/promises";import{tmpdir as Q6Q}from"os";import{join as B6Q}from"path";class fk extends Error{code;constructor(A,Q){super(A);this.code=Q;this.name="MediaRenderError"}}function H91(A={}){return{async launch(){try{return await(await import("playwright-core")).chromium.launch({headless:!0,...A})}catch(Q){throw new fk(`Failed to launch Chromium for media rendering: ${y8Q(Q)}`,"browser-launch-failed")}}}}async function Pu(A,Q={}){return j8Q(Q.browserFactory??H91(),Q.timeoutMs??30000,async(B)=>{let w=await B.newPage();try{await w.goto(A,{waitUntil:Q.waitUntil??"networkidle",timeout:Q.timeoutMs??30000});let $={...Q.width!==void 0&&{width:Q.width},...Q.height!==void 0&&{height:Q.height},...Q.format!==void 0&&{format:Q.format},printBackground:Q.printBackground??!0,preferCSSPageSize:Q.preferCSSPageSize??!0,...Q.margin!==void 0&&{margin:Q.margin}},f=await w.pdf($),I=Buffer.from(f);if(v8Q(I),Q.maxBytes!==void 0&&I.length>Q.maxBytes)throw new fk(`Rendered PDF is ${I.length} bytes, exceeding maxBytes=${Q.maxBytes}`,"output-too-large");return I}finally{await _8Q(w)}})}async function j8Q(A,Q,B){let w,$=!1,f={browser:null},I=(H)=>{H.close().catch(()=>{try{H.process?.()?.kill("SIGKILL")}catch{}})},D=new Promise((H,W)=>{w=setTimeout(()=>{if($=!0,f.browser)I(f.browser);W(new fk(`Media render timed out after ${Q}ms`,"render-timeout"))},Q)}),Y=A.launch().then((H)=>{if(f.browser=H,$)I(H);return H});try{let H=await Promise.race([Y,D]);try{return await Promise.race([B(H),D])}finally{if(!$)try{await H.close()}catch{try{H.process?.()?.kill("SIGKILL")}catch{}}}}finally{if(w)clearTimeout(w)}}async function _8Q(A){await A.close?.().catch(()=>{return})}function v8Q(A){if(A.subarray(0,4).toString("ascii")!=="%PDF")throw new fk("Rendered output was not a PDF","invalid-output")}function y8Q(A){return A instanceof Error?A.message:String(A)}import{h as PkA}from"preact";import{render as x8Q}from"preact-render-to-string";GA();function kkA(A){let Q=h8Q(A.template,A.format),B=J.record(J.unknown()).parse(A.content),w=J.record(J.unknown()).parse(A.template.schema.parse(B)),$=new cP(A.siteConfig.title),f=g8Q(A.imageBuildService),I=PkA(PP,{headCollector:$,children:PkA(MP,{imageRenderer:f,children:PkA(Q,w)})}),D=x8Q(I);if(!$.getHeadProps())$.setHeadProps({title:A.siteConfig.title});let Y=T8Q($.generateHeadHTML(),A.noindex??!0);return Xu(D,Y,A.siteConfig.title,A.siteConfig.themeMode)}function h8Q(A,Q){let B=A.renderers[Q];if(!B||typeof B!=="function")throw Error(`No ${Q} renderer for template: ${A.name}`);return B}function g8Q(A){return A?.createImageRenderer()??null}function T8Q(A,Q){if(!Q)return A;return`${A}
|
|
3611
|
-
<meta name="robots" content="noindex,nofollow">`}import{createServer as S8Q}from"http";import{lstat as X91,mkdir as U91,readFile as m8Q,writeFile as J91}from"fs/promises";import{dirname as u8Q,extname as c8Q,join as jkA,posix as p8Q,resolve as yQA,sep as W91}from"path";async function vkA(A){let Q=i8Q(A.mediaPath),B=r8Q(A.outputDir,Q),w=kkA({template:A.template,format:A.format,content:A.content,siteConfig:A.siteConfig,imageBuildService:A.imageBuildService});return await U91(u8Q(B),{recursive:!0}),await J91(B,w,"utf-8"),await l8Q(A.outputDir,A.themeCSS),{urlPath:Q,filePath:B}}async function l8Q(A,Q){let B=jkA(A,"styles");await U91(B,{recursive:!0}),await J91(jkA(B,"main.css"),Q,"utf-8")}async function ykA(A){let Q=yQA(A.rootDir),B=A.host??"127.0.0.1",w=S8Q(async(I,D)=>{try{let Y=new URL(I.url??"/",`http://${B}`),H=decodeURIComponent(Y.pathname);if(d8Q(H)){D.writeHead(403),D.end("Forbidden");return}let W=H.startsWith("/")?H.slice(1):H,F=yQA(Q,W);if(!_kA(Q,F)){D.writeHead(403),D.end("Forbidden");return}let K=await n8Q(F);if(!K||!_kA(Q,K)){D.writeHead(404),D.end("Not found");return}let Z=await m8Q(K);D.writeHead(200,{"content-type":o8Q(K)}),D.end(Z)}catch{D.writeHead(404),D.end("Not found")}});await s8Q(w,B);let $=a8Q(w),f=`http://${B}:${$}`;return{baseUrl:f,urlFor:(I)=>`${f}${I.startsWith("/")?I:`/${I}`}`,close:()=>t8Q(w)}}function i8Q(A){if(!A.startsWith("/_media/"))throw Error("Media render paths must start with /_media/");if(A.split("/").filter(Boolean).some((w)=>w===".."))throw Error("Media render path cannot contain traversal");let B=p8Q.normalize(A);if(!B.startsWith("/_media/"))throw Error("Media render path cannot contain traversal");return B.endsWith("/")?B:`${B}/`}function r8Q(A,Q){let B=yQA(A),w=Q.slice(1),$=yQA(B,w,"index.html");if(!_kA(B,$))throw Error("Media render path cannot contain traversal");return $}function d8Q(A){return A.split("/").some((Q)=>Q==="..")}function _kA(A,Q){let B=A.endsWith(W91)?A:`${A}${W91}`;return Q===A||Q.startsWith(B)}async function n8Q(A){try{let Q=await X91(A);if(Q.isSymbolicLink())return null;if(Q.isDirectory()){let B=jkA(A,"index.html"),w=await X91(B).catch(()=>null);if(!w||w.isSymbolicLink())return null;return w.isFile()?B:null}if(Q.isFile())return A;return null}catch{return null}}function o8Q(A){switch(c8Q(A).toLowerCase()){case".css":return"text/css; charset=utf-8";case".html":return"text/html; charset=utf-8";case".js":return"application/javascript; charset=utf-8";case".json":return"application/json";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".svg":return"image/svg+xml";case".webp":return"image/webp";default:return"application/octet-stream"}}async function s8Q(A,Q){await new Promise((B,w)=>{let $=(I)=>{A.off("listening",f),w(I)},f=()=>{A.off("error",$),B()};A.once("error",$),A.once("listening",f),A.listen(0,Q)})}function a8Q(A){let Q=A.address();if(typeof Q!=="object"||Q===null)throw Error("Static render server did not bind to a TCP port");return Q.port}async function t8Q(A){await new Promise((Q,B)=>{A.close((w)=>{if(w){B(w);return}Q()})})}GA();var w6Q=26214400,$6Q=60000,G91=20;class xkA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Pu,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=f6Q(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>G91)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${G91}`);let w=await this.getThemeMode(),$=await e8Q(B6Q(Q6Q(),"brain-deck-carousel-"));try{let f=await vkA({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:Y91,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ykA({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:w6Q,timeoutMs:$6Q,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${I6Q(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await A6Q($,{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 f6Q(A,Q={}){let{frontmatter:B,content:w}=y4(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function I6Q(A){let Q=A.metadata.slug;return Q.length>0?Q:D2(A.metadata.title)}var F91={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
3611
|
+
<meta name="robots" content="noindex,nofollow">`}import{createServer as S8Q}from"http";import{lstat as X91,mkdir as U91,readFile as m8Q,writeFile as J91}from"fs/promises";import{dirname as u8Q,extname as c8Q,join as jkA,posix as p8Q,resolve as yQA,sep as W91}from"path";async function vkA(A){let Q=i8Q(A.mediaPath),B=r8Q(A.outputDir,Q),w=kkA({template:A.template,format:A.format,content:A.content,siteConfig:A.siteConfig,imageBuildService:A.imageBuildService});return await U91(u8Q(B),{recursive:!0}),await J91(B,w,"utf-8"),await l8Q(A.outputDir,A.themeCSS),{urlPath:Q,filePath:B}}async function l8Q(A,Q){let B=jkA(A,"styles");await U91(B,{recursive:!0}),await J91(jkA(B,"main.css"),Q,"utf-8")}async function ykA(A){let Q=yQA(A.rootDir),B=A.host??"127.0.0.1",w=S8Q(async(I,D)=>{try{let Y=new URL(I.url??"/",`http://${B}`),H=decodeURIComponent(Y.pathname);if(d8Q(H)){D.writeHead(403),D.end("Forbidden");return}let W=H.startsWith("/")?H.slice(1):H,F=yQA(Q,W);if(!_kA(Q,F)){D.writeHead(403),D.end("Forbidden");return}let K=await n8Q(F);if(!K||!_kA(Q,K)){D.writeHead(404),D.end("Not found");return}let Z=await m8Q(K);D.writeHead(200,{"content-type":o8Q(K)}),D.end(Z)}catch{D.writeHead(404),D.end("Not found")}});await s8Q(w,B);let $=a8Q(w),f=`http://${B}:${$}`;return{baseUrl:f,urlFor:(I)=>`${f}${I.startsWith("/")?I:`/${I}`}`,close:()=>t8Q(w)}}function i8Q(A){if(!A.startsWith("/_media/"))throw Error("Media render paths must start with /_media/");if(A.split("/").filter(Boolean).some((w)=>w===".."))throw Error("Media render path cannot contain traversal");let B=p8Q.normalize(A);if(!B.startsWith("/_media/"))throw Error("Media render path cannot contain traversal");return B.endsWith("/")?B:`${B}/`}function r8Q(A,Q){let B=yQA(A),w=Q.slice(1),$=yQA(B,w,"index.html");if(!_kA(B,$))throw Error("Media render path cannot contain traversal");return $}function d8Q(A){return A.split("/").some((Q)=>Q==="..")}function _kA(A,Q){let B=A.endsWith(W91)?A:`${A}${W91}`;return Q===A||Q.startsWith(B)}async function n8Q(A){try{let Q=await X91(A);if(Q.isSymbolicLink())return null;if(Q.isDirectory()){let B=jkA(A,"index.html"),w=await X91(B).catch(()=>null);if(!w||w.isSymbolicLink())return null;return w.isFile()?B:null}if(Q.isFile())return A;return null}catch{return null}}function o8Q(A){switch(c8Q(A).toLowerCase()){case".css":return"text/css; charset=utf-8";case".html":return"text/html; charset=utf-8";case".js":return"application/javascript; charset=utf-8";case".json":return"application/json";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".svg":return"image/svg+xml";case".webp":return"image/webp";default:return"application/octet-stream"}}async function s8Q(A,Q){await new Promise((B,w)=>{let $=(I)=>{A.off("listening",f),w(I)},f=()=>{A.off("error",$),B()};A.once("error",$),A.once("listening",f),A.listen(0,Q)})}function a8Q(A){let Q=A.address();if(typeof Q!=="object"||Q===null)throw Error("Static render server did not bind to a TCP port");return Q.port}async function t8Q(A){await new Promise((Q,B)=>{A.close((w)=>{if(w){B(w);return}Q()})})}GA();var w6Q=26214400,$6Q=60000,G91=20;class xkA{context;renderPdf;getThemeMode;constructor(A,Q={}){this.context=A;this.renderPdf=Q.renderPdf??Pu,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=f6Q(Q,{brandLabel:this.resolveBrandLabel()});if(B.slides.length>G91)throw Error(`Refusing to render carousel with ${B.slides.length} slides; maxSlides=${G91}`);let w=await this.getThemeMode(),$=await e8Q(B6Q(Q6Q(),"brain-deck-carousel-"));try{let f=await vkA({outputDir:$,mediaPath:`/_media/carousel/${Q.id}`,template:Y91,format:"pdf",content:B,siteConfig:{title:B.title,themeMode:w},themeCSS:this.context.themeCSS}),I=await ykA({rootDir:$});try{return{type:"document",data:await this.renderPdf(I.urlFor(f.urlPath),{maxBytes:w6Q,timeoutMs:$6Q,printBackground:!0,preferCSSPageSize:!0}),mimeType:"application/pdf",filename:`${I6Q(Q)}-carousel.pdf`}}finally{await I.close()}}finally{await A6Q($,{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 f6Q(A,Q={}){let{frontmatter:B,content:w}=y4(A.content),$=typeof B.title==="string"?B.title:A.metadata.title,f=typeof B.event==="string"&&B.event.length>0?B.event:void 0,I=w.split(/^---$/gm).map((D)=>D.trim()).filter((D)=>D.length>0).map((D)=>({markdown:D}));return{title:$,slides:I,...Q.brandLabel?{brandLabel:Q.brandLabel}:{},...f?{eyebrow:f}:{}}}function I6Q(A){let Q=A.metadata.slug;return Q.length>0?Q:D2(A.metadata.title)}var F91={name:"@brains/decks",private:!0,version:"0.2.0-alpha.81",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/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 hkA extends NQ{deps;entityType=Ru.entityType;schema=Ru.schema;adapter=Ru;unregisterCarouselAttachmentProvider;constructor(A={}){super("decks",F91);this.deps=A}createGenerationHandler(A){return new bkA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":LkA,"deck-list":OkA,generation:$91,description:f91}}getDataSources(){return[new RkA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.registerCarouselAttachmentProvider(A),this.registerEvalHandlers(A),this.logger.info("Decks plugin registered")}async onShutdown(){this.unregisterCarouselAttachmentProvider?.(),this.unregisterCarouselAttachmentProvider=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 f=new Date().toISOString(),I={...$,metadata:{...$.metadata,status:"published",publishedAt:f}};await A.entityService.updateEntity({entity:{...I,content:this.adapter.toMarkdown(I)}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,result:{id:w}}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:h0($)}})}return{success:!0}})}registerCarouselAttachmentProvider(A){let Q={...this.deps,getThemeMode:this.deps.getThemeMode??(async()=>{try{return(await Nu(A.entityService)).themeMode??"dark"}catch{return"dark"}})};this.unregisterCarouselAttachmentProvider=A.attachments.register("deck",I91,new xkA(A,Q))}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?`
|
|
3612
3612
|
|
|
3613
3613
|
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}
|
|
3614
3614
|
|
|
3615
3615
|
Content:
|
|
3616
|
-
${B.content}`,templateName:"decks:description"})})}}function ku(){return new hkA}B0();GA();GA();hw();var gkA=J.literal("application/pdf"),TkA=J.object({title:J.string().optional(),mimeType:gkA,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()}),Ik=w2.extend({entityType:J.literal("document"),content:J.string().regex(/^data:application\/pdf;base64,.+$/),metadata:TkA});function ju(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 xQA(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function SkA(A){let Q=Buffer.from(A).toString("latin1"),B=0,w=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(w)){let I=parseInt(f[1]??f[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class hQA{entityType="document";schema=Ik;toMarkdown(A){return A.content}fromMarkdown(A){return ju(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}=ju(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var EE=new hQA;B0();GA();var H6Q=26214400,X6Q=20,W6Q=60000,gQA=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(),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()}),TQA=gQA.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 SQA extends Pw{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:TQA,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??Pu}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??X6Q,$=A.maxBytes??H6Q,f=A.timeoutMs??W6Q;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=U6Q(A),D=await this.findDocumentByDedupKey(I);if(D)return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:D.id,reused:!0};await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,{timeoutMs:f,maxBytes:$}),H=Y.data;if(H.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${H.byteLength} bytes`);let W=SkA(H);if(W>w)throw Error(`Rendered PDF has ${W} pages, exceeding maxPageCount=${w}`);let F=W>0?W:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let K=K91(A,Q),Z=A.filename??(A.renderUrl===void 0?Y.filename:`${K}.pdf`),q=EE.createDocumentEntity({dataUrl:xQA(H),filename:Z,...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:K}))await this.context.entityService.deleteEntity({entityType:"document",id:K});if(await this.context.entityService.createEntity({entity:{...q,id:K}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,K);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:K,reused:!1}}catch(Y){throw this.logger.error("Document generation failed",{jobId:Q,error:h0(Y)}),Y}}async resolveDocumentAttachment(A,Q){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:Q.timeoutMs,maxBytes:Q.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??`${K91(A,"document")}.pdf`};let B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);return B}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){let w=await this.context.entityService.getEntity({entityType:A,id:Q});if(!w)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:$}=y4(w.content),f=Array.isArray($.documents)?$.documents.filter(J6Q):[],I=f.some((D)=>D.id===B)?f:[...f,{id:B}];await this.context.entityService.updateEntity({entity:{...w,content:aM(w.content,"documents",I)}})}}function U6Q(A){return A.dedupKey??`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`}function K91(A,Q){let B=A.documentId??A.filename?.replace(/\.pdf$/i,"")??`${A.attachmentType}-${A.sourceEntityType}-${A.sourceEntityId}-${Q}`;return D2(B)}function J6Q(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}B0();function mkA(A,Q){return[YQ(A,"generate","Generate a durable PDF document entity from a source attachment or render URL, with optional target documents[] attachment.",gQA,async(B,w)=>{let $=TQA.safeParse(B);if(!$.success)return T8($.error.message);let f=await Q($.data,w);return bw({jobId:f})},{cli:{name:"document-generate"}})]}var Z91={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.80",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 F6Q=J.object({});class ukA extends YB{entityType=EE.entityType;schema=Ik;adapter=EE;pluginContext;constructor(){super("document",Z91,{},F6Q)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.jobs.registerHandler("generate",new SQA(this.logger.child("DocumentGenerationJobHandler"),A))}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return mkA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function ckA(){return new ukA}B0();GA();B0();GA();import{writeFile as K6Q}from"fs/promises";import{tmpdir as Z6Q}from"os";import{join as z6Q}from"path";var N6Q=J.object({entityType:J.string().describe("Source entity type (e.g. 'deck')"),entityId:J.string().describe("Source entity ID"),attachmentType:J.string().describe("Attachment type (e.g. 'carousel')"),outputDir:J.string().optional().describe("Directory to write the file into (defaults to the OS temp dir)")});function z91(A,Q){return[YQ(A,"preview-attachment","Resolve a registered attachment provider and write the resulting media to a file for local preview.",N6Q,async(B)=>{if(!Q.attachments.hasProvider(B.entityType,B.attachmentType))return T8(`No attachment provider registered for ${B.entityType}/${B.attachmentType}`);try{let w=await Q.attachments.resolve({sourceEntityType:B.entityType,sourceEntityId:B.entityId,attachmentType:B.attachmentType});if(!w)return T8(`Provider for ${B.entityType}/${B.attachmentType} did not produce media for ${B.entityId}`);let $=B.outputDir??Z6Q(),f=z6Q($,w.filename);return await K6Q(f,w.data),bw({path:f,mimeType:w.mimeType,bytes:w.data.length},`Wrote ${w.data.length} bytes to ${f}`)}catch(w){return T8(h0(w))}})]}var N91={name:"@brains/media-tools",private:!0,version:"0.2.0-alpha.80",description:"Dev tools around the attachment registry \u2014 preview, inspect, regenerate media",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 L6Q=J.object({});class pkA extends YB{pluginContext;constructor(A={}){super("media-tools",N91,A,L6Q)}async onRegister(A){this.pluginContext=A}async getTools(){if(!this.pluginContext)throw Error("Plugin context not initialized");return z91(this.id,this.pluginContext)}}function lkA(A={}){return new pkA(A)}B0();GA();GA();B0();var C3=J.object({title:J.string().optional()}),q91=C3.pick({title:!0}).required(),Dk=w2.extend({entityType:J.literal("base"),metadata:q91}),E6Q=Dk.extend({frontmatter:C3,body:J.string()});B0();GA();class ikA extends F2{constructor(){super({entityType:"base",schema:Dk,frontmatterSchema:C3})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,C3);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.extractTitle(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:Q}}}parseNoteFrontmatter(A){try{return this.parseFrontMatter(A.content,C3)}catch{return{}}}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}}extractTitle(A){try{let B=this.parseFrontMatter(A,C3);if(B.title)return B.title}catch{}let Q=A.match(/^#\s+(.+)$/m);if(Q?.[1])return Q[1].trim();return null}}var Yk=new ikA;GA();var rkA=J.object({defaultPrompt:J.string().default("Create a note summarizing key concepts from my knowledge base")});GA();B0();var L91=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")}),dkA=b1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:L91,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
3616
|
+
${B.content}`,templateName:"decks:description"})})}}function ku(){return new hkA}B0();GA();GA();hw();var gkA=J.literal("application/pdf"),TkA=J.object({title:J.string().optional(),mimeType:gkA,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()}),Ik=w2.extend({entityType:J.literal("document"),content:J.string().regex(/^data:application\/pdf;base64,.+$/),metadata:TkA});function ju(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 xQA(A){return`data:application/pdf;base64,${Buffer.from(A).toString("base64")}`}function SkA(A){let Q=Buffer.from(A).toString("latin1"),B=0,w=/\/Type\s*\/Pages\b[^]*?\/Count\s+(\d+)|\/Count\s+(\d+)[^]*?\/Type\s*\/Pages\b/g;for(let f of Q.matchAll(w)){let I=parseInt(f[1]??f[2]??"0",10);if(I>B)B=I}if(B>0)return B;return Q.match(/\/Type\s*\/Page(?!\w)/g)?.length??0}class hQA{entityType="document";schema=Ik;toMarkdown(A){return A.content}fromMarkdown(A){return ju(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}=ju(Q);return{entityType:"document",content:Q,metadata:{mimeType:w,...B}}}}var EE=new hQA;B0();GA();var H6Q=26214400,X6Q=20,W6Q=60000,gQA=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(),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()}),TQA=gQA.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 SQA extends Pw{context;renderPdf;constructor(A,Q,B={}){super(A,{schema:TQA,jobTypeName:"document-generate"});this.context=Q;this.renderPdf=B.renderPdf??Pu}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??X6Q,$=A.maxBytes??H6Q,f=A.timeoutMs??W6Q;if(A.pageCount!==void 0&&A.pageCount>w)throw Error(`Refusing to render ${A.pageCount} page PDF; maxPageCount=${w}`);let I=U6Q(A),D=await this.findDocumentByDedupKey(I);if(D)return await this.reportProgress(B,{progress:100,message:"Reusing existing generated document"}),{success:!0,documentId:D.id,reused:!0};await this.reportProgress(B,{progress:20,message:"Rendering PDF document"});try{let Y=await this.resolveDocumentAttachment(A,{timeoutMs:f,maxBytes:$}),H=Y.data;if(H.byteLength>$)throw Error(`Rendered PDF exceeds maxBytes=${$}: ${H.byteLength} bytes`);let W=SkA(H);if(W>w)throw Error(`Rendered PDF has ${W} pages, exceeding maxPageCount=${w}`);let F=W>0?W:A.pageCount;await this.reportProgress(B,{progress:70,message:"Storing PDF document"});let K=K91(A,Q),Z=A.filename??(A.renderUrl===void 0?Y.filename:`${K}.pdf`),q=EE.createDocumentEntity({dataUrl:xQA(H),filename:Z,...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:K}))await this.context.entityService.deleteEntity({entityType:"document",id:K});if(await this.context.entityService.createEntity({entity:{...q,id:K}}),A.targetEntityType&&A.targetEntityId)await this.attachDocumentToTarget(A.targetEntityType,A.targetEntityId,K);return await this.reportProgress(B,{progress:100,message:"PDF document generation complete"}),{success:!0,documentId:K,reused:!1}}catch(Y){throw this.logger.error("Document generation failed",{jobId:Q,error:h0(Y)}),Y}}async resolveDocumentAttachment(A,Q){if(A.renderUrl!==void 0)return{type:"document",data:await this.renderPdf(A.renderUrl,{timeoutMs:Q.timeoutMs,maxBytes:Q.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??`${K91(A,"document")}.pdf`};let B=await this.context.attachments.resolve({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:A.attachmentType});if(!B)throw Error(`No attachment provider found for ${A.sourceEntityType}/${A.attachmentType}`);return B}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){let w=await this.context.entityService.getEntity({entityType:A,id:Q});if(!w)throw Error(`Target entity not found: ${A}/${Q}`);let{frontmatter:$}=y4(w.content),f=Array.isArray($.documents)?$.documents.filter(J6Q):[],I=f.some((D)=>D.id===B)?f:[...f,{id:B}];await this.context.entityService.updateEntity({entity:{...w,content:aM(w.content,"documents",I)}})}}function U6Q(A){return A.dedupKey??`${A.attachmentType}:${A.sourceEntityType}:${A.sourceEntityId}:${A.renderUrl??"resolved-attachment"}`}function K91(A,Q){let B=A.documentId??A.filename?.replace(/\.pdf$/i,"")??`${A.attachmentType}-${A.sourceEntityType}-${A.sourceEntityId}-${Q}`;return D2(B)}function J6Q(A){return typeof A==="object"&&A!==null&&"id"in A&&typeof A.id==="string"&&A.id.length>0}B0();function mkA(A,Q){return[YQ(A,"generate","Generate a durable PDF document entity from a source attachment or render URL, with optional target documents[] attachment.",gQA,async(B,w)=>{let $=TQA.safeParse(B);if(!$.success)return T8($.error.message);let f=await Q($.data,w);return bw({jobId:f})},{cli:{name:"document-generate"}})]}var Z91={name:"@brains/document-plugin",private:!0,version:"0.2.0-alpha.81",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 F6Q=J.object({});class ukA extends YB{entityType=EE.entityType;schema=Ik;adapter=EE;pluginContext;constructor(){super("document",Z91,{},F6Q)}async onRegister(A){this.pluginContext=A,A.entities.register(this.entityType,this.schema,this.adapter,{embeddable:!1}),A.jobs.registerHandler("generate",new SQA(this.logger.child("DocumentGenerationJobHandler"),A))}async getTools(){let A=this.pluginContext;if(!A)throw Error("Plugin context not initialized");return mkA(this.id,(Q,B)=>A.jobs.enqueue({type:"generate",data:Q,toolContext:B}))}}function ckA(){return new ukA}B0();GA();B0();GA();import{writeFile as K6Q}from"fs/promises";import{tmpdir as Z6Q}from"os";import{join as z6Q}from"path";var N6Q=J.object({entityType:J.string().describe("Source entity type (e.g. 'deck')"),entityId:J.string().describe("Source entity ID"),attachmentType:J.string().describe("Attachment type (e.g. 'carousel')"),outputDir:J.string().optional().describe("Directory to write the file into (defaults to the OS temp dir)")});function z91(A,Q){return[YQ(A,"preview-attachment","Resolve a registered attachment provider and write the resulting media to a file for local preview.",N6Q,async(B)=>{if(!Q.attachments.hasProvider(B.entityType,B.attachmentType))return T8(`No attachment provider registered for ${B.entityType}/${B.attachmentType}`);try{let w=await Q.attachments.resolve({sourceEntityType:B.entityType,sourceEntityId:B.entityId,attachmentType:B.attachmentType});if(!w)return T8(`Provider for ${B.entityType}/${B.attachmentType} did not produce media for ${B.entityId}`);let $=B.outputDir??Z6Q(),f=z6Q($,w.filename);return await K6Q(f,w.data),bw({path:f,mimeType:w.mimeType,bytes:w.data.length},`Wrote ${w.data.length} bytes to ${f}`)}catch(w){return T8(h0(w))}})]}var N91={name:"@brains/media-tools",private:!0,version:"0.2.0-alpha.81",description:"Dev tools around the attachment registry \u2014 preview, inspect, regenerate media",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 L6Q=J.object({});class pkA extends YB{pluginContext;constructor(A={}){super("media-tools",N91,A,L6Q)}async onRegister(A){this.pluginContext=A}async getTools(){if(!this.pluginContext)throw Error("Plugin context not initialized");return z91(this.id,this.pluginContext)}}function lkA(A={}){return new pkA(A)}B0();GA();GA();B0();var C3=J.object({title:J.string().optional()}),q91=C3.pick({title:!0}).required(),Dk=w2.extend({entityType:J.literal("base"),metadata:q91}),E6Q=Dk.extend({frontmatter:C3,body:J.string()});B0();GA();class ikA extends F2{constructor(){super({entityType:"base",schema:Dk,frontmatterSchema:C3})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,C3);if(B.title)return this.buildMarkdown(Q,B)}catch{}return Q}fromMarkdown(A){let Q=this.extractTitle(A)??"Untitled";return{content:A,entityType:"base",metadata:{title:Q}}}parseNoteFrontmatter(A){try{return this.parseFrontMatter(A.content,C3)}catch{return{}}}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}}extractTitle(A){try{let B=this.parseFrontMatter(A,C3);if(B.title)return B.title}catch{}let Q=A.match(/^#\s+(.+)$/m);if(Q?.[1])return Q[1].trim();return null}}var Yk=new ikA;GA();var rkA=J.object({defaultPrompt:J.string().default("Create a note summarizing key concepts from my knowledge base")});GA();B0();var L91=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")}),dkA=b1({name:"note:generation",description:"Template for AI to generate notes from prompts",schema:L91,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create personal knowledge notes for research and reference.
|
|
3617
3617
|
|
|
3618
3618
|
Your task is to generate a well-structured note based on the user's prompt.
|
|
3619
3619
|
|
|
@@ -3623,7 +3623,7 @@ Guidelines:
|
|
|
3623
3623
|
3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
|
|
3624
3624
|
4. Style: Informative and educational. Write as if explaining to yourself for future reference.
|
|
3625
3625
|
5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
|
|
3626
|
-
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});B0();GA();x$();var E91=J.object({prompt:J.string(),title:J.string().optional()}),M6Q=KI.extend({title:J.string().optional()});class mQA extends E9{constructor(A,Q){super(A,Q,{schema:E91,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:Yk.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var M91={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
3626
|
+
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});B0();GA();x$();var E91=J.object({prompt:J.string(),title:J.string().optional()}),M6Q=KI.extend({title:J.string().optional()});class mQA extends E9{constructor(A,Q){super(A,Q,{schema:E91,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:Yk.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var M91={name:"@brains/note",private:!0,version:"0.2.0-alpha.81",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/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 nkA extends NQ{entityType=Yk.entityType;schema=Dk;adapter=Yk;constructor(A={}){super("note",M91,A,rkA)}createGenerationHandler(A){return new mQA(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:dkA}}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"})})}}function ME(A={}){return new nkA(A)}B0();GA();GA();B0();var V91=J.object({ref:J.string(),label:J.string()}),C91=J.enum(["pending","draft","published"]),mG=J.object({status:C91,title:J.string(),url:J.string().url(),description:J.string().optional(),domain:J.string(),capturedAt:J.string().datetime(),source:V91}),O91=mG.pick({title:!0,status:!0}),_u=w2.extend({entityType:J.literal("link"),metadata:O91}),okA=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)")});B0();class O3 extends F2{constructor(){super({entityType:"link",schema:_u,frontmatterSchema:mG})}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,mG),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 skA=new O3;B0();GA();var C6Q=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.")}),R91=b1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:C6Q,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
3627
3627
|
|
|
3628
3628
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
3629
3629
|
|
|
@@ -3645,7 +3645,7 @@ Accuracy rules:
|
|
|
3645
3645
|
|
|
3646
3646
|
`))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 P6Q}from"crypto";class VE{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(VE.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=P6Q("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}}}B0();GA();x$();var k6Q=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()}),yGw=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 cQA extends Pw{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:k6Q,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new O3,this.urlFetcher=new Hk(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:hQ.START,total:100,message:"Starting link capture"});let f=VE.generateEntityId(w);await B.report({progress:hQ.INIT,total:100,message:"Checking for existing link"});let I=await this.context.entityService.getEntity({entityType:"link",id:f});if(I){this.logger.info("Link already captured, returning existing",{url:w,entityId:f});let{frontmatter:Z}=this.linkAdapter.parseLinkContent(I.content);return{success:!0,entityId:I.id,title:Z.title,url:w,status:I.metadata.status}}await B.report({progress:hQ.FETCH,total:100,message:"Fetching webpage content"});let D=await this.urlFetcher.fetch(w);if(!D.success){if(D.errorType==="url_not_found"||D.errorType==="url_unreachable")return this.logger.warn("Link URL not accessible",{url:w,errorType:D.errorType,error:D.error}),{success:!1,error:`Could not capture link: ${D.error}`}}await B.report({progress:hQ.PROCESS,total:100,message:"Extracting content with AI"});let Y=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
|
|
3647
3647
|
|
|
3648
|
-
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:hQ.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),W=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:hQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),E=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:hQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:hQ.SAVE,total:100,message:`Saving link: "${Y.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:F,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:hQ.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:K.entityId,title:Y.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),y$.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var k91={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
3648
|
+
${D.content}`:`The URL ${w} could not be fetched. Return success: false with error: "${D.error}"`,data:{url:w,hasContent:D.success},interfacePermissionGrant:"public"});this.logger.debug("AI extraction result",{result:Y}),await B.report({progress:hQ.EXTRACT,total:100,message:"Processing extraction results"});let H=this.resolveSource($),W=new Date().toISOString();if(Y.success===!1||!Y.title||!Y.description||!Y.summary){let Z=Y.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:hQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),E=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:hQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:hQ.SAVE,total:100,message:`Saving link: "${Y.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:Y.title,url:w,description:Y.description,summary:Y.summary,domain:new URL(w).hostname,capturedAt:W,source:H}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:F,metadata:{status:"draft",title:Y.title}}});return await B.report({progress:hQ.COMPLETE,total:100,message:`Link captured: "${Y.title}"`}),{success:!0,entityId:K.entityId,title:Y.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),y$.failure(f)}}resolveSource(A){let Q=A?.channelId,B=A?.channelName;if(Q)return{ref:`matrix:${Q}`,label:B??Q};let w=A?.interfaceId??"cli";return{ref:`${w}:local`,label:w.toUpperCase()}}summarizeDataForLog(A){return{url:A.url,interfaceId:A.metadata?.interfaceId}}}var k91={name:"@brains/link",private:!0,version:"0.2.0-alpha.81",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/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 BjA extends NQ{entityType=skA.entityType;schema=_u;adapter=skA;shell;constructor(A={}){super("link",k91,A,okA)}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 cQA(this.logger.child("LinkCaptureJobHandler"),this.context,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0),this.id),Q}async interceptCreate(A,Q,B){if(A.content)try{let f=this.adapter.fromMarkdown(A.content).metadata,I=typeof f?.title==="string"?f.title:void 0,D=typeof f?.status==="string"?f.status:void 0,Y=this.extractFirstUrl(A.content);if(I&&D&&Y){let H=D2(Y)||D2(I)||`${A.entityType}-${Date.now()}`,W=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:H,entityType:A.entityType,content:A.content,metadata:{title:I,status:D},created:W,updated:W}})).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 cQA(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:R91,"link-list":b91,"link-detail":P91}}getDataSources(){return[new QjA(this.logger.child("LinksDataSource"))]}async onRegister(A){A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=J.object({url:J.string().url()}).parse(Q),$=await new Hk(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:
|
|
3649
3649
|
|
|
3650
3650
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=VE.extractUrls(Q);if(B)return B}return}}function j91(A={}){return new BjA(A)}var CE=j91;GA();var AFw=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()});B0();GA();xw();GA();B0();var _91=J.enum(["draft","published"]),RD=J.object({title:J.string(),slug:J.string().optional(),status:_91,publishedAt:J.string().datetime().optional(),description:J.string(),year:J.number(),coverImageId:J.string().optional(),url:J.string().url().optional()}),v91=RD.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:J.string()}),Xk=w2.extend({entityType:J.literal("project"),metadata:v91}),pQA=J.object({context:J.string(),problem:J.string(),solution:J.string(),outcome:J.string()}),yu=Xk.extend({frontmatter:RD,body:J.string(),structuredContent:pQA.optional(),coverImageUrl:J.string().optional()}),Wk=yu.extend({url:J.string().optional(),typeLabel:J.string().optional(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()}),_6Q=yu.extend({url:J.string(),typeLabel:J.string(),coverImageUrl:J.string().optional(),coverImageWidth:J.number().optional(),coverImageHeight:J.number().optional()});B0();GA();$$();class wjA extends yB{constructor(){super(pQA,{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 $jA=new wjA;class fjA extends F2{constructor(){super({entityType:"project",schema:Xk,frontmatterSchema:RD,supportsCoverImage:!0,bodyFormatter:$jA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,RD),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,RD),B=Q.slug??D2(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,RD)}parseStructuredContent(A){return $jA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=$jA.format(Q);return this.buildMarkdown(B,A)}}var R3=new fjA;GA();var IjA=J.object({});import{jsxDEV as X4,Fragment as y6Q}from"preact/jsx-dev-runtime";var v6Q=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return X4(ZB,{href:B,children:[w&&X4("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),X4(z$,{children:Q.title},void 0,!1,void 0,this),X4("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},DjA=({projects:A,pageTitle:Q,pagination:B,baseUrl:w="/projects"})=>{let $=Q??"Projects",f=B?.totalItems??A.length,I=`Browse all ${f} ${f===1?"project":"projects"}`;return X4(y6Q,{children:[X4(JQ,{title:$,description:I},void 0,!1,void 0,this),X4("div",{className:"project-list bg-theme",children:X4("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[X4("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),X4("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>X4(v6Q,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&X4("div",{className:"mt-12",children:X4(CG,{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 dB,Fragment as y91}from"preact/jsx-dev-runtime";var x6Q=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return dB("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:dB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?dB(ZB,{href:A.url,variant:"compact",children:[dB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),dB("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):dB("div",{},void 0,!1,void 0,this),Q&&dB(ZB,{href:Q.url,variant:"compact",className:"md:text-right",children:[dB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),dB("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)},lQA=({title:A,content:Q})=>{if(!Q)return null;return dB("section",{className:"mb-12",children:[dB("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),dB(I4,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},YjA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A;return dB(y91,{children:[dB(JQ,{title:w.title,description:w.description,...I&&{ogImage:I},ogType:"article"},void 0,!1,void 0,this),dB("article",{className:"project-detail",children:dB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:dB("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&dB(MG,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),dB("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),dB("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[dB("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),w.url&&dB(y91,{children:[dB("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),dB("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),dB("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&dB("div",{className:"case-study",children:[dB(lQA,{title:"Context",content:$.context},void 0,!1,void 0,this),dB(lQA,{title:"Problem",content:$.problem},void 0,!1,void 0,this),dB(lQA,{title:"Solution",content:$.solution},void 0,!1,void 0,this),dB(lQA,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),dB(x6Q,{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)};GA();B0();var h6Q=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)")}),HjA=b1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:h6Q,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
3651
3651
|
|
|
@@ -3669,7 +3669,7 @@ ${A.prompt}
|
|
|
3669
3669
|
|
|
3670
3670
|
Project year: ${A.year}
|
|
3671
3671
|
|
|
3672
|
-
Use the project request as the primary source of truth. If retrieved knowledge context describes a different project or conflicts with this request, ignore that unrelated context.`}class iQA extends E9{constructor(A,Q){super(A,Q,{schema:g6Q,jobTypeName:"project-generation",entityType:"project"})}async generate(A,Q){let{year:B}=A;await this.reportProgress(Q,{progress:10,message:"Generating project content with AI"});let w=await this.context.ai.generate({prompt:XjA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=D2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:f,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:f,content:R3.createProjectContent(I,D),metadata:{title:$,slug:f,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}B0();B0();function T6Q(A){let Q=AQ(A.content,RD),B=R3.parseStructuredContent(A);return yu.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class rQA extends w5{id="portfolio:entities";name="Portfolio Project DataSource";description="Fetches and transforms project entities for rendering";config={entityType:"project",defaultSort:[{field:"year",direction:"desc"},{field:"title",direction:"asc"}],defaultLimit:10,enableNavigation:!0};constructor(A){super(A);this.logger.debug("ProjectDataSource initialized")}transformEntity(A){return T6Q(A)}buildDetailResult(A,Q){return{project:A,prevProject:Q?.prev??null,nextProject:Q?.next??null}}buildListResult(A,Q,B){return{projects:A,pagination:Q,baseUrl:B.baseUrl}}}var x91={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.
|
|
3672
|
+
Use the project request as the primary source of truth. If retrieved knowledge context describes a different project or conflicts with this request, ignore that unrelated context.`}class iQA extends E9{constructor(A,Q){super(A,Q,{schema:g6Q,jobTypeName:"project-generation",entityType:"project"})}async generate(A,Q){let{year:B}=A;await this.reportProgress(Q,{progress:10,message:"Generating project content with AI"});let w=await this.context.ai.generate({prompt:XjA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=D2($);await this.reportProgress(Q,{progress:50,message:`Generated project: "${$}"`});let I={title:$,slug:f,status:"draft",description:w.description,year:B},D={context:w.context,problem:w.problem,solution:w.solution,outcome:w.outcome};return{id:f,content:R3.createProjectContent(I,D),metadata:{title:$,slug:f,status:"draft",year:B},title:$,resultExtras:{title:$}}}summarizeDataForLog(A){return{prompt:A.prompt.substring(0,100),year:A.year,title:A.title}}}B0();B0();function T6Q(A){let Q=AQ(A.content,RD),B=R3.parseStructuredContent(A);return yu.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class rQA extends w5{id="portfolio:entities";name="Portfolio Project DataSource";description="Fetches and transforms project entities for rendering";config={entityType:"project",defaultSort:[{field:"year",direction:"desc"},{field:"title",direction:"asc"}],defaultLimit:10,enableNavigation:!0};constructor(A){super(A);this.logger.debug("ProjectDataSource initialized")}transformEntity(A){return T6Q(A)}buildDetailResult(A,Q){return{project:A,prevProject:Q?.prev??null,nextProject:Q?.next??null}}buildListResult(A,Q,B){return{projects:A,pagination:Q,baseUrl:B.baseUrl}}}var x91={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.81",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/content-formatters":"workspace:*","@brains/contracts":"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 m6Q=J.object({projects:J.array(Wk),pageTitle:J.string().optional(),pagination:L9.nullable(),baseUrl:J.string().optional()});function u6Q(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 WjA extends NQ{entityType=R3.entityType;schema=Xk;adapter=R3;constructor(A={}){super("portfolio",x91,A,IjA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=u6Q(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 iQA(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":b1({name:"project-list",description:"Portfolio project list page template",schema:m6Q,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:DjA}}),"project-detail":b1({name:"project-detail",description:"Individual project case study template",schema:J.object({project:Wk,prevProject:Wk.nullable(),nextProject:Wk.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:YjA}}),generation:HjA}}getDataSources(){return[new rQA(this.logger.child("ProjectDataSource"))]}async onRegister(A){this.registerEvalHandlers(A),await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A)}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:XjA(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 f=AQ($.content,RD),I=new Date().toISOString(),D=q9(f.content,{...f.metadata,status:"published",publishedAt:I});await A.entityService.updateEntity({entity:{...$,content:D,metadata:{...$.metadata,status:"published",publishedAt:I}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,publishedAt:I}})}catch($){await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:h0($)}})}return{success:!0}})}}function UjA(A={}){return new WjA(A)}B0();GA();var h91=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),sourceChangeBatchDelayMs:J.number().int().min(0).default(1000)});B0();GA();B0();var c6Q=J.object({}),dQA=w2.extend({entityType:J.literal("topic"),metadata:c6Q}),FKw=J.object({content:J.string()}),g91=J.object({title:J.string().describe("Topic title")});var OE="topics",nB="topic",JjA="topics-projection",T91="topic:project",nQA="topics-plugin",S91="topics:batch-completed",m91="topics-source-batch";class uG extends F2{constructor(){super({entityType:nB,schema:dQA,frontmatterSchema:g91})}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:nB}}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))}}B0();GA();GA();var p6Q=J.object({title:J.string().max(100),content:J.string(),relevanceScore:J.number().min(0).max(1)}),u91=J.array(p6Q);var l6Q=J.object({topics:u91}),c91=b1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:l6Q,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
3673
3673
|
|
|
3674
3674
|
Analyze the provided content and extract meaningful topics discussed.
|
|
3675
3675
|
|
|
@@ -3772,13 +3772,13 @@ ${A.incomingTopic.content}`})}}function Q5Q(A){if(A.length===0)return"";return A
|
|
|
3772
3772
|
|
|
3773
3773
|
${Q.content}`}).join(`
|
|
3774
3774
|
|
|
3775
|
-
`)}async function RE(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=e91(A),Y=new bH(Q.entityService,B),H=w.topicMergeSynthesizer??new NjA(Q,B),W=await eQA(Q.entityService),F=new Map,K=0,Z=0,q=0;for(let L of D){B.info(`Processing batch of ${L.length} entities`);let b=Q5Q(L),_=ABA({entityTitle:`Batch of ${L.length} entities`,entityType:"batch",content:b,existingTopicTitles:W});try{let s=(await Q.ai.generate({prompt:_,templateName:"topics:extraction"})).topics.filter((n)=>n.relevanceScore>=$);for(let n of s)try{if(f){let h=await Y.findMergeCandidate({incoming:n,threshold:I,additionalCandidates:Array.from(F.values())});if(h){let g=await H.synthesize({existingTopic:h.topic,incomingTopic:n}),AA=await Y.applySynthesizedMerge({existingId:h.topic.id,synthesized:{...g,title:h.title}});if(!AA)throw Error(`Failed to merge topic: ${n.title}`);F.set(AA.id,AA),Z++;continue}}let T=HX(n.title);if(F.has(T)){q++;continue}let y=await Y.createTopicOptimistic({title:n.title,content:n.content});if(y.topic)F.set(y.topic.id,y.topic);if(y.created)K++;else q++}catch(T){B.error("Topic batch item failed",{title:n.title,error:h0(T)})}}catch(j){B.error("Batch topic extraction failed",{batchSize:L.length,promptChars:_.length,error:h0(j)})}}let E={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:S91,payload:E,broadcast:!0});return E}GA();var B5Q=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 qjA{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 f71(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 w5Q({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=B5Q.safeParse($??{});return f.success?f.data:null}}}async function w5Q(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:Y,entity:H}of B){if(!H){$++;continue}if(H.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(H)){f++;continue}I.push(H)}if(I.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f};let D=await RE(I,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});return{success:!0,sources:Q.length,...D,stale:w,missing:$,unpublished:f}}function I71(){return{priority:5,source:nQA,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:OE}}}async function D71(A){let Q=await H71(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 RE(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});A.logger.info("Batch topic extraction complete",B)}async function Y71(A){let Q=await H71(A),B=await LjA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function LjA(A,Q,B,w){let $=new bH(Q.entityService,B),f=await $.listTopics();for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await RE(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function H71(A){let Q=$5Q(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function $5Q(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var Gk=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),f5Q=Gk.extend({minRelevanceScore:J.number().optional()}),I5Q=J.object({contentA:Gk,contentB:Gk,minRelevanceScore:J.number().optional(),threshold:J.number().min(0).max(1).optional()}),Tu=J.object({title:J.string(),content:J.string()}),D5Q=J.object({existingTopics:J.array(Tu),incomingTopic:Tu,threshold:J.number().optional()}),Y5Q=J.object({existingTopics:J.array(Tu).default([]),incomingTopic:Tu.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),H5Q=J.object({entities:J.array(Gk).min(1),minRelevanceScore:J.number().optional()}),X5Q=J.object({existingTopics:J.array(Tu).optional(),entities:J.array(Gk)}),W5Q=J.object({entities:J.array(Gk)});function Jk(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:RB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function X71(A){return{title:A.title,relevanceScore:A.relevanceScore}}function U5Q(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function J5Q(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:U5Q(Q)}]}}async function bE(A){let Q=await A.entityService.listEntities({entityType:nB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:nB,id:B.id})))}async function G5Q(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function W71(A){let{context:Q,logger:B,config:w}=A,$=new zjA(Q,B),f=async(I,D,Y="")=>{let H=Jk(I,Y);return $.extractFromEntity(H,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await bE(Q);let D=f5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=Jk(D);return(await $.extractFromEntity(H,Y)).map((F)=>J5Q(F,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await bE(Q);let D=I5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=D.threshold??w.mergeSimilarityThreshold,[W,F]=await Promise.all([f(D.contentA,Y,"-a"),f(D.contentB,Y,"-b")]),K=new bH(Q.entityService,B),Z=[];for(let L of W){let b=await K.createTopic(L);if(b)Z.push(b)}let q=(await Promise.all(F.map(async(L)=>{let b=await K.findMergeCandidate({incoming:L,threshold:H,additionalCandidates:Z});if(!b)return null;return{incomingTitle:L.title,candidateTitle:b.title,candidateScore:b.score}}))).filter((L)=>L!==null),E=q.map((L)=>L.candidateTitle);return{topicsA:W.map(X71),topicsB:F.map(X71),matchingTitles:E,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await bE(Q);let D=D5Q.parse(I),Y=D.threshold??w.mergeSimilarityThreshold,H=new bH(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await H.createTopic(K);if(Z)W.push(Z)}let F=await H.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:Y,additionalCandidates:W});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await bE(Q);let D=Y5Q.parse(I),Y=new bH(Q.entityService,B);for(let K of D.existingTopics)await Y.createTopic({title:K.title,content:K.content});await G5Q(Q);let H=Jk({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await RE([H],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:nB});return{...W,topicCount:F.length,topics:F.map(KjA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await bE(Q);let D=X5Q.parse(I),Y=new bH(Q.entityService,B);for(let K of D.existingTopics??[])await Y.createTopic(K);let H=D.entities.map((K,Z)=>Jk(K,`-rebuild-${Z}`)),W=await LjA(H,Q,B,w),F=await Q.entityService.listEntities({entityType:nB});return{...W,topicCount:F.length,topics:F.map(KjA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await bE(Q);let D=H5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=new bH(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=Jk(Z,`-sequential-${K}`),E=await $.extractFromEntity(q,Y);for(let L of E)await H.createTopic({title:L.title,content:L.content});W.push({extractedTitles:E.map((L)=>L.title)})}let F=await Q.entityService.listEntities({entityType:nB});return{totalTopics:F.length,perEntity:W,topics:F.map(Uk)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await bE(Q);let Y=W5Q.parse(I).entities.map((F,K)=>Jk(F,`-batch-${K}`)),H=await RE(Y,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:nB});return{...H,topics:W.map(Uk)}})}var U71={name:"@brains/topics",private:!0,version:"0.2.0-alpha.80",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/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 K5Q=new uG;class J71 extends NQ{entityType=nB;schema=dQA;adapter=K5Q;sourceBatch=new qjA;constructor(A={}){super(OE,U71,A,h91)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:c91,"merge-synthesis":p91,"topic-list":l91,"topic-detail":i91}}getDataSources(){return[new ZjA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:JjA,targetType:nB,job:{type:T91,handler:f71({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 BN(A,nB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:I71()},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;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:nQA,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:m91,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:OE}})}}]}async onRegister(A){A.insights.register("topic-distribution",n91()),o91({context:A,pluginId:this.id}),W71({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(JjA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===nB)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 D71({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await Y71({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function QBA(A){return new J71(A)}B0();GA();B0();var G71=J.enum(["linkedin"]),F71=J.enum(["draft","queued","published","failed"]),K71=J.enum(["post","deck"]),Z71=J.object({id:J.string().min(1).describe("Document entity ID")}),bD=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:G71.describe("Target platform"),status:F71,coverImageId:J.string().optional().describe("Image entity ID for post image"),documents:J.array(Z71).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:K71.optional().describe("Source entity type (post, deck)")}),z71=bD.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}")}),Fk=w2.extend({entityType:J.literal("social-post"),metadata:z71}),BBA=Fk.extend({frontmatter:bD,body:J.string()}),wBA=BBA.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()});B0();GA();class EjA extends F2{constructor(){super({entityType:"social-post",schema:Fk,frontmatterSchema:bD,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,bD),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,bD),B=`${Q.platform}-${D2(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:Q.platform,status:Q.status,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,bD)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var uf=new EjA;B0();B0();GA();var Z5Q=EX.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),z5Q=MX.extend({query:Z5Q.optional()});function N71(A){let Q=AQ(A.content,bD);return BBA.parse({...A,frontmatter:Q.metadata,body:Q.content})}class $BA extends w5{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=z5Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return N71(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:W}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(W,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:H}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(Y,H,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?N71(w):null;return A.parse({post:$})}}GA();var q71=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional()}),MjA=J.object({linkedin:q71.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)});B0();GA();x$();CjA();import{jsxDEV as g6,Fragment as L5Q}from"preact/jsx-dev-runtime";function N5Q(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function q5Q(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var IBA=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return g6(L5Q,{children:[g6(JQ,{title:$,description:I},void 0,!1,void 0,this),g6("div",{className:"social-post-list bg-theme",children:g6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[g6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?g6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):g6("ul",{className:"space-y-6",children:A.map((D)=>g6("li",{children:g6(ZB,{href:D.url,variant:"horizontal",children:g6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&g6("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),g6("div",{className:"flex-1 min-w-0",children:[g6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[g6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),g6("time",{className:"text-sm text-theme-muted shrink-0",children:q5Q(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g6("div",{className:"flex items-center gap-2 mb-3",children:[g6(Tf,{status:D.frontmatter.status},void 0,!1,void 0,this),g6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),g6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g6("p",{className:"text-theme leading-relaxed",children:N5Q(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&g6(CG,{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 T6,Fragment as E5Q}from"preact/jsx-dev-runtime";function L71(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var DBA=({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 T6(E5Q,{children:[T6(JQ,{title:Q,description:B},void 0,!1,void 0,this),T6("section",{className:"social-post-detail",children:T6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:T6("div",{className:"max-w-3xl mx-auto",children:[T6(RW,{items:w},void 0,!1,void 0,this),T6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),T6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[T6(Tf,{status:A.frontmatter.status},void 0,!1,void 0,this),T6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),T6("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&&T6(MG,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),T6(ZB,{className:"p-8 mb-8",children:T6("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),T6("div",{className:"space-y-4 text-sm text-theme-muted",children:[T6("div",{children:[T6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",L71(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&T6("div",{children:[T6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",L71(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&T6("div",{children:T6("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 Su(A){return`social-media:${A}`}var M5Q=J.union([J.boolean(),J.object({generate:J.boolean().optional(),prompt:J.string().optional()})]),OjA=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:M5Q.optional().describe("Generic cover image generation request")}),V5Q=KI.extend({slug:J.string().optional()});class PE extends E9{constructor(A,Q){super(A,Q,{schema:OjA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let L=await this.context.ai.generate({prompt:D,templateName:Su(B)});Y=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let L=await this.context.entityService.getEntity({entityType:f,id:I});if(!L)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let _=J.object({slug:J.string()}).safeParse(L.metadata),j=_.success?_.data.slug:I,s=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3775
|
+
`)}async function RE(A,Q,B,w={}){if(A.length===0)return{created:0,merged:0,skipped:0,batches:0};let $=w.minRelevanceScore??0,f=w.autoMerge??!1,I=w.mergeSimilarityThreshold??0.85,D=e91(A),Y=new bH(Q.entityService,B),H=w.topicMergeSynthesizer??new NjA(Q,B),W=await eQA(Q.entityService),F=new Map,K=0,Z=0,q=0;for(let L of D){B.info(`Processing batch of ${L.length} entities`);let b=Q5Q(L),_=ABA({entityTitle:`Batch of ${L.length} entities`,entityType:"batch",content:b,existingTopicTitles:W});try{let s=(await Q.ai.generate({prompt:_,templateName:"topics:extraction"})).topics.filter((n)=>n.relevanceScore>=$);for(let n of s)try{if(f){let h=await Y.findMergeCandidate({incoming:n,threshold:I,additionalCandidates:Array.from(F.values())});if(h){let g=await H.synthesize({existingTopic:h.topic,incomingTopic:n}),AA=await Y.applySynthesizedMerge({existingId:h.topic.id,synthesized:{...g,title:h.title}});if(!AA)throw Error(`Failed to merge topic: ${n.title}`);F.set(AA.id,AA),Z++;continue}}let T=HX(n.title);if(F.has(T)){q++;continue}let y=await Y.createTopicOptimistic({title:n.title,content:n.content});if(y.topic)F.set(y.topic.id,y.topic);if(y.created)K++;else q++}catch(T){B.error("Topic batch item failed",{title:n.title,error:h0(T)})}}catch(j){B.error("Batch topic extraction failed",{batchSize:L.length,promptChars:_.length,error:h0(j)})}}let E={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:S91,payload:E,broadcast:!0});return E}GA();var B5Q=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 qjA{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 f71(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 w5Q({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=B5Q.safeParse($??{});return f.success?f.data:null}}}async function w5Q(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(Y)=>({ref:Y,entity:await A.context.entityService.getEntity({entityType:Y.entityType,id:Y.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:Y,entity:H}of B){if(!H){$++;continue}if(H.contentHash!==Y.contentHash){w++;continue}if(!A.isEntityPublished(H)){f++;continue}I.push(H)}if(I.length===0)return{success:!0,sources:Q.length,created:0,merged:0,skipped:0,batches:0,stale:w,missing:$,unpublished:f};let D=await RE(I,A.context,A.logger,{minRelevanceScore:A.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});return{success:!0,sources:Q.length,...D,stale:w,missing:$,unpublished:f}}function I71(){return{priority:5,source:nQA,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:OE}}}async function D71(A){let Q=await H71(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 RE(Q,A.context,A.logger,{minRelevanceScore:A.config.minRelevanceScore,autoMerge:A.config.autoMerge,mergeSimilarityThreshold:A.config.mergeSimilarityThreshold});A.logger.info("Batch topic extraction complete",B)}async function Y71(A){let Q=await H71(A),B=await LjA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function LjA(A,Q,B,w){let $=new bH(Q.entityService,B),f=await $.listTopics();for(let D of f)await $.deleteTopic(D.id);if(A.length===0)return{deleted:f.length,created:0,merged:0,skipped:0,batches:0};let I=await RE(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function H71(A){let Q=$5Q(A),B=[];for(let w of Q){let $=await A.context.entityService.listEntities({entityType:w});for(let f of $){if(!A.isEntityPublished(f))continue;B.push(f)}}return B}function $5Q(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var Gk=J.object({entityType:J.string(),content:J.string(),metadata:J.record(J.unknown()).optional()}),f5Q=Gk.extend({minRelevanceScore:J.number().optional()}),I5Q=J.object({contentA:Gk,contentB:Gk,minRelevanceScore:J.number().optional(),threshold:J.number().min(0).max(1).optional()}),Tu=J.object({title:J.string(),content:J.string()}),D5Q=J.object({existingTopics:J.array(Tu),incomingTopic:Tu,threshold:J.number().optional()}),Y5Q=J.object({existingTopics:J.array(Tu).default([]),incomingTopic:Tu.extend({relevanceScore:J.number().min(0).max(1).optional()}),threshold:J.number().optional()}),H5Q=J.object({entities:J.array(Gk).min(1),minRelevanceScore:J.number().optional()}),X5Q=J.object({existingTopics:J.array(Tu).optional(),entities:J.array(Gk)}),W5Q=J.object({entities:J.array(Gk)});function Jk(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:RB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function X71(A){return{title:A.title,relevanceScore:A.relevanceScore}}function U5Q(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function J5Q(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:U5Q(Q)}]}}async function bE(A){let Q=await A.entityService.listEntities({entityType:nB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:nB,id:B.id})))}async function G5Q(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function W71(A){let{context:Q,logger:B,config:w}=A,$=new zjA(Q,B),f=async(I,D,Y="")=>{let H=Jk(I,Y);return $.extractFromEntity(H,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await bE(Q);let D=f5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=Jk(D);return(await $.extractFromEntity(H,Y)).map((F)=>J5Q(F,H))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await bE(Q);let D=I5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=D.threshold??w.mergeSimilarityThreshold,[W,F]=await Promise.all([f(D.contentA,Y,"-a"),f(D.contentB,Y,"-b")]),K=new bH(Q.entityService,B),Z=[];for(let L of W){let b=await K.createTopic(L);if(b)Z.push(b)}let q=(await Promise.all(F.map(async(L)=>{let b=await K.findMergeCandidate({incoming:L,threshold:H,additionalCandidates:Z});if(!b)return null;return{incomingTitle:L.title,candidateTitle:b.title,candidateScore:b.score}}))).filter((L)=>L!==null),E=q.map((L)=>L.candidateTitle);return{topicsA:W.map(X71),topicsB:F.map(X71),matchingTitles:E,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await bE(Q);let D=D5Q.parse(I),Y=D.threshold??w.mergeSimilarityThreshold,H=new bH(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await H.createTopic(K);if(Z)W.push(Z)}let F=await H.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:Y,additionalCandidates:W});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await bE(Q);let D=Y5Q.parse(I),Y=new bH(Q.entityService,B);for(let K of D.existingTopics)await Y.createTopic({title:K.title,content:K.content});await G5Q(Q);let H=Jk({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await RE([H],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:nB});return{...W,topicCount:F.length,topics:F.map(KjA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await bE(Q);let D=X5Q.parse(I),Y=new bH(Q.entityService,B);for(let K of D.existingTopics??[])await Y.createTopic(K);let H=D.entities.map((K,Z)=>Jk(K,`-rebuild-${Z}`)),W=await LjA(H,Q,B,w),F=await Q.entityService.listEntities({entityType:nB});return{...W,topicCount:F.length,topics:F.map(KjA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await bE(Q);let D=H5Q.parse(I),Y=D.minRelevanceScore??w.minRelevanceScore,H=new bH(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=Jk(Z,`-sequential-${K}`),E=await $.extractFromEntity(q,Y);for(let L of E)await H.createTopic({title:L.title,content:L.content});W.push({extractedTitles:E.map((L)=>L.title)})}let F=await Q.entityService.listEntities({entityType:nB});return{totalTopics:F.length,perEntity:W,topics:F.map(Uk)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await bE(Q);let Y=W5Q.parse(I).entities.map((F,K)=>Jk(F,`-batch-${K}`)),H=await RE(Y,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:nB});return{...H,topics:W.map(Uk)}})}var U71={name:"@brains/topics",private:!0,version:"0.2.0-alpha.81",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/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 K5Q=new uG;class J71 extends NQ{entityType=nB;schema=dQA;adapter=K5Q;sourceBatch=new qjA;constructor(A={}){super(OE,U71,A,h91)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:c91,"merge-synthesis":p91,"topic-list":l91,"topic-detail":i91}}getDataSources(){return[new ZjA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:JjA,targetType:nB,job:{type:T91,handler:f71({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 BN(A,nB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:I71()},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;return this.sourceBatch.add({entityId:B.id,entityType:B.entityType,contentHash:B.contentHash}),{mode:"source-batch"}},jobOptions:()=>({priority:5,source:nQA,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:m91,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:OE}})}}]}async onRegister(A){A.insights.register("topic-distribution",n91()),o91({context:A,pluginId:this.id}),W71({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(JjA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===nB)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 D71({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await Y71({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function QBA(A){return new J71(A)}B0();GA();B0();var G71=J.enum(["linkedin"]),F71=J.enum(["draft","queued","published","failed"]),K71=J.enum(["post","deck"]),Z71=J.object({id:J.string().min(1).describe("Document entity ID")}),bD=J.object({title:J.string().describe("Short descriptive title (3-6 words) for file naming"),platform:G71.describe("Target platform"),status:F71,coverImageId:J.string().optional().describe("Image entity ID for post image"),documents:J.array(Z71).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:K71.optional().describe("Source entity type (post, deck)")}),z71=bD.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:J.string().describe("URL-friendly identifier: {platform}-{title}")}),Fk=w2.extend({entityType:J.literal("social-post"),metadata:z71}),BBA=Fk.extend({frontmatter:bD,body:J.string()}),wBA=BBA.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()});B0();GA();class EjA extends F2{constructor(){super({entityType:"social-post",schema:Fk,frontmatterSchema:bD,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,bD),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,bD),B=`${Q.platform}-${D2(Q.title)}`;return{content:A,entityType:"social-post",metadata:{title:Q.title,slug:B,platform:Q.platform,status:Q.status,publishedAt:Q.publishedAt,platformPostId:Q.platformPostId}}}parsePostFrontmatter(A){return this.parseFrontMatter(A.content,bD)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var uf=new EjA;B0();B0();GA();var Z5Q=EX.extend({platform:J.enum(["linkedin"]).optional(),status:J.enum(["draft","queued","published","failed"]).optional(),sortByQueue:J.boolean().optional(),nextInQueue:J.boolean().optional()}),z5Q=MX.extend({query:Z5Q.optional()});function N71(A){let Q=AQ(A.content,bD);return BBA.parse({...A,frontmatter:Q.metadata,body:Q.content})}class $BA extends w5{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=z5Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return N71(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:W}=await this.fetchDetail(w.id,$);return Q.parse(this.buildDetailResult(W,null))}let f={};if(w.platform)f.platform=w.platform;if(w.status)f.status=w.status;let I=Object.keys(f).length>0,D=w.sortByQueue?[{field:"queueOrder",direction:"asc"}]:this.config.defaultSort,{items:Y,pagination:H}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(Y,H,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?N71(w):null;return A.parse({post:$})}}GA();var q71=J.object({accessToken:J.string().optional(),refreshToken:J.string().optional(),organizationId:J.string().optional()}),MjA=J.object({linkedin:q71.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)});B0();GA();x$();CjA();import{jsxDEV as g6,Fragment as L5Q}from"preact/jsx-dev-runtime";function N5Q(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function q5Q(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var IBA=({posts:A,pageTitle:Q,pagination:B,baseUrl:w="/social-posts"})=>{let $=Q??"Social Posts",f=B?.totalItems??A.length,I=`Browse all ${f} social ${f===1?"post":"posts"}`;return g6(L5Q,{children:[g6(JQ,{title:$,description:I},void 0,!1,void 0,this),g6("div",{className:"social-post-list bg-theme",children:g6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[g6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?g6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):g6("ul",{className:"space-y-6",children:A.map((D)=>g6("li",{children:g6(ZB,{href:D.url,variant:"horizontal",children:g6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&g6("img",{src:D.coverImageUrl,alt:D.frontmatter.title,className:"w-full sm:w-24 h-48 sm:h-24 object-cover rounded-lg shrink-0"},void 0,!1,void 0,this),g6("div",{className:"flex-1 min-w-0",children:[g6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[g6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),g6("time",{className:"text-sm text-theme-muted shrink-0",children:q5Q(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g6("div",{className:"flex items-center gap-2 mb-3",children:[g6(Tf,{status:D.frontmatter.status},void 0,!1,void 0,this),g6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),g6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g6("p",{className:"text-theme leading-relaxed",children:N5Q(D.body,200)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&g6(CG,{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 T6,Fragment as E5Q}from"preact/jsx-dev-runtime";function L71(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var DBA=({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 T6(E5Q,{children:[T6(JQ,{title:Q,description:B},void 0,!1,void 0,this),T6("section",{className:"social-post-detail",children:T6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:T6("div",{className:"max-w-3xl mx-auto",children:[T6(RW,{items:w},void 0,!1,void 0,this),T6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),T6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[T6(Tf,{status:A.frontmatter.status},void 0,!1,void 0,this),T6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),T6("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&&T6(MG,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),T6(ZB,{className:"p-8 mb-8",children:T6("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),T6("div",{className:"space-y-4 text-sm text-theme-muted",children:[T6("div",{children:[T6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",L71(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&T6("div",{children:[T6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",L71(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&T6("div",{children:T6("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 Su(A){return`social-media:${A}`}var M5Q=J.union([J.boolean(),J.object({generate:J.boolean().optional(),prompt:J.string().optional()})]),OjA=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:M5Q.optional().describe("Generic cover image generation request")}),V5Q=KI.extend({slug:J.string().optional()});class PE extends E9{constructor(A,Q){super(A,Q,{schema:OjA,jobTypeName:"social-post-generation",entityType:"social-post"})}async generate(A,Q){let B=A.platform??"linkedin",w=A.addToQueue??!1,{prompt:$,sourceEntityType:f,sourceEntityId:I}=A,{content:D,title:Y}=A;if(D&&Y)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!Y){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let L=await this.context.ai.generate({prompt:D,templateName:Su(B)});Y=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post shaped from content"})}else if(I&&f){await this.reportProgress(Q,{progress:10,message:`Fetching source ${f}`});let L=await this.context.entityService.getEntity({entityType:f,id:I});if(!L)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let _=J.object({slug:J.string()}).safeParse(L.metadata),j=_.success?_.data.slug:I,s=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3776
3776
|
|
|
3777
3777
|
Source: ${f}/${j}
|
|
3778
3778
|
|
|
3779
3779
|
${L.content}`,templateName:Su(B)});Y=s.title,D=s.content,await this.reportProgress(Q,{progress:50,message:"Social post generated from source"})}else if($){await this.reportProgress(Q,{progress:10,message:"Generating social post with AI"});let L=await this.context.ai.generate({prompt:$,templateName:Su(B)});Y=L.title,D=L.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!Y)this.failEarly("Content or title was not generated");let W={title:Y,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},F=uf.createPostContent(W,D),Z=uf.fromMarkdown(F).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let q=await eU({entityType:"social-post",title:Y,deriveId:(L)=>`${B}-${D2(L)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),E=F;if(q!==Y){Z.title=q,Z.slug=`${B}-${D2(q)}`;let L={...W,title:q};E=uf.createPostContent(L,D)}return{id:Z.slug,content:E,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 YBA(A){if(A.length<=200)return A;return`${A.slice(0,200)}\u2026 (truncated, ${A.length} bytes)`}function C5Q(A){let Q={status:"READY",media:A.urn};if(A.title)Q.title={text:A.title};return Q}function E71(A){if(!M71(A))return null;let Q=RjA(A,"value");if(!Q)return null;let B=RjA(Q,"uploadMechanism");if(!B)return null;let w=RjA(B,"com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest");if(!w)return null;let $=w.uploadUrl,f=Q.asset;if(typeof $!=="string"||typeof f!=="string")return null;return{uploadUrl:$,assetUrn:f}}function RjA(A,Q){let B=A[Q];return M71(B)?B:null}function M71(A){return typeof A==="object"&&A!==null}class bjA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";fetch;cachedUserId=null;constructor(A,Q,B={}){this.config=A;this.logger=Q;this.fetch=B.fetch??globalThis.fetch.bind(globalThis)}async publish(A,Q,B,w){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let $=await this.getAuthor(),f=w?.[0];if(w&&w.length>1)this.logger.warn("LinkedIn document publishing supports one PDF",{count:w.length});let I=null;if(f)I={category:"DOCUMENT",urn:await this.uploadDocument($,f),title:f.filename};else if(B){let F=await this.uploadImage($,B);if(F)I={category:"IMAGE",urn:F}}let D={shareCommentary:{text:A},shareMediaCategory:I?.category??"NONE",...I&&{media:[C5Q(I)]}},Y=await this.fetch(`${this.apiBaseUrl}/ugcPosts`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({author:$,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":D},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!Y.ok){let F=YBA(await Y.text());throw this.logger.error("LinkedIn API error",{status:Y.status,error:F}),Error(`LinkedIn API error: ${Y.status} - ${F}`)}let H=Y.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:H,mediaCategory:I?.category??"NONE"});let W={id:H};if(H)W.url=`https://www.linkedin.com/feed/update/${H}`;return W}async uploadImage(A,Q){try{let B=await this.fetch(`${this.apiBaseUrl}/assets?action=registerUpload`,{method:"POST",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0"},body:JSON.stringify({registerUploadRequest:{recipes:["urn:li:digitalmediaRecipe:feedshare-image"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let D=YBA(await B.text());return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=E71(await B.json());if(!w)return this.logger.warn("LinkedIn image upload registration was malformed"),null;let{uploadUrl:$,assetUrn:f}=w,I=await this.fetch($,{method:"PUT",headers:{Authorization:`Bearer ${this.config.accessToken}`,"Content-Type":Q.mimeType},body:new Uint8Array(Q.data)});if(!I.ok)return this.logger.warn("LinkedIn image binary upload failed",{status:I.status}),null;return this.logger.info("LinkedIn image uploaded",{assetUrn:f}),f}catch(B){return this.logger.warn("LinkedIn image upload error",{error:B}),null}}async uploadDocument(A,Q){let B=await this.fetch(`${this.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-document"],owner:A,serviceRelationships:[{relationshipType:"OWNER",identifier:"urn:li:userGeneratedContent"}]}})});if(!B.ok){let f=YBA(await B.text());throw Error(`LinkedIn document upload registration failed: ${B.status} - ${f}`)}let w=E71(await B.json());if(!w)throw Error("LinkedIn document upload registration 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",{assetUrn:w.assetUrn,filename:Q.filename}),w.assetUrn}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=YBA(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 PjA(A,Q,B={}){return new bjA(A,Q,B)}B0();GA();xw();CjA();var O5Q=J.object({posts:J.array(wBA),totalCount:J.number().optional(),pagination:L9.nullable(),baseUrl:J.string().optional()}),R5Q=J.object({post:wBA});function V71(){return{linkedin:fBA,"social-post-list":b1({name:"social-post-list",description:"Social post list page template",schema:O5Q,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:IBA}}),"social-post-detail":b1({name:"social-post-detail",description:"Individual social post template",schema:R5Q,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:DBA}})}}GA();var b5Q=J.object({prompt:J.string().optional(),content:J.string().optional(),platform:J.enum(["linkedin"]).default("linkedin")}),P5Q=J.object({prompt:J.string().optional(),content:J.string().optional(),title:J.string().optional(),platform:J.enum(["linkedin"]).optional()});function C71(A){A.eval.registerHandler("generation",async(Q)=>{let B=b5Q.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
3780
3780
|
|
|
3781
|
-
${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=P5Q.parse(Q),w=[],$=_$.from(async(H)=>{let W={progress:H.progress};if(H.message!==void 0)W.message=H.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new PE(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(I.success&&I.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!H,Y=H?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:Y,progressSteps:w}})}GA();B0();class mu{sendMessage;logger;entityService;providers;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;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}if(w.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let $=w.metadata.platform,f=this.providers.get($);if(!f){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=AQ(w.content,bD),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);let Y=I.metadata.documents??[],H=await this.fetchDocumentData(Y);try{if(Y.length>0&&H.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let W=Y.length===0?await this.resolveSourceAttachment(I.metadata):[],F=H.length>0?H:W,K=F.length?await f.publish(I.content,w.metadata,D,F):await f.publish(I.content,w.metadata,D),Z=new Date().toISOString(),q=K.id||void 0,E={...I.metadata,status:"published",publishedAt:Z,...q&&{platformPostId:q}},L=uf.createPostContent(E,I.content);await this.entityService.updateEntity({entity:{...w,content:L,metadata:{...w.metadata,status:"published",publishedAt:Z,platformPostId:q}}}),await this.reportSuccess(Q,B,K.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:q})}catch(W){let F=W instanceof Error?W.message:String(W),K={...I.metadata,status:"failed"},Z=uf.createPostContent(K,I.content);await this.entityService.updateEntity({entity:{...w,content:Z,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,F),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:F})}}catch(w){let $=h0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function O71(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 R71(A,Q,B){let w=new mu({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function b71(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=h0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function P71(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${uf.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=h0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function k71(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${uf.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=h0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var j71={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.80",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/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 kjA extends NQ{entityType=uf.entityType;schema=Fk;adapter=uf;providers=new Map;constructor(A){super("social-media",j71,A,MjA)}createGenerationHandler(A){return new PE(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return V71()}getDataSources(){return[new $BA(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),O71(A,this.providers,this.logger),R71(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)b71(A,this.logger),P71(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");k71(A,this.logger),C71(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=PjA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function uu(A){return new kjA(A)}GA();var j5Q=J.enum(["draft","queued","published","failed"]),azw=J.object({status:j5Q.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class jjA{name="internal";async publish(A,Q){return{id:"internal"}}}var l9={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"},b3={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"};GA();var _5Q=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),_71=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),_5Q).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class pW{static instance=null;queues=new Map;static getInstance(){return pW.instance??=new pW,pW.instance}static resetInstance(){pW.instance=null}static createFresh(){return new pW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((I)=>I.entityId===Q);if(w)return{position:w.position};let $=B.length+1,f={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(f),{position:$}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class lW{static instance=null;providers=new Map;defaultProvider=new jjA;static getInstance(){return lW.instance??=new lW,lW.instance}static resetInstance(){lW.instance=null}static createFresh(){return new lW}constructor(){}register(A,Q){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())}}GA();GA();async function v71(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:l9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function y71(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 f=h0($);Q.retryTracker.recordFailure(A.entityId,f);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:f,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function x71(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:l9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function h71(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:l9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function g71(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:b3.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:b3.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function T71(A,Q,B){if(B)B.send({type:b3.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function S71(A,Q,B){if(B)B.send({type:b3.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var v5Q=1000;class _jA{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(v5Q,()=>this.processUnscheduledTypes())}stop(){if(y5Q(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 v71(A,this.deps.getPublishDeps());else await y71(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function y5Q(A){for(let Q of A.values())Q.stop();A.clear()}class vjA{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(){x5Q(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await g71(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 x5Q(A){for(let Q of A.values())Q.stop();A.clear()}class PH{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return PH.instance??=new PH(A),PH.instance}static resetInstance(){if(PH.instance)PH.instance.stop();PH.instance=null}static createFresh(A){return new PH(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new _jA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new vjA({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){x71(A,Q,B,this.publishDeps)}failPublish(A,Q,B){h71(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){T71(A,Q,this.config.messageBus)}failGeneration(A,Q){S71(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}" - ${h0(w)}`)}}}var m71={maxRetries:3,baseDelayMs:5000};class iW{static instance=null;retries=new Map;config;static getInstance(A){return iW.instance??=new iW(A??m71),iW.instance}static resetInstance(){iW.instance=null}static createFresh(A){return new iW(A??m71)}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),f=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:f})}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 i9(A,Q,B,w,$,f,I,D){return i9.fromTZ(i9.tp(A,Q,B,w,$,f,I),D)}i9.fromTZISO=(A,Q,B)=>i9.fromTZ(h5Q(A,Q),B);i9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=yjA(A.tz,B),$=new Date(B.getTime()-w),f=yjA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=yjA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};i9.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}};i9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function yjA(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 h5Q(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("+")?i9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):i9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}i9.minitz=i9;var xjA=32,pu=31|xjA,l71=[1,2,4,8,16],u71=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 PD(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,pu),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,Y]=f,H=parseInt(I,10)+B,W=parseInt(D,10)+B,F=parseInt(Y,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))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(H>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=H;K<=W;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),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=I;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=I;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|xjA;else if(Q===pu)this.dayOfWeek[A]=pu;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|l71[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},c71=[31,28,31,30,31,30,31,31,30,31,30,31],cG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],PD=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&pu&&l71[I-1]&$)return!0;if($&xjA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=i9.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>c71[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=i9.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(i9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=c71[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let H=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==I&&(H=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(Y-$-1))%7];if(W&&W&pu)W=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?H=H||W:H=H&&W}if(H)return this[B]=Y-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,cG[w][0],Q,cG[w][2]);if($>1){let f=w+1;for(;f<cG.length;)this[cG[f][0]]=-cG[f][2],f++;if($===3)return this[cG[w][1]]++,this[cG[w][0]]=-cG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=cG.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)):i9.fromTZ(i9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function g5Q(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 PD(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new PD(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 cu(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function T5Q(A){return cu(A)}function S5Q(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var p71=30000,HBA=[],hjA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(cu(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(cu(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=g5Q(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 u71("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new PD(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new u71(A,this.options.timezone),this.name){if(HBA.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");HBA.push(this)}return $!==void 0&&T5Q($)&&(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 PD||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new PD(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=HBA.indexOf(this);A>=0&&HBA.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>p71&&(Q=p71),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&S5Q(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new PD(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){cu(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new PD(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&&cu(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 PD(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 PD(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 PD(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 PD(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 XBA{scheduleCron(A,Q){let B=new hjA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new hjA(A).stop()}}B0();GA();var gjA=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)")}),TjA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),m5Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(TjA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),u5Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),SjA=J.union([m5Q,u5Q]);function WBA(A,Q,B){return{...YQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",gjA,async($)=>{let{action:f,entityType:I,entityId:D,position:Y}=$;switch(f){case"list":return c5Q(B,I);case"add":return p5Q(B,I,D);case"remove":return l5Q(B,I,D);case"reorder":return i5Q(B,I,D,Y);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:SjA}}async function c5Q(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function p5Q(A,Q,B){let w=mjA("add",Q,B);if(!w.success)return w.error;let $=await A.add(w.entityType,w.entityId);return{success:!0,data:{entityType:w.entityType,entityId:w.entityId,position:$.position},message:`Added to queue at position ${$.position}`}}async function l5Q(A,Q,B){let w=mjA("remove",Q,B);if(!w.success)return w.error;return await A.remove(w.entityType,w.entityId),{success:!0,data:{entityType:w.entityType,entityId:w.entityId},message:"Removed from queue"}}async function i5Q(A,Q,B,w){let $=mjA("reorder",Q,B);if(!$.success)return $.error;let f=r5Q(w);if(!f.success)return f.error;return await A.reorder($.entityType,$.entityId,f.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:f.position},message:`Moved to position ${f.position}`}}function mjA(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 r5Q(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}}B0();GA();B0();GA();var d5Q=J.object({id:J.string().min(1)});async function r71(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=n5Q(Q.content),D=w?await a5Q(A,w):void 0,Y;if($&&$.length>0){let W=await t5Q(A,$);if(W.length>0)Y=W}Y??=await s5Q(A,f,I);let H={bodyContent:B};if(D)H.imageData=D;if(Y&&Y.length>0)H.documentData=Y;return H}function n5Q(A){try{let Q=AQ(A,J.record(J.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=o5Q(Q.metadata.documents),f=i71(Q.metadata.sourceEntityType),I=i71(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function o5Q(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=d5Q.safeParse(Q);return B.success?[B.data]:[]})}function i71(A){return typeof A==="string"&&A.length>0?A:void 0}async function s5Q(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 a5Q(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=d71(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function t5Q(A,Q){return(await Promise.all(Q.map((w)=>e5Q(A,w)))).filter((w)=>w!==void 0)}async function e5Q(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=d71(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:A$Q(B,Q.id)}}function d71(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function A$Q(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}var ujA=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")}),Q$Q=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()}),B$Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),cjA=J.union([Q$Q,B$Q]);function UBA(A,Q,B){return{...YQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",ujA,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let Y=await w$Q(A,f,I,D);if(!Y)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(Y.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(f))return{success:!1,error:`No publish provider registered for ${f}. Check that the required credentials are configured.`};let H=B.get(f),{bodyContent:W,imageData:F,documentData:K}=await r71(A,Y),Z=await H.publish(W,Y.metadata,F,K);return await A.entityService.updateEntity({entity:{...Y,metadata:{...Y.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:Z.id}}}),{success:!0,data:{entityType:f,entityId:Y.id,platformId:Z.id,url:Z.url},message:`Published ${f}:${Y.id}`}}),outputSchema:cjA}}async function w$Q(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}B0();GA();function n71(A,Q){$$Q(A,Q),f$Q(A,Q)}function $$Q(A,Q){A.messaging.subscribe(l9.REGISTER,async(B)=>I$Q(Q,B.payload)),A.messaging.subscribe(l9.QUEUE,async(B)=>D$Q(A,Q,B.payload)),A.messaging.subscribe(l9.DIRECT,async(B)=>Y$Q(A,Q,B.payload)),A.messaging.subscribe(l9.REMOVE,async(B)=>H$Q(Q,B.payload)),A.messaging.subscribe(l9.REORDER,async(B)=>X$Q(Q,B.payload)),A.messaging.subscribe(l9.LIST,async(B)=>W$Q(A,Q,B.payload)),A.messaging.subscribe(l9.REPORT_SUCCESS,async(B)=>U$Q(Q,B.payload)),A.messaging.subscribe(l9.REPORT_FAILURE,async(B)=>J$Q(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function f$Q(A,Q){A.messaging.subscribe(b3.REPORT_SUCCESS,async(B)=>G$Q(Q,B.payload)),A.messaging.subscribe(b3.REPORT_FAILURE,async(B)=>F$Q(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function I$Q(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 f=h0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function D$Q(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:l9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=h0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function Y$Q(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:l9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function H$Q(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=h0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function X$Q(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=h0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function W$Q(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:l9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=h0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function U$Q(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 J$Q(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount,willRetry:f?.willRetry}),{success:!0}}async function G$Q(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 F$Q(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}}GA();async function o71(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:h0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${h0($)}`}}}function s71(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=K$Q(Q);return PH.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new XBA,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(Y,H)=>o71(Q.entityService,I,Y,H)})}function K$Q(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 a71(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var Z$Q=["draft","queued","published","failed"];async function t71(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:()=>z$Q(A)}})}async function z$Q(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=N$Q(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:q$Q(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function N$Q(A){return Z$Q.find((Q)=>Q===A)}function q$Q(A,Q){return typeof Q==="string"?Q:A}var e71={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.80",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 pjA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",e71,A??{},_71)}async onRegister(A){this.pluginContext=A,this.queueManager=pW.createFresh(),this.providerRegistry=lW.createFresh(),this.retryTracker=iW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=s71({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),n71(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await a71(A.entityService,this.queueManager,this.logger),await t71(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[WBA(this.pluginContext,this.id,this.queueManager),UBA(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(),pW.resetInstance(),lW.resetInstance(),iW.resetInstance()}}function ljA(A){return new pjA(A)}B0();GA();var Af1=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")}),ijA=J.object({cloudflare:Af1.optional()});B0();GA();var E$Q=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 M$Q(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 Qf1(A,Q,B){let w=[];if(!B)return w;return w.push(YQ(A,"query",`Query website analytics from Cloudflare.
|
|
3781
|
+
${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=P5Q.parse(Q),w=[],$=_$.from(async(H)=>{let W={progress:H.progress};if(H.message!==void 0)W.message=H.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new PE(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,Y;if(I.success&&I.entityId){let H=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!H,Y=H?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:Y,progressSteps:w}})}GA();B0();class mu{sendMessage;logger;entityService;providers;resolveAttachment;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers,this.resolveAttachment=A.resolveAttachment}async handle(A){let{entityType:Q,entityId:B}=A;if(Q!=="social-post")return;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}if(w.metadata.status==="published"){this.logger.debug("Post already published, skipping",{entityId:B});return}let $=w.metadata.platform,f=this.providers.get($);if(!f){await this.reportFailure(Q,B,`No provider configured for platform: ${$}`);return}let I=AQ(w.content,bD),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);let Y=I.metadata.documents??[],H=await this.fetchDocumentData(Y);try{if(Y.length>0&&H.length===0)throw Error(`Refusing to publish: ${Y.length} document(s) referenced but none could be fetched`);let W=Y.length===0?await this.resolveSourceAttachment(I.metadata):[],F=H.length>0?H:W,K=F.length?await f.publish(I.content,w.metadata,D,F):await f.publish(I.content,w.metadata,D),Z=new Date().toISOString(),q=K.id||void 0,E={...I.metadata,status:"published",publishedAt:Z,...q&&{platformPostId:q}},L=uf.createPostContent(E,I.content);await this.entityService.updateEntity({entity:{...w,content:L,metadata:{...w.metadata,status:"published",publishedAt:Z,platformPostId:q}}}),await this.reportSuccess(Q,B,K.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:q})}catch(W){let F=W instanceof Error?W.message:String(W),K={...I.metadata,status:"failed"},Z=uf.createPostContent(K,I.content);await this.entityService.updateEntity({entity:{...w,content:Z,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,F),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:F})}}catch(w){let $=h0(w);this.logger.error("Unexpected error in publish handler",{entityId:B,error:$}),await this.reportFailure(Q,B,$)}}async reportSuccess(A,Q,B){await this.sendMessage({type:"publish:report:success",payload:{entityType:A,entityId:Q,result:{id:B}}})}async reportFailure(A,Q,B){await this.sendMessage({type:"publish:report:failure",payload:{entityType:A,entityId:Q,error:B}})}async resolveSourceAttachment(A){if(!this.resolveAttachment||!A.sourceEntityType||!A.sourceEntityId)return[];let Q=await this.resolveAttachment({sourceEntityType:A.sourceEntityType,sourceEntityId:A.sourceEntityId,attachmentType:"carousel"});return Q?[Q]:[]}async fetchDocumentData(A){if(!A?.length)return[];let Q=[];for(let B of A){let w=await this.fetchSingleDocumentData(B.id);if(w)Q.push(w)}return Q}async fetchSingleDocumentData(A){try{let Q=await this.entityService.getEntity({entityType:"document",id:A});if(!Q){this.logger.warn("Document not found",{documentId:A});return}let B=Q.content.match(/^data:application\/pdf;base64,(.+)$/);if(!B?.[1]){this.logger.warn("Invalid document data URL format",{documentId:A});return}let w=typeof Q.metadata.filename==="string"?Q.metadata.filename:`${A}.pdf`;return{type:"document",data:Buffer.from(B[1],"base64"),mimeType:"application/pdf",filename:w}}catch(Q){this.logger.warn("Failed to fetch document",{documentId:A,error:Q});return}}async fetchImageData(A){try{let Q=await this.entityService.getEntity({entityType:"image",id:A});if(!Q){this.logger.warn("Cover image not found",{imageId:A});return}let w=Q.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2]){this.logger.warn("Invalid image data URL format",{imageId:A});return}let $=w[1],f=w[2];return{data:Buffer.from(f,"base64"),mimeType:$}}catch(Q){this.logger.warn("Failed to fetch cover image",{imageId:A,error:Q});return}}}function O71(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 R71(A,Q,B){let w=new mu({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q,resolveAttachment:A.attachments.resolve});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function b71(A,Q){A.messaging.subscribe("entity:updated",async(B)=>{let{entityType:w,entityId:$,entity:f}=B.payload;if(w!=="post")return{success:!0};if(f.metadata?.status!=="queued")return{success:!0};try{if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:$}},limit:1}})).length>0)return Q.debug(`Social post already exists for ${$}, skipping auto-generate`),{success:!0};return await A.messaging.send({type:"social:auto-generate",payload:{sourceEntityType:w,sourceEntityId:$,platform:"linkedin"}}),Q.info(`Auto-generate social post triggered for queued post ${$}`),{success:!0}}catch(D){let Y=h0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:Y}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function P71(A,Q){A.messaging.subscribe("social:auto-generate",async(B)=>{let{sourceEntityType:w,sourceEntityId:$,platform:f}=B.payload;try{let I=await A.jobs.enqueue({type:`${uf.entityType}:generation`,data:{sourceEntityType:w,sourceEntityId:$,platform:f,addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info(`Social post generation job enqueued for ${w}/${$}`,{jobId:I}),{success:!0,jobId:I}}catch(I){let D=h0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function k71(A,Q){A.messaging.subscribe("generate:execute",async(B)=>{let{entityType:w}=B.payload;if(w!=="social-post")return{success:!0};Q.info("Received generate:execute for social-post");try{let $=await A.entityService.listEntities({entityType:"post",options:{filter:{metadata:{status:"published"}},limit:5}});if($.length===0)return Q.info("No published posts found for social post generation"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"No published posts available for social post generation"}}),{success:!0};let f=null;for(let D of $)if((await A.entityService.listEntities({entityType:"social-post",options:{filter:{metadata:{sourceEntityType:"post",sourceEntityId:D.id}},limit:1}})).length===0){f=D;break}if(!f)return Q.info("All recent posts already have social posts"),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:"All recent posts already have social posts generated"}}),{success:!0};let I=await A.jobs.enqueue({type:`${uf.entityType}:generation`,data:{sourceEntityType:"post",sourceEntityId:f.id,platform:"linkedin",addToQueue:!1},toolContext:{interfaceType:"job",userId:"system"}});return Q.info("Social post generation job queued",{jobId:I,sourcePostId:f.id}),{success:!0}}catch($){let f=h0($);return Q.error("Failed to handle generate:execute:",{error:f}),await A.messaging.send({type:"generate:report:failure",payload:{entityType:"social-post",error:f}}),{success:!0}}}),Q.debug("Subscribed to generate:execute messages")}var j71={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.81",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/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 kjA extends NQ{entityType=uf.entityType;schema=Fk;adapter=uf;providers=new Map;constructor(A){super("social-media",j71,A,MjA)}createGenerationHandler(A){return new PE(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return V71()}getDataSources(){return[new $BA(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),O71(A,this.providers,this.logger),R71(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)b71(A,this.logger),P71(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");k71(A,this.logger),C71(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=PjA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function uu(A){return new kjA(A)}GA();var j5Q=J.enum(["draft","queued","published","failed"]),azw=J.object({status:j5Q.default("draft"),queueOrder:J.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:J.string().datetime().optional()});class jjA{name="internal";async publish(A,Q){return{id:"internal"}}}var l9={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"},b3={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"};GA();var _5Q=J.object({skipIfDraftExists:J.boolean().optional(),minSourceEntities:J.number().optional(),maxUnpublishedDrafts:J.number().optional(),sourceEntityType:J.string().optional()}),_71=J.object({entitySchedules:J.record(J.string(),J.string()).optional(),generationSchedules:J.record(J.string(),J.string()).optional(),generationConditions:J.record(J.string(),_5Q).optional(),maxRetries:J.number().optional().default(3),retryBaseDelayMs:J.number().optional().default(5000)});class pW{static instance=null;queues=new Map;static getInstance(){return pW.instance??=new pW,pW.instance}static resetInstance(){pW.instance=null}static createFresh(){return new pW}constructor(){}async add(A,Q){let B=this.getOrCreateQueue(A),w=B.find((I)=>I.entityId===Q);if(w)return{position:w.position};let $=B.length+1,f={entityId:Q,entityType:A,position:$,queuedAt:new Date().toISOString()};return B.push(f),{position:$}}async remove(A,Q){let B=this.queues.get(A);if(!B)return;let w=B.findIndex(($)=>$.entityId===Q);if(w===-1)return;B.splice(w,1),this.recalculatePositions(B)}async reorder(A,Q,B){let w=this.queues.get(A);if(!w)return;let $=w.findIndex((D)=>D.entityId===Q);if($===-1)return;let[f]=w.splice($,1);if(!f)return;let I=Math.max(0,Math.min(B-1,w.length));w.splice(I,0,f),this.recalculatePositions(w)}async list(A){let Q=this.queues.get(A);if(!Q)return[];return[...Q]}async getNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;return Q[0]??null}async getNextAcrossTypes(){let A=null;for(let Q of this.queues.values()){let B=Q[0];if(!B)continue;if(!A||B.queuedAt<A.queuedAt)A=B}return A}async popNext(A){let Q=this.queues.get(A);if(!Q||Q.length===0)return null;let B=Q.shift()??null;if(B)this.recalculatePositions(Q);return B}getRegisteredTypes(){return Array.from(this.queues.keys())}async getQueuedEntityTypes(){let A=[];for(let[Q,B]of this.queues.entries())if(B.length>0)A.push(Q);return A}getOrCreateQueue(A){let Q=this.queues.get(A);if(!Q)Q=[],this.queues.set(A,Q);return Q}recalculatePositions(A){A.forEach((Q,B)=>{Q.position=B+1})}}class lW{static instance=null;providers=new Map;defaultProvider=new jjA;static getInstance(){return lW.instance??=new lW,lW.instance}static resetInstance(){lW.instance=null}static createFresh(){return new lW}constructor(){}register(A,Q){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())}}GA();GA();async function v71(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:l9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function y71(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 f=h0($);Q.retryTracker.recordFailure(A.entityId,f);let I=Q.retryTracker.getRetryInfo(A.entityId);Q.onFailed?.({entityType:A.entityType,entityId:A.entityId,error:f,retryCount:I?.retryCount??1,willRetry:I?.willRetry??!1})}}function x71(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:l9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function h71(A,Q,B,w){w.retryTracker.recordFailure(Q,B);let $=w.retryTracker.getRetryInfo(Q),f={entityType:A,entityId:Q,error:B,retryCount:$?.retryCount??1,willRetry:$?.willRetry??!1};if(w.messageBus)w.messageBus.send({type:l9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function g71(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:b3.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:b3.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function T71(A,Q,B){if(B)B.send({type:b3.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function S71(A,Q,B){if(B)B.send({type:b3.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var v5Q=1000;class _jA{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(v5Q,()=>this.processUnscheduledTypes())}stop(){if(y5Q(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 v71(A,this.deps.getPublishDeps());else await y71(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function y5Q(A){for(let Q of A.values())Q.stop();A.clear()}class vjA{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(){x5Q(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await g71(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 x5Q(A){for(let Q of A.values())Q.stop();A.clear()}class PH{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return PH.instance??=new PH(A),PH.instance}static resetInstance(){if(PH.instance)PH.instance.stop();PH.instance=null}static createFresh(A){return new PH(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new _jA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new vjA({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){x71(A,Q,B,this.publishDeps)}failPublish(A,Q,B){h71(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){T71(A,Q,this.config.messageBus)}failGeneration(A,Q){S71(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}" - ${h0(w)}`)}}}var m71={maxRetries:3,baseDelayMs:5000};class iW{static instance=null;retries=new Map;config;static getInstance(A){return iW.instance??=new iW(A??m71),iW.instance}static resetInstance(){iW.instance=null}static createFresh(A){return new iW(A??m71)}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),f=Date.now()+$;this.retries.set(A,{entityId:A,retryCount:w,lastError:Q,nextRetryAt:f})}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 i9(A,Q,B,w,$,f,I,D){return i9.fromTZ(i9.tp(A,Q,B,w,$,f,I),D)}i9.fromTZISO=(A,Q,B)=>i9.fromTZ(h5Q(A,Q),B);i9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=yjA(A.tz,B),$=new Date(B.getTime()-w),f=yjA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=yjA(A.tz,I);if(D-f===0)return I;if(!Q&&D-f>0)return I;if(Q)throw Error("Invalid date passed to fromTZ()");return $}};i9.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}};i9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function yjA(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 h5Q(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("+")?i9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):i9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}i9.minitz=i9;var xjA=32,pu=31|xjA,l71=[1,2,4,8,16],u71=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 PD(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,pu),this.dayOfWeek[7]&&(this.dayOfWeek[0]=this.dayOfWeek[7])}partToArray(A,Q,B,w){let $=this[A],f=A==="day"&&this.lastDayOfMonth;if(Q===""&&!f)throw TypeError("CronPattern: configuration entry "+A+" ("+Q+") is empty, check for trailing spaces.");if(Q==="*")return $.fill(w);let I=Q.split(",");if(I.length>1)for(let D=0;D<I.length;D++)this.partToArray(A,I[D],B,w);else Q.indexOf("-")!==-1&&Q.indexOf("/")!==-1?this.handleRangeWithStepping(Q,A,B,w):Q.indexOf("-")!==-1?this.handleRange(Q,A,B,w):Q.indexOf("/")!==-1?this.handleStepping(Q,A,B,w):Q!==""&&this.handleNumber(Q,A,B,w)}throwAtIllegalCharacters(A){for(let Q=0;Q<A.length;Q++)if((Q===5?/[^/*0-9,\-#L]+/:/[^/*0-9,-]+/).test(A[Q]))throw TypeError("CronPattern: configuration entry "+Q+" ("+A[Q]+") contains illegal characters.")}handleNumber(A,Q,B,w){let $=this.extractNth(A,Q),f=parseInt($[0],10)+B;if(isNaN(f))throw TypeError("CronPattern: "+Q+" is not a number: '"+A+"'");this.setPart(Q,f,$[1]||w)}setPart(A,Q,B){if(!Object.prototype.hasOwnProperty.call(this,A))throw TypeError("CronPattern: Invalid part specified: "+A);if(A==="dayOfWeek"){if(Q===7&&(Q=0),Q<0||Q>6)throw RangeError("CronPattern: Invalid value for dayOfWeek: "+Q);this.setNthWeekdayOfMonth(Q,B);return}if(A==="second"||A==="minute"){if(Q<0||Q>=60)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="hour"){if(Q<0||Q>=24)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="day"){if(Q<0||Q>=31)throw RangeError("CronPattern: Invalid value for "+A+": "+Q)}else if(A==="month"&&(Q<0||Q>=12))throw RangeError("CronPattern: Invalid value for "+A+": "+Q);this[A][Q]=B}handleRangeWithStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].match(/^(\d+)-(\d+)\/(\d+)$/);if(f===null)throw TypeError("CronPattern: Syntax error, illegal range with stepping: '"+A+"'");let[,I,D,Y]=f,H=parseInt(I,10)+B,W=parseInt(D,10)+B,F=parseInt(Y,10);if(isNaN(H))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(W))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(H>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=H;K<=W;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),f=$[0].split("-");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal range: '"+A+"'");let I=parseInt(f[0],10)+B,D=parseInt(f[1],10)+B;if(isNaN(I))throw TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(I>D)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let Y=I;Y<=D;Y++)this.setPart(Q,Y,$[1]||w)}handleStepping(A,Q,B,w){let $=this.extractNth(A,Q),f=$[0].split("/");if(f.length!==2)throw TypeError("CronPattern: Syntax error, illegal stepping: '"+A+"'");f[0]===""&&(f[0]="*");let I=0;f[0]!=="*"&&(I=parseInt(f[0],10)+B);let D=parseInt(f[1],10);if(isNaN(D))throw TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(D===0)throw TypeError("CronPattern: Syntax error, illegal stepping: 0");if(D>this[Q].length)throw TypeError("CronPattern: Syntax error, max steps for part is ("+this[Q].length+")");for(let Y=I;Y<this[Q].length;Y+=D)this.setPart(Q,Y,$[1]||w)}replaceAlphaDays(A){return A.replace(/-sun/gi,"-7").replace(/sun/gi,"0").replace(/mon/gi,"1").replace(/tue/gi,"2").replace(/wed/gi,"3").replace(/thu/gi,"4").replace(/fri/gi,"5").replace(/sat/gi,"6")}replaceAlphaMonths(A){return A.replace(/jan/gi,"1").replace(/feb/gi,"2").replace(/mar/gi,"3").replace(/apr/gi,"4").replace(/may/gi,"5").replace(/jun/gi,"6").replace(/jul/gi,"7").replace(/aug/gi,"8").replace(/sep/gi,"9").replace(/oct/gi,"10").replace(/nov/gi,"11").replace(/dec/gi,"12")}handleNicknames(A){let Q=A.trim().toLowerCase();return Q==="@yearly"||Q==="@annually"?"0 0 1 1 *":Q==="@monthly"?"0 0 1 * *":Q==="@weekly"?"0 0 * * 0":Q==="@daily"?"0 0 * * *":Q==="@hourly"?"0 * * * *":A}setNthWeekdayOfMonth(A,Q){if(typeof Q!="number"&&Q==="L")this.dayOfWeek[A]=this.dayOfWeek[A]|xjA;else if(Q===pu)this.dayOfWeek[A]=pu;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|l71[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},c71=[31,28,31,30,31,30,31,31,30,31,30,31],cG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],PD=class A{tz;ms;second;minute;hour;day;month;year;constructor(Q,B){if(this.tz=B,Q&&Q instanceof Date)if(!isNaN(Q))this.fromDate(Q);else throw TypeError("CronDate: Invalid date passed to CronDate constructor");else if(Q===void 0)this.fromDate(new Date);else if(Q&&typeof Q=="string")this.fromString(Q);else if(Q instanceof A)this.fromCronDate(Q);else throw TypeError("CronDate: Invalid type ("+typeof Q+") passed to CronDate constructor")}isNthWeekdayOfMonth(Q,B,w,$){let f=new Date(Date.UTC(Q,B,w)).getUTCDay(),I=0;for(let D=1;D<=w;D++)new Date(Date.UTC(Q,B,D)).getUTCDay()===f&&I++;if($&pu&&l71[I-1]&$)return!0;if($&xjA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let Y=w+1;Y<=D;Y++)if(new Date(Date.UTC(Q,B,Y)).getUTCDay()===f)return!1;return!0}return!1}fromDate(Q){if(this.tz!==void 0)if(typeof this.tz=="number")this.ms=Q.getUTCMilliseconds(),this.second=Q.getUTCSeconds(),this.minute=Q.getUTCMinutes()+this.tz,this.hour=Q.getUTCHours(),this.day=Q.getUTCDate(),this.month=Q.getUTCMonth(),this.year=Q.getUTCFullYear(),this.apply();else{let B=i9.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>c71[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=i9.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(i9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=c71[this.month]:I=new Date(Date.UTC(this.year,this.month+1,0,0,0,0,0)).getUTCDate());let D=!w.starDOW&&B=="day"?new Date(Date.UTC(this.year,this.month,1,0,0,0,0)).getUTCDay():void 0;for(let Y=this[B]+$;Y<w[B].length;Y++){let H=w[B][Y];if(B==="day"&&w.lastDayOfMonth&&Y-$==I&&(H=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(Y-$-1))%7];if(W&&W&pu)W=this.isNthWeekdayOfMonth(this.year,this.month,Y-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?H=H||W:H=H&&W}if(H)return this[B]=Y-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,cG[w][0],Q,cG[w][2]);if($>1){let f=w+1;for(;f<cG.length;)this[cG[f][0]]=-cG[f][2],f++;if($===3)return this[cG[w][1]]++,this[cG[w][0]]=-cG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=cG.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)):i9.fromTZ(i9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function g5Q(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 PD(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new PD(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 cu(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function T5Q(A){return cu(A)}function S5Q(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var p71=30000,HBA=[],hjA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(cu(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(cu(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=g5Q(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 u71("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new PD(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new u71(A,this.options.timezone),this.name){if(HBA.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");HBA.push(this)}return $!==void 0&&T5Q($)&&(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 PD||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new PD(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=HBA.indexOf(this);A>=0&&HBA.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>p71&&(Q=p71),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&S5Q(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new PD(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){cu(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new PD(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&&cu(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 PD(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 PD(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 PD(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 PD(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 XBA{scheduleCron(A,Q){let B=new hjA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new hjA(A).stop()}}B0();GA();var gjA=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)")}),TjA=J.object({position:J.number(),entityType:J.string(),entityId:J.string(),queuedAt:J.string()}),m5Q=J.object({success:J.literal(!0),message:J.string().optional(),data:J.object({queue:J.array(TjA).optional(),entityType:J.string().optional(),entityId:J.string().optional(),position:J.number().optional()}).optional()}),u5Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),SjA=J.union([m5Q,u5Q]);function WBA(A,Q,B){return{...YQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",gjA,async($)=>{let{action:f,entityType:I,entityId:D,position:Y}=$;switch(f){case"list":return c5Q(B,I);case"add":return p5Q(B,I,D);case"remove":return l5Q(B,I,D);case"reorder":return i5Q(B,I,D,Y);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:SjA}}async function c5Q(A,Q){let B=[];if(Q)B=await A.list(Q);else{let $=A.getRegisteredTypes();for(let f of $){let I=await A.list(f);B.push(...I)}B.sort((f,I)=>new Date(f.queuedAt).getTime()-new Date(I.queuedAt).getTime())}if(B.length===0)return{success:!0,data:{queue:[]},message:"No items in queue"};return{success:!0,data:{queue:B.map(($,f)=>({position:f+1,entityType:$.entityType,entityId:$.entityId,queuedAt:$.queuedAt}))},message:`${B.length} items in queue`}}async function p5Q(A,Q,B){let w=mjA("add",Q,B);if(!w.success)return w.error;let $=await A.add(w.entityType,w.entityId);return{success:!0,data:{entityType:w.entityType,entityId:w.entityId,position:$.position},message:`Added to queue at position ${$.position}`}}async function l5Q(A,Q,B){let w=mjA("remove",Q,B);if(!w.success)return w.error;return await A.remove(w.entityType,w.entityId),{success:!0,data:{entityType:w.entityType,entityId:w.entityId},message:"Removed from queue"}}async function i5Q(A,Q,B,w){let $=mjA("reorder",Q,B);if(!$.success)return $.error;let f=r5Q(w);if(!f.success)return f.error;return await A.reorder($.entityType,$.entityId,f.position),{success:!0,data:{entityType:$.entityType,entityId:$.entityId,position:f.position},message:`Moved to position ${f.position}`}}function mjA(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 r5Q(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}}B0();GA();B0();GA();var d5Q=J.object({id:J.string().min(1)});async function r71(A,Q){let{bodyContent:B,coverImageId:w,documents:$,sourceEntityType:f,sourceEntityId:I}=n5Q(Q.content),D=w?await a5Q(A,w):void 0,Y;if($&&$.length>0){let W=await t5Q(A,$);if(W.length>0)Y=W}Y??=await s5Q(A,f,I);let H={bodyContent:B};if(D)H.imageData=D;if(Y&&Y.length>0)H.documentData=Y;return H}function n5Q(A){try{let Q=AQ(A,J.record(J.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0,$=o5Q(Q.metadata.documents),f=i71(Q.metadata.sourceEntityType),I=i71(Q.metadata.sourceEntityId);return{bodyContent:Q.content,...w&&{coverImageId:w},...$.length>0&&{documents:$},...f&&{sourceEntityType:f},...I&&{sourceEntityId:I}}}catch{return{bodyContent:A}}}function o5Q(A){if(!Array.isArray(A))return[];return A.flatMap((Q)=>{let B=d5Q.safeParse(Q);return B.success?[B.data]:[]})}function i71(A){return typeof A==="string"&&A.length>0?A:void 0}async function s5Q(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 a5Q(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=d71(B.content);if(!w?.mimeType.startsWith("image/"))return;return{data:w.data,mimeType:w.mimeType}}async function t5Q(A,Q){return(await Promise.all(Q.map((w)=>e5Q(A,w)))).filter((w)=>w!==void 0)}async function e5Q(A,Q){let B=await A.entityService.getEntity({entityType:"document",id:Q.id});if(!B?.content)return;let w=d71(B.content);if(w?.mimeType!=="application/pdf")return;return{type:"document",data:w.data,mimeType:"application/pdf",filename:A$Q(B,Q.id)}}function d71(A){let Q=A.match(/^data:([^;]+);base64,(.+)$/);if(!Q?.[1]||!Q[2])return;return{mimeType:Q[1],data:Buffer.from(Q[2],"base64")}}function A$Q(A,Q){let B=A.metadata.filename;return typeof B==="string"&&B.length>0?B:`${Q}.pdf`}var ujA=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")}),Q$Q=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()}),B$Q=J.object({success:J.literal(!1),error:J.string(),code:J.string().optional()}),cjA=J.union([Q$Q,B$Q]);function UBA(A,Q,B){return{...YQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",ujA,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let Y=await w$Q(A,f,I,D);if(!Y)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(Y.metadata.status==="published")return{success:!1,error:"Entity is already published"};if(!B.has(f))return{success:!1,error:`No publish provider registered for ${f}. Check that the required credentials are configured.`};let H=B.get(f),{bodyContent:W,imageData:F,documentData:K}=await r71(A,Y),Z=await H.publish(W,Y.metadata,F,K);return await A.entityService.updateEntity({entity:{...Y,metadata:{...Y.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:Z.id}}}),{success:!0,data:{entityType:f,entityId:Y.id,platformId:Z.id,url:Z.url},message:`Published ${f}:${Y.id}`}}),outputSchema:cjA}}async function w$Q(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}B0();GA();function n71(A,Q){$$Q(A,Q),f$Q(A,Q)}function $$Q(A,Q){A.messaging.subscribe(l9.REGISTER,async(B)=>I$Q(Q,B.payload)),A.messaging.subscribe(l9.QUEUE,async(B)=>D$Q(A,Q,B.payload)),A.messaging.subscribe(l9.DIRECT,async(B)=>Y$Q(A,Q,B.payload)),A.messaging.subscribe(l9.REMOVE,async(B)=>H$Q(Q,B.payload)),A.messaging.subscribe(l9.REORDER,async(B)=>X$Q(Q,B.payload)),A.messaging.subscribe(l9.LIST,async(B)=>W$Q(A,Q,B.payload)),A.messaging.subscribe(l9.REPORT_SUCCESS,async(B)=>U$Q(Q,B.payload)),A.messaging.subscribe(l9.REPORT_FAILURE,async(B)=>J$Q(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function f$Q(A,Q){A.messaging.subscribe(b3.REPORT_SUCCESS,async(B)=>G$Q(Q,B.payload)),A.messaging.subscribe(b3.REPORT_FAILURE,async(B)=>F$Q(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function I$Q(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 f=h0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function D$Q(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:l9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=h0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function Y$Q(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:l9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function H$Q(A,Q){let{entityType:B,entityId:w}=Q;try{return await A.queueManager.remove(B,w),A.logger.debug(`Entity removed from queue: ${w}`,{entityType:B}),{success:!0}}catch($){let f=h0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function X$Q(A,Q){let{entityType:B,entityId:w,position:$}=Q;try{return await A.queueManager.reorder(B,w,$),A.logger.debug(`Entity reordered: ${w}`,{entityType:B,newPosition:$}),{success:!0}}catch(f){let I=h0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function W$Q(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:l9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=h0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function U$Q(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 J$Q(A,Q){let{entityType:B,entityId:w,error:$}=Q;A.scheduler.failPublish(B,w,$);let f=A.retryTracker.getRetryInfo(w);return A.logger.info(`Publish reported failure: ${w}`,{entityType:B,error:$,retryCount:f?.retryCount,willRetry:f?.willRetry}),{success:!0}}async function G$Q(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 F$Q(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}}GA();async function o71(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:h0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${h0($)}`}}}function s71(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=K$Q(Q);return PH.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new XBA,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(Y,H)=>o71(Q.entityService,I,Y,H)})}function K$Q(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 a71(A,Q,B){let w=A.getEntityTypes();for(let f of w){let I=await A.listEntities({entityType:f,options:{filter:{metadata:{status:"queued"}}}});for(let D of I)await Q.add(D.entityType,D.id)}let $=0;for(let f of w){let I=await Q.list(f);$+=I.length}if($>0)B.info(`Rebuilt queue with ${$} queued entities`)}var Z$Q=["draft","queued","published","failed"];async function t71(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:()=>z$Q(A)}})}async function z$Q(A){let Q=A.entityService.getEntityTypes(),B=[],w={draft:0,queued:0,published:0,failed:0};for(let $ of Q){let f=await A.entityService.listEntities({entityType:$});for(let I of f){let D=N$Q(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:q$Q(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function N$Q(A){return Z$Q.find((Q)=>Q===A)}function q$Q(A,Q){return typeof Q==="string"?Q:A}var e71={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.81",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 pjA extends YB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",e71,A??{},_71)}async onRegister(A){this.pluginContext=A,this.queueManager=pW.createFresh(),this.providerRegistry=lW.createFresh(),this.retryTracker=iW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=s71({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),n71(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await a71(A.entityService,this.queueManager,this.logger),await t71(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[WBA(this.pluginContext,this.id,this.queueManager),UBA(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(),pW.resetInstance(),lW.resetInstance(),iW.resetInstance()}}function ljA(A){return new pjA(A)}B0();GA();var Af1=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")}),ijA=J.object({cloudflare:Af1.optional()});B0();GA();var E$Q=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 M$Q(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 Qf1(A,Q,B){let w=[];if(!B)return w;return w.push(YQ(A,"query",`Query website analytics from Cloudflare.
|
|
3782
3782
|
|
|
3783
3783
|
Date range options (use only one):
|
|
3784
3784
|
- No params: yesterday only
|
|
@@ -3916,7 +3916,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,E$Q,
|
|
|
3916
3916
|
}
|
|
3917
3917
|
}
|
|
3918
3918
|
}
|
|
3919
|
-
`,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}))}}GA();var djA=7,V$Q=10;function wf1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=DV(),B=cl(djA),w=aF(B),$=aF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:V$Q})]);return{days:djA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:djA}}}}var $f1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
3919
|
+
`,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}))}}GA();var djA=7,V$Q=10;function wf1(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=DV(),B=cl(djA),w=aF(B),$=aF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:V$Q})]);return{days:djA,startDate:w,endDate:$,pageviews:f.pageviews,visitors:f.visitors,topPages:I}}catch(f){return{error:f instanceof Error?f.message:"Failed to fetch analytics",days:djA}}}}var $f1={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.81",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 ff1 extends YB{cloudflareClient;constructor(A={}){super("analytics",$f1,A,ijA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new rjA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",wf1(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:Bf1(Q)}})}async getTools(){return Qf1(this.id,this.getContext(),this.cloudflareClient)}}function O$Q(A={}){return new ff1(A)}var JBA=O$Q;B0();GA();hw();var R$Q=new Set(["description","excerpt","summary","tagline","story"]);function b$Q(A){if(A.endsWith("s"))return A;return FI(A)}function njA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return njA(A._def.innerType,!0,B);if(w==="ZodDefault")return njA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function ojA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=njA(Q),f=B._def.typeName,I={name:A,label:XX(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((Y)=>Y.kind==="datetime"))return{...I,widget:"datetime"};if(R$Q.has(A))return{...I,widget:"text"};return{...I,widget:"string"}}case"ZodNumber":return{...I,widget:"number"};case"ZodBoolean":return{...I,widget:"boolean"};case"ZodEnum":{let D=B._def.values;return{...I,widget:"select",options:D}}case"ZodArray":{let D=B._def.type,Y=ojA("item",D);if(Y.widget==="object"&&Y.fields)return{...I,widget:"list",fields:Y.fields};return{...I,widget:"list",field:{name:A,label:XX(A),widget:Y.widget}}}case"ZodObject":{let D=B.shape,Y=Object.entries(D).map(([H,W])=>ojA(H,W));return{...I,widget:"object",fields:Y}}default:return{...I,widget:"string"}}}function If1(A,Q){let B=Object.entries(A.shape).map(([w,$])=>ojA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function Df1(A){let Q=[],B=[];for(let w of A.entityTypes){let $=A.getFrontmatterSchema(w);if(!$)continue;let f=A.getAdapter(w),I=f?.hasBody!==!1,D=A.entityDisplay?.[w],Y=w===li?"Note":XX(w),H=D?.label??Y,W=D?.pluralName??b$Q(H);if(f?.isSingleton){B.push({name:w,label:H,file:`${w}/${w}.md`,fields:If1($,I)});continue}if(w===li){Q.push({name:w,label:W,folder:".",create:!0,extension:"md",format:"raw",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:W,folder:w,create:!0,extension:"md",format:"frontmatter",fields:If1($,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}},media_folder:"image",public_folder:"/images",collections:Q}}function sjA(A){return`<!doctype html>
|
|
3920
3920
|
<html>
|
|
3921
3921
|
<head>
|
|
3922
3922
|
<meta charset="utf-8" />
|
|
@@ -3927,7 +3927,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,E$Q,
|
|
|
3927
3927
|
</head>
|
|
3928
3928
|
<body></body>
|
|
3929
3929
|
</html>
|
|
3930
|
-
`}GA();var Yf1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
3930
|
+
`}GA();var Yf1={name:"@brains/cms",private:!0,version:"0.2.0-alpha.81",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/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 k$Q=J.object({label:J.string().optional(),pluralName:J.string().optional()}).passthrough(),j$Q=J.object({entityDisplay:J.record(k$Q).optional(),routePath:J.string().default("/cms")});function _$Q(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function v$Q(A,Q){let B=A.entityDisplay??Q?.entityDisplay;return B?{entityDisplay:B}:{}}async function y$Q(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 x$Q(A,Q={}){let{repo:B,branch:w}=await y$Q(A);return Df1({repo:B,branch:w,...A.siteUrl&&{baseUrl:A.siteUrl},entityTypes:A.entityService.getEntityTypes(),getFrontmatterSchema:($)=>A.entities.getEffectiveFrontmatterSchema($),getAdapter:($)=>A.entities.getAdapter($),...Q.entityDisplay&&{entityDisplay:Q.entityDisplay}})}async function Hf1(A,Q={}){return YX(await x$Q(A,Q))}class ajA extends YB{constructor(A={}){super("cms",Yf1,A,j$Q)}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=_$Q(this.config.routePath);return[{path:this.config.routePath,method:"GET",public:!0,handler:async()=>{return new Response(sjA({cmsConfigPath:A}),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:A,method:"GET",public:!0,handler:async()=>{try{let Q=await Hf1(this.getContext(),v$Q(this.config,this.getContext()));return new Response(Q,{headers:{"Content-Type":"application/yaml; charset=utf-8"}})}catch(Q){return new Response(Q instanceof Error?Q.message:"CMS unavailable",{status:503,headers:{"Content-Type":"text/plain; charset=utf-8"}})}}}]}}function kE(A){return new ajA(A)}B0();GA();B0();GA();var GBA=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],h$Q=new Set(GBA);function tjA(A){return h$Q.has(A)}var Xf1=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:J7.default("public")});class FBA{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let Q={...A,...Xf1.parse(A)},B=`${Q.pluginId}:${Q.id}`;this.widgets.set(B,Q),this.logger.debug("Dashboard widget registered",{key:B,title:Q.title,rendererName:Q.rendererName})}unregister(A,Q){if(Q){this.widgets.delete(`${A}:${Q}`);return}for(let B of this.widgets.keys())if(B.startsWith(`${A}:`))this.widgets.delete(B)}get(A,Q){return this.widgets.get(`${A}:${Q}`)}list(A={}){let Q=typeof A==="string"?{section:A}:A,B=Q.permissionLevel??"public";return Array.from(this.widgets.values()).filter((w)=>!Q.section||w.section===Q.section).filter((w)=>G7.hasPermission(B,w.visibility)).sort((w,$)=>w.priority-$.priority)}get size(){return this.widgets.size}}GA();class KBA{id="dashboard:dashboard";name="Dashboard DataSource";description="Aggregates dashboard widgets from all plugins";registry;logger;constructor(A,Q){this.registry=A,this.logger=Q.child("DashboardDataSource")}async getDashboardData(A={}){let Q={},B=A.widgets??this.registry.list({...A.permissionLevel!==void 0&&{permissionLevel:A.permissionLevel}}),w=await Promise.allSettled(B.map(async($)=>{let f=await $.dataProvider(),{dataProvider:I,component:D,clientScript:Y,visibility:H="public",...W}=$;return{key:`${$.pluginId}:${$.id}`,widget:{...W,visibility:H},data:f}}));for(let $=0;$<w.length;$++){let f=w[$],I=B[$];if(!f||!I)continue;if(f.status==="fulfilled")Q[f.value.key]={widget:f.value.widget,data:f.value.data};else this.logger.error("Widget data provider failed",{widgetId:I.id,pluginId:I.pluginId,error:h0(f.reason)})}return{widgets:Q}}async fetch(A,Q,B){return await this.getDashboardData()}}import{render as W9Q}from"preact-render-to-string";var Wf1=`
|
|
3931
3931
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
3932
3932
|
html, body { min-height: 100%; max-width: 100%; }
|
|
3933
3933
|
body {
|
|
@@ -5167,7 +5167,7 @@ ${Wf1}`;import{jsxDEV as kH,Fragment as Gf1}from"preact/jsx-dev-runtime";functio
|
|
|
5167
5167
|
}
|
|
5168
5168
|
});
|
|
5169
5169
|
})();`;function K9Q({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=J9Q(A.widgets),$=Boolean(A.character.role)||Boolean(A.character.purpose)||A.character.values.length>0,f=A.appInfo.interactions,I=`layout${$?" has-identity":""}`,D=A.operatorAccess&&!A.operatorAccess.isOperator&&A.operatorAccess.hiddenWidgetCount>0,Y=new Date;return eQ("html",{lang:"en","data-theme":"dark",children:[eQ("head",{children:[eQ("meta",{charSet:"utf-8"},void 0,!1,void 0,this),eQ("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),eQ("title",{children:A.title},void 0,!1,void 0,this),eQ("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),eQ("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),eQ("link",{href:U9Q,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&eQ("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),eQ("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:Jf1}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),eQ("body",{children:[eQ("main",{class:"console","data-component":"dashboard:dashboard",children:[eQ(Ff1,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),eQ("section",{class:I,children:[$&&eQ("div",{class:"identity-column",children:[eQ(Zf1,{character:A.character},void 0,!1,void 0,this),eQ(ejA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&eQ(Vf1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),eQ("div",{class:"main-column",children:[eQ(Kf1,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&eQ(Vf1,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((H)=>eQ(ZBA,{widget:H},`${H.widget.pluginId}:${H.widget.id}`,!1,void 0,this)),w.secondary.map((H)=>eQ(ZBA,{widget:H},`${H.widget.pluginId}:${H.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),eQ("div",{class:"sidebar-column",children:[!$&&eQ(ejA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((H)=>eQ(ZBA,{widget:H},`${H.widget.pluginId}:${H.widget.id}`,!1,void 0,this)),eQ(zf1,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),eQ(Ef1,{appInfo:A.appInfo,now:Y},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),eQ(Mf1,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),eQ("script",{dangerouslySetInnerHTML:{__html:G9Q}},void 0,!1,void 0,this),eQ("script",{dangerouslySetInnerHTML:{__html:F9Q}},void 0,!1,void 0,this),A.widgetScripts.map((H,W)=>eQ("script",{dangerouslySetInnerHTML:{__html:H}},`widget-script:${W}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Cf1(A){return`<!doctype html>
|
|
5170
|
-
${W9Q(eQ(K9Q,{input:A},void 0,!1,void 0,this))}`}function Of1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var Rf1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
5170
|
+
${W9Q(eQ(K9Q,{input:A},void 0,!1,void 0,this))}`}function Of1(A,Q){let B={},w=new Set;for(let[$,f]of Object.entries(A)){let I=Q?.get(f.widget.pluginId,f.widget.id);if(B[$]={...f,...I?.component?{component:I.component}:{}},I?.clientScript)w.add(I.clientScript)}return{widgets:B,widgetScripts:Array.from(w)}}var Rf1={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.81",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 z9Q=J.object({version:J.string().default("1.0.0"),routePath:J.string().default("/dashboard"),themeCSS:J.string().optional()}),N9Q=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:J7.default("public"),component:J.custom().optional(),clientScript:J.string().optional(),dataProvider:J.function().returns(J.promise(J.unknown()))}).superRefine((A,Q)=>{if(!tjA(A.rendererName)&&!A.component)Q.addIssue({code:J.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),q9Q=J.object({pluginId:J.string(),widgetId:J.string().optional()});function L9Q(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 Q_A extends YB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",Rf1,A??{},z9Q)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new FBA(this.logger),this.datasource=new KBA(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=N9Q.parse(Q.payload),w=L9Q(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:GBA.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:h0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=q9Q.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 gR()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((s)=>G7.hasPermission($,s.visibility)),D=f.length-I.length,[Y,H]=await Promise.all([this.datasource.getDashboardData({permissionLevel:$,widgets:I}),Q.appInfo()]),W=Q.identity.get(),F=Q.identity.getProfile(),K=this.siteUrl??(()=>{try{return new URL(A.url).origin}catch{return}})(),Z={...H,endpoints:H.endpoints.filter((s)=>G7.hasPermission($,s.visibility)),interactions:H.interactions.filter((s)=>G7.hasPermission($,s.visibility))},q=F.name||H.model||"Brain Dashboard",E=new URL(A.url),L=`${E.pathname}${E.search}`,b=encodeURIComponent(L),_=Of1(Y.widgets,this.widgetRegistry),j={title:q,baseUrl:K,widgets:_.widgets,widgetScripts:_.widgetScripts,character:W,profile:F,appInfo:Z,...this.config.themeCSS!==void 0&&{themeCSS:this.config.themeCSS},operatorAccess:{isOperator:w,hiddenWidgetCount:D,loginUrl:`/login?return_to=${b}`,logoutUrl:`/logout?return_to=${b}`}};return new Response(Cf1(j),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function k3(A){return new Q_A(A)}B0();GA();var E9Q=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:J7,component:J.custom().optional()}),M9Q=J.object({widget:E9Q,data:J.unknown()}),V9Q=J.object({widgets:J.record(M9Q)});GA();B0();GA();import{h as T9Q}from"preact";GA();c4();B0();var Kk=J.enum(["draft","queued","published","failed"]),iu=J.object({subject:J.string(),status:Kk,entityIds:J.array(J.string()).optional(),scheduledFor:J.string().datetime().optional(),sentAt:J.string().datetime().optional(),buttondownId:J.string().optional(),sourceEntityType:J.string().optional()}),bf1=iu.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}),ru=w2.extend({entityType:J.literal("newsletter"),metadata:bf1});B0();class Pf1 extends F2{constructor(){super({entityType:"newsletter",schema:ru,frontmatterSchema:iu})}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}}}var kf1=new Pf1;B0();B0();GA();var C9Q=EX.extend({status:J.enum(["draft","queued","published","failed"]).optional()}),O9Q=MX.extend({query:C9Q.optional()});function jf1(A){try{let{content:Q}=AQ(A.content,iu);return Q}catch{return A.content}}class B_A extends w5{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=O9Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=jf1(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:UX(Q,150),created:A.created,url:`/newsletters/${A.id}`};if(A.metadata.sentAt)B.sentAt=A.metadata.sentAt;return B}buildListResult(A,Q,B){return{newsletters:A,totalCount:Q?.totalItems??A.length,pagination:Q}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A),$=B.entityService;if(w.id)return this.fetchSingleNewsletter(w.id,Q,$);let f=w.status,I=f?{filter:{metadata:{status:f}}}:void 0,{items:D,pagination:Y}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,Y,w))}async fetchSingleNewsletter(A,Q,B){let w=await B.getEntity({entityType:this.config.entityType,id:A});if(!w)throw Error(`Newsletter not found: ${A}`);let $=await this.resolveNavigation(w,B),f=[];if(w.metadata.entityIds?.length){let Y=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(W)=>{let F=await B.getEntity({entityType:Y,id:W});if(F){let K=F.metadata;return{id:W,title:K.title??W,url:`/${Y}s/${K.slug??W}`}}return null}))).filter((W)=>W!==null)}let I=jf1(w),D={id:w.id,subject:w.metadata.subject,status:w.metadata.status,content:I,created:w.created,updated:w.updated,sentAt:w.metadata.sentAt,scheduledFor:w.metadata.scheduledFor,newsletter:w,prevNewsletter:$.prev?{id:$.prev.id,subject:$.prev.subject,url:$.prev.url}:null,nextNewsletter:$.next?{id:$.next.id,subject:$.next.subject,url:$.next.url}:null,sourceEntities:f.length>0?f:void 0};return Q.parse(D)}}B0();GA();var R9Q=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 w_A extends E9{constructor(A,Q){super(A,Q,{schema:R9Q,jobTypeName:"newsletter:generation",entityType:"newsletter"})}async generate(A,Q){let B=A.addToQueue??!1,{prompt:w,sourceEntityIds:$,sourceEntityType:f}=A,{content:I,subject:D}=A;if(I){if(!D)this.failEarly("Subject is required when providing content directly");await this.reportProgress(Q,{progress:50,message:"Using provided content"})}else if($&&$.length>0){let K=f??"post";await this.reportProgress(Q,{progress:10,message:`Fetching ${$.length} source entities`});let q=(await Promise.all($.map((j)=>this.context.entityService.getEntity({entityType:K,id:j})))).filter((j)=>j!=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 L=`Create an engaging newsletter that highlights these blog posts:
|
|
5171
5171
|
|
|
5172
5172
|
${q.map((j)=>`## ${j.metadata.title}
|
|
5173
5173
|
|
|
@@ -5236,14 +5236,14 @@ Newsletter-specific guidelines:
|
|
|
5236
5236
|
- "Reply and let me know..."
|
|
5237
5237
|
- "Until next time..."
|
|
5238
5238
|
|
|
5239
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});GA();B0();import{jsxDEV as r7,Fragment as _9Q}from"preact/jsx-dev-runtime";var P9Q=J.object({id:J.string(),subject:J.string(),status:Kk,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),k9Q=J.object({newsletters:J.array(P9Q),totalCount:J.number(),pagination:L9.nullable()}),j9Q=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return r7(_9Q,{children:[r7(JQ,{title:f,description:I},void 0,!1,void 0,this),r7("div",{className:"newsletter-list bg-theme",children:r7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[r7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?r7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):r7("div",{className:"space-y-4",children:A.map((D)=>r7(ZB,{href:D.url,children:[r7(z$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),r7(n$,{children:r7("div",{className:"flex items-center gap-3",children:[r7(Tf,{status:D.status},void 0,!1,void 0,this),r7("span",{className:"text-sm text-theme-muted",children:W6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&r7("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&r7(CG,{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)},vf1=b1({name:"newsletter-list",description:"Newsletter list page template",schema:k9Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:j9Q}});GA();B0();import{jsxDEV as iw,Fragment as h9Q}from"preact/jsx-dev-runtime";var v9Q=J.object({id:J.string(),title:J.string(),url:J.string()}),yf1=J.object({id:J.string(),subject:J.string(),url:J.string()}),y9Q=J.object({id:J.string(),subject:J.string(),status:Kk,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(v9Q).optional(),prevNewsletter:yf1.nullable().optional(),nextNewsletter:yf1.nullable().optional()}),x9Q=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:Y})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,F=$?"Sent":"Created";return iw(h9Q,{children:[iw(JQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),iw("section",{className:"newsletter-detail-section",children:iw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:iw("div",{className:"max-w-3xl mx-auto",children:[iw(RW,{items:H},void 0,!1,void 0,this),iw("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),iw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[iw(Tf,{status:Q},void 0,!1,void 0,this),iw("span",{children:[F,": ",W6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&iw("span",{children:["Scheduled for: ",W6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&iw(ZB,{variant:"compact",className:"mb-8",children:[iw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),iw("ul",{className:"space-y-1",children:I.map((K)=>iw("li",{children:iw("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),iw(I4,{markdown:B},void 0,!1,void 0,this),(D??Y)&&iw("nav",{className:"mt-12 pt-8 border-t border-theme",children:iw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?iw(ZB,{href:D.url,variant:"compact",children:[iw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),iw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):iw("div",{},void 0,!1,void 0,this),Y&&iw(ZB,{href:Y.url,variant:"compact",className:"md:text-right",children:[iw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),iw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},xf1=b1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:y9Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:x9Q}});var hf1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
5239
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});GA();B0();import{jsxDEV as r7,Fragment as _9Q}from"preact/jsx-dev-runtime";var P9Q=J.object({id:J.string(),subject:J.string(),status:Kk,excerpt:J.string(),created:J.string(),sentAt:J.string().optional(),url:J.string()}),k9Q=J.object({newsletters:J.array(P9Q),totalCount:J.number(),pagination:L9.nullable()}),j9Q=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return r7(_9Q,{children:[r7(JQ,{title:f,description:I},void 0,!1,void 0,this),r7("div",{className:"newsletter-list bg-theme",children:r7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[r7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?r7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):r7("div",{className:"space-y-4",children:A.map((D)=>r7(ZB,{href:D.url,children:[r7(z$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),r7(n$,{children:r7("div",{className:"flex items-center gap-3",children:[r7(Tf,{status:D.status},void 0,!1,void 0,this),r7("span",{className:"text-sm text-theme-muted",children:W6(D.sentAt??D.created,{style:"long"})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D.excerpt&&r7("p",{className:"text-theme-muted line-clamp-2",children:D.excerpt},void 0,!1,void 0,this)]},D.id,!0,void 0,this))},void 0,!1,void 0,this),w&&w.totalPages>1&&r7(CG,{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)},vf1=b1({name:"newsletter-list",description:"Newsletter list page template",schema:k9Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:j9Q}});GA();B0();import{jsxDEV as iw,Fragment as h9Q}from"preact/jsx-dev-runtime";var v9Q=J.object({id:J.string(),title:J.string(),url:J.string()}),yf1=J.object({id:J.string(),subject:J.string(),url:J.string()}),y9Q=J.object({id:J.string(),subject:J.string(),status:Kk,content:J.string(),created:J.string(),updated:J.string(),sentAt:J.string().optional(),scheduledFor:J.string().optional(),sourceEntities:J.array(v9Q).optional(),prevNewsletter:yf1.nullable().optional(),nextNewsletter:yf1.nullable().optional()}),x9Q=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:Y})=>{let H=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,F=$?"Sent":"Created";return iw(h9Q,{children:[iw(JQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),iw("section",{className:"newsletter-detail-section",children:iw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:iw("div",{className:"max-w-3xl mx-auto",children:[iw(RW,{items:H},void 0,!1,void 0,this),iw("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),iw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[iw(Tf,{status:Q},void 0,!1,void 0,this),iw("span",{children:[F,": ",W6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&iw("span",{children:["Scheduled for: ",W6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&iw(ZB,{variant:"compact",className:"mb-8",children:[iw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),iw("ul",{className:"space-y-1",children:I.map((K)=>iw("li",{children:iw("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),iw(I4,{markdown:B},void 0,!1,void 0,this),(D??Y)&&iw("nav",{className:"mt-12 pt-8 border-t border-theme",children:iw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?iw(ZB,{href:D.url,variant:"compact",children:[iw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),iw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:D.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this):iw("div",{},void 0,!1,void 0,this),Y&&iw(ZB,{href:Y.url,variant:"compact",className:"md:text-right",children:[iw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),iw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:Y.subject},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},xf1=b1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:y9Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:x9Q}});var hf1={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.81",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 S9Q=J.object({});class $_A extends NQ{entityType="newsletter";schema=ru;adapter=kf1;constructor(A={}){super("newsletter",hf1,A,S9Q)}createGenerationHandler(A){return new w_A(this.logger,A)}getTemplates(){return{generation:_f1,"newsletter-list":vf1,"newsletter-detail":xf1}}getDataSources(){return[new B_A(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:()=>T9Q(cRA,{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}=Q.payload;if(B!=="newsletter")return{success:!0};try{let $=await A.entityService.getEntity({entityType:"newsletter",id:w});if(!$)return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:`Newsletter not found: ${w}`}}),{success:!0};if($.metadata.status==="published")return{success:!0};let f=await A.messaging.send({type:"buttondown:send",payload:{entityId:w,subject:$.metadata.subject,content:$.content}}),I=new Date().toISOString(),D=!("noop"in f)&&f.data?f.data.emailId:void 0;return await A.entityService.updateEntity({entity:{...$,metadata:{...$.metadata,status:"published",sentAt:I,buttondownId:D}}}),await A.messaging.send({type:"publish:report:success",payload:{entityType:B,entityId:w,sentAt:I}}),this.logger.info(`Published newsletter: ${w}`),{success:!0}}catch($){let f=h0($);return await A.messaging.send({type:"publish:report:failure",payload:{entityType:B,entityId:w,error:f}}),{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:h0(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:
|
|
5240
5240
|
|
|
5241
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function f_A(A={}){return new $_A(A)}B0();GA();class Zk{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}B0();GA();var m9Q=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)")}),u9Q=J.object({email:J.string().email().describe("Email address to unsubscribe")}),c9Q=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function gf1(A,Q,B){let w=new Zk(Q,B);return[YQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",m9Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return bw({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return T8(h0(f))}}),YQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",u9Q,async($)=>{try{return await w.unsubscribe($.email),bw({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return T8(h0(f))}}),YQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",c9Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return bw({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return T8(h0(f))}})]}GA();async function Tf1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=h0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Sf1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
5241
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function f_A(A={}){return new $_A(A)}B0();GA();class Zk{config;logger;constructor(A,Q){this.config=A;this.logger=Q}async request(A,Q={}){let B=`https://api.buttondown.email/v1${A}`;this.logger.debug("Buttondown API request",{endpoint:A,method:Q.method??"GET"});let w=await fetch(B,{...Q,headers:{Authorization:`Token ${this.config.apiKey}`,"Content-Type":"application/json",...Q.headers}});if(!w.ok){let $=await w.json().catch(()=>({})),f=$.detail??$.message??`HTTP ${w.status}`;throw this.logger.error("Buttondown API error",{endpoint:A,status:w.status,error:f}),Error(`Buttondown API error: ${f}`)}return w.json()}async createSubscriber(A){let Q={email_address:A.email,type:this.config.doubleOptIn?"unactivated":"regular"};if(A.name)Q.metadata={name:A.name};if(A.tags&&A.tags.length>0)Q.tags=A.tags;this.logger.info("Creating subscriber",{email:A.email});try{return await this.request("/subscribers",{method:"POST",body:JSON.stringify(Q)})}catch(B){if(B instanceof Error&&B.message.includes("already subscribed")){let w=B.message.match(/id=([a-f0-9-]+)/);return this.logger.info("Subscriber already exists",{email:A.email}),{id:w?.[1]??"existing",email:A.email,subscriber_type:"already_subscribed"}}throw B}}async unsubscribe(A){this.logger.info("Unsubscribing",{email:A}),await this.request(`/subscribers/${encodeURIComponent(A)}`,{method:"DELETE"})}async listSubscribers(A){let Q=new URLSearchParams;if(A?.type)Q.set("type",A.type);if(A?.limit)Q.set("page_size",String(A.limit));let B=Q.toString(),w=B?`/subscribers?${B}`:"/subscribers";return this.request(w)}async createEmail(A){let Q={subject:A.subject,body:A.body,status:A.status??"draft"};if(A.publish_date)Q.publish_date=A.publish_date;return this.logger.info("Creating email",{subject:A.subject,status:A.status??"draft"}),this.request("/emails",{method:"POST",body:JSON.stringify(Q)})}async getEmail(A){return this.request(`/emails/${A}`)}async validateCredentials(){try{return await this.request("/subscribers?page_size=1"),!0}catch{return!1}}}B0();GA();var m9Q=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)")}),u9Q=J.object({email:J.string().email().describe("Email address to unsubscribe")}),c9Q=J.object({type:J.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:J.number().optional().describe("Maximum number of results")});function gf1(A,Q,B){let w=new Zk(Q,B);return[YQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",m9Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return bw({subscriberId:f.id,email:f.email,status:f.subscriber_type,message:I?"already_subscribed":"subscribed"},I?`${$.email} is already subscribed`:`Subscribed ${$.email} successfully`)}catch(f){return T8(h0(f))}}),YQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",u9Q,async($)=>{try{return await w.unsubscribe($.email),bw({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return T8(h0(f))}}),YQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",c9Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return bw({subscribers:f.results.map((I)=>({id:I.id,email:I.email,status:I.subscriber_type})),count:f.count},`Found ${f.count} subscribers`)}catch(f){return T8(h0(f))}})]}GA();async function Tf1(A,Q,B,w){if(A.entityType!=="post")return{success:!0,skipped:!0,reason:"Only post entity types trigger auto-send"};let $=await B.getEntity({entityType:"post",id:A.entityId});if(!$)return{success:!1,error:`Post ${A.entityId} not found`};w.info("Auto-sending newsletter for published post",{postId:$.id,title:$.metadata.title});try{let f=await Q.createEmail({subject:$.metadata.title,body:$.content,status:"about_to_send"});return w.info("Newsletter sent for post",{postId:$.id,emailId:f.id}),{success:!0,emailId:f.id}}catch(f){let I=h0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var Sf1={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.81",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 l9Q=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 I_A extends YB{constructor(A={}){super("buttondown",Sf1,A,l9Q)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new Zk({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:h0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await Tf1(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 gf1(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 D_A(A={}){return new I_A(A)}var i9Q=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 mf1(A={}){let Q=i9Q.parse(A);return[f_A({}),D_A({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}B0();GA();import{existsSync as w7Q,mkdirSync as $7Q,writeFileSync as f7Q}from"fs";import{join as lG}from"path";GA();var Y_A=J.object({baseFolder:J.string().default("_obsidian")});GA();function r9Q(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof J.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof J.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof J.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function d9Q(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 uf1(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=r9Q($),Y=d9Q(f),H={name:w,type:Y.type,required:I},W=D!==void 0?D:Y.defaultValue;if(W!==void 0)H.defaultValue=W;if(Y.enumValues)H.enumValues=Y.enumValues;B.push(H)}return B}function n9Q(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 cf1(A,Q,B=""){let w=["---"];for(let $ of Q){let f=n9Q($,A);if(f==="")w.push(`${$.name}:`);else w.push(`${$.name}: ${f}`)}if(w.push("---"),w.push(""),B)w.push(B);else w.push("<!-- Write your content here -->"),w.push("");return w.join(`
|
|
5242
5242
|
`)}GA();var o9Q={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function s9Q(A){let Q={name:A.name,id:A.name,type:o9Q[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function pf1(A,Q){let B={filesPaths:A,fields:Q.map(s9Q)};return`---
|
|
5243
5243
|
${YX(B)}---
|
|
5244
|
-
`}GA();var a9Q=new Set(["entityType"]),t9Q={base:"Notes"},e9Q=new Set(["base"]);function A7Q(A){let Q=["file.name"];for(let B of A)if(!a9Q.has(B.name))Q.push(B.name);return Q}function Q7Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function lf1(A,Q){let B=t9Q[A]??ml(A),w=Q7Q(Q),$=A7Q(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[e9Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:YX(D),hasStatus:w}}function if1(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 YX(B)}function rf1(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 YX(B)}var df1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.80",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 I7Q={mkdir:$7Q,writeFile:f7Q,existsFile:w7Q},D7Q=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class H_A extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",df1,A,Y_A);this.deps={...I7Q,...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[YQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",D7Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((L)=>Q.includes(L)):B,$=lG(A.dataDir,this.config.baseFolder),f=lG($,"templates"),I=lG($,"fileClasses"),D=lG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],H=[],W=[],F=[],K=[],Z=[];for(let L of w){let b=A.entities.getEffectiveFrontmatterSchema(L);if(!b){this.logger.debug(`Skipping ${L}: no frontmatter schema`),H.push(L);continue}let _=uf1(b),j=A.entities.getAdapter(L),s=j?.isSingleton===!0,n=pf1(L,_);if(this.deps.writeFile(lG(I,`${L}.md`),n),W.push(L),s){K.push(L),this.logger.debug(`Generated fileClass (singleton): ${L}`);continue}let T=j?.getBodyTemplate()??"",y=cf1(L,_,T);this.deps.writeFile(lG(f,`${L}.md`),y),Y.push(L);let h=lf1(L,_),g=lG(D,h.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,h.content),F.push(L),this.logger.debug(`Generated base: ${h.filename}`);if(h.hasStatus)Z.push({entityType:L,fields:_});this.logger.debug(`Generated template + fileClass: ${L}`)}let q=if1(K);if(q){let L=lG(D,"Settings.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=rf1(Z);if(E){let L=lG(D,"Pipeline.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,E),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${Y.length} templates, ${W.length} fileClasses, ${F.length} bases (${H.length} skipped)`),bw({generated:Y,skipped:H,fileClasses:W,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),T8(B instanceof Error?B.message:"Unknown error")}}}function X_A(A,Q){return new H_A(A,Q)}B0();GA();B0();var W_A=J.enum(["new","planned","in-progress","done","declined"]),U_A=J.enum(["low","medium","high","critical"]),du=J.object({title:J.string(),status:W_A,priority:U_A.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),nf1=J.object({title:J.string(),status:W_A,priority:U_A,requested:J.number().int(),slug:J.string()}),nu=w2.extend({entityType:J.literal("wish"),metadata:nf1}),J_A=J.object({});B0();GA();class ou extends F2{constructor(){super({entityType:"wish",schema:nu,frontmatterSchema:du})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,du);return{frontmatter:du.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=D2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var G_A=new ou;GA();GA();async function of1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=D2(Q.title);return A.getEntity({entityType:"wish",id:f})}class zBA{logger;context;adapter=new ou;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await of1({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:H,description:W}=this.adapter.parseWishContent(f.content),F=H.requested+1,K=this.adapter.createWishContent({...H,requested:F},W);return await this.context.entityService.updateEntity({entity:{...f,content:K,metadata:{...f.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:F}),{success:!0,entityId:f.id,existed:!0,requested:F}}let I=D2(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var sf1={critical:0,high:1,medium:2,low:3};function af1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return sf1[Q.metadata.priority]-sf1[B.metadata.priority]})}var tf1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.80",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 ef1 extends NQ{entityType=G_A.entityType;schema=nu;adapter=G_A;constructor(A={}){super("wishlist",tf1,A,J_A)}async interceptCreate(A,Q,B){let w=await new zBA(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 af1(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 zBA(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 H7Q(A={}){return new ef1(A)}var NBA=H7Q;B0();GA();B0();var su=J.object({title:J.string(),target:J.string()}),AI1=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),au=w2.extend({entityType:J.literal("prompt"),metadata:AI1});B0();GA();class F_A extends F2{constructor(){super({entityType:"prompt",schema:au,frontmatterSchema:su})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,su);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,su),B=D2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var qBA=new F_A;var QI1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.80",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 K_A extends NQ{entityType=qBA.entityType;schema=au;adapter=qBA;constructor(){super("prompt",QI1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function jE(){return new K_A}B0();GA();class LBA{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(W7Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function W7Q(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}}GA();Kf();var BI1={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")},wI1={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 fI1(A,Q){return[U7Q(A,Q),J7Q(A,Q)]}function U7Q(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:BI1,handler:async(B)=>{let w=J.object(BI1).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 J7Q(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:wI1,handler:async(B)=>{let w=J.object(wI1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:H,title:W,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:Y},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(E[0]){let T={imageEntityId:E[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await $I1(Q.entityService,K,Z,E[0].id),T.coverSet=!0;return{success:!0,data:T}}Q.provider.triggerDownload(f).catch(()=>{});let L;try{L=await Q.fetchImage(H)}catch(T){return{success:!1,error:T instanceof Error?T.message:"Image download failed"}}let b=W??`Stock photo ${$}`,_=LK.createImageEntity({dataUrl:L,title:b,alt:F??b}),j={id:$,..._,metadata:{..._.metadata,sourceUrl:H}},{entityId:s}=await Q.entityService.createEntity({entity:j}),n={imageEntityId:s,alreadyExisted:!1,attribution:q};if(K&&Z)await $I1(Q.entityService,K,Z,s),n.coverSet=!0;return{success:!0,data:n}}}}async function $I1(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Kf();var II1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.80",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 F7Q=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class Z_A extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",II1,A,F7Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new LBA(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=fI1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??_Y}),this.cachedTools}}function z_A(A={},Q={}){return new Z_A(A,Q)}B0();GA();B0();B0();GA();var DI1=J.enum(["ai","foundation","work"]),YI1=J.object({suffix:DI1,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),tu=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(YI1).min(1)}),EBA=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),eu=w2.extend({entityType:J.literal("ecosystem-section"),metadata:EBA});class HI1 extends F2{constructor(){super({entityType:"ecosystem-section",schema:eu,frontmatterSchema:EBA})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var N_A=new HI1;GA();function K7Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function q_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Ac(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function MBA(A){let Q=K7Q(A),w=q_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return tu.parse({eyebrow:q_A(Q,"Eyebrow"),headline:q_A(Q,"Headline"),cards:w.map(($)=>({suffix:Ac($,"Suffix"),title:Ac($,"Title"),body:Ac($,"Body"),linkLabel:Ac($,"Link Label"),linkHref:Ac($,"Link Href")}))})}function XI1(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(`
|
|
5244
|
+
`}GA();var a9Q=new Set(["entityType"]),t9Q={base:"Notes"},e9Q=new Set(["base"]);function A7Q(A){let Q=["file.name"];for(let B of A)if(!a9Q.has(B.name))Q.push(B.name);return Q}function Q7Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function lf1(A,Q){let B=t9Q[A]??ml(A),w=Q7Q(Q),$=A7Q(Q),f=[{type:"table",name:`All ${B}`,order:$}];if(w)f.push({type:"table",name:"By Status",groupBy:{property:"status",direction:"ASC"},order:$});let D={filters:{and:[e9Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:YX(D),hasStatus:w}}function if1(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 YX(B)}function rf1(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 YX(B)}var df1={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.81",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 I7Q={mkdir:$7Q,writeFile:f7Q,existsFile:w7Q},D7Q=J.object({entityTypes:J.array(J.string()).optional().describe("Entity types to generate templates for (default: all)")});class H_A extends YB{deps;constructor(A={},Q={}){super("obsidian-vault",df1,A,Y_A);this.deps={...I7Q,...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[YQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",D7Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((L)=>Q.includes(L)):B,$=lG(A.dataDir,this.config.baseFolder),f=lG($,"templates"),I=lG($,"fileClasses"),D=lG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let Y=[],H=[],W=[],F=[],K=[],Z=[];for(let L of w){let b=A.entities.getEffectiveFrontmatterSchema(L);if(!b){this.logger.debug(`Skipping ${L}: no frontmatter schema`),H.push(L);continue}let _=uf1(b),j=A.entities.getAdapter(L),s=j?.isSingleton===!0,n=pf1(L,_);if(this.deps.writeFile(lG(I,`${L}.md`),n),W.push(L),s){K.push(L),this.logger.debug(`Generated fileClass (singleton): ${L}`);continue}let T=j?.getBodyTemplate()??"",y=cf1(L,_,T);this.deps.writeFile(lG(f,`${L}.md`),y),Y.push(L);let h=lf1(L,_),g=lG(D,h.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,h.content),F.push(L),this.logger.debug(`Generated base: ${h.filename}`);if(h.hasStatus)Z.push({entityType:L,fields:_});this.logger.debug(`Generated template + fileClass: ${L}`)}let q=if1(K);if(q){let L=lG(D,"Settings.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=rf1(Z);if(E){let L=lG(D,"Pipeline.base");if(!this.deps.existsFile(L))this.deps.writeFile(L,E),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${Y.length} templates, ${W.length} fileClasses, ${F.length} bases (${H.length} skipped)`),bw({generated:Y,skipped:H,fileClasses:W,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),T8(B instanceof Error?B.message:"Unknown error")}}}function X_A(A,Q){return new H_A(A,Q)}B0();GA();B0();var W_A=J.enum(["new","planned","in-progress","done","declined"]),U_A=J.enum(["low","medium","high","critical"]),du=J.object({title:J.string(),status:W_A,priority:U_A.default("medium"),requested:J.number().int().default(1),declinedReason:J.string().optional()}),nf1=J.object({title:J.string(),status:W_A,priority:U_A,requested:J.number().int(),slug:J.string()}),nu=w2.extend({entityType:J.literal("wish"),metadata:nf1}),J_A=J.object({});B0();GA();class ou extends F2{constructor(){super({entityType:"wish",schema:nu,frontmatterSchema:du})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,du);return{frontmatter:du.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=D2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var G_A=new ou;GA();GA();async function of1(A,Q){let B=`${Q.title}: ${Q.description}`,$=(await A.search({query:B,options:{types:["wish"],limit:1}}))[0];if($&&$.score>=A.similarityThreshold)return $.entity;let f=D2(Q.title);return A.getEntity({entityType:"wish",id:f})}class zBA{logger;context;adapter=new ou;constructor(A,Q){this.logger=A;this.context=Q}async process(A,Q,B){let w=A.title??A.prompt??"Untitled wish",$=A.content??A.prompt??"",f=await of1({search:(H)=>this.context.entityService.search(H),getEntity:(H)=>this.context.entityService.getEntity(H),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:H,description:W}=this.adapter.parseWishContent(f.content),F=H.requested+1,K=this.adapter.createWishContent({...H,requested:F},W);return await this.context.entityService.updateEntity({entity:{...f,content:K,metadata:{...f.metadata,requested:F}}}),this.logger.info("Incremented wish request count",{id:f.id,requested:F}),{success:!0,entityId:f.id,existed:!0,requested:F}}let I=D2(w),D=A.options?.priority??"medium",Y=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:Y,metadata:{title:w,status:"new",priority:D,requested:1,slug:I}}}),this.logger.info("Created new wish",{id:I,title:w}),{success:!0,entityId:I,existed:!1,requested:1}}}var sf1={critical:0,high:1,medium:2,low:3};function af1(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return sf1[Q.metadata.priority]-sf1[B.metadata.priority]})}var tf1={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.81",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 ef1 extends NQ{entityType=G_A.entityType;schema=nu;adapter=G_A;constructor(A={}){super("wishlist",tf1,A,J_A)}async interceptCreate(A,Q,B){let w=await new zBA(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 af1(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 zBA(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 H7Q(A={}){return new ef1(A)}var NBA=H7Q;B0();GA();B0();var su=J.object({title:J.string(),target:J.string()}),AI1=J.object({title:J.string(),target:J.string(),slug:J.string().optional()}),au=w2.extend({entityType:J.literal("prompt"),metadata:AI1});B0();GA();class F_A extends F2{constructor(){super({entityType:"prompt",schema:au,frontmatterSchema:su})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,su);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,su),B=D2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var qBA=new F_A;var QI1={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.81",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 K_A extends NQ{entityType=qBA.entityType;schema=au;adapter=qBA;constructor(){super("prompt",QI1,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function jE(){return new K_A}B0();GA();class LBA{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(W7Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function W7Q(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}}GA();Kf();var BI1={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")},wI1={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 fI1(A,Q){return[U7Q(A,Q),J7Q(A,Q)]}function U7Q(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:BI1,handler:async(B)=>{let w=J.object(BI1).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 J7Q(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:wI1,handler:async(B)=>{let w=J.object(wI1).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:Y,imageUrl:H,title:W,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:Y},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:H}}}});if(E[0]){let T={imageEntityId:E[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await $I1(Q.entityService,K,Z,E[0].id),T.coverSet=!0;return{success:!0,data:T}}Q.provider.triggerDownload(f).catch(()=>{});let L;try{L=await Q.fetchImage(H)}catch(T){return{success:!1,error:T instanceof Error?T.message:"Image download failed"}}let b=W??`Stock photo ${$}`,_=LK.createImageEntity({dataUrl:L,title:b,alt:F??b}),j={id:$,..._,metadata:{..._.metadata,sourceUrl:H}},{entityId:s}=await Q.entityService.createEntity({entity:j}),n={imageEntityId:s,alreadyExisted:!1,attribution:q};if(K&&Z)await $I1(Q.entityService,K,Z,s),n.coverSet=!0;return{success:!0,data:n}}}}async function $I1(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Kf();var II1={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.81",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 F7Q=J.object({provider:J.enum(["unsplash"]).default("unsplash"),apiKey:J.string().optional().describe("Stock photo provider API key")});class Z_A extends YB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",II1,A,F7Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new LBA(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=fI1(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??_Y}),this.cachedTools}}function z_A(A={},Q={}){return new Z_A(A,Q)}B0();GA();B0();B0();GA();var DI1=J.enum(["ai","foundation","work"]),YI1=J.object({suffix:DI1,title:J.string(),body:J.string(),linkLabel:J.string(),linkHref:J.string()}),tu=J.object({eyebrow:J.string(),headline:J.string(),cards:J.array(YI1).min(1)}),EBA=J.object({title:J.string(),slug:J.string(),status:J.enum(["draft","published"])}),eu=w2.extend({entityType:J.literal("ecosystem-section"),metadata:EBA});class HI1 extends F2{constructor(){super({entityType:"ecosystem-section",schema:eu,frontmatterSchema:EBA})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var N_A=new HI1;GA();function K7Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function q_A(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Ac(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function MBA(A){let Q=K7Q(A),w=q_A(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return tu.parse({eyebrow:q_A(Q,"Eyebrow"),headline:q_A(Q,"Headline"),cards:w.map(($)=>({suffix:Ac($,"Suffix"),title:Ac($,"Title"),body:Ac($,"Body"),linkLabel:Ac($,"Link Label"),linkHref:Ac($,"Link Href")}))})}function XI1(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(`
|
|
5245
5245
|
`)}var Z7Q=J.object({query:J.object({id:J.string().optional()}).optional()}).passthrough();class VBA{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=Z7Q.parse(A??{}).query?.id??"rizom-ecosystem",f=await B.entityService.getEntity({entityType:"ecosystem-section",id:$});if(!f)throw Error(`Ecosystem section not found: ${$}`);return Q.parse(MBA(f.content))}}B0();var z7Q=r0A({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 rW(...A){return z7Q(wP(A))}import{jsxDEV as GCw}from"preact/jsx-dev-runtime";import{jsxDEV as zCw}from"preact/jsx-dev-runtime";import{jsxDEV as ECw}from"preact/jsx-dev-runtime";import{jsxDEV as q7Q}from"preact/jsx-dev-runtime";var L_A="px-6 md:px-10 xl:px-20",N7Q=`${L_A} relative z-[1]`,E_A=({id:A,className:Q,children:B})=>q7Q("section",{id:A,className:rW(N7Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as CBA}from"preact/jsx-dev-runtime";var L7Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},Qc=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=L7Q[Q];return CBA("span",{className:rW("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[CBA("span",{className:"text-theme",children:A},void 0,!1,void 0,this),CBA("span",{className:rW(f??"text-accent",w),children:"."},void 0,!1,void 0,this),CBA("span",{className:rW("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as yCw}from"preact/jsx-dev-runtime";import{jsxDEV as TCw}from"preact/jsx-dev-runtime";import{jsxDEV as cCw,Fragment as uCw}from"preact/jsx-dev-runtime";import{jsxDEV as iCw}from"preact/jsx-dev-runtime";import{Fragment as M_A}from"preact";import{jsxDEV as Bc}from"preact/jsx-dev-runtime";var E7Q=/(\*[^*]+\*)/;function V_A(A,Q){let B=A.split(`
|
|
5246
|
-
`);return Bc(M_A,{children:B.map((w,$)=>Bc(M_A,{children:[$>0&&Bc("br",{},void 0,!1,void 0,this),w.split(E7Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Bc("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Bc(M_A,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as pf,Fragment as v7Q}from"preact/jsx-dev-runtime";var M7Q="italic text-accent font-normal",V7Q="You are here",C7Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},O7Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},R7Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},b7Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",P7Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",k7Q="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",j7Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",_7Q=({card:A})=>{let Q=A.linkLabel===V7Q,B=A.linkHref.trim().length===0,w=pf(v7Q,{children:[pf(Qc,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),pf("span",{className:`${b7Q} ${C7Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),pf("p",{className:P7Q,children:A.body},void 0,!1,void 0,this),Q?pf("span",{className:j7Q,children:A.linkLabel},void 0,!1,void 0,this):pf("span",{className:k7Q,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?O7Q[A.suffix]:"border-white/10"}`;return Q||B?pf("div",{className:$,children:w},void 0,!1,void 0,this):pf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${R7Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},C_A=({eyebrow:A,headline:Q,cards:B})=>pf(E_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[pf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[pf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),pf("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:V_A(Q,M7Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),pf("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)=>pf(_7Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var y7Q=[{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 WI1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:y7Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var x7Q=WI1();var O_A=b1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:tu,formatter:{parse:MBA,format:XI1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:C_A}});var UI1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
5246
|
+
`);return Bc(M_A,{children:B.map((w,$)=>Bc(M_A,{children:[$>0&&Bc("br",{},void 0,!1,void 0,this),w.split(E7Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return Bc("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return Bc(M_A,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as pf,Fragment as v7Q}from"preact/jsx-dev-runtime";var M7Q="italic text-accent font-normal",V7Q="You are here",C7Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},O7Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},R7Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},b7Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",P7Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",k7Q="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",j7Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",_7Q=({card:A})=>{let Q=A.linkLabel===V7Q,B=A.linkHref.trim().length===0,w=pf(v7Q,{children:[pf(Qc,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),pf("span",{className:`${b7Q} ${C7Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),pf("p",{className:P7Q,children:A.body},void 0,!1,void 0,this),Q?pf("span",{className:j7Q,children:A.linkLabel},void 0,!1,void 0,this):pf("span",{className:k7Q,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?O7Q[A.suffix]:"border-white/10"}`;return Q||B?pf("div",{className:$,children:w},void 0,!1,void 0,this):pf("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${R7Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},C_A=({eyebrow:A,headline:Q,cards:B})=>pf(E_A,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[pf("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[pf("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),pf("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:V_A(Q,M7Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),pf("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)=>pf(_7Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var y7Q=[{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 WI1(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:y7Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var x7Q=WI1();var O_A=b1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:tu,formatter:{parse:MBA,format:XI1},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:C_A}});var UI1={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.81",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 R_A extends NQ{entityType="ecosystem-section";schema=eu;adapter=N_A;constructor(A={}){super("rizom-ecosystem",UI1,A,J.object({}).default({}))}getTemplates(){return{ecosystem:O_A}}getDataSources(){return[new VBA]}}function _E(A={}){return new R_A(A)}GA();B0();B0();GA();$$();GA();B0();var A9="agent",JI1="agent-discovery",GI1="agent:generation",FI1="agent-network",KI1="AgentNetworkWidget",wc="agent-discovery:entities",b_A="agent-list",P_A="agent-detail",J6="skill",ZI1="skill",OBA="skill-derivation",zI1="skill:project",NI1="skill-derivation",qI1="skill:skill-derivation",LI1="skills";var zk=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),kD=J.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),jH=LY.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)"),status:kD,discoveredAt:J.string().datetime().describe("When this agent was first discovered")}),EI1=jH.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:J.string().datetime().optional(),slug:J.string()}),Nk=w2.extend({entityType:J.literal(A9),metadata:EI1}),$c=Nk.extend({frontmatter:jH,about:J.string(),skills:J.array(zk),notes:J.string()}),qk=$c.extend({url:J.string().optional(),typeLabel:J.string().optional()}),g7Q=$c.extend({url:J.string(),typeLabel:J.string()});GA();var T7Q=J.array(zk);function MI1(A){let Q=T7Q.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(`
|
|
5247
5247
|
`)}function VI1(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
5248
5248
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((Y)=>Y.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var S7Q=J.object({about:J.string(),skills:J.array(zk),notes:J.string()}),CI1=new yB(S7Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:MI1,parser:VI1},{key:"notes",label:"Notes",type:"string"}]});class jD extends F2{constructor(){super({entityType:A9,schema:Nk,frontmatterSchema:jH})}fromMarkdown(A){let Q=this.parseFrontMatter(A,jH),B=fV(Q.url);return{content:A,entityType:A9,metadata:{name:Q.name,url:Q.url,status:Q.status,discoveredAt:Q.discoveredAt,slug:B}}}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},status:kD.parse(A.status),discoveredAt:A.discoveredAt},B=CI1.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=CI1.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,jH),body:this.parseAgentContent(A.content)}}}B0();var m7Q=new jD,u7Q=EX.extend({status:kD.optional()}),c7Q=MX.extend({query:u7Q.optional()});function p7Q(A){let Q=AQ(A.content,jH),B=m7Q.parseAgentContent(A.content);return $c.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class RBA extends w5{id=wc;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:A9,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return p7Q(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=c7Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=kD.safeParse(B.status);return{agents:A,pagination:Q,baseUrl:B.baseUrl,selectedStatus:w.success?w.data:"all"}}async fetch(A,Q,B){let{query:w}=this.parseQuery(A);if(w.id)return super.fetch(A,Q,B);let{items:$,pagination:f}=await this.fetchList(w,B.entityService,w.status?{filter:{metadata:{status:w.status}}}:void 0);return Q.parse(this.buildListResult($,f,w))}}B0();GA();x$();B0();async function OI1(A,Q){let w=`${(A.startsWith("http")?A:`https://${A}`).replace(/\/$/,"")}/.well-known/agent-card.json`;try{let $=await Q(w);if(!$.ok)return null;let f=await $.json();return Jv(f)}catch{return null}}function bBA(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""}GA();var l7Q=new jD;function RI1(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function j3(A){let Q=new Set,B=[];for(let w of A){let $=RI1(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function i7Q(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function bI1(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=new Map,[f,I]=await Promise.all([A.entityService.listEntities({entityType:J6}),A.entityService.listEntities({entityType:A9})]),D=(Y)=>{for(let H of j3(Y))$.set(H,($.get(H)??0)+1)};for(let Y of f)D(Y.metadata.tags);for(let Y of I){let H=l7Q.parseAgentContent(Y.content);D(H.skills.flatMap((W)=>W.tags))}return Array.from($.entries()).map(([Y,H])=>({tag:Y,count:H})).filter((Y)=>Y.count>=B).sort(i7Q).slice(0,w)}function PI1(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(`
|
|
5249
5249
|
`)}var r7Q=new jD;function kI1(A,Q={}){let B=A.anchor?.name??A.brainName,w=A.anchor?.kind??"professional",$=[];if(A.anchor?.description)$.push(A.anchor.description);if(A.description)$.push(A.description);let f=Q.status??"discovered",I=new Date().toISOString();return{content:r7Q.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
|
|
@@ -5343,7 +5343,7 @@ ${YX(B)}---
|
|
|
5343
5343
|
setView("agents");
|
|
5344
5344
|
setTagFilter("all");
|
|
5345
5345
|
});
|
|
5346
|
-
})();`;import{jsxDEV as xQ}from"preact/jsx-dev-runtime";function QfQ({item:A}){return xQ("li",{class:"list-item",children:[xQ("div",{class:"list-main",children:[xQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),xQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&xQ("div",{class:"list-tags",children:A.tags.map((Q)=>xQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xQ("div",{class:"list-meta",children:A.status==="discovered"&&xQ("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 BfQ({item:A}){return xQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[xQ("div",{class:"list-main",children:xQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),xQ("div",{class:"list-meta",children:xQ("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 wfQ({kind:A,items:Q,active:B}){return xQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?xQ("ul",{class:"list agent-network-list",children:Q.map((w)=>xQ(QfQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):xQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function $fQ({skills:A,count:Q,filters:B}){return xQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[xQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[xQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[xQ("span",{class:"count",children:Q},void 0,!1,void 0,this),xQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>xQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[xQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),xQ("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?xQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>xQ(BfQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):xQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function __A({data:A}){let Q=hI1.safeParse(A);if(!Q.success)return xQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return xQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[xQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[xQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",xQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",xQ("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),xQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:j_A.map((w)=>{let $=w==="all";return xQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[xQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),xQ("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),j_A.map((w)=>xQ(wfQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),xQ($fQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function TI1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:FI1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:KI1,component:__A,clientScript:kBA,dataProvider:async()=>gI1(A)}}),{success:!0}})}function SI1(){return'## Agent directory\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 `confirmed: true`. Do not ask for another confirmation for that explicit 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- If the previous turn identified one specific unsaved agent domain and offered to add/save it, 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`.\n- Calling and saving agents are separate actions: if an agent is not saved yet, tell the user it is not saved in the local agent directory yet and ask them to add/save it first. Prefer the words `add/save it first` in that response.\n- If the user asks to `call`, `talk to`, `ask`, or contact an unsaved domain/URL, do not call `system_create` on that first request. First explain that it is not saved and ask whether to add/save it first. Only save it after explicit add/save intent or an affirmative follow-up to your save offer.\n- If a user gives an agent URL, do not call it directly. Save the agent first, then use its local agent id.\n- A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\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- If more than one saved agent could match the user\u2019s name-based reference, ask which saved agent they mean before calling anything.\n- Do not create a wish or any other entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add or save that agent.'}B0();xw();GA();import{jsxDEV as mI1}from"preact/jsx-dev-runtime";function jBA(A){try{return new URL(A).hostname}catch{return A}}var _BA=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return mI1("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)},vBA=({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 mI1("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 K2,Fragment as DfQ}from"preact/jsx-dev-runtime";var ffQ=({skills:A})=>{if(A.length===0)return null;return K2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>K2("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 IfQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function uI1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var v_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return K2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[K2(_BA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),K2("div",{className:"flex-1 min-w-0",children:[K2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[K2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),K2(vBA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&K2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&K2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&K2(ffQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[K2("span",{className:"text-xs text-theme-muted",children:jBA(Q.url)},void 0,!1,void 0,this),K2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${IfQ(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)},cI1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),Y=A.filter((K)=>K.frontmatter.status==="discovered"),H=D.length,W=Y.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return K2(DfQ,{children:[K2(JQ,{title:f,description:F},void 0,!1,void 0,this),K2("div",{className:"agent-list bg-theme",children:K2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[K2("div",{className:"mb-8 pb-6 border-b border-theme",children:[K2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),K2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),K2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[W," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-wrap gap-2 text-sm",children:[K2("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),K2("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),K2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&K2("section",{className:"mb-10",children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),K2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:D.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&K2("section",{children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("div",{children:[K2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),K2("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),K2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&K2("section",{children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),K2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:A.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&K2("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"&&K2("div",{className:"mt-12",children:K2(CG,{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"&&K2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?K2("a",{href:uI1(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):K2("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),K2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?K2("a",{href:uI1(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):K2("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 I2,Fragment as WfQ}from"preact/jsx-dev-runtime";function YfQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var fc=({children:A})=>I2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),HfQ=({skill:A})=>I2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[I2("div",{className:"flex-1",children:[I2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),I2("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&&I2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>I2("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),XfQ=({label:A,value:Q,valueClassName:B})=>I2("div",{className:"flex justify-between text-[13px]",children:[I2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),I2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),pI1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=jBA(w.url),Y=w.status==="approved";return I2(WfQ,{children:[I2(JQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),I2("article",{className:"agent-detail",children:I2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[I2("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),I2("div",{className:"flex items-start gap-6 mb-8",children:[I2(_BA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),I2("div",{children:[I2("div",{className:"flex items-center gap-3 mb-1",children:[I2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),I2(vBA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),I2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&I2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&I2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),I2("span",{className:"text-sm",children:["Discovered ",YfQ(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),I2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&I2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[I2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),I2("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),I2("div",{className:"flex flex-col md:flex-row gap-12",children:[I2("div",{className:"flex-[2] min-w-0",children:[$&&I2("section",{className:"mb-8",children:[I2(fc,{children:"About"},void 0,!1,void 0,this),I2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&I2("section",{className:"mb-8",children:[I2(fc,{children:"Skills"},void 0,!1,void 0,this),I2("div",{className:"flex flex-col gap-2.5",children:f.map((H)=>I2(HfQ,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&I2("section",{className:"mb-8",children:[I2(fc,{children:"Notes"},void 0,!1,void 0,this),I2("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),I2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[I2("section",{className:"mb-8",children:[I2(fc,{children:"Brain"},void 0,!1,void 0,this),I2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[I2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&I2("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),I2("section",{className:"mb-8",children:[I2(fc,{children:"Connection"},void 0,!1,void 0,this),I2("div",{className:"flex flex-col gap-3",children:[I2("div",{children:[I2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),I2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I2(XfQ,{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),I2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&I2("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:[I2("div",{className:"min-h-[1px]",children:Q&&I2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[I2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),I2("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),I2("div",{className:"min-h-[1px] md:text-right",children:B&&I2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[I2("span",{children:"Next \u2192"},void 0,!1,void 0,this),I2("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 UfQ=J.object({agents:J.array(qk),pageTitle:J.string().optional(),pagination:L9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),kD])});function lI1(){return{[b_A]:b1({name:b_A,description:"Agent directory list page template",schema:UfQ,dataSourceId:wc,requiredPermission:"public",layout:{component:cI1}}),[P_A]:b1({name:P_A,description:"Individual agent profile template",schema:J.object({agent:qk,prevAgent:qk.nullable(),nextAgent:qk.nullable()}),dataSourceId:wc,requiredPermission:"public",layout:{component:pI1}})}}var yBA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.80",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/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 GfQ=new jD;class y_A extends NQ{entityType=A9;schema=Nk;adapter=GfQ;constructor(){super(JI1,yBA)}interceptCreate(A,Q,B){return jI1(A,Q,B,this.id)}createGenerationHandler(A){return new k_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return lI1()}getDataSources(){return[new RBA(this.logger.child("AgentDataSource"))]}async onRegister(A){TI1(A,this.id)}async getInstructions(){return SI1()}}function x_A(){return new y_A}B0();GA();B0();var Lk=VI,iI1=VI,Ic=w2.extend({entityType:J.literal(J6),metadata:iI1});B0();class Ek extends F2{constructor(){super({entityType:J6,schema:Ic,frontmatterSchema:Lk})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Lk);return{content:A,entityType:J6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}B0();GA();var FfQ=J.object({skills:J.array(Lk).max(8)}),rI1=b1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:FfQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5346
|
+
})();`;import{jsxDEV as xQ}from"preact/jsx-dev-runtime";function QfQ({item:A}){return xQ("li",{class:"list-item",children:[xQ("div",{class:"list-main",children:[xQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),xQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&xQ("div",{class:"list-tags",children:A.tags.map((Q)=>xQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xQ("div",{class:"list-meta",children:A.status==="discovered"&&xQ("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 BfQ({item:A}){return xQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[xQ("div",{class:"list-main",children:xQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),xQ("div",{class:"list-meta",children:xQ("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 wfQ({kind:A,items:Q,active:B}){return xQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?xQ("ul",{class:"list agent-network-list",children:Q.map((w)=>xQ(QfQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):xQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function $fQ({skills:A,count:Q,filters:B}){return xQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[xQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[xQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[xQ("span",{class:"count",children:Q},void 0,!1,void 0,this),xQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>xQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[xQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),xQ("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?xQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>xQ(BfQ,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):xQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function __A({data:A}){let Q=hI1.safeParse(A);if(!Q.success)return xQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return xQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[xQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[xQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",xQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),xQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",xQ("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),xQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:j_A.map((w)=>{let $=w==="all";return xQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[xQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),xQ("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),j_A.map((w)=>xQ(wfQ,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),xQ($fQ,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function TI1(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:FI1,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:KI1,component:__A,clientScript:kBA,dataProvider:async()=>gI1(A)}}),{success:!0}})}function SI1(){return'## Agent directory\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 `confirmed: true`. Do not ask for another confirmation for that explicit 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- If the previous turn identified one specific unsaved agent domain and offered to add/save it, 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`.\n- Calling and saving agents are separate actions: if an agent is not saved yet, tell the user it is not saved in the local agent directory yet and ask them to add/save it first. Prefer the words `add/save it first` in that response.\n- If the user asks to `call`, `talk to`, `ask`, or contact an unsaved domain/URL, do not call `system_create` on that first request. First explain that it is not saved and ask whether to add/save it first. Only save it after explicit add/save intent or an affirmative follow-up to your save offer.\n- If a user gives an agent URL, do not call it directly. Save the agent first, then use its local agent id.\n- A URL-based or unsaved-domain agent contact request is a save-first directory case, not a wishlist case.\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- If more than one saved agent could match the user\u2019s name-based reference, ask which saved agent they mean before calling anything.\n- Do not create a wish or any other entity for a missing, archived/removed, or ambiguous agent unless the user explicitly asks you to add or save that agent.'}B0();xw();GA();import{jsxDEV as mI1}from"preact/jsx-dev-runtime";function jBA(A){try{return new URL(A).hostname}catch{return A}}var _BA=({name:A,className:Q=""})=>{let B=A.charAt(0).toUpperCase(),w=0;for(let f=0;f<A.length;f++)w=A.charCodeAt(f)+((w<<5)-w);let $=Math.abs(w)%360;return mI1("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)},vBA=({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 mI1("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 K2,Fragment as DfQ}from"preact/jsx-dev-runtime";var ffQ=({skills:A})=>{if(A.length===0)return null;return K2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>K2("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 IfQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function uI1(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var v_A=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return K2("a",{href:$,className:`flex items-start gap-5 p-6 rounded-xl border border-theme bg-theme-subtle hover:shadow-lg transition-shadow ${f?"":"opacity-70"}`,children:[K2(_BA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),K2("div",{className:"flex-1 min-w-0",children:[K2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[K2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),K2(vBA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&K2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&K2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&K2(ffQ,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[K2("span",{className:"text-xs text-theme-muted",children:jBA(Q.url)},void 0,!1,void 0,this),K2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${IfQ(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)},cI1=({agents:A,pageTitle:Q,pagination:B,baseUrl:w="/agents",selectedStatus:$})=>{let f=Q??"Agent Directory",I=B?.totalItems??A.length,D=A.filter((K)=>K.frontmatter.status==="approved"),Y=A.filter((K)=>K.frontmatter.status==="discovered"),H=D.length,W=Y.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return K2(DfQ,{children:[K2(JQ,{title:f,description:F},void 0,!1,void 0,this),K2("div",{className:"agent-list bg-theme",children:K2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[K2("div",{className:"mb-8 pb-6 border-b border-theme",children:[K2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),K2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),K2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[H," approved"]},void 0,!0,void 0,this),K2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-theme-muted",children:[W," discovered"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-wrap gap-2 text-sm",children:[K2("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),K2("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),K2("a",{href:`${w}?status=discovered`,className:`px-3 py-1 rounded-full border transition-colors ${$==="discovered"?"border-theme text-heading bg-theme-subtle":"border-theme text-theme-muted hover:text-heading"}`,children:"Discovered"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$==="all"&&D.length>0&&K2("section",{className:"mb-10",children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),K2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:D.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&Y.length>0&&K2("section",{children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("div",{children:[K2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),K2("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),K2("span",{className:"text-sm text-theme-muted",children:Y.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:Y.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&K2("section",{children:[K2("div",{className:"flex items-center justify-between mb-4",children:[K2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),K2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K2("div",{className:"flex flex-col gap-4",children:A.map((K)=>K2(v_A,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&K2("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"&&K2("div",{className:"mt-12",children:K2(CG,{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"&&K2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?K2("a",{href:uI1(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):K2("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),K2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?K2("a",{href:uI1(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):K2("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 I2,Fragment as WfQ}from"preact/jsx-dev-runtime";function YfQ(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var fc=({children:A})=>I2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),HfQ=({skill:A})=>I2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[I2("div",{className:"flex-1",children:[I2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),I2("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&&I2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>I2("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),XfQ=({label:A,value:Q,valueClassName:B})=>I2("div",{className:"flex justify-between text-[13px]",children:[I2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),I2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),pI1=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=jBA(w.url),Y=w.status==="approved";return I2(WfQ,{children:[I2(JQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),I2("article",{className:"agent-detail",children:I2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[I2("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),I2("div",{className:"flex items-start gap-6 mb-8",children:[I2(_BA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),I2("div",{children:[I2("div",{className:"flex items-center gap-3 mb-1",children:[I2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),I2(vBA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),I2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&I2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&I2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),I2("span",{className:"text-sm",children:["Discovered ",YfQ(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),I2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!Y&&I2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[I2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),I2("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),I2("div",{className:"flex flex-col md:flex-row gap-12",children:[I2("div",{className:"flex-[2] min-w-0",children:[$&&I2("section",{className:"mb-8",children:[I2(fc,{children:"About"},void 0,!1,void 0,this),I2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&I2("section",{className:"mb-8",children:[I2(fc,{children:"Skills"},void 0,!1,void 0,this),I2("div",{className:"flex flex-col gap-2.5",children:f.map((H)=>I2(HfQ,{skill:H},H.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&I2("section",{className:"mb-8",children:[I2(fc,{children:"Notes"},void 0,!1,void 0,this),I2("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),I2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[I2("section",{className:"mb-8",children:[I2(fc,{children:"Brain"},void 0,!1,void 0,this),I2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[I2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&I2("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),I2("section",{className:"mb-8",children:[I2(fc,{children:"Connection"},void 0,!1,void 0,this),I2("div",{className:"flex flex-col gap-3",children:[I2("div",{children:[I2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),I2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I2(XfQ,{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),I2("a",{href:w.url.replace(/\/a2a\/?$/,""),target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center px-5 py-3 bg-theme-dark text-theme-inverse rounded-lg text-sm font-medium hover:opacity-90 transition-opacity",children:["Visit ",D," \u2197"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),(Q??B)&&I2("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:[I2("div",{className:"min-h-[1px]",children:Q&&I2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[I2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),I2("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),I2("div",{className:"min-h-[1px] md:text-right",children:B&&I2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[I2("span",{children:"Next \u2192"},void 0,!1,void 0,this),I2("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 UfQ=J.object({agents:J.array(qk),pageTitle:J.string().optional(),pagination:L9.nullable(),baseUrl:J.string().optional(),selectedStatus:J.union([J.literal("all"),kD])});function lI1(){return{[b_A]:b1({name:b_A,description:"Agent directory list page template",schema:UfQ,dataSourceId:wc,requiredPermission:"public",layout:{component:cI1}}),[P_A]:b1({name:P_A,description:"Individual agent profile template",schema:J.object({agent:qk,prevAgent:qk.nullable(),nextAgent:qk.nullable()}),dataSourceId:wc,requiredPermission:"public",layout:{component:pI1}})}}var yBA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.81",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/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 GfQ=new jD;class y_A extends NQ{entityType=A9;schema=Nk;adapter=GfQ;constructor(){super(JI1,yBA)}interceptCreate(A,Q,B){return jI1(A,Q,B,this.id)}createGenerationHandler(A){return new k_A(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return lI1()}getDataSources(){return[new RBA(this.logger.child("AgentDataSource"))]}async onRegister(A){TI1(A,this.id)}async getInstructions(){return SI1()}}function x_A(){return new y_A}B0();GA();B0();var Lk=VI,iI1=VI,Ic=w2.extend({entityType:J.literal(J6),metadata:iI1});B0();class Ek extends F2{constructor(){super({entityType:J6,schema:Ic,frontmatterSchema:Lk})}fromMarkdown(A){let Q=this.parseFrontMatter(A,Lk);return{content:A,entityType:J6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}B0();GA();var FfQ=J.object({skills:J.array(Lk).max(8)}),rI1=b1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:FfQ,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5347
5347
|
|
|
5348
5348
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
5349
5349
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -5493,9 +5493,9 @@ Context:
|
|
|
5493
5493
|
${JSON.stringify(w,null,2)}
|
|
5494
5494
|
|
|
5495
5495
|
Draft SWOT:
|
|
5496
|
-
${JSON.stringify(B,null,2)}`}function cBA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function gfQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class pBA{logger;context;adapter=new iG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=T_A.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 p_A(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:H}=await this.context.ai.generateObject(await yfQ(this.context,w),S_A),W=S_A.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await hfQ(this.context,w,W),SBA);$=SBA.parse(F.object),gfQ(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:cBA($.strengths),weaknesses:cBA($.weaknesses),opportunities:cBA($.opportunities),threats:cBA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}GA();import{jsxDEV as r9}from"preact/jsx-dev-runtime";var lBA=J.object({title:J.string(),detail:J.string().optional()}),TfQ=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(lBA).default([]),weaknesses:J.array(lBA).default([]),opportunities:J.array(lBA).default([]),threats:J.array(lBA).default([]),derivedAt:J.string()})]);function SfQ({items:A}){if(A.length===0)return r9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return r9("ul",{class:"swot-list",children:A.map((Q)=>r9("li",{class:"swot-item",children:[r9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?r9("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 iBA({title:A,tone:Q,items:B}){return r9("section",{class:`swot-cell is-${Q}`,children:[r9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),r9(SfQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function r_A({data:A}){let Q=TfQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return r9("div",{"data-swot-widget":!0,children:r9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return r9("div",{"data-swot-widget":!0,children:r9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[r9(iBA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),r9(iBA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),r9(iBA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),r9(iBA,{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)}GA();var d_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
5496
|
+
${JSON.stringify(B,null,2)}`}function cBA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function gfQ(A,Q){let B=["strengths","weaknesses","opportunities","threats"];for(let w of B){let $=new Set(A[w].map((f)=>f.theme.trim().toLowerCase()));for(let f of Q[w]){let I=f.sourceTheme.trim().toLowerCase();if(!$.has(I))throw Error(`SWOT refinement invented theme "${f.sourceTheme}" in ${w}`)}}}class pBA{logger;context;adapter=new iG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=T_A.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 p_A(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:H}=await this.context.ai.generateObject(await yfQ(this.context,w),S_A),W=S_A.parse(H);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await hfQ(this.context,w,W),SBA);$=SBA.parse(F.object),gfQ(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:cBA($.strengths),weaknesses:cBA($.weaknesses),opportunities:cBA($.opportunities),threats:cBA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let Y=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(Y)await this.context.entityService.updateEntity({entity:{...Y,content:D,metadata:{derivedAt:I}}});else await this.context.entityService.createEntity({entity:{id:"swot",entityType:"swot",content:D,metadata:{derivedAt:I}}});return this.logger.info("SWOT derivation complete",{derivedAt:I,brainSkillCount:w.summary.brainSkillCount,approvedAgentCount:w.summary.approvedAgentCount,discoveredAgentCount:w.summary.discoveredAgentCount}),{entityId:"swot"}}}GA();import{jsxDEV as r9}from"preact/jsx-dev-runtime";var lBA=J.object({title:J.string(),detail:J.string().optional()}),TfQ=J.discriminatedUnion("status",[J.object({status:J.literal("generating")}),J.object({status:J.literal("ready"),strengths:J.array(lBA).default([]),weaknesses:J.array(lBA).default([]),opportunities:J.array(lBA).default([]),threats:J.array(lBA).default([]),derivedAt:J.string()})]);function SfQ({items:A}){if(A.length===0)return r9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return r9("ul",{class:"swot-list",children:A.map((Q)=>r9("li",{class:"swot-item",children:[r9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?r9("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 iBA({title:A,tone:Q,items:B}){return r9("section",{class:`swot-cell is-${Q}`,children:[r9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),r9(SfQ,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function r_A({data:A}){let Q=TfQ.safeParse(A);if(!Q.success||Q.data.status==="generating")return r9("div",{"data-swot-widget":!0,children:r9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return r9("div",{"data-swot-widget":!0,children:r9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[r9(iBA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),r9(iBA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),r9(iBA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),r9(iBA,{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)}GA();var d_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.81",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 n_A=new iG;class o_A extends NQ{entityType="swot";schema=Mk;adapter=n_A;initialSyncComplete=!1;constructor(){super("swot",d_A)}async onRegister(A){let Q=new pBA(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=_$.from(async()=>{});if(!f)throw Error("Expected progress reporter to be created");await Q.process({reason:"eval"},"eval-swot-derive",f);let I=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!I)throw Error("Expected SWOT entity to be created during eval");return n_A.parseSwotContent(I.content).frontmatter});let B=async(f)=>{try{return await A.jobs.enqueue({type:"derive",data:{reason:f},options:{source:this.id,priority:10,deduplication:"coalesce",deduplicationKey:"swot",metadata:{operationType:"data_processing",operationTarget:`swot:${f}`}}})}catch(I){return this.logger.error("Failed to queue SWOT derivation",{error:I,reason:f}),null}},w=async(f)=>{if(!await A.entityService.getEntity({entityType:"swot",id:"swot"}))await B(f)};A.messaging.subscribe("sync:initial:completed",async()=>{return this.initialSyncComplete=!0,await w("initial-missing-entity"),{success:!0}}),A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:"swot",pluginId:this.id,title:"SWOT",section:"secondary",priority:14,rendererName:"SwotWidget",component:r_A,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=n_A.parseSwotContent(f.content);return{status:"ready",...I}}}}),{success:!0}});let $=async(f)=>{let{entityType:I}=f.payload;if(!this.initialSyncComplete)return{success:!0};if(I!=="agent"&&I!=="skill")return{success:!0};return await B("entity-change"),{success:!0}};A.messaging.subscribe("entity:created",$),A.messaging.subscribe("entity:updated",$),A.messaging.subscribe("entity:deleted",$)}}function s_A(){return new o_A}B0();$$();GA();var Ikw=new iG,I41=J.object({name:J.string(),description:J.string(),tags:J.array(J.string())}),a_A=J.enum(["discovered","approved"]),ufQ=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:a_A,discoveredAt:J.string().datetime()}),cfQ=w2.extend({entityType:J.literal("agent"),metadata:J.object({name:J.string(),url:J.string().url(),status:a_A,slug:J.string()})}),pfQ=w2.extend({entityType:J.literal("skill"),metadata:VI}),lfQ=J.object({about:J.string(),skills:J.array(I41),notes:J.string()});function ifQ(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(`
|
|
5497
5497
|
`)}function rfQ(A){if(!A.trim())return[];return A.split(`
|
|
5498
|
-
`).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 dfQ=new yB(lfQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:ifQ,parser:rfQ},{key:"notes",label:"Notes",type:"string"}]});class D41 extends F2{constructor(){super({entityType:"agent",schema:cfQ,frontmatterSchema:ufQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=dfQ.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 Y41 extends F2{constructor(){super({entityType:"skill",schema:pfQ,frontmatterSchema:VI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,VI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Dkw=new D41,Ykw=new Y41,Hkw=J.object({skills:J.array(VI),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:a_A,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(I41),notes:J.string().default("")}))});var nfQ=J.object({}).strict();function rBA(A={}){return nfQ.parse(A),[s_A()]}B0();GA();xw();V6();GA();B0();var dBA=ti.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.)")}),_3=LY.extend(dBA.shape);B0();QJ();GA();var ofQ=new VX;class nBA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([pV(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Nu(w)]),Y=ofQ.parseProfileBody($,_3),H=f.sort(z_).slice(0,3).map(Mu),W=I.sort(z_).slice(0,3).map(bu);if(!D.cta)throw Error("CTA not configured in site-info");let F={profile:Y,posts:H,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(F)}}B0();QJ();var sfQ=new VX;class oBA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await pV(B.entityService),f={profile:sfQ.parseProfileBody(w,_3)};return Q.parse(f)}}import{jsxDEV as _w,Fragment as efQ}from"preact/jsx-dev-runtime";var afQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",tfQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",t_A=({number:A,title:Q,blurb:B,children:w})=>_w("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:_w("div",{className:"max-w-6xl mx-auto",children:_w("div",{className:afQ,children:[_w(hRA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),_w("div",{className:tfQ,"aria-hidden":"true"},void 0,!1,void 0,this),_w("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),e_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),H=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})),W=A.name||"Home",F=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return _w(efQ,{children:[_w(JQ,{title:W,description:F,ogType:"website"},void 0,!1,void 0,this),_w("div",{className:"homepage-list bg-theme",children:[_w("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:_w("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&_w("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[_w("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),_w("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&_w("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:m1A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&_w("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:m1A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_w(t_A,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:_w(S1A,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&_w(t_A,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:_w(S1A,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&_w(t_A,{number:"03",title:"About",blurb:I.about?.blurb,children:_w("div",{className:"flex flex-col gap-8",children:[A.description&&_w("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&&_w(gRA,{subjects:A.expertise},void 0,!1,void 0,this),_w("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",_w("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),_w(LRA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Qw,Fragment as AIQ}from"preact/jsx-dev-runtime";var AvA=({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 Qw(AIQ,{children:[Qw(JQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Qw("div",{className:"about-page bg-theme",children:[Qw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Qw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Qw("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&&Qw("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),Qw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Qw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Qw(I4,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Qw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Qw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Qw("li",{className:Lm({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Qw("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&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Qw("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)&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Qw("div",{className:"space-y-4",children:[A.email&&Qw("p",{className:"text-lg",children:Qw("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&&Qw("p",{className:"text-lg",children:Qw("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&&Qw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Qw(T5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as d9,Fragment as H41}from"preact/jsx-dev-runtime";var QvA=()=>{return d9(H41,{children:[d9(JQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),d9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:d9("div",{className:"text-center max-w-md",children:[d9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),d9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),d9("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),d9(T5,{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)},BvA=()=>{return d9(H41,{children:[d9(JQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),d9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:d9("div",{className:"text-center max-w-md",children:[d9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),d9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),d9("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),d9(T5,{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)};GA();var X41=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')")}),W41=J.object({entityDisplay:J.object({post:X41,deck:X41}).describe("Display metadata for post and deck entity types (required for homepage)")});var U41={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.80",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 wvA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",U41,A,W41)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",dBA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new nBA(w,$);A.entities.registerDataSource(f);let I=new oBA;A.entities.registerDataSource(I);let D=J.object({profile:_3,posts:J.array(SG),decks:J.array(Ou),postsListUrl:J.string(),decksListUrl:J.string(),cta:$kA,sections:J.record(J.string(),Di)}),Y=J.object({profile:_3}),H=J.object({});A.templates.register({"homepage-list":b1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:e_A}}),about:b1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:AvA}}),"subscribe-thanks":b1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:QvA}}),"subscribe-error":b1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:BvA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function J41(A){return new wvA(A??{})}var G41=[{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 sBA}from"preact/jsx-dev-runtime";function F41({sections:A,siteInfo:Q,slots:B,wordmark:w}){return sBA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[sBA(CRA,{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),sBA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),sBA(MRA,{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 BIQ={layouts:{default:F41},routes:G41,plugin:J41,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"}}}},Yc=BIQ;var K41=`/*
|
|
5498
|
+
`).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 dfQ=new yB(lfQ,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:ifQ,parser:rfQ},{key:"notes",label:"Notes",type:"string"}]});class D41 extends F2{constructor(){super({entityType:"agent",schema:cfQ,frontmatterSchema:ufQ})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=dfQ.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 Y41 extends F2{constructor(){super({entityType:"skill",schema:pfQ,frontmatterSchema:VI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,VI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var Dkw=new D41,Ykw=new Y41,Hkw=J.object({skills:J.array(VI),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:a_A,discoveredAt:J.string().datetime().optional(),about:J.string(),skills:J.array(I41),notes:J.string().default("")}))});var nfQ=J.object({}).strict();function rBA(A={}){return nfQ.parse(A),[s_A()]}B0();GA();xw();V6();GA();B0();var dBA=ti.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.)")}),_3=LY.extend(dBA.shape);B0();QJ();GA();var ofQ=new VX;class nBA{postsListUrl;decksListUrl;id="professional:homepage-list";name="Homepage List DataSource";description="Fetches profile, blog posts, and presentation decks for homepage";constructor(A,Q){this.postsListUrl=A;this.decksListUrl=Q}async fetch(A,Q,B){let w=B.entityService,[$,f,I,D]=await Promise.all([pV(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),Nu(w)]),Y=ofQ.parseProfileBody($,_3),H=f.sort(z_).slice(0,3).map(Mu),W=I.sort(z_).slice(0,3).map(bu);if(!D.cta)throw Error("CTA not configured in site-info");let F={profile:Y,posts:H,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(F)}}B0();QJ();var sfQ=new VX;class oBA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await pV(B.entityService),f={profile:sfQ.parseProfileBody(w,_3)};return Q.parse(f)}}import{jsxDEV as _w,Fragment as efQ}from"preact/jsx-dev-runtime";var afQ="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",tfQ="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",t_A=({number:A,title:Q,blurb:B,children:w})=>_w("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:_w("div",{className:"max-w-6xl mx-auto",children:_w("div",{className:afQ,children:[_w(hRA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),_w("div",{className:tfQ,"aria-hidden":"true"},void 0,!1,void 0,this),_w("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),e_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,Y=Q.map((Z)=>({id:Z.id,url:Z.url,title:Z.metadata.title,date:Z.metadata.publishedAt||Z.created,description:Z.frontmatter.excerpt,series:Z.frontmatter.seriesName&&Z.frontmatter.seriesIndex?{name:Z.frontmatter.seriesName,index:Z.frontmatter.seriesIndex}:void 0})),H=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})),W=A.name||"Home",F=A.intro||A.description||D||"Professional site",K=Boolean(A.description)||A.expertise!==void 0&&A.expertise.length>0;return _w(efQ,{children:[_w(JQ,{title:W,description:F,ogType:"website"},void 0,!1,void 0,this),_w("div",{className:"homepage-list bg-theme",children:[_w("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:_w("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&_w("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[_w("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),_w("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&_w("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:m1A(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&_w("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:m1A(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_w(t_A,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:_w(S1A,{items:Y,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),H.length>0&&_w(t_A,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:_w(S1A,{items:H,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&_w(t_A,{number:"03",title:"About",blurb:I.about?.blurb,children:_w("div",{className:"flex flex-col gap-8",children:[A.description&&_w("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&&_w(gRA,{subjects:A.expertise},void 0,!1,void 0,this),_w("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",_w("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),_w(LRA,{cta:f,variant:"editorial",socialLinks:A.socialLinks},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Qw,Fragment as AIQ}from"preact/jsx-dev-runtime";var AvA=({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 Qw(AIQ,{children:[Qw(JQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),Qw("div",{className:"about-page bg-theme",children:[Qw("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:Qw("div",{className:"relative z-10 max-w-4xl mx-auto",children:[Qw("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&&Qw("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),Qw("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&Qw("section",{className:"content-section-reveal mb-20 md:mb-28",children:Qw(I4,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&Qw("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),Qw("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>Qw("li",{className:Lm({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),Qw("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&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),Qw("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)&&Qw("section",{children:[Qw("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),Qw("div",{className:"space-y-4",children:[A.email&&Qw("p",{className:"text-lg",children:Qw("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&&Qw("p",{className:"text-lg",children:Qw("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&&Qw("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>Qw(T5,{href:$.url,external:!0,variant:"secondary",size:"md",children:$.label||$.platform},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as d9,Fragment as H41}from"preact/jsx-dev-runtime";var QvA=()=>{return d9(H41,{children:[d9(JQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),d9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:d9("div",{className:"text-center max-w-md",children:[d9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),d9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),d9("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),d9(T5,{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)},BvA=()=>{return d9(H41,{children:[d9(JQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),d9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:d9("div",{className:"text-center max-w-md",children:[d9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),d9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),d9("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),d9(T5,{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)};GA();var X41=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')")}),W41=J.object({entityDisplay:J.object({post:X41,deck:X41}).describe("Display metadata for post and deck entity types (required for homepage)")});var U41={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.81",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 wvA extends YB{dependencies=["blog","decks"];constructor(A){super("professional-site",U41,A,W41)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",dBA);let Q=this.config.entityDisplay.post,B=this.config.entityDisplay.deck,w=`/${Q.pluralName??Q.label.toLowerCase()+"s"}`,$=`/${B.pluralName??B.label.toLowerCase()+"s"}`,f=new nBA(w,$);A.entities.registerDataSource(f);let I=new oBA;A.entities.registerDataSource(I);let D=J.object({profile:_3,posts:J.array(SG),decks:J.array(Ou),postsListUrl:J.string(),decksListUrl:J.string(),cta:$kA,sections:J.record(J.string(),Di)}),Y=J.object({profile:_3}),H=J.object({});A.templates.register({"homepage-list":b1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:e_A}}),about:b1({name:"about",description:"About page with full profile information",schema:Y,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:AvA}}),"subscribe-thanks":b1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:H,requiredPermission:"public",layout:{component:QvA}}),"subscribe-error":b1({name:"subscribe-error",description:"Newsletter subscription error page",schema:H,requiredPermission:"public",layout:{component:BvA}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function J41(A){return new wvA(A??{})}var G41=[{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 sBA}from"preact/jsx-dev-runtime";function F41({sections:A,siteInfo:Q,slots:B,wordmark:w}){return sBA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[sBA(CRA,{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),sBA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),sBA(MRA,{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 BIQ={layouts:{default:F41},routes:G41,plugin:J41,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"}}}},Yc=BIQ;var K41=`/*
|
|
5499
5499
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
5500
5500
|
*
|
|
5501
5501
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -5883,7 +5883,7 @@ ${JSON.stringify(B,null,2)}`}function cBA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5883
5883
|
|
|
5884
5884
|
.btn-primary:disabled { opacity: 0.5; }
|
|
5885
5885
|
}
|
|
5886
|
-
`;var Ck=K41;import{join as fIQ}from"path";var Z41={name:"@brains/rover",version:"0.2.0-alpha.80",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"start:core":"cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"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/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/media-tools":"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/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var z41=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","discord","a2a"],N41=[...z41.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],IIQ=[...N41,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo","media-tools"],DIQ=["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."],q41=vK({name:"rover",version:Z41.version,model:"gpt-5.4-mini",site:Yc,theme:Ck,presets:{core:z41,default:N41,full:IIQ},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:DIQ,capabilities:[["prompt",jE,void 0],["image",Sx,void 0],["cms",kE,{}],["auth-service",bg,void 0],["notifications",bU0,void 0],["email-resend",no0,void 0],["dashboard",k3,void 0],["dashboard-root",k3,{routePath:"/"}],["blog",JkA,{}],["series",zkA,void 0],["decks",ku,void 0],["document",ckA,void 0],["media-tools",lkA,void 0],["note",ME,{}],["link",CE,{}],["portfolio",UjA,{}],["topics",QBA,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",ljA,{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",uu,{autoGenerateOnBlogPublish:!0}],["newsletter",mf1,{doubleOptIn:!0}],["obsidian-vault",X_A,{autoSync:!0}],["wishlist",NBA,{}],["stock-photo",z_A,{}],["agents",hBA,void 0],["assessment",rBA,void 0],["directory-sync",yL,{seedContent:!0,seedContentPath:fIQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",JBA,{}],["rizom-ecosystem",_E,void 0],["site-info",NE,void 0],["site-builder",zE,{cms:{}}]],interfaces:[["mcp",JZ,()=>({})],["discord",nZ,()=>({})],["webserver",oZ,()=>({})],["a2a",pb,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});hK();B0();GA();GA();B0();var aBA=J.object({routeId:J.string(),sectionId:J.string()}),Hc=w2.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:aBA});B0();class L41 extends F2{constructor(){super({entityType:"site-content",schema:Hc,frontmatterSchema:aBA})}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 $vA=new L41;GA();var tBA=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")}),C_w=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 fvA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((W)=>W.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let W of f)for(let F of W.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:W.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:W.id,sectionId:F.id,templateName:F.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:W.id,sectionId:F.id,templateName:F.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:W.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let K=`${W.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:W.id,sectionId:F.id});continue}}I.push({route:W,section:F})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],H=[];for(let{route:W,section:F}of I){let K=`${W.id}:${F.id}`,Z=F.template,q={routeId:W.id,sectionId:F.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:W.id,sectionId:F.id,routeTitle:W.title||Q?.title||"",routeDescription:W.description||Q?.description||"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};H.push({type:"shell:content-generation",data:q})}if(H.length>0){let W=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(H,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)Y.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:F}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class IvA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new fvA(A)}async generateContent(A,Q){let B=tBA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}$$();GA();function Xc(A,Q){return Q?A.optional():A}function YvA(A){switch(A.type){case"string":return Xc(J.string(),A.optional);case"number":return Xc(J.number(),A.optional);case"enum":{let Q=[...A.options];return Xc(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=YvA(w);return Xc(J.object(Q),A.optional)}case"array":{let Q=J.array(YIQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Xc(Q,A.optional)}}}function YIQ(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]=YvA($);return J.object(B)}}}function DvA(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])=>DvA(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,$])=>DvA(w,$)),B}}}}function HIQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=YvA(I);let w=J.object(B),$=new yB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>DvA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function HvA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,HIQ(Q,B)]))}GA();var E41=J.object({namespace:J.string(),sections:J.record(J.any())}),M41=J.object({definitions:J.union([E41,J.array(E41)]).optional()});B0();function V41(A,Q){return[YQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",tBA,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var C41={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.80",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 XvA extends YB{siteContentService;constructor(A={}){super("site-content",C41,A,M41)}async onRegister(A){A.entities.register("site-content",Hc,$vA);for(let Q of JX(this.config.definitions))A.templates.register(HvA(Q),Q.namespace);this.siteContentService=new IvA(A)}async getTools(){return V41(()=>this.siteContentService,this.id)}}function Wc(A={}){return new XvA(A)}B0();GA();xw();GA();B0();var O41=J.enum(["available","early access","coming soon","planned"]),R41=J.object({title:J.string(),description:J.string()}),rG=J.object({name:J.string(),availability:O41,order:J.number()}),eBA=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(R41).min(1).max(6),story:J.string()}),WIQ=rG.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),Ok=w2.extend({entityType:J.literal("product"),metadata:WIQ}),AwA=Ok.extend({frontmatter:rG,body:eBA,labels:J.record(J.string(),J.string())}),QwA=AwA.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional()});B0();GA();$$();class Rk extends yB{constructor(){super(eBA,{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 WvA extends F2{constructor(){super({entityType:"product",schema:Ok,frontmatterSchema:rG,bodyFormatter:new Rk})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,rG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,rG),B=D2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var BwA=new WvA;GA();B0();var b41=J.object({title:J.string(),description:J.string()}),P41=J.object({title:J.string(),description:J.string()}),UIQ=J.object({title:J.string(),description:J.string()}),k41=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),dG=J.object({headline:J.string(),tagline:J.string()}),JIQ=J.object({title:J.string(),description:J.string()}),wwA=J.object({vision:J.string(),pillars:J.array(b41).min(1).max(6),approach:J.array(JIQ).min(1).max(6),productsIntro:J.string(),technologies:J.array(UIQ).min(1).max(6),benefits:J.array(P41).min(1).max(6),cta:k41}),j41=dG.pick({headline:!0}).extend({slug:J.string()}),bk=w2.extend({entityType:J.literal("products-overview"),metadata:j41}),Uc=bk.extend({frontmatter:dG,body:wwA,labels:J.record(J.string(),J.string())});B0();GA();$$();class Pk extends yB{constructor(){super(wwA,{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 UvA extends F2{constructor(){super({entityType:"products-overview",schema:bk,frontmatterSchema:dG,bodyFormatter:new Pk})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,dG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,dG),B=D2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var JvA=new UvA;B0();GA();var GIQ=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function _41(A,Q){let B=AQ(A.content,rG),w=Q.parse(B.content),$=Q.getLabels();return AwA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function v41(A,Q){let B=AQ(A.content,dG),w=Q.parse(B.content),$=Q.getLabels();return Uc.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class $wA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new Pk;productFormatter=new Rk;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=GIQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let W=v41(H,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:_41(H,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:v41(D,this.overviewFormatter),products:I.map((Y)=>_41(Y,this.productFormatter))})}}import{jsxDEV as B1,Fragment as ZIQ}from"preact/jsx-dev-runtime";var y41=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(ZIQ,{children:[B1(JQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),B1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[B1("style",{children:`
|
|
5886
|
+
`;var Ck=K41;import{join as fIQ}from"path";var Z41={name:"@brains/rover",version:"0.2.0-alpha.81",type:"module",private:!0,main:"./src/index.ts",files:["src","brain.eval.yaml","env.schema.template"],scripts:{"start:core":"cd test-apps/core && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:default":"cd test-apps/default && INIT_CWD=$PWD bun run --filter @rizom/brain dev:start","start:full":"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/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/media-tools":"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/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var z41=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","discord","a2a"],N41=[...z41.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],IIQ=[...N41,"portfolio","topics","content-pipeline","document","social-media","newsletter","stock-photo","media-tools"],DIQ=["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."],q41=vK({name:"rover",version:Z41.version,model:"gpt-5.4-mini",site:Yc,theme:Ck,presets:{core:z41,default:N41,full:IIQ},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:DIQ,capabilities:[["prompt",jE,void 0],["image",Sx,void 0],["cms",kE,{}],["auth-service",bg,void 0],["notifications",bU0,void 0],["email-resend",no0,void 0],["dashboard",k3,void 0],["dashboard-root",k3,{routePath:"/"}],["blog",JkA,{}],["series",zkA,void 0],["decks",ku,void 0],["document",ckA,void 0],["media-tools",lkA,void 0],["note",ME,{}],["link",CE,{}],["portfolio",UjA,{}],["topics",QBA,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",ljA,{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",uu,{autoGenerateOnBlogPublish:!0}],["newsletter",mf1,{doubleOptIn:!0}],["obsidian-vault",X_A,{autoSync:!0}],["wishlist",NBA,{}],["stock-photo",z_A,{}],["agents",hBA,void 0],["assessment",rBA,void 0],["directory-sync",yL,{seedContent:!0,seedContentPath:fIQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",JBA,{}],["rizom-ecosystem",_E,void 0],["site-info",NE,void 0],["site-builder",zE,{cms:{}}]],interfaces:[["mcp",JZ,()=>({})],["discord",nZ,()=>({})],["webserver",oZ,()=>({})],["a2a",pb,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"public"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"},dns:{enabled:!0,provider:"bunny"}}});hK();B0();GA();GA();B0();var aBA=J.object({routeId:J.string(),sectionId:J.string()}),Hc=w2.extend({entityType:J.literal("site-content"),template:J.string().optional(),content:J.string(),metadata:aBA});B0();class L41 extends F2{constructor(){super({entityType:"site-content",schema:Hc,frontmatterSchema:aBA})}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 $vA=new L41;GA();var tBA=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")}),C_w=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 fvA{context;constructor(A){this.context=A}createJobOptions(A,Q){if(!A)return;return{source:A.operationType??Q,rootJobId:A.rootJobId??`${Q}-${Date.now()}`,metadata:{operationType:A.operationType??"content_operations",progressToken:A.progressToken,pluginId:A.pluginId??"site-content"}}}async fetchRoutes(){let A=await this.context.messaging.send({type:"site-builder:routes:list",payload:{}});if("noop"in A)throw Error("No handler for site-builder:routes:list \u2014 is site-builder plugin loaded?");if(!A.success||!A.data)throw Error("Failed to fetch routes from site-builder");return A.data}async generate(A,Q,B){let w=this.context.logger.child("SiteContentOperations"),$=await this.fetchRoutes(),f=$;if(A.routeId){if(f=$.filter((W)=>W.id===A.routeId),f.length===0)throw Error(`Route not found: ${A.routeId}`)}let I=[];for(let W of f)for(let F of W.sections){if(A.sectionId&&F.id!==A.sectionId)continue;if(F.content){w.debug("Section has static content, skipping",{routeId:W.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:W.id,sectionId:F.id,templateName:F.template});continue}if(!K.canGenerate){w.debug("Template doesn't support generation, skipping",{routeId:W.id,sectionId:F.id,templateName:F.template,capabilities:K});continue}}else{w.debug("Section has no template, skipping",{routeId:W.id,sectionId:F.id});continue}if(!A.force&&!A.dryRun){let K=`${W.id}:${F.id}`;if(await this.context.entityService.getEntity({entityType:"site-content",id:K})){w.debug("Content already exists, skipping",{routeId:W.id,sectionId:F.id});continue}}I.push({route:W,section:F})}let D=I.length;if(A.dryRun)return{jobs:[],totalSections:D,queuedSections:D,batchId:`dry-run-${Date.now()}`};let Y=[],H=[];for(let{route:W,section:F}of I){let K=`${W.id}:${F.id}`,Z=F.template,q={routeId:W.id,sectionId:F.id,entityId:K,entityType:"site-content",templateName:Z,context:{prompt:typeof F.content==="string"?F.content:void 0,data:{routeId:W.id,sectionId:F.id,routeTitle:W.title||Q?.title||"",routeDescription:W.description||Q?.description||"",sectionContent:F.content},conversationId:"system"},siteConfig:Q};H.push({type:"shell:content-generation",data:q})}if(H.length>0){let W=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(H,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)Y.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:Y,totalSections:D,queuedSections:Y.length,batchId:F}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class IvA{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new fvA(A)}async generateContent(A,Q){let B=tBA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}$$();GA();function Xc(A,Q){return Q?A.optional():A}function YvA(A){switch(A.type){case"string":return Xc(J.string(),A.optional);case"number":return Xc(J.number(),A.optional);case"enum":{let Q=[...A.options];return Xc(J.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=YvA(w);return Xc(J.object(Q),A.optional)}case"array":{let Q=J.array(YIQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return Xc(Q,A.optional)}}}function YIQ(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]=YvA($);return J.object(B)}}}function DvA(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])=>DvA(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,$])=>DvA(w,$)),B}}}}function HIQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=YvA(I);let w=J.object(B),$=new yB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>DvA(f,I))});return{name:A,description:Q.description,schema:w,formatter:$,requiredPermission:Q.requiredPermission??"public",layout:{component:Q.layout,...Q.fullscreen!==void 0?{fullscreen:Q.fullscreen}:{}},...Q.runtimeScripts?{runtimeScripts:Q.runtimeScripts}:{}}}function HvA(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,HIQ(Q,B)]))}GA();var E41=J.object({namespace:J.string(),sections:J.record(J.any())}),M41=J.object({definitions:J.union([E41,J.array(E41)]).optional()});B0();function V41(A,Q){return[YQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",tBA,async(B,w)=>{let $=A();if(!$)return{success:!1,error:"Site content service not initialized"};if(B.sectionId&&!B.routeId)return{success:!1,error:"sectionId requires routeId to be specified"};let f={rootJobId:`generate-${Date.now()}`,progressToken:w.progressToken,pluginId:Q,operationType:"content_operations",interfaceType:w.interfaceType,channelId:w.channelId},I=await $.generateContent(B,f);return{success:!0,message:`Generated ${I.queuedSections} of ${I.totalSections} sections. ${I.queuedSections>0?"Jobs are running in the background.":"No new content to generate."}`,data:{batchId:I.batchId,jobsQueued:I.queuedSections,totalSections:I.totalSections,jobs:I.jobs}}})]}var C41={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.81",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 XvA extends YB{siteContentService;constructor(A={}){super("site-content",C41,A,M41)}async onRegister(A){A.entities.register("site-content",Hc,$vA);for(let Q of JX(this.config.definitions))A.templates.register(HvA(Q),Q.namespace);this.siteContentService=new IvA(A)}async getTools(){return V41(()=>this.siteContentService,this.id)}}function Wc(A={}){return new XvA(A)}B0();GA();xw();GA();B0();var O41=J.enum(["available","early access","coming soon","planned"]),R41=J.object({title:J.string(),description:J.string()}),rG=J.object({name:J.string(),availability:O41,order:J.number()}),eBA=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(R41).min(1).max(6),story:J.string()}),WIQ=rG.pick({name:!0,availability:!0,order:!0}).extend({slug:J.string()}),Ok=w2.extend({entityType:J.literal("product"),metadata:WIQ}),AwA=Ok.extend({frontmatter:rG,body:eBA,labels:J.record(J.string(),J.string())}),QwA=AwA.extend({url:J.string().optional(),typeLabel:J.string().optional(),listUrl:J.string().optional(),listLabel:J.string().optional()});B0();GA();$$();class Rk extends yB{constructor(){super(eBA,{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 WvA extends F2{constructor(){super({entityType:"product",schema:Ok,frontmatterSchema:rG,bodyFormatter:new Rk})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,rG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,rG),B=D2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var BwA=new WvA;GA();B0();var b41=J.object({title:J.string(),description:J.string()}),P41=J.object({title:J.string(),description:J.string()}),UIQ=J.object({title:J.string(),description:J.string()}),k41=J.object({heading:J.string(),buttonText:J.string(),link:J.string()}),dG=J.object({headline:J.string(),tagline:J.string()}),JIQ=J.object({title:J.string(),description:J.string()}),wwA=J.object({vision:J.string(),pillars:J.array(b41).min(1).max(6),approach:J.array(JIQ).min(1).max(6),productsIntro:J.string(),technologies:J.array(UIQ).min(1).max(6),benefits:J.array(P41).min(1).max(6),cta:k41}),j41=dG.pick({headline:!0}).extend({slug:J.string()}),bk=w2.extend({entityType:J.literal("products-overview"),metadata:j41}),Uc=bk.extend({frontmatter:dG,body:wwA,labels:J.record(J.string(),J.string())});B0();GA();$$();class Pk extends yB{constructor(){super(wwA,{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 UvA extends F2{constructor(){super({entityType:"products-overview",schema:bk,frontmatterSchema:dG,bodyFormatter:new Pk})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,dG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,dG),B=D2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var JvA=new UvA;B0();GA();var GIQ=J.object({entityType:J.string(),query:J.object({id:J.string().optional()}).optional()});function _41(A,Q){let B=AQ(A.content,rG),w=Q.parse(B.content),$=Q.getLabels();return AwA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function v41(A,Q){let B=AQ(A.content,dG),w=Q.parse(B.content),$=Q.getLabels();return Uc.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class $wA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new Pk;productFormatter=new Rk;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=GIQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let H=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!H)throw Error("Products overview entity not found");let W=v41(H,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let H=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!H)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:_41(H,this.productFormatter)})}let[f,I]=await Promise.all([$.listEntities({entityType:"products-overview",options:{limit:1}}),$.listEntities({entityType:"product",options:{sortFields:[{field:"order",direction:"asc"}]}})]),D=f[0];if(!D)throw Error("Products overview entity not found");return Q.parse({overview:v41(D,this.overviewFormatter),products:I.map((Y)=>_41(Y,this.productFormatter))})}}import{jsxDEV as B1,Fragment as ZIQ}from"preact/jsx-dev-runtime";var y41=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(ZIQ,{children:[B1(JQ,{title:B.headline,description:B.tagline},void 0,!1,void 0,this),B1("header",{className:"relative w-full min-h-[80vh] flex items-end px-6 md:px-12 bg-brand-dark overflow-hidden",children:[B1("style",{children:`
|
|
5887
5887
|
@keyframes wave-drift {
|
|
5888
5888
|
from { transform: translateX(0); }
|
|
5889
5889
|
to { transform: translateX(-50%); }
|
|
@@ -5911,7 +5911,7 @@ ${JSON.stringify(B,null,2)}`}function cBA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5911
5911
|
@media (prefers-reduced-motion: reduce) {
|
|
5912
5912
|
.detail-wave { animation: none; }
|
|
5913
5913
|
}
|
|
5914
|
-
`},void 0,!1,void 0,this),o1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:o1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[o1("path",{d:"M0,200 C67,140 133,140 200,200 C267,260 333,260 400,200 C467,140 533,140 600,200 C667,260 733,260 800,200 C867,140 933,140 1000,200 C1067,260 1133,260 1200,200 C1267,140 1333,140 1400,200 C1467,260 1533,260 1600,200",className:"stroke-accent",strokeWidth:"2",strokeMiterlimit:"10",fill:"none",opacity:"0.15"},void 0,!1,void 0,this),o1("path",{d:"M0,230 C67,170 133,170 200,230 C267,290 333,290 400,230 C467,170 533,170 600,230 C667,290 733,290 800,230 C867,170 933,170 1000,230 C1067,290 1133,290 1200,230 C1267,170 1333,170 1400,230 C1467,290 1533,290 1600,230",className:"stroke-accent",strokeWidth:"1.5",strokeMiterlimit:"10",fill:"none",opacity:"0.06"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),o1("div",{className:"relative z-10 max-w-5xl mx-auto w-full px-6 md:px-12 pt-12 md:pt-20 pb-16 md:pb-24",children:[o1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:o1("ol",{className:"flex flex-wrap items-center gap-1",children:[o1("li",{className:"flex items-center gap-1",children:o1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o1("li",{className:"flex items-center gap-1",children:[o1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),o1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("li",{className:"flex items-center gap-1",children:[o1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),o1("span",{className:"text-white font-medium",children:Q.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("div",{className:"mb-6 hero-stagger-1",children:o1(Tf,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),o1("h1",{className:"text-5xl md:text-6xl lg:text-[7rem] font-bold text-white tracking-tighter leading-[0.95] mb-6 md:mb-8 hero-stagger-1",children:Q.name},void 0,!1,void 0,this),o1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),o1("p",{className:"text-lg md:text-xl text-white/70 leading-relaxed max-w-xl hero-stagger-3",children:B.tagline},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:o1("div",{className:"max-w-4xl mx-auto space-y-16",children:[o1("div",{children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),o1("p",{className:"text-2xl md:text-3xl lg:text-4xl leading-relaxed text-heading font-light",children:B.promise},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.audience},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),o1(CP,{tags:B.values,variant:"accent",size:"md"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:o1("div",{className:"container mx-auto max-w-5xl",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),o1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,Y)=>o1("div",{children:o1("div",{className:"flex items-start gap-6",children:[o1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(Y+1).padStart(2,"0")},void 0,!1,void 0,this),o1("div",{className:"pt-2",children:[o1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),o1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),o1("p",{className:"text-white/70 leading-relaxed",children:D.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},D.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:o1("div",{className:"max-w-3xl mx-auto",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),o1("div",{className:"space-y-6",children:I.map((D,Y)=>o1("p",{className:Y===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},Y,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"cta-bg-pattern bg-brand-dark pt-24 md:pt-32 pb-40 md:pb-48 -mb-[60px] px-6 md:px-12",children:o1("div",{className:"max-w-4xl mx-auto",children:[o1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),o1("h2",{className:"text-3xl md:text-5xl font-bold text-white max-w-2xl mb-4",children:B.tagline},void 0,!1,void 0,this),o1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),o1(T5,{href:$,variant:"outline-light",size:"lg",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var GvA=J.object({route:J.string().default("/products")});var h41={name:"@brains/products",private:!0,version:"0.2.0-alpha.80",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/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var qIQ=J.object({overview:Uc,products:J.array(QwA)}),LIQ=J.object({product:QwA});class FvA extends NQ{entityType=BwA.entityType;schema=Ok;adapter=BwA;constructor(A={}){super("products",h41,A,GvA)}getTemplates(){return{"product-list":b1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:qIQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:y41}}),"product-detail":b1({name:"product-detail",description:"Individual product detail page",schema:LIQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:x41}})}}getDataSources(){return[new $wA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",bk,JvA)}}function KvA(A={}){return new FvA(A)}import{join as rIQ}from"path";import{jsxDEV as fwA,Fragment as EIQ}from"preact/jsx-dev-runtime";var kk=({children:A})=>fwA(EIQ,{children:[fwA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:fwA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),fwA("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 Wyw}from"preact/jsx-dev-runtime";import{jsxDEV as VIQ}from"preact/jsx-dev-runtime";var IwA="px-6 md:px-10 xl:px-20",MIQ=`${IwA} relative z-[1]`,v3=({id:A,className:Q,children:B})=>VIQ("section",{id:A,className:a1(MIQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as Nyw}from"preact/jsx-dev-runtime";import{jsxDEV as Eyw}from"preact/jsx-dev-runtime";import{jsxDEV as PIQ}from"preact/jsx-dev-runtime";var CIQ="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)]",OIQ={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)]"},RIQ={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)]"},bIQ="w-full md:w-auto",yE=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>PIQ("a",{href:A,className:a1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",CIQ,OIQ[Q],RIQ[B],w&&bIQ,$),children:f},void 0,!1,void 0,this);import{jsxDEV as Pyw}from"preact/jsx-dev-runtime";import{jsxDEV as vyw}from"preact/jsx-dev-runtime";import{Fragment as hyw}from"preact";import{jsxDEV as Tyw}from"preact/jsx-dev-runtime";import{jsxDEV as g41}from"preact/jsx-dev-runtime";var DwA=({sections:A})=>g41(kk,{children:g41("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);B0();GA();var T41=`/*
|
|
5914
|
+
`},void 0,!1,void 0,this),o1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:o1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[o1("path",{d:"M0,200 C67,140 133,140 200,200 C267,260 333,260 400,200 C467,140 533,140 600,200 C667,260 733,260 800,200 C867,140 933,140 1000,200 C1067,260 1133,260 1200,200 C1267,140 1333,140 1400,200 C1467,260 1533,260 1600,200",className:"stroke-accent",strokeWidth:"2",strokeMiterlimit:"10",fill:"none",opacity:"0.15"},void 0,!1,void 0,this),o1("path",{d:"M0,230 C67,170 133,170 200,230 C267,290 333,290 400,230 C467,170 533,170 600,230 C667,290 733,290 800,230 C867,170 933,170 1000,230 C1067,290 1133,290 1200,230 C1267,170 1333,170 1400,230 C1467,290 1533,290 1600,230",className:"stroke-accent",strokeWidth:"1.5",strokeMiterlimit:"10",fill:"none",opacity:"0.06"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),o1("div",{className:"relative z-10 max-w-5xl mx-auto w-full px-6 md:px-12 pt-12 md:pt-20 pb-16 md:pb-24",children:[o1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:o1("ol",{className:"flex flex-wrap items-center gap-1",children:[o1("li",{className:"flex items-center gap-1",children:o1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o1("li",{className:"flex items-center gap-1",children:[o1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),o1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("li",{className:"flex items-center gap-1",children:[o1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),o1("span",{className:"text-white font-medium",children:Q.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("div",{className:"mb-6 hero-stagger-1",children:o1(Tf,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),o1("h1",{className:"text-5xl md:text-6xl lg:text-[7rem] font-bold text-white tracking-tighter leading-[0.95] mb-6 md:mb-8 hero-stagger-1",children:Q.name},void 0,!1,void 0,this),o1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),o1("p",{className:"text-lg md:text-xl text-white/70 leading-relaxed max-w-xl hero-stagger-3",children:B.tagline},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:o1("div",{className:"max-w-4xl mx-auto space-y-16",children:[o1("div",{children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),o1("p",{className:"text-2xl md:text-3xl lg:text-4xl leading-relaxed text-heading font-light",children:B.promise},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o1("div",{children:[o1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),o1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.audience},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),o1(CP,{tags:B.values,variant:"accent",size:"md"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:o1("div",{className:"container mx-auto max-w-5xl",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),o1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,Y)=>o1("div",{children:o1("div",{className:"flex items-start gap-6",children:[o1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(Y+1).padStart(2,"0")},void 0,!1,void 0,this),o1("div",{className:"pt-2",children:[o1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),o1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),o1("p",{className:"text-white/70 leading-relaxed",children:D.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},D.title,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:o1("div",{className:"max-w-3xl mx-auto",children:[o1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),o1("div",{className:"space-y-6",children:I.map((D,Y)=>o1("p",{className:Y===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},Y,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o1("section",{className:"cta-bg-pattern bg-brand-dark pt-24 md:pt-32 pb-40 md:pb-48 -mb-[60px] px-6 md:px-12",children:o1("div",{className:"max-w-4xl mx-auto",children:[o1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),o1("h2",{className:"text-3xl md:text-5xl font-bold text-white max-w-2xl mb-4",children:B.tagline},void 0,!1,void 0,this),o1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),o1(T5,{href:$,variant:"outline-light",size:"lg",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};GA();var GvA=J.object({route:J.string().default("/products")});var h41={name:"@brains/products",private:!0,version:"0.2.0-alpha.81",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/plugins":"workspace:*","@brains/utils":"workspace:*"},devDependencies:{"@brains/app":"workspace:*","@brains/eslint-config":"workspace:*","@brains/typescript-config":"workspace:*","@types/bun":"latest","bun-types":"latest",eslint:"^8.56.0",typescript:"^5.3.3"}};var qIQ=J.object({overview:Uc,products:J.array(QwA)}),LIQ=J.object({product:QwA});class FvA extends NQ{entityType=BwA.entityType;schema=Ok;adapter=BwA;constructor(A={}){super("products",h41,A,GvA)}getTemplates(){return{"product-list":b1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:qIQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:y41}}),"product-detail":b1({name:"product-detail",description:"Individual product detail page",schema:LIQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:x41}})}}getDataSources(){return[new $wA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",bk,JvA)}}function KvA(A={}){return new FvA(A)}import{join as rIQ}from"path";import{jsxDEV as fwA,Fragment as EIQ}from"preact/jsx-dev-runtime";var kk=({children:A})=>fwA(EIQ,{children:[fwA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:fwA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),fwA("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 Wyw}from"preact/jsx-dev-runtime";import{jsxDEV as VIQ}from"preact/jsx-dev-runtime";var IwA="px-6 md:px-10 xl:px-20",MIQ=`${IwA} relative z-[1]`,v3=({id:A,className:Q,children:B})=>VIQ("section",{id:A,className:a1(MIQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as Nyw}from"preact/jsx-dev-runtime";import{jsxDEV as Eyw}from"preact/jsx-dev-runtime";import{jsxDEV as PIQ}from"preact/jsx-dev-runtime";var CIQ="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)]",OIQ={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)]"},RIQ={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)]"},bIQ="w-full md:w-auto",yE=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>PIQ("a",{href:A,className:a1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",CIQ,OIQ[Q],RIQ[B],w&&bIQ,$),children:f},void 0,!1,void 0,this);import{jsxDEV as Pyw}from"preact/jsx-dev-runtime";import{jsxDEV as vyw}from"preact/jsx-dev-runtime";import{Fragment as hyw}from"preact";import{jsxDEV as Tyw}from"preact/jsx-dev-runtime";import{jsxDEV as g41}from"preact/jsx-dev-runtime";var DwA=({sections:A})=>g41(kk,{children:g41("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);B0();GA();var T41=`/*
|
|
5915
5915
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
5916
5916
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
5917
5917
|
* so the variant canvases
|
|
@@ -8397,7 +8397,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var f
|
|
|
8397
8397
|
`).map((Q)=>Q.trim()).find((Q)=>Q.length>0&&!Q.startsWith("#"))??""}var C4Q=5,O4Q=4,qD1=[G6,W4,_D];class qwA{context;constructor(A){this.context=A}async retrieve(A){let Q=A.query?.trim()??"",B=Math.max(1,A.limit??C4Q),w=await this.resolveSpaceId(A),I=(await this.loadCandidates(Q,B)).filter((D)=>{if(!w||A.includeOtherSpaces)return!0;return this.getEntitySpaceId(D.entity)===w}).filter((D)=>this.matchesIdentity(D.entity,A)).sort((D,Y)=>{let H=w?this.getEntitySpaceId(D.entity)===w:!1,W=w?this.getEntitySpaceId(Y.entity)===w:!1;if(H!==W)return H?-1:1;if(Y.score!==D.score)return Y.score-D.score;return Date.parse(Y.entity.updated)-Date.parse(D.entity.updated)}).slice(0,B).map((D)=>this.toMemory(D));return{query:Q,...w?{spaceId:w}:{},results:I}}async resolveSpaceId(A){if(A.interfaceType&&A.channelId)return _H({interfaceType:A.interfaceType,channelId:A.channelId});if(!A.conversationId)return;let Q=await this.context.conversations.get(A.conversationId);return Q?_H(Q):void 0}async loadCandidates(A,Q){let B=Q*O4Q;if(A.length>0)return(await this.context.entityService.search({query:A,options:{types:qD1,limit:B}})).map((f)=>({entity:f.entity,score:f.score,excerpt:f.excerpt}));return(await Promise.all(qD1.map(($)=>this.context.entityService.listEntities({entityType:$,options:{limit:B,sortFields:[{field:"updated",direction:"desc"}]}})))).flat().map(($)=>({entity:$,score:0,excerpt:Nc($)}))}toMemory(A){let{entity:Q}=A,B=Q.metadata;return{id:Q.id,entityType:Q.entityType,conversationId:B.conversationId,spaceId:this.getEntitySpaceId(Q),channelId:B.channelId,...B.channelName?{channelName:B.channelName}:{},interfaceType:B.interfaceType,updated:Q.updated,score:A.score,excerpt:A.excerpt||Nc(Q),...Q.entityType===G6?{messageCount:Q.metadata.messageCount,entryCount:Q.metadata.entryCount}:{status:Q.metadata.status}}}matchesIdentity(A,Q){if(!Q.actorId&&!Q.canonicalId)return!0;return this.getIdentityReferences(A).some((B)=>{if(Q.canonicalId&&B.canonicalId===Q.canonicalId)return!0;if(!Q.actorId)return!1;return B.actorId===Q.actorId||B.sourceActorIds?.includes(Q.actorId)===!0})}getIdentityReferences(A){if(this.isSummaryEntity(A))return A.metadata.participants??[];if(this.isDecisionEntity(A))return[...A.metadata.decidedBy??[],...A.metadata.mentionedBy??[]];return[...A.metadata.assignedTo??[],...A.metadata.requestedBy??[]]}isSummaryEntity(A){return A.entityType===G6}isDecisionEntity(A){return A.entityType===W4}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return _H(Q)}}var RvA=J.object({role:J.enum(["user","assistant","system"]),content:J.string(),timestamp:J.string().datetime().optional(),actor:TV.optional(),source:SV.optional()}),R4Q=J.object({conversationId:J.string().default("eval-conversation"),messages:J.array(RvA)}),b4Q=J.object({conversationId:J.string()}),P4Q=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(RvA)}),LwA=J.object({actorId:J.string(),canonicalId:J.string().optional(),displayName:J.string().optional()}),k4Q=LwA.extend({roles:J.array(J.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:J.array(J.string()).optional()}),j4Q=J.object({actorId:J.string().optional(),canonicalId:J.string().optional(),displayName:J.string()}),_4Q=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(),status:J.string().optional(),participants:J.array(k4Q).optional(),decidedBy:J.array(LwA).optional(),mentionedBy:J.array(LwA).optional(),assignedTo:J.array(j4Q).optional(),requestedBy:J.array(LwA).optional()}),v4Q=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(),memory:J.array(_4Q).optional()}),y4Q=J.object({conversationId:J.string().default("eval-conversation"),existingSummary:J.string().optional(),existingMessageCount:J.number().int().min(0).default(0),messages:J.array(RvA)});function ED1(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=R4Q.parse($),I=OvA(f.messages,f.conversationId),Y=await new hk(Q,B,w).extract(I);return Y.entries.map((H)=>{let W=Y.decisions.filter((K)=>K.timeRange.start>=H.timeRange.start).filter((K)=>K.timeRange.end<=H.timeRange.end).map((K)=>K.text),F=Y.actionItems.filter((K)=>K.timeRange.start>=H.timeRange.start).filter((K)=>K.timeRange.end<=H.timeRange.end).map((K)=>K.text);return{...H,decisions:W,actionItems:F,keyPointsText:H.keyPoints.join(`
|
|
8398
8398
|
`),decisionsText:W.join(`
|
|
8399
8399
|
`),actionItemsText:F.join(`
|
|
8400
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=y4Q.parse($),I=OvA(f.messages,f.conversationId),D=f.existingSummary?LD1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new x3(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=v4Q.parse($),I=f.memory?g4Q(Q,f.memory):Q;return new qwA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=P4Q.parse($),I=OvA(f.messages,f.conversationId),D=x4Q({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),Y=f.existingSummary?LD1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,H=[],W=[],F=h4Q({context:Q,conversation:D,messages:I,existing:Y,upserted:H,deleted:W,projectionDecision:f.projectionDecision});return{result:await new x3(F,B,w).projectConversation(f.conversationId),summaries:H.filter((q)=>q.entityType==="summary"),decisions:H.filter((q)=>q.entityType==="decision"),actionItems:H.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=b4Q.parse($);return new x3(Q,B,w).projectConversation(f.conversationId)})}function LD1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",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 OvA(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 x4Q(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 h4Q(A){let Q=_H(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 g4Q(A,Q){let B=Q.map(T4Q),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??Nc($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function T4Q(A){if(A.entityType==="summary")return S4Q(A);if(A.entityType==="decision")return m4Q(A);return u4Q(A)}function bvA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:RB(A.content),created:Q,updated:Q}}function S4Q(A){return{...bvA(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 m4Q(A){return{...bvA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:_H(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 u4Q(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...bvA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:_H(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 MD1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.80",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/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 p4Q=new dW,l4Q=new vk,i4Q=new yk,r4Q=J.object({conversationId:J.string()});class PvA extends NQ{entityType=G6;schema=Gc;adapter=p4Q;constructor(A={}){super(HwA,MD1,A,qvA)}getConfig(){return this.config}getTemplates(){return{"summary-list":e41,"summary-detail":AD1,"ai-response":QD1}}getDataSources(){return[new CvA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:G6,job:{type:r41,handler:new FwA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await BN(A,G6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:NvA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:HwA}}},sourceChange:{sourceKind:si,sourceTypes:[si],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Xv],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:NvA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:HwA}}}}}]}parseConversationMessagePayload(A){return r4Q.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return gE({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(W4,Fc,l4Q),A.entities.register(_D,Kc,i4Q),$D1({context:A,pluginId:this.id}),ID1({context:A,pluginId:this.id}),KD1({context:A,pluginId:this.id}),ND1({context:A,pluginId:this.id,config:this.config}),ED1({context:A,logger:this.logger,config:this.config})}}function kvA(A){return new PvA(A)}B0();GA();B0();var nG=J.object({title:J.string(),section:J.string(),order:J.number().int(),sourcePath:J.string(),description:J.string().optional(),slug:J.string().optional()}),VD1=nG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:J.string()}),Sk=w2.extend({entityType:J.literal("doc"),metadata:VD1}),oG=Sk.extend({frontmatter:nG,body:J.string()});B0();GA();class jvA extends F2{constructor(){super({entityType:"doc",schema:Sk,frontmatterSchema:nG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,nG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,nG),B=Q.slug??D2(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 EwA=new jvA;B0();function CD1(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 OD1(A){let Q=AQ(A.content,nG);return oG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class MwA extends w5{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 OD1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let W=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(W.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=CD1(f.items),D=I.findIndex((W)=>W.id===$.item.id),Y=D>0?I[D-1]:null,H=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:Y,nextDoc:H})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:CD1(A),pagination:Q,baseUrl:B.baseUrl}}}B0();xw();GA();import{jsxDEV as q5}from"preact/jsx-dev-runtime";var d4Q=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function qc(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 VwA(A){let Q=new Map;for(let B of qc(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function mk(A){return`/docs/${A.metadata.slug}`}function CwA(A){return`section-${A+1}`}function uk(A){return d4Q[A]??String(A+1)}var PD1="text-[var(--docs-text)] font-bold",kD1="text-[var(--docs-accent)] font-bold",jD1="text-[var(--docs-text-muted)]",n4Q="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",o4Q="docs-font-display text-[var(--docs-heading)]",RD1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",bD1="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",_vA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",nW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:n4Q,display:o4Q,button:`${RD1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${RD1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},_D1=()=>q5("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:[q5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[q5("span",{className:PD1,children:"brains"},void 0,!1,void 0,this),q5("span",{className:kD1,children:"."},void 0,!1,void 0,this),q5("span",{className:jD1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[q5("a",{className:bD1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),q5("a",{className:bD1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),q5("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),vD1=()=>q5("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:[q5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[q5("span",{className:PD1,children:"rizom"},void 0,!1,void 0,this),q5("span",{className:kD1,children:"."},void 0,!1,void 0,this),q5("span",{className:jD1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[q5("a",{className:_vA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),q5("a",{className:_vA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),q5("a",{className:_vA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),q5("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),s4Q=`
|
|
8400
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=y4Q.parse($),I=OvA(f.messages,f.conversationId),D=f.existingSummary?LD1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new x3(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=v4Q.parse($),I=f.memory?g4Q(Q,f.memory):Q;return new qwA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=P4Q.parse($),I=OvA(f.messages,f.conversationId),D=x4Q({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),Y=f.existingSummary?LD1({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,H=[],W=[],F=h4Q({context:Q,conversation:D,messages:I,existing:Y,upserted:H,deleted:W,projectionDecision:f.projectionDecision});return{result:await new x3(F,B,w).projectConversation(f.conversationId),summaries:H.filter((q)=>q.entityType==="summary"),decisions:H.filter((q)=>q.entityType==="decision"),actionItems:H.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=b4Q.parse($);return new x3(Q,B,w).projectConversation(f.conversationId)})}function LD1(A){return{id:A.conversationId,entityType:"summary",content:A.content,contentHash:"eval-existing-summary",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 OvA(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 x4Q(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 h4Q(A){let Q=_H(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 g4Q(A,Q){let B=Q.map(T4Q),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??Nc($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function T4Q(A){if(A.entityType==="summary")return S4Q(A);if(A.entityType==="decision")return m4Q(A);return u4Q(A)}function bvA(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:RB(A.content),created:Q,updated:Q}}function S4Q(A){return{...bvA(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 m4Q(A){return{...bvA(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:_H(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 u4Q(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...bvA(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:_H(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 MD1={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.81",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/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 p4Q=new dW,l4Q=new vk,i4Q=new yk,r4Q=J.object({conversationId:J.string()});class PvA extends NQ{entityType=G6;schema=Gc;adapter=p4Q;constructor(A={}){super(HwA,MD1,A,qvA)}getConfig(){return this.config}getTemplates(){return{"summary-list":e41,"summary-detail":AD1,"ai-response":QD1}}getDataSources(){return[new CvA(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:G6,job:{type:r41,handler:new FwA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await BN(A,G6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:NvA,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:HwA}}},sourceChange:{sourceKind:si,sourceTypes:[si],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Xv],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:NvA,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:HwA}}}}}]}parseConversationMessagePayload(A){return r4Q.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return gE({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(W4,Fc,l4Q),A.entities.register(_D,Kc,i4Q),$D1({context:A,pluginId:this.id}),ID1({context:A,pluginId:this.id}),KD1({context:A,pluginId:this.id}),ND1({context:A,pluginId:this.id,config:this.config}),ED1({context:A,logger:this.logger,config:this.config})}}function kvA(A){return new PvA(A)}B0();GA();B0();var nG=J.object({title:J.string(),section:J.string(),order:J.number().int(),sourcePath:J.string(),description:J.string().optional(),slug:J.string().optional()}),VD1=nG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:J.string()}),Sk=w2.extend({entityType:J.literal("doc"),metadata:VD1}),oG=Sk.extend({frontmatter:nG,body:J.string()});B0();GA();class jvA extends F2{constructor(){super({entityType:"doc",schema:Sk,frontmatterSchema:nG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,nG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,nG),B=Q.slug??D2(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 EwA=new jvA;B0();function CD1(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 OD1(A){let Q=AQ(A.content,nG);return oG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class MwA extends w5{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 OD1(A)}async fetch(A,Q,B){let w=this.parseQuery(A);if(!w.query.id){let W=await this.fetchList({...w.query,limit:1000,page:void 0,pageSize:void 0},B.entityService);return Q.parse(this.buildListResult(W.items,null,w.query))}let[$,f]=await Promise.all([this.fetchDetail(w.query.id,B.entityService),this.fetchList({limit:1000},B.entityService)]),I=CD1(f.items),D=I.findIndex((W)=>W.id===$.item.id),Y=D>0?I[D-1]:null,H=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:Y,nextDoc:H})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:CD1(A),pagination:Q,baseUrl:B.baseUrl}}}B0();xw();GA();import{jsxDEV as q5}from"preact/jsx-dev-runtime";var d4Q=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function qc(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 VwA(A){let Q=new Map;for(let B of qc(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function mk(A){return`/docs/${A.metadata.slug}`}function CwA(A){return`section-${A+1}`}function uk(A){return d4Q[A]??String(A+1)}var PD1="text-[var(--docs-text)] font-bold",kD1="text-[var(--docs-accent)] font-bold",jD1="text-[var(--docs-text-muted)]",n4Q="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",o4Q="docs-font-display text-[var(--docs-heading)]",RD1="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",bD1="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",_vA="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",nW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:n4Q,display:o4Q,button:`${RD1} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${RD1} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},_D1=()=>q5("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:[q5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[q5("span",{className:PD1,children:"brains"},void 0,!1,void 0,this),q5("span",{className:kD1,children:"."},void 0,!1,void 0,this),q5("span",{className:jD1,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[q5("a",{className:bD1,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),q5("a",{className:bD1,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),q5("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),vD1=()=>q5("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:[q5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[q5("span",{className:PD1,children:"rizom"},void 0,!1,void 0,this),q5("span",{className:kD1,children:"."},void 0,!1,void 0,this),q5("span",{className:jD1,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[q5("a",{className:_vA,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),q5("a",{className:_vA,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),q5("a",{className:_vA,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),q5("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),s4Q=`
|
|
8401
8401
|
.docs-handbook {
|
|
8402
8402
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
8403
8403
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -8549,7 +8549,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var f
|
|
|
8549
8549
|
background: transparent;
|
|
8550
8550
|
}
|
|
8551
8551
|
|
|
8552
|
-
`,yD1=()=>q5("style",{children:s4Q},void 0,!1,void 0,this);import{jsxDEV as W2,Fragment as a4Q}from"preact/jsx-dev-runtime";var OwA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>W2(a4Q,{children:[W2(JQ,{title:A,description:Q},void 0,!1,void 0,this),W2(yD1,{},void 0,!1,void 0,this),W2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[W2(_D1,{},void 0,!1,void 0,this),W2("div",{className:`${nW.wrap} ${f}`.trim(),children:[B,$&&W2(vD1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),xD1=({docsCount:A,sectionsCount:Q,startDoc:B})=>W2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[W2("p",{className:`${nW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),W2("h1",{className:`${nW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",W2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("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),W2("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:[W2("div",{children:[W2("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),W2("div",{children:[W2("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),W2("div",{children:[W2("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),W2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&W2("a",{className:nW.primaryButton,href:mk(B),children:"Start reading"},void 0,!1,void 0,this),W2("a",{className:nW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),hD1=({groups:A})=>W2("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:[W2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),W2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>W2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[W2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[uk(B),"."]},void 0,!0,void 0,this),W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${CwA(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),gD1=({group:A,index:Q})=>W2("article",{className:"mb-16 last:mb-0",id:CwA(Q),children:[W2("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:[W2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[uk(Q),"."]},void 0,!0,void 0,this),W2("h2",{className:`${nW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),W2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>W2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:W2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:mk(B),children:[W2("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&&W2("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),TD1=({title:A})=>W2("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:[W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),W2("span",{children:"/"},void 0,!1,void 0,this),W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),W2("span",{children:"/"},void 0,!1,void 0,this),W2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),SD1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>W2("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:W2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[W2("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),W2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return W2("li",{className:f?"mb-[22px]":"mb-3.5",children:[W2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${CwA($)}`,children:[W2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[uk($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&W2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return W2("li",{children:W2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:mk(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),mD1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return W2("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?W2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:mk(A),children:[W2("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),W2("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):W2("span",{},void 0,!1,void 0,this),Q&&W2("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:mk(Q),children:[W2("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),W2("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 ck}from"preact/jsx-dev-runtime";var vvA=({docs:A})=>{let Q=qc(A),B=VwA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return ck(OwA,{title:"Documentation",description:"Brains documentation",children:[ck(xD1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),ck("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:[ck(hD1,{groups:B},void 0,!1,void 0,this),ck("div",{children:B.map((f,I)=>ck(gD1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as U4}from"preact/jsx-dev-runtime";var yvA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=VwA(Q.length>0?Q:[A]),f=qc(Q.length>0?Q:[A]),I=f.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return U4(OwA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[U4(TD1,{title:A.metadata.title},void 0,!1,void 0,this),U4("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[U4(SD1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),U4("article",{className:"min-w-0",children:[U4("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[U4("p",{className:`${nW.label} m-0 mb-6 flex items-baseline gap-3`,children:[U4("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[uk(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),U4("h1",{className:`${nW.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&&U4("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),U4("div",{className:"docs-article__body",children:U4(I4,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),U4(mD1,{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 t4Q=J.object({docs:J.array(oG),pagination:L9.nullable(),baseUrl:J.string().optional()}),e4Q=J.object({doc:oG,docs:J.array(oG),prevDoc:oG.nullable(),nextDoc:oG.nullable()});function uD1(){return{"doc-list":b1({name:"doc-list",description:"Documentation index template",schema:t4Q,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:vvA}}),"doc-detail":b1({name:"doc-detail",description:"Documentation page template",schema:e4Q,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:yvA}})}}var cD1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.80",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 xvA extends NQ{entityType=EwA.entityType;schema=Sk;adapter=EwA;constructor(){super("docs",cD1,{},void 0)}getTemplates(){return uD1()}getDataSources(){return[new MwA(this.logger.child("DocDataSource"))]}}function hvA(){return new xvA}B0();GA();GA();$$();var pD1=J.object({label:J.string(),href:J.string()}),lD1=J.object({label:J.string(),title:J.string(),detail:J.string()}),QDQ=J.object({eyebrow:J.string(),name:J.string(),sub:J.string()}),BDQ=J.object({tone:J.enum(["capture","synthesis","share"]),title:J.string(),text:J.string()}),gvA=J.object({captures:J.number(),links:J.number(),topics:J.number(),summaries:J.number(),peers:J.number()}),pk=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:pD1,secondaryCta:pD1,inputs:J.array(lD1).min(1),outputs:J.array(lD1).min(1),core:QDQ,legend:J.array(BDQ).min(1)}),TvA=pk.extend({counts:gvA}),iD1={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."}]},rD1=new yB(pk,{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 RwA(A){return rD1.parse(A)}function dD1(A){return rD1.format(A)}GA();var wDQ=J.object({query:J.object({routeId:J.string().default("home"),sectionId:J.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),$DQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class SvA{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=wDQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return iD1;return pk.parse(RwA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries($DQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return gvA.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 w1}from"preact/jsx-dev-runtime";var nD1=J.object({label:J.string(),href:J.string()}),fDQ=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:nD1,secondaryCta:nD1,signals:J.array(J.object({label:J.string(),value:J.string(),note:J.string()}))}),IDQ=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()}))}),DDQ=J.object({title:J.string(),intro:J.string(),cards:J.array(J.object({label:J.string(),title:J.string(),text:J.string()}))}),YDQ=J.object({title:J.string(),intro:J.string(),points:J.array(J.string())}),HDQ={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."]},XDQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function oD1({href:A,label:Q}){return w1("a",{href:A,className:XDQ,children:Q},void 0,!1,void 0,this)}function WDQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(kk,{children:[w1("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:[w1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[w1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),w1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),w1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex items-center gap-5 md:gap-8",children:[w1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>w1(oD1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),w1("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),w1("main",{children:Q},void 0,!1,void 0,this),w1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:w1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),w1("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),w1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>w1(oD1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),w1("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 UDQ=({sections:A,siteInfo:Q})=>w1(WDQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function JDQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(v3,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:w1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[w1(yE,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(yE,{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),w1("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:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),w1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>w1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[w1("div",{className:"flex items-center justify-between gap-4",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),w1("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),w1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),w1("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 GDQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(v3,{id:"operating-loop",className:"py-section",children:[w1("div",{className:"max-w-[840px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),w1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>w1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[w1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),w1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),w1("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 FDQ({title:A,intro:Q,cards:B}){return w1(v3,{className:"py-section",children:w1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:w1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[w1("div",{children:[w1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),w1("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),w1("div",{className:"grid gap-4",children:B.map((w)=>w1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),w1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),w1("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 KDQ({title:A,intro:Q,points:B}){return w1(v3,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[w1("div",{className:"max-w-[920px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),w1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>w1("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 ZDQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},zDQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Lc=(A,Q,B=`${Q}s`)=>`${zDQ(A)} ${A===1?Q:B}`;function NDQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:Y,counts:H}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Lc(H.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Lc(H.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Lc(H.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Lc(H.summaries,"summary","summaries")}];return w1(v3,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[w1("div",{className:"mx-auto max-w-[1040px] text-center",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[w1(yE,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(yE,{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),w1("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:[w1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[w1("div",{className:"flex flex-col gap-3.5",children:f.map((F)=>w1("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:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:F.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),w1("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),w1("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:[w1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),w1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),W.map((F)=>w1("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)),w1("div",{className:"relative z-[1] px-6 text-center",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Lc(H.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:I.map((F)=>w1("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:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:F.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:Y.map((F)=>w1("div",{className:"text-left",children:[w1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[w1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${ZDQ(F.tone)}`},void 0,!1,void 0,this),F.title]},void 0,!0,void 0,this),w1("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 qDQ=b1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:TvA,formatter:{parse:(A)=>TvA.parse({...RwA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>dD1(pk.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:NDQ}}),LDQ=(A)=>JDQ(fDQ.parse(A)),EDQ=(A)=>GDQ(IDQ.parse(A)),MDQ=(A)=>FDQ(DDQ.parse(A)),VDQ=(A)=>KDQ(YDQ.parse(A)),sD1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},aD1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:LDQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...sD1,label:"Primary CTA"},secondaryCta:{...sD1,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:EDQ,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:MDQ,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:VDQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},CDQ=[{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:HDQ}]}],tD1=zvA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:UDQ,routes:CDQ,templates:{"home-diagram":qDQ},dataSources:[new SvA]});var eD1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],AY1=[...eD1,"image","site-info","site-content","site-builder"],RDQ=[...AY1,"docs","decks"],bDQ=["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.'],QY1=vK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:tD1,theme:jk,presets:{core:eD1,default:AY1,full:RDQ},evalDisable:["webserver","mcp","discord"],agentInstructions:bDQ,capabilities:[["prompt",jE,void 0],["note",ME,{}],["link",CE,{}],["image",Sx,void 0],["topics",QBA,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",kvA,{}],["docs",hvA,void 0],["decks",ku,void 0],["agents",hBA,void 0],["assessment",rBA,void 0],["auth-service",bg,void 0],["cms",kE,{}],["dashboard",k3,void 0],["directory-sync",yL,{seedContent:!0,seedContentPath:ODQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Wc,{definitions:aD1}],["rizom-ecosystem",_E,void 0],["site-info",NE,void 0],["site-builder",zE,{}]],interfaces:[["mcp",JZ,()=>({})],["discord",nZ,()=>({captureUrls:!0})],["a2a",pb,()=>({})],["webserver",oZ,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as DWQ}from"fs";import{join as YWQ}from"path";import{execSync as HWQ}from"child_process";import{parseArgs as jDQ}from"util";var _DQ={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"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function oW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function h3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function BY1(A){let{values:Q,positionals:B}=jDQ({args:A,options:_DQ,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:oW(Q,"model"),domain:oW(Q,"domain"),"content-repo":oW(Q,"content-repo"),backend:oW(Q,"backend"),"push-to":oW(Q,"push-to"),"ai-api-key":oW(Q,"ai-api-key"),"no-interactive":h3(Q,"no-interactive"),preview:h3(Q,"preview"),deploy:h3(Q,"deploy"),regen:h3(Q,"regen"),all:h3(Q,"all"),only:oW(Q,"only"),"dry-run":h3(Q,"dry-run"),"startup-check":h3(Q,"startup-check"),"storage-dir":oW(Q,"storage-dir"),yes:h3(Q,"yes"),remote:oW(Q,"remote"),token:oW(Q,"token")}}}Ec();import{mkdirSync as aXQ}from"fs";import{join as tXQ}from"path";import{execSync as eXQ}from"child_process";var PwA={name:"@rizom/brain",version:"0.2.0-alpha.80",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 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 ZY1,writeFileSync as Vc,chmodSync as Cc,existsSync as ovA,readFileSync as svA}from"fs";import{basename as avA,dirname as tvA,join as k8,resolve as UYQ}from"path";import{fileURLToPath as JYQ}from"url";var wY1=`ARG BUN_VERSION=1.3.10
|
|
8552
|
+
`,yD1=()=>q5("style",{children:s4Q},void 0,!1,void 0,this);import{jsxDEV as W2,Fragment as a4Q}from"preact/jsx-dev-runtime";var OwA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>W2(a4Q,{children:[W2(JQ,{title:A,description:Q},void 0,!1,void 0,this),W2(yD1,{},void 0,!1,void 0,this),W2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[W2(_D1,{},void 0,!1,void 0,this),W2("div",{className:`${nW.wrap} ${f}`.trim(),children:[B,$&&W2(vD1,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),xD1=({docsCount:A,sectionsCount:Q,startDoc:B})=>W2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[W2("p",{className:`${nW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),W2("h1",{className:`${nW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",W2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("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),W2("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:[W2("div",{children:[W2("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),W2("div",{children:[W2("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),W2("div",{children:[W2("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),W2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&W2("a",{className:nW.primaryButton,href:mk(B),children:"Start reading"},void 0,!1,void 0,this),W2("a",{className:nW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),hD1=({groups:A})=>W2("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:[W2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),W2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>W2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[W2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[uk(B),"."]},void 0,!0,void 0,this),W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${CwA(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),gD1=({group:A,index:Q})=>W2("article",{className:"mb-16 last:mb-0",id:CwA(Q),children:[W2("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:[W2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[uk(Q),"."]},void 0,!0,void 0,this),W2("h2",{className:`${nW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),W2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>W2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:W2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:mk(B),children:[W2("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&&W2("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),TD1=({title:A})=>W2("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:[W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),W2("span",{children:"/"},void 0,!1,void 0,this),W2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),W2("span",{children:"/"},void 0,!1,void 0,this),W2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),SD1=({groups:A,activeGroupIndex:Q,activeSlug:B})=>W2("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:W2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[W2("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),W2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return W2("li",{className:f?"mb-[22px]":"mb-3.5",children:[W2("a",{className:`mb-2 flex items-baseline gap-2.5 docs-font-label text-[11px] uppercase leading-[1.4] tracking-[0.06em] transition-colors duration-150 hover:text-[var(--docs-text)] ${f?"text-[var(--docs-text)]":"text-[var(--docs-text-muted)]"}`,href:`/docs#${CwA($)}`,children:[W2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[uk($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&W2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return W2("li",{children:W2("a",{className:`docs-rail__doc relative block py-1.5 docs-font-body text-sm leading-[1.4] tracking-normal transition-[color,padding-left] duration-150 hover:text-[var(--docs-text)] ${D?"pl-3.5 font-medium text-[var(--docs-accent)]":"text-[var(--docs-text-muted)]"}`,href:mk(I),"aria-current":D?"page":void 0,children:I.metadata.title},void 0,!1,void 0,this)},I.id,!1,void 0,this)})},void 0,!1,void 0,this)]},w.section,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),mD1=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return W2("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?W2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:mk(A),children:[W2("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),W2("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):W2("span",{},void 0,!1,void 0,this),Q&&W2("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:mk(Q),children:[W2("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),W2("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 ck}from"preact/jsx-dev-runtime";var vvA=({docs:A})=>{let Q=qc(A),B=VwA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return ck(OwA,{title:"Documentation",description:"Brains documentation",children:[ck(xD1,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),ck("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:[ck(hD1,{groups:B},void 0,!1,void 0,this),ck("div",{children:B.map((f,I)=>ck(gD1,{group:f,index:I},f.section,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as U4}from"preact/jsx-dev-runtime";var yvA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=VwA(Q.length>0?Q:[A]),f=qc(Q.length>0?Q:[A]),I=f.findIndex((Y)=>Y.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((Y)=>Y.docs.some((H)=>H.metadata.slug===A.metadata.slug)),0);return U4(OwA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[U4(TD1,{title:A.metadata.title},void 0,!1,void 0,this),U4("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[U4(SD1,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),U4("article",{className:"min-w-0",children:[U4("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[U4("p",{className:`${nW.label} m-0 mb-6 flex items-baseline gap-3`,children:[U4("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[uk(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),U4("h1",{className:`${nW.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&&U4("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),U4("div",{className:"docs-article__body",children:U4(I4,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),U4(mD1,{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 t4Q=J.object({docs:J.array(oG),pagination:L9.nullable(),baseUrl:J.string().optional()}),e4Q=J.object({doc:oG,docs:J.array(oG),prevDoc:oG.nullable(),nextDoc:oG.nullable()});function uD1(){return{"doc-list":b1({name:"doc-list",description:"Documentation index template",schema:t4Q,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:vvA}}),"doc-detail":b1({name:"doc-detail",description:"Documentation page template",schema:e4Q,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:yvA}})}}var cD1={name:"@brains/doc",private:!0,version:"0.2.0-alpha.81",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 xvA extends NQ{entityType=EwA.entityType;schema=Sk;adapter=EwA;constructor(){super("docs",cD1,{},void 0)}getTemplates(){return uD1()}getDataSources(){return[new MwA(this.logger.child("DocDataSource"))]}}function hvA(){return new xvA}B0();GA();GA();$$();var pD1=J.object({label:J.string(),href:J.string()}),lD1=J.object({label:J.string(),title:J.string(),detail:J.string()}),QDQ=J.object({eyebrow:J.string(),name:J.string(),sub:J.string()}),BDQ=J.object({tone:J.enum(["capture","synthesis","share"]),title:J.string(),text:J.string()}),gvA=J.object({captures:J.number(),links:J.number(),topics:J.number(),summaries:J.number(),peers:J.number()}),pk=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:pD1,secondaryCta:pD1,inputs:J.array(lD1).min(1),outputs:J.array(lD1).min(1),core:QDQ,legend:J.array(BDQ).min(1)}),TvA=pk.extend({counts:gvA}),iD1={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."}]},rD1=new yB(pk,{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 RwA(A){return rD1.parse(A)}function dD1(A){return rD1.format(A)}GA();var wDQ=J.object({query:J.object({routeId:J.string().default("home"),sectionId:J.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),$DQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class SvA{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=wDQ.parse(A??{}),$=await this.fetchContent(B,w.query.routeId,w.query.sectionId),f=await this.fetchCounts(B);return Q.parse({...$,counts:f})}async fetchContent(A,Q,B){let w=await A.entityService.getEntity({entityType:"site-content",id:`${Q}:${B}`});if(!w?.content)return iD1;return pk.parse(RwA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries($DQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return gvA.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 w1}from"preact/jsx-dev-runtime";var nD1=J.object({label:J.string(),href:J.string()}),fDQ=J.object({eyebrow:J.string(),headline:J.string(),intro:J.string(),primaryCta:nD1,secondaryCta:nD1,signals:J.array(J.object({label:J.string(),value:J.string(),note:J.string()}))}),IDQ=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()}))}),DDQ=J.object({title:J.string(),intro:J.string(),cards:J.array(J.object({label:J.string(),title:J.string(),text:J.string()}))}),YDQ=J.object({title:J.string(),intro:J.string(),points:J.array(J.string())}),HDQ={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."]},XDQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function oD1({href:A,label:Q}){return w1("a",{href:A,className:XDQ,children:Q},void 0,!1,void 0,this)}function WDQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(kk,{children:[w1("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:[w1("a",{href:"/",className:"font-nav text-[20px]","aria-label":"Relay home",children:[w1("span",{className:"font-bold text-theme",children:"relay"},void 0,!1,void 0,this),w1("span",{className:"font-bold text-accent",children:"."},void 0,!1,void 0,this),w1("span",{className:"text-theme-muted",children:"brain"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex items-center gap-5 md:gap-8",children:[w1("div",{className:"hidden items-center gap-6 md:flex",children:B.map(($)=>w1(oD1,{...$},`${$.href}-${$.label}`,!1,void 0,this))},void 0,!1,void 0,this),w1("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),w1("main",{children:Q},void 0,!1,void 0,this),w1("footer",{className:"relative z-[1] border-t border-theme-light px-6 py-8 md:px-10 xl:px-20",children:w1("div",{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.22em] text-theme-light",children:A.copyright},void 0,!1,void 0,this),w1("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),w1("div",{className:"flex flex-wrap items-center gap-5",children:[B.map(($)=>w1(oD1,{...$},`footer-${$.href}-${$.label}`,!1,void 0,this)),w1("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 UDQ=({sections:A,siteInfo:Q})=>w1(WDQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function JDQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(v3,{className:"min-h-[92vh] pt-[152px] pb-20 md:pt-[190px]",children:w1("div",{className:"grid gap-10 lg:grid-cols-[minmax(0,1fr)_420px] lg:items-end",children:[w1("div",{children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mt-7 max-w-[980px] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("p",{className:"mt-7 max-w-[720px] font-body text-body-lg text-theme-muted",children:B},void 0,!1,void 0,this),w1("div",{className:"mt-10 flex flex-col gap-3 sm:flex-row",children:[w1(yE,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(yE,{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),w1("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:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.24em] text-theme-light",children:"Live relay signals"},void 0,!1,void 0,this),w1("div",{className:"mt-5 grid gap-3",children:f.map((I)=>w1("div",{className:"rounded-[22px] border border-card-divider bg-bg-muted p-5",children:[w1("div",{className:"flex items-center justify-between gap-4",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.18em] text-secondary",children:I.label},void 0,!1,void 0,this),w1("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),w1("p",{className:"mt-4 font-display text-display-sm text-theme",children:I.value},void 0,!1,void 0,this),w1("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 GDQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(v3,{id:"operating-loop",className:"py-section",children:[w1("div",{className:"max-w-[840px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-secondary",children:A},void 0,!1,void 0,this),w1("h2",{className:"mt-5 font-display text-display-md text-theme",children:Q},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:w.map(($)=>w1("article",{className:"min-h-[300px] rounded-[28px] border border-card-panel-border bg-card-panel-bg p-6",children:[w1("p",{className:"font-label text-label-sm text-accent",children:$.phase},void 0,!1,void 0,this),w1("h3",{className:"mt-16 font-display text-display-sm text-theme",children:$.title},void 0,!1,void 0,this),w1("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 FDQ({title:A,intro:Q,cards:B}){return w1(v3,{className:"py-section",children:w1("div",{className:"rounded-[36px] border border-theme-light bg-bg-muted p-6 md:p-10",children:w1("div",{className:"grid gap-8 lg:grid-cols-[360px_1fr]",children:[w1("div",{children:[w1("h2",{className:"font-display text-display-md text-theme",children:A},void 0,!1,void 0,this),w1("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),w1("div",{className:"grid gap-4",children:B.map((w)=>w1("article",{className:"rounded-[24px] border border-card-divider bg-bg-subtle/70 p-5",children:[w1("p",{className:"font-label text-label-xs uppercase tracking-[0.22em] text-accent",children:w.label},void 0,!1,void 0,this),w1("h3",{className:"mt-3 font-nav text-heading-lg text-theme",children:w.title},void 0,!1,void 0,this),w1("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 KDQ({title:A,intro:Q,points:B}){return w1(v3,{className:"min-h-[78vh] pt-[150px] pb-section md:pt-[190px]",children:[w1("div",{className:"max-w-[920px]",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:"Relay model"},void 0,!1,void 0,this),w1("h1",{className:"mt-6 font-display text-display-lg text-theme",children:A},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-12 grid gap-4 md:grid-cols-3",children:B.map((w)=>w1("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 ZDQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},zDQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Lc=(A,Q,B=`${Q}s`)=>`${zDQ(A)} ${A===1?Q:B}`;function NDQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:Y,counts:H}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Lc(H.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Lc(H.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Lc(H.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Lc(H.summaries,"summary","summaries")}];return w1(v3,{className:"pt-[150px] pb-section md:pt-[190px]",id:"diagram",children:[w1("div",{className:"mx-auto max-w-[1040px] text-center",children:[w1("p",{className:"font-label text-label-sm uppercase tracking-[0.28em] text-accent",children:A},void 0,!1,void 0,this),w1("h1",{className:"mx-auto mt-7 max-w-[22ch] font-display text-display-lg text-theme",children:Q},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-10 flex flex-col justify-center gap-3 sm:flex-row",children:[w1(yE,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(yE,{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),w1("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:[w1("div",{className:"grid items-center gap-8 lg:grid-cols-[1fr_1.4fr_1fr]",children:[w1("div",{className:"flex flex-col gap-3.5",children:f.map((F)=>w1("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:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:F.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),w1("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),w1("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:[w1("div",{className:"absolute inset-0 rounded-full border border-dashed border-accent/30"},void 0,!1,void 0,this),w1("div",{className:"absolute inset-6 animate-spin rounded-full border border-dashed border-secondary/40 [animation-duration:28s]"},void 0,!1,void 0,this),W.map((F)=>w1("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)),w1("div",{className:"relative z-[1] px-6 text-center",children:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.28em] text-accent",children:D.eyebrow},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-display text-[36px] leading-none text-theme",children:D.name},void 0,!1,void 0,this),w1("p",{className:"mt-2 font-body text-[13px] text-theme-muted",children:D.sub},void 0,!1,void 0,this),w1("p",{className:"mt-4 font-label text-[10px] uppercase tracking-[0.18em] text-theme-light",children:[Lc(H.links,"link")," indexed"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w1("div",{className:"flex flex-col gap-3.5",children:I.map((F)=>w1("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:[w1("p",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-secondary",children:F.label},void 0,!1,void 0,this),w1("h2",{className:"mt-1.5 font-display text-[18px] font-medium text-theme",children:F.title},void 0,!1,void 0,this),w1("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),w1("div",{className:"mt-14 grid gap-4 border-t border-theme-light pt-8 md:grid-cols-3",children:Y.map((F)=>w1("div",{className:"text-left",children:[w1("h2",{className:"font-display text-[16px] font-medium text-theme",children:[w1("span",{className:`mr-2.5 inline-block h-3 w-3 rounded-[3px] align-middle ${ZDQ(F.tone)}`},void 0,!1,void 0,this),F.title]},void 0,!0,void 0,this),w1("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 qDQ=b1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:TvA,formatter:{parse:(A)=>TvA.parse({...RwA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>dD1(pk.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:NDQ}}),LDQ=(A)=>JDQ(fDQ.parse(A)),EDQ=(A)=>GDQ(IDQ.parse(A)),MDQ=(A)=>FDQ(DDQ.parse(A)),VDQ=(A)=>KDQ(YDQ.parse(A)),sD1={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},aD1={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:LDQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...sD1,label:"Primary CTA"},secondaryCta:{...sD1,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:EDQ,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:MDQ,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:VDQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},CDQ=[{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:HDQ}]}],tD1=zvA({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:UDQ,routes:CDQ,templates:{"home-diagram":qDQ},dataSources:[new SvA]});var eD1=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],AY1=[...eD1,"image","site-info","site-content","site-builder"],RDQ=[...AY1,"docs","decks"],bDQ=["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.'],QY1=vK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:tD1,theme:jk,presets:{core:eD1,default:AY1,full:RDQ},evalDisable:["webserver","mcp","discord"],agentInstructions:bDQ,capabilities:[["prompt",jE,void 0],["note",ME,{}],["link",CE,{}],["image",Sx,void 0],["topics",QBA,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",kvA,{}],["docs",hvA,void 0],["decks",ku,void 0],["agents",hBA,void 0],["assessment",rBA,void 0],["auth-service",bg,void 0],["cms",kE,{}],["dashboard",k3,void 0],["directory-sync",yL,{seedContent:!0,seedContentPath:ODQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",Wc,{definitions:aD1}],["rizom-ecosystem",_E,void 0],["site-info",NE,void 0],["site-builder",zE,{}]],interfaces:[["mcp",JZ,()=>({})],["discord",nZ,()=>({captureUrls:!0})],["a2a",pb,()=>({})],["webserver",oZ,()=>({})]],permissions:{rules:[{pattern:"cli:*",level:"anchor"},{pattern:"mcp:stdio",level:"anchor"},{pattern:"mcp:http",level:"anchor"},{pattern:"discord:*",level:"public"}]},deployment:{cdn:{enabled:!0,provider:"bunny"}}});import{readFileSync as DWQ}from"fs";import{join as YWQ}from"path";import{execSync as HWQ}from"child_process";import{parseArgs as jDQ}from"util";var _DQ={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"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"}};function oW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function h3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function BY1(A){let{values:Q,positionals:B}=jDQ({args:A,options:_DQ,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:oW(Q,"model"),domain:oW(Q,"domain"),"content-repo":oW(Q,"content-repo"),backend:oW(Q,"backend"),"push-to":oW(Q,"push-to"),"ai-api-key":oW(Q,"ai-api-key"),"no-interactive":h3(Q,"no-interactive"),preview:h3(Q,"preview"),deploy:h3(Q,"deploy"),regen:h3(Q,"regen"),all:h3(Q,"all"),only:oW(Q,"only"),"dry-run":h3(Q,"dry-run"),"startup-check":h3(Q,"startup-check"),"storage-dir":oW(Q,"storage-dir"),yes:h3(Q,"yes"),remote:oW(Q,"remote"),token:oW(Q,"token")}}}Ec();import{mkdirSync as aXQ}from"fs";import{join as tXQ}from"path";import{execSync as eXQ}from"child_process";var PwA={name:"@rizom/brain",version:"0.2.0-alpha.81",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 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 ZY1,writeFileSync as Vc,chmodSync as Cc,existsSync as ovA,readFileSync as svA}from"fs";import{basename as avA,dirname as tvA,join as k8,resolve as UYQ}from"path";import{fileURLToPath as JYQ}from"url";var wY1=`ARG BUN_VERSION=1.3.10
|
|
8553
8553
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
8554
8554
|
|
|
8555
8555
|
WORKDIR /app
|
|
@@ -8626,6 +8626,7 @@ env:
|
|
|
8626
8626
|
- AI_API_KEY
|
|
8627
8627
|
- GIT_SYNC_TOKEN
|
|
8628
8628
|
- DISCORD_BOT_TOKEN
|
|
8629
|
+
- SETUP_EMAIL_TO
|
|
8629
8630
|
- SETUP_EMAIL_API_KEY
|
|
8630
8631
|
- SETUP_EMAIL_FROM
|
|
8631
8632
|
|
|
@@ -9159,6 +9160,16 @@ LINKEDIN_ACCESS_TOKEN=
|
|
|
9159
9160
|
# @sensitive
|
|
9160
9161
|
BUTTONDOWN_API_KEY=
|
|
9161
9162
|
|
|
9163
|
+
# Passkey setup email via Resend
|
|
9164
|
+
# @required @sensitive
|
|
9165
|
+
SETUP_EMAIL_TO=
|
|
9166
|
+
|
|
9167
|
+
# @required @sensitive
|
|
9168
|
+
SETUP_EMAIL_API_KEY=
|
|
9169
|
+
|
|
9170
|
+
# @required @sensitive
|
|
9171
|
+
SETUP_EMAIL_FROM=
|
|
9172
|
+
|
|
9162
9173
|
# Cloudflare analytics
|
|
9163
9174
|
# @sensitive
|
|
9164
9175
|
CLOUDFLARE_ACCOUNT_ID=
|
|
@@ -9223,11 +9234,24 @@ GIT_SYNC_TOKEN=`};var BYQ="none";var wYQ="@plugin(@varlock/bitwarden-plugin",vwA
|
|
|
9223
9234
|
`}function DYQ(A){let Q=A.startsWith("@")?A:`@brains/${A}`;return QYQ(new URL(import.meta.resolve(`${Q}/package.json`)).pathname)}function YYQ(A){let Q=FY1(A,"env.schema.template");if(GY1(Q))return Q;let B=FY1(A,".env.schema");if(GY1(B))return B;return}function HYQ(A){return A.startsWith("@brains/")?A.slice(8):A}function XYQ(A){switch(HYQ(A)){case"rover":return _wA.rover;case"ranger":return _wA.ranger;case"relay":return _wA.relay;default:return""}}function WYQ(A,Q=DYQ){try{let B=Q(A),w=YYQ(B);if(w)return AYQ(w,"utf-8").trimEnd()}catch{}return XYQ(A)}function KY1(A,Q=A,B){let w=$YQ(B);return`${[IYQ(Q,w).trimEnd(),WYQ(A),DY1.trimEnd(),YY1.trimEnd(),HY1(w).trimEnd()].filter((f)=>f.length>0).join(`
|
|
9224
9235
|
|
|
9225
9236
|
`)}
|
|
9226
|
-
`}var GYQ=`^${PwA.version}`,FYQ="^10.27.2";function zY1(A,Q){let B=ovA(k8(A,"brain.yaml"))?T3(A):void 0,w=B?.brain??Q.model,$=B?.domain??Q.domain??`${w}.rizom.ai`;if(ZYQ(A,w,$,Q.contentRepo),xYQ(A),TYQ(A,w),qYQ(A),yYQ(A),SYQ(A),NY1(w))hYQ(A),gYQ(A);if(LYQ(A,w,Q.backend),Q.apiKey)EYQ(A,Q.apiKey,Q.contentRepo);if(Q.deploy)NYQ(A,Q.regen),MYQ(A,Q.regen),VYQ(A,Q.regen),PYQ(A,Q.regen),OYQ(A,Q.regen),kYQ(A,Q.regen),vYQ(A,Q.regen)}function J4(A,Q,B=!1,w=!1){if(ZY1(tvA(A),{recursive:!0}),w){if(Vc(A,Q),B)Cc(A,493);return}try{Vc(A,Q,{flag:"wx"})}catch($){if($ instanceof Error&&"code"in $&&$.code==="EEXIST")return;throw $}if(B)Cc(A,493)}function Oc(A){let{path:Q,content:B,executable:w=!1,legacyContents:$=[],shouldReconcile:f,regen:I=!1}=A;if(ZY1(tvA(Q),{recursive:!0}),I){if(Vc(Q,B),w)Cc(Q,493);return}if(!ovA(Q)){if(Vc(Q,B,{flag:"wx"}),w)Cc(Q,493);return}let D=svA(Q,"utf-8");if(D===B)return;let Y=$.includes(D),H=f?.(D)??!1;if(!Y&&!H)return;if(Vc(Q,B),w)Cc(Q,493)}function NY1(A){return A!=="rover"}function KYQ(A){return}function ZYQ(A,Q,B,w){let $=
|
|
9227
|
-
|
|
9237
|
+
`}var GYQ=`^${PwA.version}`,FYQ="^10.27.2";function zY1(A,Q){let B=ovA(k8(A,"brain.yaml"))?T3(A):void 0,w=B?.brain??Q.model,$=B?.domain??Q.domain??`${w}.rizom.ai`;if(ZYQ(A,w,$,Q.contentRepo),xYQ(A),TYQ(A,w),qYQ(A),yYQ(A),SYQ(A),NY1(w))hYQ(A),gYQ(A);if(LYQ(A,w,Q.backend),Q.apiKey)EYQ(A,Q.apiKey,Q.contentRepo);if(Q.deploy)NYQ(A,Q.regen),MYQ(A,Q.regen),VYQ(A,Q.regen),PYQ(A,Q.regen),OYQ(A,Q.regen),kYQ(A,Q.regen),vYQ(A,Q.regen)}function J4(A,Q,B=!1,w=!1){if(ZY1(tvA(A),{recursive:!0}),w){if(Vc(A,Q),B)Cc(A,493);return}try{Vc(A,Q,{flag:"wx"})}catch($){if($ instanceof Error&&"code"in $&&$.code==="EEXIST")return;throw $}if(B)Cc(A,493)}function Oc(A){let{path:Q,content:B,executable:w=!1,legacyContents:$=[],shouldReconcile:f,regen:I=!1}=A;if(ZY1(tvA(Q),{recursive:!0}),I){if(Vc(Q,B),w)Cc(Q,493);return}if(!ovA(Q)){if(Vc(Q,B,{flag:"wx"}),w)Cc(Q,493);return}let D=svA(Q,"utf-8");if(D===B)return;let Y=$.includes(D),H=f?.(D)??!1;if(!Y&&!H)return;if(Vc(Q,B),w)Cc(Q,493)}function NY1(A){return A!=="rover"}function KYQ(A){return}function ZYQ(A,Q,B,w){let $=Q==="rover"?` auth-service:
|
|
9238
|
+
setupEmail: \${SETUP_EMAIL_TO}
|
|
9239
|
+
email-resend:
|
|
9240
|
+
apiKey: \${SETUP_EMAIL_API_KEY}
|
|
9241
|
+
from: \${SETUP_EMAIL_FROM}
|
|
9242
|
+
`:"",f=w?`plugins:
|
|
9243
|
+
${$} directory-sync:
|
|
9228
9244
|
git:
|
|
9229
9245
|
repo: ${w.replace("github:","")}
|
|
9230
9246
|
authToken: \${GIT_SYNC_TOKEN}
|
|
9247
|
+
`:$?`plugins:
|
|
9248
|
+
${$}
|
|
9249
|
+
# Uncomment to enable git-backed sync of brain content:
|
|
9250
|
+
# plugins:
|
|
9251
|
+
# directory-sync:
|
|
9252
|
+
# git:
|
|
9253
|
+
# repo: your-org/brain-data
|
|
9254
|
+
# authToken: \${GIT_SYNC_TOKEN}
|
|
9231
9255
|
`:`plugins: {}
|
|
9232
9256
|
|
|
9233
9257
|
# Uncomment to enable git-backed sync of brain content:
|
|
@@ -9236,30 +9260,30 @@ GIT_SYNC_TOKEN=`};var BYQ="none";var wYQ="@plugin(@varlock/bitwarden-plugin",vwA
|
|
|
9236
9260
|
# git:
|
|
9237
9261
|
# repo: your-org/brain-data
|
|
9238
9262
|
# authToken: \${GIT_SYNC_TOKEN}
|
|
9239
|
-
`,
|
|
9263
|
+
`,I=KYQ(Q),D=I?`# Start from the model's built-in site/theme. Edit src/site.ts and src/theme.css,
|
|
9240
9264
|
# remove site.package when you're ready to switch to the local site convention.
|
|
9241
9265
|
# src/theme.css already layers on top of the built-in theme by default.
|
|
9242
9266
|
site:
|
|
9243
|
-
package: "${
|
|
9244
|
-
theme: "${
|
|
9267
|
+
package: "${I.sitePackage}"
|
|
9268
|
+
theme: "${I.themePackage}"
|
|
9245
9269
|
|
|
9246
|
-
`:"",
|
|
9270
|
+
`:"",Y=`brain: ${Q}
|
|
9247
9271
|
domain: ${B}
|
|
9248
9272
|
|
|
9249
9273
|
# Plugin preset \u2014 "core" is the minimal on-ramp. Use "default" or "full"
|
|
9250
9274
|
# for richer presets, or list capability ids in add: / remove: to fine-tune.
|
|
9251
9275
|
preset: core
|
|
9252
9276
|
|
|
9253
|
-
${
|
|
9277
|
+
${D}# Permissions
|
|
9254
9278
|
anchors: []
|
|
9255
9279
|
|
|
9256
9280
|
# Plugin overrides
|
|
9257
|
-
${
|
|
9281
|
+
${f}
|
|
9258
9282
|
# Optional deprecated fallback for MCP clients that cannot use OAuth/passkeys:
|
|
9259
9283
|
# plugins:
|
|
9260
9284
|
# mcp:
|
|
9261
9285
|
# authToken: \${MCP_AUTH_TOKEN}
|
|
9262
|
-
`;J4(k8(A,"brain.yaml"),
|
|
9286
|
+
`;J4(k8(A,"brain.yaml"),Y)}var zYQ=[`# Required
|
|
9263
9287
|
AI_API_KEY=
|
|
9264
9288
|
|
|
9265
9289
|
# Optional: separate key for image generation (defaults to AI_API_KEY)
|
|
@@ -9289,6 +9313,9 @@ MCP_AUTH_TOKEN=
|
|
|
9289
9313
|
|
|
9290
9314
|
# Optional
|
|
9291
9315
|
DISCORD_BOT_TOKEN=
|
|
9316
|
+
SETUP_EMAIL_TO=
|
|
9317
|
+
SETUP_EMAIL_API_KEY=
|
|
9318
|
+
SETUP_EMAIL_FROM=
|
|
9292
9319
|
|
|
9293
9320
|
# Deploy (only needed with --deploy)
|
|
9294
9321
|
KAMAL_REGISTRY_PASSWORD=
|