@rizom/brain 0.2.0-alpha.72 → 0.2.0-alpha.73
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 +31 -31
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/site.js +58 -58
- package/dist/site.js.map +1 -1
- package/package.json +1 -1
package/dist/brain.js
CHANGED
|
@@ -491,7 +491,7 @@ ${F}`,args:{...$,...D,id:I.id,confirmed:!0,contentHash:I.contentHash}}},{visibil
|
|
|
491
491
|
hash text NOT NULL,
|
|
492
492
|
created_at numeric
|
|
493
493
|
)
|
|
494
|
-
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let H of B)if(!I||Number(I[2])<H.folderMillis){for(let Y of H.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(D)}var Qd=p(()=>{B80();z5()});async function w80(A,Q){let B=Q?.child("entity-migrate")??wQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=Ll(A);B.debug("Running entity database migrations...");try{await Ml($,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 oM(w,{migrationsFolder:D}),await Vl($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var $80=p(()=>{Qd();E$A();GA()});async function f80(A,Q){let B=Q?.child("job-queue-migrate")??wQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ql(A);B.debug("Running job queue migrations...");try{await Cl($,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 oM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var I80=p(()=>{Qd();W$A();GA()});async function D80(A,Q){let B=Q?.child("conversation-migrate")??wQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=hl(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 oM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var H80=p(()=>{Qd();B9A();GA()});class mv{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Jj,migrateEntities:w80,migrateJobQueue:f80,migrateConversations:D80}}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 IXA=p(()=>{er();$80();I80();H80()});var Bd;var DXA=p(()=>{GA();Bd=G.object({theme:G.object({primaryColor:G.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:G.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var X80;var Y80=p(()=>{X80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.72",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 uQ=v((yg1,wd)=>{(function(){function A(QA,FA){Object.defineProperty(w.prototype,QA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",FA[0],FA[1])}})}function Q(QA){if(QA===null||typeof QA!=="object")return null;return QA=aA&&QA[aA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var cA=QA+"."+FA;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.",FA,QA),ZA[cA]=!0)}function w(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function $(){}function f(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function I(){}function D(QA){return""+QA}function H(QA){try{D(QA);var FA=!1}catch(I0){FA=!0}if(FA){FA=console;var cA=FA.error,w0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return cA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",w0),D(QA)}}function Y(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===X0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case n:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case LA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case d:return"Portal";case XA:return QA.displayName||"Context";case MA:return(QA._context.displayName||"Context")+".Consumer";case q0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case g0:return FA=QA.displayName||null,FA!==null?FA:Y(QA.type)||"Memo";case N0:FA=QA._payload,QA=QA._init;try{return Y(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===N0)return"<...>";try{var FA=Y(QA);return FA?"<"+FA+">":"<...>"}catch(cA){return"<...>"}}function F(){var QA=B0.A;return QA===null?null:QA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(QA){if(OA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function q(QA,FA){function cA(){wA||(wA=!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)",FA))}cA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:cA,configurable:!0})}function E(){var QA=Y(this.type);return A1[QA]||(A1[QA]=!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.")),QA=this.props.ref,QA!==void 0?QA:null}function C(QA,FA,cA,w0,I0,b0){var eA=cA.ref;return QA={$$typeof:t,type:QA,key:FA,props:cA,_owner:w0},(eA!==void 0?eA:null)!==null?Object.defineProperty(QA,"ref",{enumerable:!1,get:E}):Object.defineProperty(QA,"ref",{enumerable:!1,value:null}),QA._store={},Object.defineProperty(QA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(QA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(QA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:b0}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function R(QA,FA){return FA=C(QA.type,FA,QA.props,QA._owner,QA._debugStack,QA._debugTask),QA._store&&(FA._store.validated=QA._store.validated),FA}function k(QA){P(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===N0&&(QA._payload.status==="fulfilled"?P(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function P(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(H(QA.key),o(""+QA.key)):FA.toString(36)}function S(QA){switch(QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason;default:switch(typeof QA.status==="string"?QA.then(I,I):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function x(QA,FA,cA,w0,I0){var b0=typeof QA;if(b0==="undefined"||b0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(b0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case d:eA=!0;break;case N0:return eA=QA._init,x(eA(QA._payload),FA,cA,w0,I0)}}if(eA){eA=QA,I0=I0(eA);var t0=w0===""?"."+r(eA,0):w0;return z0(I0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),x(I0,FA,cA,"",function(S1){return S1})):I0!=null&&(P(I0)&&(I0.key!=null&&(eA&&eA.key===I0.key||H(I0.key)),cA=R(I0,cA+(I0.key==null||eA&&eA.key===I0.key?"":(""+I0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&P(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),I0=cA),FA.push(I0)),1}if(eA=0,t0=w0===""?".":w0+":",z0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],b0=t0+r(w0,Q1),eA+=x(w0,FA,cA,b0,I0);else if(Q1=Q(QA),typeof Q1==="function")for(Q1===QA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),QA=Q1.call(QA),Q1=0;!(w0=QA.next()).done;)w0=w0.value,b0=t0+r(w0,Q1++),eA+=x(w0,FA,cA,b0,I0);else if(b0==="object"){if(typeof QA.then==="function")return x(S(QA),FA,cA,w0,I0);throw FA=String(QA),Error("Objects are not valid as a React child (found: "+(FA==="[object Object]"?"object with keys {"+Object.keys(QA).join(", ")+"}":FA)+"). If you meant to render a collection of children, use an array instead.")}return eA}function y(QA,FA,cA){if(QA==null)return QA;var w0=[],I0=0;return x(QA,w0,"","",function(b0){return FA.call(cA,b0,I0++)}),w0}function g(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var cA=FA();if(cA.then(function(I0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=I0)}},function(I0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=I0)}}),FA=QA._ioInfo,FA!=null){FA.value=cA;var w0=cA.displayName;typeof w0==="string"&&(FA.name=w0)}QA._status===-1&&(QA._status=0,QA._result=cA)}if(QA._status===1)return FA=QA._result,FA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
494
|
+
`;await A.session.run($);let I=(await A.values(hA`SELECT id, hash, created_at FROM ${hA.identifier(w)} ORDER BY created_at DESC LIMIT 1`))[0]??void 0,D=[];for(let H of B)if(!I||Number(I[2])<H.folderMillis){for(let Y of H.sql)D.push(A.run(hA.raw(Y)));D.push(A.run(hA`INSERT INTO ${hA.identifier(w)} ("hash", "created_at") VALUES(${H.hash}, ${H.folderMillis})`))}await A.session.migrate(D)}var Qd=p(()=>{B80();z5()});async function w80(A,Q){let B=Q?.child("entity-migrate")??wQ.getInstance().child("entity-migrate"),{db:w,client:$,url:f}=Ll(A);B.debug("Running entity database migrations...");try{await Ml($,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 oM(w,{migrationsFolder:D}),await Vl($),B.debug("Entity database migrations completed successfully")}catch(I){throw B.error("Entity database migration failed:",I),I}finally{$.close()}}var $80=p(()=>{Qd();E$A();GA()});async function f80(A,Q){let B=Q?.child("job-queue-migrate")??wQ.getInstance().child("job-queue-migrate"),{db:w,client:$,url:f}=ql(A);B.debug("Running job queue migrations...");try{await Cl($,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 oM(w,{migrationsFolder:D}),B.debug("Job queue migrations completed successfully")}catch(I){throw B.error("Job queue migration failed:",I),I}finally{$.close()}}var I80=p(()=>{Qd();W$A();GA()});async function D80(A,Q){let B=Q?.child("conversation-migrate")??wQ.getInstance().child("conversation-migrate"),{db:w,client:$,url:f}=hl(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 oM(w,{migrationsFolder:D}),B.debug("Conversation database migrations completed successfully")}catch(I){throw B.error("Conversation database migration failed:",I),I}finally{$.close()}}var H80=p(()=>{Qd();B9A();GA()});class mv{logger;migrations;constructor(A,Q){this.logger=A,this.migrations=Q??{getStandardConfigWithDirectories:Jj,migrateEntities:w80,migrateJobQueue:f80,migrateConversations:D80}}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 IXA=p(()=>{er();$80();I80();H80()});var Bd;var DXA=p(()=>{GA();Bd=G.object({theme:G.object({primaryColor:G.string().describe("Primary color for the CLI theme").default("#0066cc"),accentColor:G.string().describe("Accent color for the CLI theme").default("#ff6600")}).describe("Theme configuration for the CLI interface").default({primaryColor:"#0066cc",accentColor:"#ff6600"})})});var X80;var Y80=p(()=>{X80={name:"@brains/chat-repl",private:!0,version:"0.2.0-alpha.73",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 uQ=v((yg1,wd)=>{(function(){function A(QA,FA){Object.defineProperty(w.prototype,QA,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",FA[0],FA[1])}})}function Q(QA){if(QA===null||typeof QA!=="object")return null;return QA=aA&&QA[aA]||QA["@@iterator"],typeof QA==="function"?QA:null}function B(QA,FA){QA=(QA=QA.constructor)&&(QA.displayName||QA.name)||"ReactClass";var cA=QA+"."+FA;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.",FA,QA),ZA[cA]=!0)}function w(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function $(){}function f(QA,FA,cA){this.props=QA,this.context=FA,this.refs=uA,this.updater=cA||VA}function I(){}function D(QA){return""+QA}function H(QA){try{D(QA);var FA=!1}catch(I0){FA=!0}if(FA){FA=console;var cA=FA.error,w0=typeof Symbol==="function"&&Symbol.toStringTag&&QA[Symbol.toStringTag]||QA.constructor.name||"Object";return cA.call(FA,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",w0),D(QA)}}function Y(QA){if(QA==null)return null;if(typeof QA==="function")return QA.$$typeof===X0?null:QA.displayName||QA.name||null;if(typeof QA==="string")return QA;switch(QA){case BA:return"Fragment";case UA:return"Profiler";case n:return"StrictMode";case K0:return"Suspense";case qA:return"SuspenseList";case LA:return"Activity"}if(typeof QA==="object")switch(typeof QA.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),QA.$$typeof){case d:return"Portal";case XA:return QA.displayName||"Context";case MA:return(QA._context.displayName||"Context")+".Consumer";case q0:var FA=QA.render;return QA=QA.displayName,QA||(QA=FA.displayName||FA.name||"",QA=QA!==""?"ForwardRef("+QA+")":"ForwardRef"),QA;case g0:return FA=QA.displayName||null,FA!==null?FA:Y(QA.type)||"Memo";case N0:FA=QA._payload,QA=QA._init;try{return Y(QA(FA))}catch(cA){}}return null}function W(QA){if(QA===BA)return"<>";if(typeof QA==="object"&&QA!==null&&QA.$$typeof===N0)return"<...>";try{var FA=Y(QA);return FA?"<"+FA+">":"<...>"}catch(cA){return"<...>"}}function F(){var QA=B0.A;return QA===null?null:QA.getOwner()}function K(){return Error("react-stack-top-frame")}function Z(QA){if(OA.call(QA,"key")){var FA=Object.getOwnPropertyDescriptor(QA,"key").get;if(FA&&FA.isReactWarning)return!1}return QA.key!==void 0}function q(QA,FA){function cA(){wA||(wA=!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)",FA))}cA.isReactWarning=!0,Object.defineProperty(QA,"key",{get:cA,configurable:!0})}function E(){var QA=Y(this.type);return A1[QA]||(A1[QA]=!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.")),QA=this.props.ref,QA!==void 0?QA:null}function C(QA,FA,cA,w0,I0,b0){var eA=cA.ref;return QA={$$typeof:t,type:QA,key:FA,props:cA,_owner:w0},(eA!==void 0?eA:null)!==null?Object.defineProperty(QA,"ref",{enumerable:!1,get:E}):Object.defineProperty(QA,"ref",{enumerable:!1,value:null}),QA._store={},Object.defineProperty(QA._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(QA,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(QA,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:I0}),Object.defineProperty(QA,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:b0}),Object.freeze&&(Object.freeze(QA.props),Object.freeze(QA)),QA}function R(QA,FA){return FA=C(QA.type,FA,QA.props,QA._owner,QA._debugStack,QA._debugTask),QA._store&&(FA._store.validated=QA._store.validated),FA}function k(QA){P(QA)?QA._store&&(QA._store.validated=1):typeof QA==="object"&&QA!==null&&QA.$$typeof===N0&&(QA._payload.status==="fulfilled"?P(QA._payload.value)&&QA._payload.value._store&&(QA._payload.value._store.validated=1):QA._store&&(QA._store.validated=1))}function P(QA){return typeof QA==="object"&&QA!==null&&QA.$$typeof===t}function o(QA){var FA={"=":"=0",":":"=2"};return"$"+QA.replace(/[=:]/g,function(cA){return FA[cA]})}function r(QA,FA){return typeof QA==="object"&&QA!==null&&QA.key!=null?(H(QA.key),o(""+QA.key)):FA.toString(36)}function S(QA){switch(QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason;default:switch(typeof QA.status==="string"?QA.then(I,I):(QA.status="pending",QA.then(function(FA){QA.status==="pending"&&(QA.status="fulfilled",QA.value=FA)},function(FA){QA.status==="pending"&&(QA.status="rejected",QA.reason=FA)})),QA.status){case"fulfilled":return QA.value;case"rejected":throw QA.reason}}throw QA}function x(QA,FA,cA,w0,I0){var b0=typeof QA;if(b0==="undefined"||b0==="boolean")QA=null;var eA=!1;if(QA===null)eA=!0;else switch(b0){case"bigint":case"string":case"number":eA=!0;break;case"object":switch(QA.$$typeof){case t:case d:eA=!0;break;case N0:return eA=QA._init,x(eA(QA._payload),FA,cA,w0,I0)}}if(eA){eA=QA,I0=I0(eA);var t0=w0===""?"."+r(eA,0):w0;return z0(I0)?(cA="",t0!=null&&(cA=t0.replace(gA,"$&/")+"/"),x(I0,FA,cA,"",function(S1){return S1})):I0!=null&&(P(I0)&&(I0.key!=null&&(eA&&eA.key===I0.key||H(I0.key)),cA=R(I0,cA+(I0.key==null||eA&&eA.key===I0.key?"":(""+I0.key).replace(gA,"$&/")+"/")+t0),w0!==""&&eA!=null&&P(eA)&&eA.key==null&&eA._store&&!eA._store.validated&&(cA._store.validated=2),I0=cA),FA.push(I0)),1}if(eA=0,t0=w0===""?".":w0+":",z0(QA))for(var Q1=0;Q1<QA.length;Q1++)w0=QA[Q1],b0=t0+r(w0,Q1),eA+=x(w0,FA,cA,b0,I0);else if(Q1=Q(QA),typeof Q1==="function")for(Q1===QA.entries&&(TA||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),TA=!0),QA=Q1.call(QA),Q1=0;!(w0=QA.next()).done;)w0=w0.value,b0=t0+r(w0,Q1++),eA+=x(w0,FA,cA,b0,I0);else if(b0==="object"){if(typeof QA.then==="function")return x(S(QA),FA,cA,w0,I0);throw FA=String(QA),Error("Objects are not valid as a React child (found: "+(FA==="[object Object]"?"object with keys {"+Object.keys(QA).join(", ")+"}":FA)+"). If you meant to render a collection of children, use an array instead.")}return eA}function y(QA,FA,cA){if(QA==null)return QA;var w0=[],I0=0;return x(QA,w0,"","",function(b0){return FA.call(cA,b0,I0++)}),w0}function g(QA){if(QA._status===-1){var FA=QA._ioInfo;FA!=null&&(FA.start=FA.end=performance.now()),FA=QA._result;var cA=FA();if(cA.then(function(I0){if(QA._status===0||QA._status===-1){QA._status=1,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="fulfilled",cA.value=I0)}},function(I0){if(QA._status===0||QA._status===-1){QA._status=2,QA._result=I0;var b0=QA._ioInfo;b0!=null&&(b0.end=performance.now()),cA.status===void 0&&(cA.status="rejected",cA.reason=I0)}}),FA=QA._ioInfo,FA!=null){FA.value=cA;var w0=cA.displayName;typeof w0==="string"&&(FA.name=w0)}QA._status===-1&&(QA._status=0,QA._result=cA)}if(QA._status===1)return FA=QA._result,FA===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
|
|
495
495
|
|
|
496
496
|
Your code should look like:
|
|
497
497
|
const MyComponent = lazy(() => import('./MyComponent'))
|
|
@@ -1703,7 +1703,7 @@ Example bad output: "A dreamlike crystal formation glowing with ethereal light i
|
|
|
1703
1703
|
Title: "${A.entityTitle??D}"
|
|
1704
1704
|
|
|
1705
1705
|
Content:
|
|
1706
|
-
${A.entityContent}`,Hl1);H=`${w.trim()} ${R.imagePrompt}`}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(R)})}}await this.reportProgress(B,{progress:vQ.PROCESS,message:"Generating image"});let Y=this.context.identity.get(),W=this.context.identity.getProfile(),K=j70(Y,W)+H,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:y0(R)}),C$.failure(R)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let q=U2(D),E=pF.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:vQ.SAVE,message:`Updating ${f} with cover image`});let R=await kl(this.context.entityService,f,I,this.logger);if(!R)return C$.failure(Error(`Target entity not found: ${f}/${I}`));let k=Sv(R,q);await this.context.entities.update(k),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:vQ.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(H){return this.logger.error("Image generation job failed",{jobId:Q,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var v70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.72",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 Wl1=G.object({defaultAspectRatio:G.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class EUA extends KQ{entityType=pF.entityType;schema=gv;adapter=pF;constructor(A={}){super("image",v70,A,Wl1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await LD(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 En(A,this.logger)}async onRegister(A){let Q=new En(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function yx(A){return new EUA(A)}$0();import{StdioServerTransport as Ul1}from"@modelcontextprotocol/sdk/server/stdio.js";function x70(){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 LUA(){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 Ln(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 LUA()}class NH{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return NH.instance??=new NH(A),NH.instance}static resetInstance(){if(NH.instance)NH.instance.stop(),NH.instance=null}static createFresh(A){return new NH(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?Ln(this.config.logger):x70()}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 Ul1,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 h70}from"crypto";import{WebStandardStreamableHTTPServerTransport as Jl1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as Gl1}from"@modelcontextprotocol/sdk/types.js";var Fl1={"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 Kl1(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 iU{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?Ln(this.config.logger):LUA(),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 iU.instance??=new iU(A),iU.instance}static resetInstance(){iU.instance=null}static createFresh(A){return new iU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Fl1))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:`${Kl1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${Zl1(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&&Gl1(B))w=new Jl1({sessionIdGenerator:()=>h70(),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??h70();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 Zl1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as zl1}from"crypto";import{mkdir as ql1,readFile as Cl1,writeFile as El1,chmod as Ll1}from"fs/promises";import{dirname as Ml1,join as Vl1}from"path";function y70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function g70(A){try{return new URL(A)}catch{return}}function MUA(A,Q){if(A===Q)return!0;let B=g70(A),w=g70(Q);if(!B||!w)return!1;if(!y70(B.hostname)||!y70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&Nl1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function Nl1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function VUA(A,Q){return A.some((B)=>MUA(B,Q))}var bl1="oauth-auth-codes.json",Ol1=600;function T70(){return Math.floor(Date.now()/1000)}function Rl1(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 Pl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Rl1)}}async function _l1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Mn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Vl1(A.storageDir,A.storeFile??bl1)}async createCode(A){let Q=T70(),B={code:`ocd_${zl1()}`,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+Ol1};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=T70(),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 zH("Authorization code not found");if(f.consumed_at!==void 0)throw new zH("Authorization code already consumed");if(f.expires_at<=Q)throw new zH("Authorization code expired");if(f.client_id!==A.clientId)throw new zH("Authorization code client mismatch");if(!MUA(f.redirect_uri,A.redirectUri))throw new zH("Authorization code redirect URI mismatch");let I=await _l1(A.codeVerifier);if(f.code_challenge!==I)throw new zH("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new zH("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Pl1(JSON.parse(await Cl1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await ql1(Ml1(this.storeFile),{recursive:!0,mode:448}),await El1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1706
|
+
${A.entityContent}`,Hl1);H=`${w.trim()} ${R.imagePrompt}`}catch(R){this.logger.warn("AI prompt distillation failed, using fallback",{error:y0(R)})}}await this.reportProgress(B,{progress:vQ.PROCESS,message:"Generating image"});let Y=this.context.identity.get(),W=this.context.identity.getProfile(),K=j70(Y,W)+H,Z;try{Z=await this.context.ai.generateImage(K,{...$&&{aspectRatio:$}})}catch(R){return this.logger.error("Image generation failed",{jobId:Q,error:y0(R)}),C$.failure(R)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let q=U2(D),E=pF.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:vQ.SAVE,message:`Updating ${f} with cover image`});let R=await kl(this.context.entityService,f,I,this.logger);if(!R)return C$.failure(Error(`Target entity not found: ${f}/${I}`));let k=Sv(R,q);await this.context.entities.update(k),this.logger.debug("Updated target entity with cover image",{targetEntityType:f,targetEntityId:I,imageId:q})}return await this.reportProgress(B,{progress:vQ.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(H){return this.logger.error("Image generation job failed",{jobId:Q,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{title:A.title,promptLength:A.prompt.length,aspectRatio:A.aspectRatio,targetEntityType:A.targetEntityType,targetEntityId:A.targetEntityId}}}var v70={name:"@brains/image-plugin",private:!0,version:"0.2.0-alpha.73",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 Wl1=G.object({defaultAspectRatio:G.enum(["1:1","16:9","9:16","4:3","3:4"]).default("16:9").describe("Default aspect ratio for generated images")});class EUA extends KQ{entityType=pF.entityType;schema=gv;adapter=pF;constructor(A={}){super("image",v70,A,Wl1)}getEntityTypeConfig(){return{embeddable:!1}}async interceptCreate(A,Q,B){if(!A.targetEntityType||!A.targetEntityId)return{kind:"continue",input:A};let w=await LD(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 En(A,this.logger)}async onRegister(A){let Q=new En(A,this.logger);A.jobs.registerHandler("image-generate",Q)}}function yx(A){return new EUA(A)}$0();import{StdioServerTransport as Ul1}from"@modelcontextprotocol/sdk/server/stdio.js";function x70(){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 LUA(){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 Ln(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 LUA()}class NH{static instance=null;mcpServer=null;transport=null;config;logger;static getInstance(A){return NH.instance??=new NH(A),NH.instance}static resetInstance(){if(NH.instance)NH.instance.stop(),NH.instance=null}static createFresh(A){return new NH(A)}constructor(A={}){this.config=A,this.logger=this.config.logger?Ln(this.config.logger):x70()}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 Ul1,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 h70}from"crypto";import{WebStandardStreamableHTTPServerTransport as Jl1}from"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";import{isInitializeRequest as Gl1}from"@modelcontextprotocol/sdk/types.js";var Fl1={"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 Kl1(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 iU{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?Ln(this.config.logger):LUA(),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 iU.instance??=new iU(A),iU.instance}static resetInstance(){iU.instance=null}static createFresh(A){return new iU(A)}withCors(A){let Q=new Headers(A.headers);for(let[B,w]of Object.entries(Fl1))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:`${Kl1(A)}/.well-known/oauth-protected-resource`,...Q};return`Bearer ${Object.entries(w).map(([f,I])=>`${f}="${Zl1(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&&Gl1(B))w=new Jl1({sessionIdGenerator:()=>h70(),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??h70();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 Zl1(A){return A.replace(/["\\]/g,(Q)=>`\\${Q}`)}import{randomUUID as zl1}from"crypto";import{mkdir as ql1,readFile as Cl1,writeFile as El1,chmod as Ll1}from"fs/promises";import{dirname as Ml1,join as Vl1}from"path";function y70(A){let Q=A.toLowerCase();return Q==="localhost"||Q==="[::1]"||Q==="::1"||Q.startsWith("127.")}function g70(A){try{return new URL(A)}catch{return}}function MUA(A,Q){if(A===Q)return!0;let B=g70(A),w=g70(Q);if(!B||!w)return!1;if(!y70(B.hostname)||!y70(w.hostname))return!1;return B.protocol===w.protocol&&B.port===w.port&&Nl1(B.pathname,w.pathname)&&B.search===w.search&&B.hash===w.hash}function Nl1(A,Q){return A===Q||A===`${Q}/debug`||Q===`${A}/debug`}function VUA(A,Q){return A.some((B)=>MUA(B,Q))}var bl1="oauth-auth-codes.json",Ol1=600;function T70(){return Math.floor(Date.now()/1000)}function Rl1(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 Pl1(A){if(!A||typeof A!=="object")return{codes:[]};let Q=A.codes;if(!Array.isArray(Q))return{codes:[]};return{codes:Q.filter(Rl1)}}async function _l1(A){let Q=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(A));return Buffer.from(Q).toString("base64url")}class Mn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=Vl1(A.storageDir,A.storeFile??bl1)}async createCode(A){let Q=T70(),B={code:`ocd_${zl1()}`,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+Ol1};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=T70(),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 zH("Authorization code not found");if(f.consumed_at!==void 0)throw new zH("Authorization code already consumed");if(f.expires_at<=Q)throw new zH("Authorization code expired");if(f.client_id!==A.clientId)throw new zH("Authorization code client mismatch");if(!MUA(f.redirect_uri,A.redirectUri))throw new zH("Authorization code redirect URI mismatch");let I=await _l1(A.codeVerifier);if(f.code_challenge!==I)throw new zH("PKCE verification failed");B={...f,consumed_at:Q},w.codes[$]=B,await this.writeStore(w)}),!B)throw new zH("Authorization code not consumed");return B}async enqueueWrite(A){return this.writeQueue=this.writeQueue.then(A,A),this.writeQueue}async readStore(){try{return Pl1(JSON.parse(await Cl1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{codes:[]};throw A}}async writeStore(A){await ql1(Ml1(this.storeFile),{recursive:!0,mode:448}),await El1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1707
1707
|
`,{mode:384}),await Ll1(this.storeFile,384)}}class zH extends Error{constructor(A){super(A);this.name="InvalidGrantError"}}import{randomUUID as yY0}from"crypto";GA();import{randomUUID as S70}from"crypto";import{mkdir as kl1,readFile as jl1,writeFile as vl1,chmod as xl1}from"fs/promises";import{dirname as hl1,join as yl1}from"path";var gl1="oauth-clients.json",Tl1=G.enum(["none","client_secret_basic","client_secret_post"]),Sl1=G.object({redirect_uris:G.array(G.string().url()).min(1),token_endpoint_auth_method:Tl1.default("none"),grant_types:G.array(G.enum(["authorization_code","refresh_token"])).default(["authorization_code","refresh_token"]),response_types:G.array(G.literal("code")).default(["code"]),scope:G.string().optional(),client_name:G.string().optional(),client_uri:G.string().url().optional(),logo_uri:G.string().url().optional(),contacts:G.array(G.string()).optional()});function ml1(){return Math.floor(Date.now()/1000)}function ul1(){return`ocs_${S70().replaceAll("-","")}`}function cl1(A){if(!A||typeof A!=="object")return{clients:[]};let Q=A.clients;if(!Array.isArray(Q))return{clients:[]};return{clients:Q.filter(pl1)}}function pl1(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 Vn{storeFile;writeQueue=Promise.resolve();constructor(A){this.storeFile=yl1(A.storageDir,A.storeFile??gl1)}async registerClient(A){let Q=Sl1.safeParse(A);if(!Q.success)throw new gx(Q.error.message);let B=Q.data,w=ml1(),$=`oc_${S70()}`,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:ul1(),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 cl1(JSON.parse(await jl1(this.storeFile,"utf8")))}catch(A){if(A.code==="ENOENT")return{clients:[]};throw A}}async writeStore(A){await kl1(hl1(this.storeFile),{recursive:!0,mode:448}),await vl1(this.storeFile,`${JSON.stringify(A,null,2)}
|
|
1708
1708
|
`,{mode:384}),await xl1(this.storeFile,384)}}class gx extends Error{constructor(A){super(A);this.name="InvalidClientMetadataError"}}function m70(A){return Buffer.from(JSON.stringify(A)).toString("base64url")}function ll1(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,H=Q.slice(D,D+I);return new Uint8Array([...u70(f),...u70(H)])}function u70(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 bUA(A,Q){let B={typ:"JWT",alg:"ES256",kid:A.kid},w=`${m70(B)}.${m70(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(ll1(f)).toString("base64url")}`}import{createHash as il1}from"crypto";import{mkdir as rl1,readFile as dl1,writeFile as nl1,chmod as ol1}from"fs/promises";import{dirname as sl1,join as al1}from"path";var tl1="oauth-signing-key.jwk";function c70(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 p70(A){let Q=JSON.stringify({crv:A.crv,kty:A.kty,x:A.x,y:A.y});return il1("sha256").update(Q).digest("base64url")}function el1(A){return{kty:"EC",crv:"P-256",x:A.x,y:A.y,kid:A.kid,use:"sig",alg:"ES256"}}async function Ai1(){let A=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]),Q=await crypto.subtle.exportKey("jwk",A.privateKey);if(!c70(Q))throw Error("Generated OAuth signing key is not a P-256 private JWK");let B=p70(Q);return{...Q,kid:B,use:"sig",alg:"ES256"}}class bn{keyFile;cachedKey;loadPromise;constructor(A){this.keyFile=al1(A.storageDir,A.keyFile??tl1)}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 Ai1();return await rl1(sl1(this.keyFile),{recursive:!0,mode:448}),await nl1(this.keyFile,`${JSON.stringify(Q,null,2)}
|
|
1709
1709
|
`,{mode:384}),await ol1(this.keyFile,384),Q}async getPublicJwk(){return el1(await this.getPrivateJwk())}async readExistingKey(){try{let A=JSON.parse(await dl1(this.keyFile,"utf8"));if(!c70(A))throw Error(`OAuth signing key at ${this.keyFile} is not a private P-256 JWK`);let Q=typeof A.kid==="string"?A.kid:p70(A);return{...A,kid:Q,use:"sig",alg:"ES256"}}catch(A){if(A.code==="ENOENT")return;throw A}}}var S2={};OB(S2,{trimPadding:()=>i70,toUTF8String:()=>Yi1,toBuffer:()=>fi1,toBase64:()=>Di1,isBase64URL:()=>Wi1,isBase64:()=>Xi1,fromUTF8String:()=>Hi1,fromBuffer:()=>Ii1});var l70=(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},Qi1=l70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),Bi1=l70("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),wi1=/^[-A-Za-z0-9\-_]*$/,$i1=/^[-A-Za-z0-9+/]*={0,3}$/,ZX={};ZX.toArrayBuffer=(A,Q)=>{let B=A.length,w=A.length*0.75,$,f=0,I,D,H,Y;if(A[A.length-1]==="="){if(w--,A[A.length-2]==="=")w--}let W=new ArrayBuffer(w),F=new Uint8Array(W),K=Q?Bi1:Qi1;for($=0;$<B;$+=4)I=K[A.charCodeAt($)],D=K[A.charCodeAt($+1)],H=K[A.charCodeAt($+2)],Y=K[A.charCodeAt($+3)],F[f++]=I<<2|D>>4,F[f++]=(D&15)<<4|H>>2,F[f++]=(H&3)<<6|Y&63;return W};ZX.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 $};ZX.toString=(A,Q)=>{return new TextDecoder().decode(ZX.toArrayBuffer(A,Q))};ZX.fromString=(A,Q)=>{return ZX.fromArrayBuffer(new TextEncoder().encode(A),Q)};ZX.validate=(A,Q)=>{if(!(typeof A==="string"||A instanceof String))return!1;try{return Q?wi1.test(A):$i1.test(A)}catch(B){return!1}};ZX.base64=ZX;var rU=ZX;function fi1(A,Q="base64url"){let B=rU.toArrayBuffer(A,Q==="base64url");return new Uint8Array(B)}function Ii1(A,Q="base64url"){let B=new Uint8Array(A);return rU.fromArrayBuffer(B.buffer,Q==="base64url")}function Di1(A){let Q=rU.toArrayBuffer(A,!0);return rU.fromArrayBuffer(Q)}function Hi1(A){return rU.fromString(A,!0)}function Yi1(A){return rU.toString(A,!0)}function Xi1(A){return rU.validate(A,!1)}function Wi1(A){return A=i70(A),rU.validate(A,!0)}function i70(A){return A.replace(/=/g,"")}var W7={};OB(W7,{encode:()=>ji1,decodeFirst:()=>ki1});function RV(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 On=0,Tx=1,OUA=2,RUA=3,PUA=4,_UA=5,kUA=6,r70=7;function NX(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==Tx){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 Pn{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 d70(A,Q,B){return RV(A,Q,B)}function Ui1(A,Q,B){let[w,$]=d70(A,Q,B);return[-w-1,$]}function n70(A,Q,B){let[w,$]=RV(A,Q,B),f=B+$;return[new Uint8Array(A.buffer.slice(f,f+w)),$+w]}var Ji1=new TextDecoder;function Gi1(A,Q,B){let[w,$]=n70(A,Q,B);return[Ji1.decode(w),$]}function Fi1(A,Q,B){if(Q===0)return[[],1];let[w,$]=RV(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[Y,W]=Gz(A,B+f);I.push(Y),f+=W}return[I,f]}var Rn="Map is not supported or well formed";function Ki1(A,Q,B){if(Q===0)return[new Map,1];let[w,$]=RV(A,Q,B),f=$,I=new Map;for(let D=0;D<w;D++){let H=A.byteLength-B-f;if(H<=0)throw Error(Rn);let[Y,W]=Gz(A,B+f);if(f+=W,H-=W,H<=0)throw Error(Rn);if(typeof Y!=="string"&&typeof Y!=="number")throw Error(Rn);if(I.has(Y))throw Error(Rn);let[F,K]=Gz(A,B+f);f+=K,I.set(Y,F)}return[I,f]}function Zi1(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 Ni1(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 zi1(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 qi1(A,Q,B){let[w,$]=RV(A,Q,B),[f,I]=Gz(A,B+$);return[new Pn(w,f),$+I]}function Gz(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 On:return d70(A,$,Q);case Tx:return Ui1(A,$,Q);case OUA:return n70(A,$,Q);case RUA:return Gi1(A,$,Q);case PUA:return Fi1(A,$,Q);case _UA:return Ki1(A,$,Q);case kUA:return qi1(A,$,Q);case r70: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 Zi1(A,Q);case 26:return Ni1(A,Q);case 27:return zi1(A,Q)}}throw Error(`Unsupported or not well formed at ${Q}`)}function Ci1(A){if(A===!0)return 245;else if(A===!1)return 244;else if(A===null)return 246;return 247}function Ei1(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 Li1(A){if(typeof A=="number"){if(Number.isSafeInteger(A))if(A<0)return NX(Tx,Math.abs(A));else return NX(On,A);return[Ei1(A)]}else if(A<0n)return NX(Tx,A*-1n);else return NX(On,A)}var Mi1=new TextEncoder;function Vi1(A,Q){Q.push(...NX(RUA,A.length)),Q.push(Mi1.encode(A))}function bi1(A,Q){Q.push(...NX(OUA,A.length)),Q.push(A)}function Oi1(A,Q){Q.push(...NX(PUA,A.length));for(let B of A)Sx(B,Q)}function Ri1(A,Q){Q.push(new Uint8Array(NX(_UA,A.size)));for(let[B,w]of A.entries())Sx(B,Q),Sx(w,Q)}function Pi1(A,Q){Q.push(...NX(kUA,A.tag)),Sx(A.value,Q)}function Sx(A,Q){if(typeof A=="boolean"||A===null||A==null){Q.push(Ci1(A));return}if(typeof A=="number"||typeof A=="bigint"){Q.push(...Li1(A));return}if(typeof A=="string"){Vi1(A,Q);return}if(A instanceof Uint8Array){bi1(A,Q);return}if(Array.isArray(A)){Oi1(A,Q);return}if(A instanceof Map){Ri1(A,Q);return}if(A instanceof Pn){Pi1(A,Q);return}throw Error("Not implemented")}function jUA(A,Q){if(A.byteLength===0||A.byteLength<=Q||Q<0)throw Error("No data");if(A instanceof Uint8Array)return Gz(new DataView(A.buffer),Q);else if(A instanceof ArrayBuffer)return Gz(new DataView(A),Q);return Gz(A,Q)}function vUA(A){let Q=[];Sx(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 ki1(A){let Q=new Uint8Array(A),B=jUA(Q,0),[w]=B;return w}function ji1(A){return vUA(A)}var qX={};OB(qX,{verify:()=>PH0,getRandomValues:()=>e70,digest:()=>t70});function o70(A){let Q=A.get(g2.kty);return xUA(Q)&&Q===NI.OKP}function fK(A){let Q=A.get(g2.kty);return xUA(Q)&&Q===NI.EC2}function PV(A){let Q=A.get(g2.kty);return xUA(Q)&&Q===NI.RSA}var g2;(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"})(g2||(g2={}));var NI;(function(A){A[A.OKP=1]="OKP",A[A.EC2=2]="EC2",A[A.RSA=3]="RSA"})(NI||(NI={}));function xUA(A){return Object.values(NI).indexOf(A)>=0}var K9;(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"})(K9||(K9={}));function s70(A){return Object.values(K9).indexOf(A)>=0}var IQ;(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"})(IQ||(IQ={}));function zX(A){return Object.values(IQ).indexOf(A)>=0}function IK(A){if([IQ.RS1].indexOf(A)>=0)return"SHA-1";else if([IQ.ES256,IQ.PS256,IQ.RS256].indexOf(A)>=0)return"SHA-256";else if([IQ.ES384,IQ.PS384,IQ.RS384].indexOf(A)>=0)return"SHA-384";else if([IQ.ES512,IQ.PS512,IQ.RS512,IQ.EdDSA].indexOf(A)>=0)return"SHA-512";throw Error(`Could not map COSE alg value of ${A} to a WebCrypto alg`)}var mx=void 0;function wf(){return new Promise((Q,B)=>{if(mx)return Q(mx);let w=xi1.stubThisGlobalThisCrypto();if(w)return mx=w,Q(mx);return B(new a70)})}class a70 extends Error{constructor(){super("An instance of the Crypto API could not be located");this.name="MissingWebCrypto"}}var xi1={stubThisGlobalThisCrypto:()=>globalThis.crypto,setCachedCrypto:(A)=>{mx=A}};async function t70(A,Q){let B=await wf(),w=IK(Q),$=await B.subtle.digest(w,A);return new Uint8Array($)}async function e70(A){return(await wf()).getRandomValues(A),A}async function _V(A){let Q=await wf(),{keyData:B,algorithm:w}=A;return Q.subtle.importKey("jwk",B,w,!1,["verify"])}async function _n(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await wf(),I=Q.get(g2.alg),D=Q.get(g2.crv),H=Q.get(g2.x),Y=Q.get(g2.y);if(!I)throw Error("Public key was missing alg (EC2)");if(!D)throw Error("Public key was missing crv (EC2)");if(!H)throw Error("Public key was missing x (EC2)");if(!Y)throw Error("Public key was missing y (EC2)");let W;if(D===K9.P256)W="P-256";else if(D===K9.P384)W="P-384";else if(D===K9.P521)W="P-521";else throw Error(`Unexpected COSE crv value of ${D} (EC2)`);let F={kty:"EC",crv:W,x:S2.fromBuffer(H),y:S2.fromBuffer(Y),ext:!1},Z=await _V({keyData:F,algorithm:{name:"ECDSA",namedCurve:W}}),q=IK(I);if($)q=IK($);let E={name:"ECDSA",hash:{name:q}};return f.subtle.verify(E,Z,B,w)}function hUA(A){if([IQ.EdDSA].indexOf(A)>=0)return"Ed25519";else if([IQ.ES256,IQ.ES384,IQ.ES512,IQ.ES256K].indexOf(A)>=0)return"ECDSA";else if([IQ.RS256,IQ.RS384,IQ.RS512,IQ.RS1].indexOf(A)>=0)return"RSASSA-PKCS1-v1_5";else if([IQ.PS256,IQ.PS384,IQ.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 kn(A){let{cosePublicKey:Q,signature:B,data:w,shaHashOverride:$}=A,f=await wf(),I=Q.get(g2.alg),D=Q.get(g2.n),H=Q.get(g2.e);if(!I)throw Error("Public key was missing alg (RSA)");if(!zX(I))throw Error(`Public key had invalid alg ${I} (RSA)`);if(!D)throw Error("Public key was missing n (RSA)");if(!H)throw Error("Public key was missing e (RSA)");let Y={kty:"RSA",alg:"",n:S2.fromBuffer(D),e:S2.fromBuffer(H),ext:!1},W={name:hUA(I),hash:{name:IK(I)}},F={name:hUA(I)};if($)W.hash.name=IK($);if(W.name==="RSASSA-PKCS1-v1_5"){if(W.hash.name==="SHA-256")Y.alg="RS256";else if(W.hash.name==="SHA-384")Y.alg="RS384";else if(W.hash.name==="SHA-512")Y.alg="RS512";else if(W.hash.name==="SHA-1")Y.alg="RS1"}else if(W.name==="RSA-PSS"){let Z=0;if(W.hash.name==="SHA-256")Y.alg="PS256",Z=32;else if(W.hash.name==="SHA-384")Y.alg="PS384",Z=48;else if(W.hash.name==="SHA-512")Y.alg="PS512",Z=64;F.saltLength=Z}else throw Error(`Unexpected RSA key algorithm ${I} (${W.name})`);let K=await _V({keyData:Y,algorithm:W});return f.subtle.verify(F,K,B,w)}function jn(A){let Q=H2.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 a6(A){let Q;if(typeof A==="string")if(S2.isBase64URL(A))Q=S2.toBase64(A);else if(S2.isBase64(A))Q=A;else throw Error("Certificate is not a valid base64 or base64url string");else Q=S2.fromBuffer(A,"base64");let B="";for(let w=0;w<Math.ceil(Q.length/64);w+=1){let $=64*w;B+=`${Q.substr($,64)}
|
|
@@ -2282,8 +2282,8 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2282
2282
|
</form>
|
|
2283
2283
|
</main>
|
|
2284
2284
|
</body>
|
|
2285
|
-
</html>`}function iFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function rFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(pY0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Js(A){let Q=Hs(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function hX(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}GA();var Fs="email:send",iY0=G.object({to:G.string().email(),subject:G.string().min(1),text:G.string().min(1),html:G.string().min(1).optional(),sensitivity:G.enum(["normal","secret"]).default("normal")}).strict();$0();GA();var rY0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.
|
|
2286
|
-
`),sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=dY0.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,this.config.setupEmail,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function Vy(A){return new oFA(A)}GA();var sFA=G.object({transport:G.enum(["stdio","http"]).default("http"),httpPort:G.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:G.string().describe("Bearer token for HTTP transport authentication").optional()});function aY0(A,Q){return[]}$0();function aFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=gL.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 tY0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.72",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 hK extends aY{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",tY0,Q,sFA)}async getTools(){return aY0(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"});aFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=nb();return this.httpServer=iU.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||nb()))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=NH.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(){NH.resetInstance(),iU.resetInstance()}}$0();GA();var eD=D1(cS0(),1);GA();$0();var jCA=G.object({botToken:G.string().min(1).describe("Discord bot token"),allowedChannels:G.array(G.string()).default([]),requireMention:G.boolean().default(!0),allowDMs:G.boolean().default(!0),showTypingIndicator:G.boolean().default(!0),statusMessage:G.string().default("Mention me to chat"),useThreads:G.boolean().default(!0),threadAutoArchive:G.union([G.literal(60),G.literal(1440),G.literal(4320),G.literal(10080)]).default(1440),...Yj.shape,captureUrlEmoji:G.string().default("\uD83D\uDD16")});var pS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.72",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 vCA=2000,mC2=8000,uC2=100;function ze(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class KZ extends LN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",pS0,A,jCA);this.fetchText=Q.fetchText??_p}async onRegister(A){await super.onRegister(A),this.client=new eD.Client({intents:[eD.GatewayIntentBits.Guilds,eD.GatewayIntentBits.GuildMessages,eD.GatewayIntentBits.MessageContent,eD.GatewayIntentBits.DirectMessages],partials:[eD.Partials.Channel]}),this.client.on(eD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(eD.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(!ze(B))return;let w=Gk(Q,vCA);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(!ze(B))return;let w=Gk(Q,vCA),$;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(!ze(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,vCA)),!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 H=Q||$||!this.config.requireMention||w;if(I&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:f}));if(!H){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 Y=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,C=Z.size;if(!this.isUploadableTextFile(q,E))continue;if(!this.isFileSizeAllowed(C))continue;try{let R=await this.fetchText(Z.url);Y+=`
|
|
2285
|
+
</html>`}function iFA(A){return new Response(A,{headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function rFA(A){let Q=`${new URL(A.url).pathname}${new URL(A.url).search}`;return new Response(pY0(Q,"Operator login required"),{status:401,headers:{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}})}function Js(A){let Q=Hs(A),B=new URL(Q);return{origin:B.origin,rpID:B.hostname}}function hX(A){return A.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}GA();var Fs="email:send",iY0=G.object({to:G.string().email(),subject:G.string().min(1),text:G.string().min(1),html:G.string().min(1).optional(),sensitivity:G.enum(["normal","secret"]).default("normal")}).strict();$0();GA();var rY0={name:"@brains/notifications",private:!0,version:"0.2.0-alpha.73",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 nFA="notifications:send",zo1=G.object({}),qo1=G.discriminatedUnion("type",[G.object({type:G.literal("email"),address:G.string().email()}).strict()]),Co1=G.object({recipient:qo1,title:G.string().min(1),body:G.string().min(1),html:G.string().min(1).optional(),sensitivity:G.enum(["normal","secret"]).default("normal")}).strict(),dY0=G.discriminatedUnion("status",[G.object({status:G.literal("sent"),deliveryId:G.string().optional()}).strict(),G.object({status:G.literal("failed")}).strict()]);class nY0 extends RB{constructor(A={}){super("notifications",rY0,A,zo1)}async onRegister(A){A.messaging.subscribe(nFA,async(Q)=>{let B=Co1.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:Fs,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 oY0(A={}){return new nY0(A)}$0();GA();var sY0={name:"@brains/auth-service",private:!0,version:"0.2.0-alpha.73",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 Lo1=G.object({issuer:G.string().optional(),trustedIssuers:G.array(G.string()).default([]),allowLocalhostIssuers:G.boolean().optional(),storageDir:G.string().default("./data/auth"),setupEmail:G.string().email().optional()}),Mo1=G.object({}),Ks;function nb(){return Ks}class oFA extends RB{service;constructor(A={}){super("auth-service",sY0,A,Lo1)}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 Gs({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(),Ks=this.service}async onReady(A){await this.requestSetupEmailIfNeeded(A)}async onShutdown(){if(Ks===this.service)Ks=void 0;this.service=void 0}async getTools(){return[xQ(this.id,"get_passkey_setup_url","Get the first-passkey setup URL when operator setup is required. Anchor-only.",Mo1,async()=>{let A=this.getService();if(await A.hasPasskeyCredentials())return _8({status:"complete"});let Q=await A.getOperatorSetupRequired();if(Q)return _8({status:"setup_required",setupUrl:Q.setupUrl,expiresAt:Q.expiresAt});return _8({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;if(await Q.hasSetupEmailDelivery(B.setupTokenId,this.config.setupEmail))return;let w=new Date(B.expiresAt*1000).toISOString(),$=await A.messaging.send({type:nFA,payload:{recipient:{type:"email",address:this.config.setupEmail},title:"Set up your brain passkey",body:["Set up your brain passkey using this single-use link:","",B.setupUrl,"",`This link expires at ${w}.`,"The first successful passkey registration completes setup and closes this link."].join(`
|
|
2286
|
+
`),sensitivity:"secret"}});if(!("success"in $)||!$.success||!$.data){A.logger.warn("Passkey setup email delivery was not confirmed");return}let f=dY0.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,this.config.setupEmail,f.data.deliveryId?{deliveryId:f.data.deliveryId}:{})}}function Vy(A){return new oFA(A)}GA();var sFA=G.object({transport:G.enum(["stdio","http"]).default("http"),httpPort:G.number().describe("Port for HTTP transport (only used when transport is 'http')").default(3333),authToken:G.string().describe("Bearer token for HTTP transport authentication").optional()});function aY0(A,Q){return[]}$0();function aFA(A,Q){A.messaging.subscribe("job-progress",async(B)=>{let w=gL.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 tY0={name:"@brains/mcp",private:!0,version:"0.2.0-alpha.73",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 hK extends aY{mcpTransport;stdioServer;httpServer;domain;constructor(A={}){let Q={...A,authToken:A.authToken??process.env.MCP_AUTH_TOKEN};super("mcp",tY0,Q,sFA)}async getTools(){return aY0(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"});aFA(A,this.logger)}getOrCreateHttpServer(){if(this.httpServer)return this.httpServer;let A=nb();return this.httpServer=iU.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||nb()))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=NH.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(){NH.resetInstance(),iU.resetInstance()}}$0();GA();var eD=D1(cS0(),1);GA();$0();var jCA=G.object({botToken:G.string().min(1).describe("Discord bot token"),allowedChannels:G.array(G.string()).default([]),requireMention:G.boolean().default(!0),allowDMs:G.boolean().default(!0),showTypingIndicator:G.boolean().default(!0),statusMessage:G.string().default("Mention me to chat"),useThreads:G.boolean().default(!0),threadAutoArchive:G.union([G.literal(60),G.literal(1440),G.literal(4320),G.literal(10080)]).default(1440),...Yj.shape,captureUrlEmoji:G.string().default("\uD83D\uDD16")});var pS0={name:"@brains/discord",private:!0,version:"0.2.0-alpha.73",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 vCA=2000,mC2=8000,uC2=100;function ze(A){return!!A&&typeof A==="object"&&"send"in A&&"sendTyping"in A}class KZ extends LN{client=null;fetchText;pendingConfirmations=new Map;typingIntervals=new Map;constructor(A,Q={}){super("discord",pS0,A,jCA);this.fetchText=Q.fetchText??_p}async onRegister(A){await super.onRegister(A),this.client=new eD.Client({intents:[eD.GatewayIntentBits.Guilds,eD.GatewayIntentBits.GuildMessages,eD.GatewayIntentBits.MessageContent,eD.GatewayIntentBits.DirectMessages],partials:[eD.Partials.Channel]}),this.client.on(eD.Events.MessageCreate,(Q)=>{this.handleMessage(Q)}),this.client.once(eD.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(!ze(B))return;let w=Gk(Q,vCA);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(!ze(B))return;let w=Gk(Q,vCA),$;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(!ze(w))return!1;try{return await(await w.messages.fetch(Q)).edit(B.slice(0,vCA)),!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 H=Q||$||!this.config.requireMention||w;if(I&&(!H||this.willRouteUseNonSpaceConversation(A)))await this.capturePassiveSpaceMessage(A,f).catch((F)=>this.logger.error("Passive Discord space capture failed",{error:F,channelId:f}));if(!H){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 Y=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,C=Z.size;if(!this.isUploadableTextFile(q,E))continue;if(!this.isFileSizeAllowed(C))continue;try{let R=await this.fetchText(Z.url);Y+=`
|
|
2287
2287
|
|
|
2288
2288
|
`+this.formatFileUploadMessage(q,R)}catch(R){this.logger.error("Failed to download attachment",{error:R,filename:q})}}}if(Y=Y.trim(),!Y)return;let W=A.channel.id;await this.routeToAgent(Y,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:cY(A,uC2),autoArchiveDuration:this.config.threadAutoArchive})).id}catch(Y){this.logger.error("Failed to create thread",{error:Y})}let I=`discord-${f}`,D=this.context.permissions.getUserLevel("discord",B.author.id,w),H=this.getChannelName(B);this.startProcessingInput(f);try{let Y=this.client?.channels.cache.get(f);if(ze(Y))this.startTypingIndicator(Y);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:H,...this.buildUserMessageMetadata(B,Q,H,{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(Y){this.logger.error("Error handling message",{error:Y,channelId:f}),this.sendMessageToChannel({channelId:f,message:`**Error:** ${Y instanceof Error?Y.message:"Unknown error"}`})}finally{this.endProcessingInput(),this.stopTypingIndicator(f)}}async handleConfirmationResponse(A,Q,B){let w=sL(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}))},mC2);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)=>ZU(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()}}$0();import{resolve as eO,join as OE2}from"path";var xCA=(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 H,Y=!1,W;if(A[D])W=A[D][0][0],w.req.routeIndex=D;else W=D===A.length&&$||void 0;if(W)try{H=await W(w,()=>I(D+1))}catch(F){if(F instanceof Error&&Q)w.error=F,H=await Q(F,w),Y=!0;else throw F}else if(w.finalized===!1&&B)H=await B(w);if(H&&(w.finalized===!1||Y))w.res=H;return w}}};var lS0=Symbol();var iS0=async(A,Q=Object.create(null))=>{let{all:B=!1,dot:w=!1}=Q,f=(A instanceof qe?A.raw.headers:A.headers).get("Content-Type");if(f?.startsWith("multipart/form-data")||f?.startsWith("application/x-www-form-urlencoded"))return cC2(A,{all:B,dot:w});return{}};async function cC2(A,Q){let B=await A.formData();if(B)return pC2(B,Q);return{}}function pC2(A,Q){let B=Object.create(null);if(A.forEach((w,$)=>{if(!(Q.all||$.endsWith("[]")))B[$]=w;else lC2(B,$,w)}),Q.dot)Object.entries(B).forEach(([w,$])=>{if(w.includes("."))iC2(B,w,$),delete B[w]});return B}var lC2=(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]},iC2=(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 yCA=(A)=>{let Q=A.split("/");if(Q[0]==="")Q.shift();return Q},rS0=(A)=>{let{groups:Q,path:B}=rC2(A),w=yCA(B);return dC2(w,Q)},rC2=(A)=>{let Q=[];return A=A.replace(/\{[^}]+\}/g,(B,w)=>{let $=`@${w}`;return Q.push([$,B]),$}),{groups:Q,path:A}},dC2=(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},Ce={},dS0=(A,Q)=>{if(A==="*")return"*";let B=A.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(B){let w=`${A}#${Q}`;if(!Ce[w])if(B[2])Ce[w]=Q&&Q[0]!==":"&&Q[0]!=="*"?[w,B[1],new RegExp(`^${B[2]}(?=/${Q})`)]:[A,B[1],new RegExp(`^${B[2]}$`)];else Ce[w]=[A,B[1],!0];return Ce[w]}return null},Ee=(A,Q)=>{try{return Q(A)}catch{return A.replace(/(?:%[0-9A-Fa-f]{2})+/g,(B)=>{try{return Q(B)}catch{return B}})}},gCA=(A)=>Ee(A,decodeURI),TCA=(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),H=Q.slice(B,D);return gCA(H.includes("%25")?H.replace(/%25/g,"%2525"):H)}else if($===63||$===35)break}return Q.slice(B,w)};var nS0=(A)=>{let Q=TCA(A);return Q.length>1&&Q.at(-1)==="/"?Q.slice(0,-1):Q},cq=(A,Q,...B)=>{if(B.length)Q=cq(Q,...B);return`${A?.[0]==="/"?"":"/"}${A}${Q==="/"?"":`${A?.at(-1)==="/"?"":"/"}${Q?.[0]==="/"?Q.slice(1):Q}`}`},Le=(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)},hCA=(A)=>{if(!/[%+]/.test(A))return A;if(A.indexOf("+")!==-1)A=A.replace(/\+/g," ");return A.indexOf("%")!==-1?Ee(A,SCA):A},oS0=(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 H=I+Q.length+2,Y=A.indexOf("&",H);return hCA(A.slice(H,Y===-1?void 0:Y))}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 H=A.slice(f+1,D===-1?I===-1?void 0:I:D);if(w)H=hCA(H);if(f=I,H==="")continue;let Y;if(D===-1)Y="";else if(Y=A.slice(D+1,I===-1?void 0:I),w)Y=hCA(Y);if(B){if(!($[H]&&Array.isArray($[H])))$[H]=[];$[H].push(Y)}else $[H]??=Y}return Q?$[Q]:$},sS0=oS0,aS0=(A,Q)=>{return oS0(A,Q,!0)},SCA=decodeURIComponent;var tS0=(A)=>Ee(A,SCA),qe=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)?tS0(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)?tS0(w):w}return A}#$(A){return this.#Q[1]?this.#Q[1][A]:A}query(A){return sS0(this.url,A)}queries(A){return aS0(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 iS0(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[lS0](){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 eS0={Stringify:1,BeforeStream:2,Stream:3},Am0=(A,Q)=>{let B=new String(A);return B.isEscaped=!0,B.callbacks=Q,B};var mCA=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((H)=>mCA(H,Q,!1,w,$))).then(()=>$[0]));if(B)return Am0(await I,f);else return I};var nC2="text/plain; charset=UTF-8",uCA=(A,Q)=>{return{"Content-Type":A,...Q}},YT=(A,Q)=>new Response(A,Q),Qm0=class{#A;#Q;env={};#B;finalized=!1;error;#f;#$;#w;#X;#H;#Y;#D;#W;#U;constructor(A,Q){if(this.#A=A,Q)this.#$=Q.executionCtx,this.env=Q.env,this.#Y=Q.notFoundHandler,this.#U=Q.path,this.#W=Q.matchResult}get req(){return this.#Q??=new qe(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||=YT(null,{headers:this.#D??=new Headers})}set res(A){if(this.#w&&A){A=YT(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.#H??=(Q)=>this.html(Q),this.#H(...A)};setLayout=(A)=>this.#X=A;getLayout=()=>this.#X;setRenderer=(A)=>{this.#H=A};header=(A,Q,B)=>{if(this.finalized)this.#w=YT(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 YT(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,uCA(nC2,B))};json=(A,Q,B)=>{return this.#I(JSON.stringify(A),Q,uCA("application/json",B))};html=(A,Q,B)=>{let w=($)=>this.#I($,Q,uCA("text/html; charset=UTF-8",B));return typeof A==="object"?mCA(A,eS0.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.#Y??=()=>YT(),this.#Y(this)}};var Kw="ALL",Bm0="all",wm0=["get","post","put","delete","options","patch"],Me="Can not add a route since the matcher is already built.",Ve=class extends Error{};var cCA="__COMPOSED_HANDLER";var oC2=(A)=>{return A.text("404 Not Found",404)},$m0=(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)},fm0=class A{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#A="/";routes=[];constructor(Q={}){[...wm0,Bm0].forEach((f)=>{this[f]=(I,...D)=>{if(typeof I==="string")this.#A=I;else this.#f(f,this.#A,I);return D.forEach((H)=>{this.#f(f,this.#A,H)}),this}}),this.on=(f,I,...D)=>{for(let H of[I].flat()){this.#A=H;for(let Y of[f].flat())D.map((W)=>{this.#f(Y.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(Kw,this.#A,D)}),this};let{strict:w,...$}=Q;Object.assign(this,$),this.getPath=w??!0?Q.getPath??TCA:nS0}#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=oC2;errorHandler=$m0;route(Q,B){let w=this.basePath(Q);return B.routes.map(($)=>{let f;if(B.errorHandler===$m0)f=$.handler;else f=async(I,D)=>(await xCA([],B.errorHandler)(I,()=>$.handler(I,D))).res,f[cCA]=$.handler;w.#f($.method,$.path,f)}),this}basePath(Q){let B=this.#Q();return B._basePath=cq(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)$=(H)=>H;else $=w.replaceRequest;let I=f?(H)=>{let Y=f(H);return Array.isArray(Y)?Y:[Y]}:(H)=>{let Y=void 0;try{Y=H.executionCtx}catch{}return[H.env,Y]};$||=(()=>{let H=cq(this._basePath,Q),Y=H==="/"?0:H.length;return(W)=>{let F=new URL(W.url);return F.pathname=F.pathname.slice(Y)||"/",new Request(F,W)}})();let D=async(H,Y)=>{let W=await B($(H.req.raw),...I(H));if(W)return W;await Y()};return this.#f(Kw,cq(Q,"*"),D),this}#f(Q,B,w){Q=Q.toUpperCase(),B=cq(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 Qm0(Q,{path:f,matchResult:I,env:w,executionCtx:B,notFoundHandler:this.#B});if(I[0].length===1){let Y;try{Y=I[0][0][0][0](D,async()=>{D.res=await this.#B(D)})}catch(W){return this.#$(W,D)}return Y instanceof Promise?Y.then((W)=>W||(D.finalized?D.res:this.#B(D))).catch((W)=>this.#$(W,D)):Y??this.#B(D)}let H=xCA(I[0],this.errorHandler,this.#B);return(async()=>{try{let Y=await H(D);if(!Y.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return Y.res}catch(Y){return this.#$(Y,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${cq("/",Q)}`,B),w,$)};fire=()=>{addEventListener("fetch",(Q)=>{Q.respondWith(this.#w(Q.request,Q,void 0,Q.request.method))})}};var XT=[];function be(A,Q){let B=this.buildAllMatchers(),w=($,f)=>{let I=B[$]||B[Kw],D=I[2][f];if(D)return D;let H=f.match(I[0]);if(!H)return[[],XT];let Y=H.indexOf("",1);return[I[1][Y],H]};return this.match=w,w(A,Q)}var Oe="[^/]+",WT=".*",UT="(?:|/.*)",pq=Symbol(),sC2=new Set(".\\+*[^]$()");function aC2(A,Q){if(A.length===1)return Q.length===1?A<Q?-1:1:-1;if(Q.length===1)return 1;if(A===WT||A===UT)return 1;else if(Q===WT||Q===UT)return-1;if(A===Oe)return 1;else if(Q===Oe)return-1;return A.length===Q.length?A<Q?-1:1:Q.length-A.length}var Im0=class A{#A;#Q;#B=Object.create(null);insert(Q,B,w,$,f){if(Q.length===0){if(this.#A!==void 0)throw pq;if(f)return;this.#A=B;return}let[I,...D]=Q,H=I==="*"?D.length===0?["","",WT]:["","",Oe]:I==="/*"?["","",UT]:I.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),Y;if(H){let W=H[1],F=H[2]||Oe;if(W&&H[2]){if(F===".*")throw pq;if(F=F.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(F))throw pq}if(Y=this.#B[F],!Y){if(Object.keys(this.#B).some((K)=>K!==WT&&K!==UT))throw pq;if(f)return;if(Y=this.#B[F]=new A,W!=="")Y.#Q=$.varIndex++}if(!f&&W!=="")w.push([W,Y.#Q])}else if(Y=this.#B[I],!Y){if(Object.keys(this.#B).some((W)=>W.length>1&&W!==WT&&W!==UT))throw pq;if(f)return;Y=this.#B[I]=new A}Y.insert(D,B,w,$,f)}buildRegExpStr(){let B=Object.keys(this.#B).sort(aC2).map((w)=>{let $=this.#B[w];return(typeof $.#Q==="number"?`(${w})@${$.#Q}`:sC2.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 Dm0=class{#A={varIndex:0};#Q=new Im0;insert(A,Q,B){let w=[],$=[];for(let I=0;;){let D=!1;if(A=A.replace(/\{[^}]+\}/g,(H)=>{let Y=`@\\${I}`;return $[I]=[Y,H],I++,D=!0,Y}),!D)break}let f=A.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let I=$.length-1;I>=0;I--){let[D]=$[I];for(let H=f.length-1;H>=0;H--)if(f[H].indexOf(D)!==-1){f[H]=f[H].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 tC2=[/^$/,[],Object.create(null)],Hm0=Object.create(null);function Ym0(A){return Hm0[A]??=new RegExp(A==="*"?"":`^${A.replace(/\/\*$|([.\\+*[^\]$()])/g,(Q,B)=>B?`\\${B}`:"(?:|/.*)")}$`)}function eC2(){Hm0=Object.create(null)}function AE2(A){let Q=new Dm0,B=[];if(A.length===0)return tC2;let w=A.map((Y)=>[!/\*|\/:/.test(Y[0]),...Y]).sort(([Y,W],[F,K])=>Y?1:F?-1:W.length-K.length),$=Object.create(null);for(let Y=0,W=-1,F=w.length;Y<F;Y++){let[K,Z,q]=w[Y];if(K)$[Z]=[q.map(([C])=>[C,Object.create(null)]),XT];else W++;let E;try{E=Q.insert(Z,W,K)}catch(C){throw C===pq?new Ve(Z):C}if(K)continue;B[W]=q.map(([C,R])=>{let k=Object.create(null);R-=1;for(;R>=0;R--){let[P,o]=E[R];k[P]=o}return[C,k]})}let[f,I,D]=Q.buildRegExp();for(let Y=0,W=B.length;Y<W;Y++)for(let F=0,K=B[Y].length;F<K;F++){let Z=B[Y][F]?.[1];if(!Z)continue;let q=Object.keys(Z);for(let E=0,C=q.length;E<C;E++)Z[q[E]]=D[Z[q[E]]]}let H=[];for(let Y in I)H[Y]=B[I[Y]];return[f,H,$]}function sO(A,Q){if(!A)return;for(let B of Object.keys(A).sort((w,$)=>$.length-w.length))if(Ym0(B).test(Q))return[...A[B]];return}var Re=class{name="RegExpRouter";#A;#Q;constructor(){this.#A={[Kw]:Object.create(null)},this.#Q={[Kw]:Object.create(null)}}add(A,Q,B){let w=this.#A,$=this.#Q;if(!w||!$)throw Error(Me);if(!w[A])[w,$].forEach((D)=>{D[A]=Object.create(null),Object.keys(D[Kw]).forEach((H)=>{D[A][H]=[...D[Kw][H]]})});if(Q==="/*")Q="*";let f=(Q.match(/\/:/g)||[]).length;if(/\*$/.test(Q)){let D=Ym0(Q);if(A===Kw)Object.keys(w).forEach((H)=>{w[H][Q]||=sO(w[H],Q)||sO(w[Kw],Q)||[]});else w[A][Q]||=sO(w[A],Q)||sO(w[Kw],Q)||[];Object.keys(w).forEach((H)=>{if(A===Kw||A===H)Object.keys(w[H]).forEach((Y)=>{D.test(Y)&&w[H][Y].push([B,f])})}),Object.keys($).forEach((H)=>{if(A===Kw||A===H)Object.keys($[H]).forEach((Y)=>D.test(Y)&&$[H][Y].push([B,f]))});return}let I=Le(Q)||[Q];for(let D=0,H=I.length;D<H;D++){let Y=I[D];Object.keys($).forEach((W)=>{if(A===Kw||A===W)$[W][Y]||=[...sO(w[W],Y)||sO(w[Kw],Y)||[]],$[W][Y].push([B,f-H+D+1])})}}match=be;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,eC2(),A}#B(A){let Q=[],B=A===Kw;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!==Kw)Q.push(...Object.keys(w[Kw]).map((f)=>[f,w[Kw][f]]))}),!B)return null;else return AE2(Q)}};var QE2=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[Kw],f={};for(let I in $[2])f[I]=[$[2][I][0].slice(),XT];this.#A[A]=[$[0],$[1].map((I)=>Array.isArray(I)?I.slice():0),f]}if(Q==="/*"||Q==="*"){let $=[B,{}];if(A===Kw)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===Kw)for(let I in this.#A)this.#f(I,Q,B,$,f);else this.#f(A,Q,B,$,f)}buildAllMatchers(){return this.#A}match=be};var pCA=class{name="SmartRouter";#A=[];#Q=[];constructor(A){this.#A=A.routers}add(A,Q,B){if(!this.#Q)throw Error(Me);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 H=0,Y=w.length;H<Y;H++)D.add(...w[H]);I=D.match(A,Q)}catch(H){if(H instanceof Ve)continue;throw H}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 JT=Object.create(null),BE2=(A)=>{for(let Q in A)return!0;return!1},Xm0=class A{#A;#Q;#B;#f=0;#$=JT;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=rS0(B),I=[];for(let D=0,H=f.length;D<H;D++){let Y=f[D],W=f[D+1],F=dS0(Y,W),K=Array.isArray(F)?F[0]:Y;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,H,Y)=>Y.indexOf(D)===H),score:this.#f}}),$}#w(Q,B,w,$,f){for(let I=0,D=B.#A.length;I<D;I++){let H=B.#A[I],Y=H[w]||H[Kw],W={};if(Y!==void 0){if(Y.params=Object.create(null),Q.push(Y),$!==JT||f&&f!==JT)for(let F=0,K=Y.possibleKeys.length;F<K;F++){let Z=Y.possibleKeys[F],q=W[Y.score];Y.params[Z]=f?.[Z]&&!q?f[Z]:$[Z]??f?.[Z],W[Y.score]=!0}}}}search(Q,B){let w=[];this.#$=JT;let f=[this],I=yCA(B),D=[],H=I.length,Y=null;for(let W=0;W<H;W++){let F=I[W],K=W===H-1,Z=[];for(let E=0,C=f.length;E<C;E++){let R=f[E],k=R.#Q[F];if(k)if(k.#$=R.#$,K){if(k.#Q["*"])this.#w(w,k.#Q["*"],Q,R.#$);this.#w(w,k,Q,R.#$)}else Z.push(k);for(let P=0,o=R.#B.length;P<o;P++){let r=R.#B[P],S=R.#$===JT?{}:{...R.#$};if(r==="*"){let c=R.#Q["*"];if(c)this.#w(w,c,Q,R.#$),c.#$=S,Z.push(c);continue}let[x,y,g]=r;if(!F&&!(g instanceof RegExp))continue;let AA=R.#Q[x];if(g instanceof RegExp){if(Y===null){Y=Array(H);let HA=B[0]==="/"?1:0;for(let _=0;_<H;_++)Y[_]=HA,HA+=I[_].length+1}let c=B.substring(Y[W]),JA=g.exec(c);if(JA){if(S[y]=JA[0],this.#w(w,AA,Q,R.#$,S),BE2(AA.#Q)){AA.#$=S;let HA=JA[0].match(/\//)?.length??0;(D[HA]||=[]).push(AA)}continue}}if(g===!0||g.test(F))if(S[y]=F,K){if(this.#w(w,AA,Q,S,R.#$),AA.#Q["*"])this.#w(w,AA.#Q["*"],Q,S,R.#$)}else AA.#$=S,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 lCA=class{name="TrieRouter";#A;constructor(){this.#A=new Xm0}add(A,Q,B){let w=Le(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 aO=class extends fm0{constructor(A={}){super(A);this.router=A.router??new pCA({routers:[new Re,new lCA]})}};import{stat as DE2}from"fs/promises";import{join as HE2}from"path";var tO=/^\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 iCA=(A,Q=$E2)=>{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 wE2={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"},$E2=wE2;var Wm0=(...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 Um0={br:".br",zstd:".zst",gzip:".gz"},fE2=Object.keys(Um0),IE2="index.html",Jm0=(A)=>{let Q=A.root??"./",B=A.path,w=A.join??Wm0;return async($,f)=>{if($.finalized)return f();let I;if(A.path)I=A.path;else try{if(I=gCA($.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,IE2);let H=A.getContent,Y=await H(D,$);if(Y instanceof Response)return $.newResponse(Y.body,Y);if(Y){let W=A.mimes&&iCA(D,A.mimes)||iCA(D);if($.header("Content-Type",W||"application/octet-stream"),A.precompressed&&(!W||tO.test(W))){let F=new Set($.req.header("Accept-Encoding")?.split(",").map((K)=>K.trim()));for(let K of fE2){if(!F.has(K))continue;let Z=await H(D+Um0[K],$);if(Z){Y=Z,$.header("Content-Encoding",K),$.header("Vary","Accept-Encoding",{append:!0});break}}}return await A.onFound?.(D,$),$.body(Y)}await A.onNotFound?.(D,$),await f();return}};var rCA=(A)=>{return async function(B,w){return Jm0({...A,getContent:async(I)=>{let D=Bun.file(I);return await D.exists()?D:null},join:HE2,isDir:async(I)=>{let D;try{D=(await DE2(I)).isDirectory()}catch{}return D}})(B,w)}};var dCA="x-hono-disable-ssg",CgB=(()=>{try{return new Response("SSG is disabled",{status:404,headers:{[dCA]:"true"}})}catch{return null}})();var{write:BTB}=Bun;var WE2=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 Gm0=(A)=>{return(...Q)=>{if(typeof Q[0]==="function"){let[B,w]=Q;return async function(f,I){let D=await B(f),H=await A(f,D,w);if(H)return H;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 Pe=(A)=>("server"in A.env)?A.env.server:A.env;var UE2=Gm0((A,Q)=>{let B=Pe(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 JE2=["gzip","deflate"],GE2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,Fm0=(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||!FE2(w.res)||!KE2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??JE2.find((Y)=>I?.includes(Y));if(!D||!w.res.body)return;let H=new CompressionStream(D);w.res=new Response(w.res.body.pipeThrough(H),w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}},FE2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&tO.test(Q)},KE2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!GE2.test(Q)};import{Readable as Km0}from"stream";import{createDeflate as ZE2,createGzip as NE2}from"zlib";var zE2=["gzip","deflate"],qE2=/(?:^|,)\s*?no-transform\s*?(?:,|$)/i,Zm0=(A)=>{if(typeof CompressionStream<"u")return Fm0(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||!CE2(w.res)||!EE2(w.res))return;let I=w.req.header("Accept-Encoding"),D=A?.encoding??zE2.find((H)=>I?.includes(H));if(!D||!w.res.body)return;try{let H=D==="gzip"?NE2():ZE2(),Y=w.res.body,F=Km0.fromWeb(Y).pipe(H),K=Km0.toWeb(F);w.res=new Response(K,w.res),w.res.headers.delete("Content-Length"),w.res.headers.set("Content-Encoding",D)}catch(H){console.error("Compression error:",H)}}},CE2=(A)=>{let Q=A.headers.get("Content-Type");return Q&&tO.test(Q)},EE2=(A)=>{let Q=A.headers.get("Cache-Control");return!Q||!qE2.test(Q)};var LE2=(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},Nm0=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(LE2(B,$))}if(!B)return null;return Array.prototype.map.call(new Uint8Array(B),($)=>$.toString(16).padStart(2,"0")).join("")};var ME2=["cache-control","content-location","date","etag","expires","vary"],zm0=(A)=>A.replace(/^W\//,"");function VE2(A,Q){return Q!=null&&Q.split(/,\s*/).some((B)=>zm0(B)===zm0(A))}function bE2(A){if(!A){if(crypto&&crypto.subtle)A=(Q)=>crypto.subtle.digest({name:"SHA-1"},Q)}return A}var qm0=(A)=>{let Q=A?.retainedHeaders??ME2,B=A?.weak??!1,w=bE2(A?.generateDigest);return async function(f,I){let D=f.req.header("If-None-Match")??null;await I();let H=f.res,Y=H.headers.get("ETag");if(!Y){if(!w)return;let W=await Nm0(H.clone().body,w);if(W===null)return;Y=B?`W/"${W}"`:`"${W}"`}if(VE2(Y,D))f.res=new Response(null,{status:304,statusText:"Not Modified",headers:{ETag:Y}}),f.res.headers.forEach((W,F)=>{if(Q.indexOf(F.toLowerCase())===-1)f.res.headers.delete(F)});else f.res.headers.set("ETag",Y)}};$0();function _e(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}`,H=await Q.send({type:`plugin:${A.pluginId}:tool:execute`,payload:{toolName:D,args:I,interfaceType:"webserver",userId:"anonymous"},sender:"webserver"}),Y=typeof H==="object"&&"data"in H?H.data:H,W=Pk.safeParse(Y),F=W.success?W.data:Y,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 Cm0="public, max-age=31536000, immutable";class ke{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:eO(process.cwd(),A.productionDistDir),sharedImagesDir:eO(process.cwd(),A.sharedImagesDir),...A.previewDistDir&&{previewDistDir:eO(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 aO;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("/*",Zm0());return Q.use("/*",qm0()),Q.use("/*",async(B,w)=>{if(await w(),A.immutableExtensions.test(B.req.path))B.header("Cache-Control",Cm0);else B.header("Cache-Control",A.defaultCache)}),Q.use("/*",this.createCleanUrlMiddleware(A.distDir)),Q.use("/*",rCA({root:A.distDir})),Q.notFound(async(B)=>{let w=Bun.file(OE2(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 _e(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=eO(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":Cm0}})}createCleanUrlMiddleware(A){return async(Q,B)=>{let w=Q.req.path;if(w.includes(".")||w==="/"){await B();return}let $=eO(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=eO(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 Lm0}from"fs";import{join as Mm0}from"path";GA();var nCA=G.object({enablePreview:G.boolean().default(!0).describe("Enable the preview site server when preview assets are configured"),previewDistDir:G.string().default("./dist/site-preview").describe("Directory for preview site files"),productionDistDir:G.string().describe("Directory for production site files").default("./dist/site-production"),sharedImagesDir:G.string().default("./dist/images").describe("Shared directory for optimized images"),previewPort:G.number().default(4321).describe("Port for preview server"),productionPort:G.number().describe("Port for production server").default(8080),apiPort:G.number().describe("Port for API route server (plugin HTTP endpoints)").default(3335)});var oCA=`<!DOCTYPE html>
|
|
2289
2289
|
<html lang="en">
|
|
@@ -2352,7 +2352,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2352
2352
|
<p>Once built, this page will be replaced with your actual website.</p>
|
|
2353
2353
|
</div>
|
|
2354
2354
|
</body>
|
|
2355
|
-
</html>`;var Em0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.
|
|
2355
|
+
</html>`;var Em0={name:"@brains/webserver",private:!0,version:"0.2.0-alpha.73",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 ZZ extends aY{serverManager;siteUrl;previewUrl;constructor(A={}){super("webserver",Em0,A,nCA)}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 ke({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&&!Lm0(this.config.previewDistDir))await A(this.config.previewDistDir,{recursive:!0}),await Q(Mm0(this.config.previewDistDir,"index.html"),oCA),this.logger.debug(`Created preview directory at ${this.config.previewDistDir}`);if(!Lm0(this.config.productionDistDir))await A(this.config.productionDistDir,{recursive:!0}),await Q(Mm0(this.config.productionDistDir,"index.html"),oCA),this.logger.debug(`Created production directory at ${this.config.productionDistDir}`)}}$0();GA();var Vm0=G.object({port:G.number().default(3334),organization:G.string().optional(),trustedTokens:G.record(G.string()).optional(),outboundTokens:G.record(G.string()).optional(),requestTimeoutMs:G.number().positive().default(30000),streamIdleTimeoutMs:G.number().positive().default(60000),maxNetworkAttempts:G.number().int().positive().default(2)});$0();function PE2(A,Q){return`${A.name} is ${Q.name}'s ${A.role}. Its purpose is: ${A.purpose}.`}function bm0(A){let{character:Q,profile:B,version:w,domain:$,organization:f,tools:I}=A,H=`${A.baseUrl??($?`https://${$}`:"http://localhost:8080")}/a2a`,Y=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:cl,description:"Anchor (operator) identity for this brain",params:W}];return{name:Q.name,description:PE2(Q,B),url:H,version:w,protocolVersion:"0.2.2",capabilities:{streaming:!0,pushNotifications:!1,extensions:F},skills:Y,defaultInputModes:["text/plain"],defaultOutputModes:["text/plain"],...f&&{provider:{organization:f,url:H}},...A.authEnabled&&{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer"}},security:[{bearerAuth:[]}]}}}$0();var sCA=new Set(["completed","failed","canceled","rejected"]);class aCA{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(sCA.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 Om0=G.array(G.object({kind:G.string(),text:G.string().optional(),data:G.record(G.unknown()).optional()})),_E2=G.object({message:G.object({kind:G.literal("message").optional(),messageId:G.string().optional(),role:G.enum(["user","agent"]).optional(),parts:Om0,contextId:G.string().optional(),taskId:G.string().optional()}),configuration:G.object({historyLength:G.number().optional()}).optional()}),Rm0=G.object({id:G.string(),historyLength:G.number().optional()});function tCA(A,Q){return{jsonrpc:"2.0",id:A,result:Q}}function sX(A,Q,B){return{jsonrpc:"2.0",id:A,error:{code:Q,message:B}}}var Pm0=G.object({jsonrpc:G.string(),id:G.union([G.string(),G.number()]),method:G.string(),params:G.record(G.unknown()).optional()});async function _m0(A,Q){let{id:B,method:w,params:$}=A;switch(w){case"message/send":return kE2(B,$??{},Q);case"tasks/get":return vE2(B,$??{},Q);case"tasks/cancel":return xE2(B,$??{},Q);default:return sX(B,-32601,`Method not found: ${w}`)}}async function kE2(A,Q,B){let w=_E2.safeParse(Q);if(!w.success)return sX(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 sX(A,-32602,"Message must contain at least one text part");let f=$.map((W)=>W.text).join(`
|
|
2356
2356
|
`),I=w.data.message.contextId,D=B.taskManager.createTask(f,I),H=D.task.id;B.taskManager.updateState(H,"working"),jE2(H,f,D.conversationId,B);let Y=B.taskManager.getTask(H);if(!Y)return sX(A,-32603,"Internal error: task disappeared");return tCA(A,Y.task)}function jE2(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 km0=G.object({message:G.object({kind:G.string(),parts:Om0,contextId:G.string().optional()})});function jm0(A,Q,B){let $=Q.parts.filter((Y)=>Y.kind==="text"&&typeof Y.text==="string").map((Y)=>Y.text).join(`
|
|
2357
2357
|
`)||"No message text",f=B.taskManager.createTask($,Q.contextId),I=f.task.id;B.taskManager.updateState(I,"working");let D=new TextEncoder,H=new ReadableStream({start(Y){let W=!1;function F(E){if(W)return;try{Y.enqueue(D.encode(`data: ${JSON.stringify(E)}
|
|
2358
2358
|
|
|
@@ -2360,7 +2360,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2360
2360
|
|
|
2361
2361
|
`);$=I.pop()??"";for(let D of I){let H=D.split(`
|
|
2362
2362
|
`).find((C)=>C.startsWith("data: "));if(!H)continue;let Y;try{Y=JSON.parse(H.slice(6))}catch{return B.cancel().catch(()=>{}),{success:!1,error:"Malformed SSE event from remote agent"}}let W=Y.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((C)=>C.kind==="text"&&typeof C.text==="string").map((C)=>C.text).join(`
|
|
2363
|
-
`)||"No response text";return{success:!0,data:{state:Z,response:E}}}f=await xm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class GT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class FT extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function cE2(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 GT(w))},w)})])}catch(I){if(I instanceof GT)throw I;if($.signal.aborted)throw new GT(w);throw I}finally{if(f)clearTimeout(f)}}async function xm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new FT(Q)),Q)})])}catch(w){if(w instanceof FT)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function pE2(A){if(A instanceof GT||A instanceof FT)return!0;return A instanceof Error}function lE2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof FT)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function ym0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??hE2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??yE2,maxNetworkAttempts:A.maxNetworkAttempts??gE2};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:vm0,visibility:"anchor",handler:async(w)=>{let $=G.object(vm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=TE2(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 H=await A.entityService.getEntity({entityType:"agent",id:D});if(!H)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(H.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,W=await SE2(Y,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let F=W.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return mE2(F,I,Q,K,B)}}}var eCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.72",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 rE2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class AR extends aY{agentCard;taskManager=new aCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",eCA,A,Vm0)}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)=>HI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=bm0({character:Q,profile:B,version:eCA.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(rE2))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 aO;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=Pm0.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=km0.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}=jm0(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 _m0(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[ym0({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")}}}}$0();class AEA{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),H=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:H,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 Ap0=D1(ac0(),1);import{extname as lO2}from"path";var ae=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function dq(A){let Q=lO2(A).toLowerCase();return ae.includes(Q)}function tc0(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 eEA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as iO2,relative as rO2,sep as ec0,join as dO2}from"path";function A4(A,Q){return iO2(Q)?Q:dO2(A,Q)}function DR(A,Q){let B=A4(A,Q),w=rO2(A,B);return ec0==="/"?w:w.split(ec0).join("/")}function nO2(A,Q){if(!DR(Q,A).startsWith("image/"))return!1;return dq(A)}function oO2(A,Q){if(DR(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return nO2(A,Q)}class ALA{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=Ap0.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(!oO2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=DR(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=A4(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 Qp0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return sO2(Q)}function Bp0(A){if(A)A.stop();return}function wp0(A,Q){if(A)A.setCallback(Q)}async function sO2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,H=new AEA(Q,$,f,I,D),Y=new ALA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,F)=>{await H.handleFileChange(W,F)}});return await Y.start(),Y}async function $p0(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:$}}$0();class QLA{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??Z5(),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 BLA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new QLA({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 wLA{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{dirname as QR2,extname as BR2}from"path";import{extname as aO2,join as te}from"path";function ee(A,Q){let w=DR(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]=fp0(D);I=f.join(":")}else I=fp0(f[0]??"");return{entityType:$,id:I}}function Ip0(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?te(A,`${$[0]}${w}`):te(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],H=I.slice(0,-1);if(f)return te(A,...H,`${D}${w}`);return te(A,B,...H,`${D}${w}`)}function Dp0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return eEA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?eEA(B[1]):".md"}function fp0(A){let Q=aO2(A).toLowerCase();return Q===".md"||ae.includes(Q)?A.slice(0,-Q.length):A}ED();import{mkdir as wR2,readFile as QAA,writeFile as Jp0,stat as $R2,utimes as fR2}from"fs/promises";import{join as AAA}from"path";import{mkdir as Hp0,readdir as eO2,stat as AR2}from"fs/promises";import{access as tO2}from"fs/promises";async function w$(A){try{return await tO2(A),!0}catch{return!1}}async function $LA(A,Q){return Up0(A,Q,{includeImages:!1})}async function Yp0(A,Q){return Up0(A,Q,{includeImages:!0})}async function Xp0(A,Q){if(!await w$(A))await Hp0(A,{recursive:!0});for(let B of Q)if(B!=="base")await Hp0(AAA(A,B),{recursive:!0})}async function Wp0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await w$(A))return{files:B,stats:w};let $=await $LA(A,Q);for(let f of $)try{let I=AAA(A,f),D=await AR2(I),{entityType:H}=ee(A,f);B.push({path:f,entityType:H,modified:D.mtime}),w.totalFiles++,w.byEntityType[H]=(w.byEntityType[H]??0)+1}catch{continue}return{files:B,stats:w}}async function Up0(A,Q,B){let w=[];if(!await w$(A))return w;let $=async(f,I="",D=!1)=>{let H=await eO2(f,{withFileTypes:!0});for(let Y of H){let W=I?AAA(I,Y.name):Y.name;if(Y.isFile()&&!Y.name.endsWith(".invalid")){if(Y.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&dq(Y.name))w.push(W)}else if(Y.isDirectory()&&!Y.name.startsWith(".")){if(I===""&&!Q.hasEntityType(Y.name))continue;let F=AAA(f,Y.name),K=Y.name==="image"&&I==="";await $(F,W,D||K)}}};return await $(A),w}class fLA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ee(this.syncPath,A)}async readEntity(A){let Q=A4(this.syncPath,A),B=await $R2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D;if(dq(A)){let Y=(await QAA(Q)).toString("base64"),W=BR2(A);D=`data:${tc0(W)};base64,${Y}`}else D=await QAA(Q,"utf-8");return{entityType:w,id:$,content:D,created:f,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let f=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=f?.[1]?Buffer.from(f[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await w$(Q)){let f=B?await QAA(Q):await QAA(Q,"utf-8"),I=hB(B?f.toString("base64"):f),D=hB(B?w.toString("base64"):w);if(I===D)return}if(A.entityType!=="base")await wR2(QR2(Q),{recursive:!0});if(B)await Jp0(Q,w);else await Jp0(Q,w,"utf-8");let $=new Date(A.updated);await fR2(Q,$,$)}getFilePath(A,Q,B=".md"){return Ip0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,Dp0(A))}async getAllMarkdownFiles(){return $LA(this.syncPath,this.entityService)}async getAllSyncFiles(){return Yp0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await Xp0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=hB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return Wp0(this.syncPath,this.entityService)}async syncDirectoryExists(){return w$(this.syncPath)}async fileExists(A){return w$(A)}}Bf();GA();Bf();async function BAA(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}=uF(I),H=oN(D),Y=cF(D);if(!H||!Y)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:H,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Gp0=G.object({title:G.string(),slug:G.string().optional(),coverImageUrl:G.string().url(),coverImageId:G.string().optional(),coverImageAlt:G.string().optional()});class ILA{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=JF(A)}catch{return null}let{frontmatter:B}=Q,w=Gp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??U2($),customAlt:D}}async convert(A){let Q;try{Q=JF(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Gp0.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(!JU(I))return{content:A,converted:!1};let H={postTitle:$,postSlug:f??U2($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(H),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=Y,{content:$N(W,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:y0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return BAA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}Bf();GA();class PT{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=BXA(A);for(let $ of w){if(!JU($.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++),H=``;w=w.replace(I.originalMarkdown,H),$++,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:y0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return BAA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class DLA{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 H=f.slice(D,D+B),Y=await w(H);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.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 IR2,appendFile as DR2,readFile as HR2,writeFile as YR2,access as XR2}from"fs/promises";import{join as Fp0}from"path";class HLA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof G.ZodError)return!0;let Q=y0(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 IR2($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=Fp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),H=y0(Q),Y=`${D} - ${A}: ${H}
|
|
2363
|
+
`)||"No response text";return{success:!0,data:{state:Z,response:E}}}f=await xm0(B,Q)}return{success:!1,error:"Stream ended without a terminal event"}}class GT extends Error{timeoutMs;constructor(A){super(`request timed out after ${A}ms`);this.timeoutMs=A;this.name="A2ARequestTimeoutError"}}class FT extends Error{timeoutMs;constructor(A){super(`A2A stream stalled waiting for final event after ${A}ms`);this.timeoutMs=A;this.name="A2AStreamIdleTimeoutError"}}async function cE2(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 GT(w))},w)})])}catch(I){if(I instanceof GT)throw I;if($.signal.aborted)throw new GT(w);throw I}finally{if(f)clearTimeout(f)}}async function xm0(A,Q){let B;try{return await Promise.race([A.read(),new Promise((w,$)=>{B=setTimeout(()=>$(new FT(Q)),Q)})])}catch(w){if(w instanceof FT)A.cancel().catch(()=>{});throw w}finally{if(B)clearTimeout(B)}}function pE2(A){if(A instanceof GT||A instanceof FT)return!0;return A instanceof Error}function lE2(A,Q){let B=Q>1?` after ${Q} attempts`:"";if(A instanceof FT)return`${A.message}${B}`;let w=A instanceof Error?A.message:"Unknown network error";return`Failed to reach remote agent${B}: ${w}`}function ym0(A={}){let Q=A.fetch??globalThis.fetch,B={requestTimeoutMs:A.requestTimeoutMs??hE2,streamIdleTimeoutMs:A.streamIdleTimeoutMs??yE2,maxNetworkAttempts:A.maxNetworkAttempts??gE2};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:vm0,visibility:"anchor",handler:async(w)=>{let $=G.object(vm0).safeParse(w);if(!$.success)return{success:!1,error:`Invalid input: ${$.error.message}`};let{agent:f,message:I}=$.data,D=TE2(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 H=await A.entityService.getEntity({entityType:"agent",id:D});if(!H)return{success:!1,error:`Agent ${D} is not in your directory. Add it first.`};if(H.metadata.status!=="approved")return{success:!1,error:`Agent ${D} is discovered but not approved yet. Approve it first.`};let Y=`https://${D}`,W=await SE2(Y,Q);if(!W)return{success:!1,error:`Could not fetch Agent Card from ${Y}`};let F=W.url,K;if(A.outboundTokens)try{let Z=new URL(F).hostname;K=A.outboundTokens[Z]}catch{}return mE2(F,I,Q,K,B)}}}var eCA={name:"@brains/a2a",private:!0,version:"0.2.0-alpha.73",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 rE2={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","X-Content-Type-Options":"nosniff"};class AR extends aY{agentCard;taskManager=new aCA;agentService;permissionContext;app;hasWebserver=!1;constructor(A={}){super("a2a",eCA,A,Vm0)}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)=>HI.safeParse(D.metadata)).filter((D)=>D.success).map((D)=>D.data)}catch{}this.agentCard=bm0({character:Q,profile:B,version:eCA.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(rE2))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 aO;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=Pm0.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=km0.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}=jm0(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 _m0(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[ym0({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")}}}}$0();class AEA{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),H=await B({type:"directory-delete",data:{entityId:D,entityType:I,filePath:f}});this.logger.info("Queued delete job for removed file",{jobId:H,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 Ap0=D1(ac0(),1);import{extname as lO2}from"path";var ae=[".png",".jpg",".jpeg",".webp",".gif",".svg"];function dq(A){let Q=lO2(A).toLowerCase();return ae.includes(Q)}function tc0(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 eEA(A){switch(A.toLowerCase()){case"jpeg":return".jpg";case"svg+xml":return".svg";default:return`.${A.toLowerCase()}`}}import{isAbsolute as iO2,relative as rO2,sep as ec0,join as dO2}from"path";function A4(A,Q){return iO2(Q)?Q:dO2(A,Q)}function DR(A,Q){let B=A4(A,Q),w=rO2(A,B);return ec0==="/"?w:w.split(ec0).join("/")}function nO2(A,Q){if(!DR(Q,A).startsWith("image/"))return!1;return dq(A)}function oO2(A,Q){if(DR(Q,A).split("/")[0]?.startsWith("_"))return!1;if(A.endsWith(".md"))return!0;return nO2(A,Q)}class ALA{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=Ap0.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(!oO2(Q,this.syncPath))return;this.logger.debug("File change detected",{event:A,path:Q});let B=DR(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=A4(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 Qp0(A,Q){if(A?.isWatching())return Q.logger.debug("Already watching directory"),A;return sO2(Q)}function Bp0(A){if(A)A.stop();return}function wp0(A,Q){if(A)A.setCallback(Q)}async function sO2(A){let{logger:Q,syncPath:B,watchInterval:w,importEntities:$,jobQueueCallback:f,fileOperations:I,deleteOnFileRemoval:D}=A,H=new AEA(Q,$,f,I,D),Y=new ALA({syncPath:B,watchInterval:w,logger:Q,onFileChange:async(W,F)=>{await H.handleFileChange(W,F)}});return await Y.start(),Y}async function $p0(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:$}}$0();class QLA{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??Z5(),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 BLA{syncInProgress=!1;logger;fileOperations;batchOperationsManager;constructor(A){this.logger=A.logger,this.fileOperations=A.fileOperations,this.batchOperationsManager=new QLA({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 wLA{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{dirname as QR2,extname as BR2}from"path";import{extname as aO2,join as te}from"path";function ee(A,Q){let w=DR(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]=fp0(D);I=f.join(":")}else I=fp0(f[0]??"");return{entityType:$,id:I}}function Ip0(A,Q,B,w=".md"){let $=Q.split(":").filter((Y)=>Y.length>0),f=B==="base";if($.length===1)return f?te(A,`${$[0]}${w}`):te(A,B,`${$[0]}${w}`);let I=$;if($[0]===B)I=$.slice(1);let D=I[I.length-1],H=I.slice(0,-1);if(f)return te(A,...H,`${D}${w}`);return te(A,B,...H,`${D}${w}`)}function Dp0(A){if(A.entityType!=="image")return".md";let Q=A.metadata.format;if(Q)return eEA(Q);let B=A.content.match(/^data:image\/([a-z+]+);base64,/i);return B?.[1]?eEA(B[1]):".md"}function fp0(A){let Q=aO2(A).toLowerCase();return Q===".md"||ae.includes(Q)?A.slice(0,-Q.length):A}ED();import{mkdir as wR2,readFile as QAA,writeFile as Jp0,stat as $R2,utimes as fR2}from"fs/promises";import{join as AAA}from"path";import{mkdir as Hp0,readdir as eO2,stat as AR2}from"fs/promises";import{access as tO2}from"fs/promises";async function w$(A){try{return await tO2(A),!0}catch{return!1}}async function $LA(A,Q){return Up0(A,Q,{includeImages:!1})}async function Yp0(A,Q){return Up0(A,Q,{includeImages:!0})}async function Xp0(A,Q){if(!await w$(A))await Hp0(A,{recursive:!0});for(let B of Q)if(B!=="base")await Hp0(AAA(A,B),{recursive:!0})}async function Wp0(A,Q){let B=[],w={totalFiles:0,byEntityType:{}};if(!await w$(A))return{files:B,stats:w};let $=await $LA(A,Q);for(let f of $)try{let I=AAA(A,f),D=await AR2(I),{entityType:H}=ee(A,f);B.push({path:f,entityType:H,modified:D.mtime}),w.totalFiles++,w.byEntityType[H]=(w.byEntityType[H]??0)+1}catch{continue}return{files:B,stats:w}}async function Up0(A,Q,B){let w=[];if(!await w$(A))return w;let $=async(f,I="",D=!1)=>{let H=await eO2(f,{withFileTypes:!0});for(let Y of H){let W=I?AAA(I,Y.name):Y.name;if(Y.isFile()&&!Y.name.endsWith(".invalid")){if(Y.name.endsWith(".md"))w.push(W);else if(B.includeImages&&D&&dq(Y.name))w.push(W)}else if(Y.isDirectory()&&!Y.name.startsWith(".")){if(I===""&&!Q.hasEntityType(Y.name))continue;let F=AAA(f,Y.name),K=Y.name==="image"&&I==="";await $(F,W,D||K)}}};return await $(A),w}class fLA{syncPath;entityService;constructor(A,Q){this.syncPath=A,this.entityService=Q}parseEntityFromPath(A){return ee(this.syncPath,A)}async readEntity(A){let Q=A4(this.syncPath,A),B=await $R2(Q),{entityType:w,id:$}=this.parseEntityFromPath(A),f=B.birthtime.getTime()>0?B.birthtime:B.mtime,I=B.mtime,D;if(dq(A)){let Y=(await QAA(Q)).toString("base64"),W=BR2(A);D=`data:${tc0(W)};base64,${Y}`}else D=await QAA(Q,"utf-8");return{entityType:w,id:$,content:D,created:f,updated:I}}async writeEntity(A){let Q=this.getEntityFilePath(A),B=A.entityType==="image",w;if(B){let f=A.content.match(/^data:image\/[a-z+]+;base64,(.+)$/i);w=f?.[1]?Buffer.from(f[1],"base64"):Buffer.from(A.content,"base64")}else w=this.entityService.serializeEntity(A);if(await w$(Q)){let f=B?await QAA(Q):await QAA(Q,"utf-8"),I=hB(B?f.toString("base64"):f),D=hB(B?w.toString("base64"):w);if(I===D)return}if(A.entityType!=="base")await wR2(QR2(Q),{recursive:!0});if(B)await Jp0(Q,w);else await Jp0(Q,w,"utf-8");let $=new Date(A.updated);await fR2(Q,$,$)}getFilePath(A,Q,B=".md"){return Ip0(this.syncPath,A,Q,B)}getEntityFilePath(A){return this.getFilePath(A.id,A.entityType,Dp0(A))}async getAllMarkdownFiles(){return $LA(this.syncPath,this.entityService)}async getAllSyncFiles(){return Yp0(this.syncPath,this.entityService)}async ensureDirectoryStructure(A){await Xp0(this.syncPath,A)}shouldUpdateEntity(A,Q){let B=hB(Q.content);return A.contentHash!==B}async gatherFileStatus(){return Wp0(this.syncPath,this.entityService)}async syncDirectoryExists(){return w$(this.syncPath)}async fileExists(A){return w$(A)}}Bf();GA();Bf();async function BAA(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}=uF(I),H=oN(D),Y=cF(D);if(!H||!Y)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:H,width:Y.width,height:Y.height,sourceUrl:$}}});return w.debug("Created image entity from URL",{sourceUrl:$,imageId:W.entityId}),W.entityId}var Gp0=G.object({title:G.string(),slug:G.string().optional(),coverImageUrl:G.string().url(),coverImageId:G.string().optional(),coverImageAlt:G.string().optional()});class ILA{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("FrontmatterImageConverter")}detectCoverImageUrl(A){let Q;try{Q=JF(A)}catch{return null}let{frontmatter:B}=Q,w=Gp0.safeParse(B);if(!w.success)return null;if(w.data.coverImageId)return null;let{title:$,slug:f,coverImageUrl:I,coverImageAlt:D}=w.data;if(!JU(I))return null;return{sourceUrl:I,postTitle:$,postSlug:f??U2($),customAlt:D}}async convert(A){let Q;try{Q=JF(A)}catch(Y){return this.logger.debug("Parse failed",{error:Y}),{content:A,converted:!1}}let{frontmatter:B}=Q,w=Gp0.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(!JU(I))return{content:A,converted:!1};let H={postTitle:$,postSlug:f??U2($),sourceUrl:I,customAlt:D};try{let Y=await this.createImageEntity(H),W={...B};return delete W.coverImageUrl,delete W.coverImageAlt,W.coverImageId=Y,{content:$N(W,Q.content),converted:!0,imageId:Y}}catch(Y){return this.logger.warn("Failed to convert coverImageUrl",{url:I,error:y0(Y)}),{content:A,converted:!1}}}async createImageEntity(A){let{postTitle:Q,postSlug:B,sourceUrl:w,customAlt:$}=A,f=`Cover image for ${Q}`;return BAA({id:`${B}-cover`,title:f,alt:$??f,sourceUrl:w},this.entityService,this.fetcher,this.logger)}}Bf();GA();class PT{entityService;fetcher;logger;constructor(A,Q,B=WH){this.entityService=A;this.fetcher=B;this.logger=Q.child("MarkdownImageConverter")}detectInlineImages(A,Q){let B=[],w=BXA(A);for(let $ of w){if(!JU($.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++),H=``;w=w.replace(I.originalMarkdown,H),$++,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:y0(D)})}return{content:w,converted:$>0,convertedCount:$}}async createImageEntity(A,Q){let{sourceUrl:B,alt:w,postSlug:$}=A;return BAA({id:`${$}-inline-${Q}`,title:w||`Inline image ${Q+1} for ${$}`,alt:w||"",sourceUrl:B},this.entityService,this.fetcher,this.logger)}}class DLA{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 H=f.slice(D,D+B),Y=await w(H);$.imported+=Y.imported,$.skipped+=Y.skipped,$.failed+=Y.failed,$.quarantined+=Y.quarantined,$.errors.push(...Y.errors),$.quarantinedFiles.push(...Y.quarantinedFiles),$.jobIds.push(...Y.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 IR2,appendFile as DR2,readFile as HR2,writeFile as YR2,access as XR2}from"fs/promises";import{join as Fp0}from"path";class HLA{logger;syncPath;constructor(A,Q){this.logger=A;this.syncPath=Q}isValidationError(A){if(A instanceof G.ZodError)return!0;let Q=y0(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 IR2($,f),B.quarantined++,B.quarantinedFiles.push(A);let I=Fp0(this.syncPath,".import-errors.log"),D=new Date().toISOString(),H=y0(Q),Y=`${D} - ${A}: ${H}
|
|
2364
2364
|
\u2192 ${A}.invalid
|
|
2365
2365
|
|
|
2366
2366
|
`;await DR2(I,Y),this.logger.warn("Quarantined invalid entity file",{originalPath:A,quarantinePath:`${A}.invalid`,error:H})}catch(I){this.logger.error("Failed to quarantine invalid file",{path:A,error:I}),B.failed++,B.errors.push({path:A,error:"Failed to quarantine invalid file"})}}async markAsRecoveredIfNeeded(A){let Q=Fp0(this.syncPath,".import-errors.log");try{await XR2(Q)}catch{return}try{let B=await HR2(Q,"utf-8");if(B.includes(A)){let $=`${new Date().toISOString()} - [RECOVERED] ${A}
|
|
@@ -2387,7 +2387,7 @@ ${R}`)}if(w!==void 0&&f?.algorithms!==void 0){let C=f.algorithms.map((R)=>R.alg)
|
|
|
2387
2387
|
*...and ${A.files.length-10} more files*`)}if(A.exists&&A.stats.totalFiles===0)Q.push(`
|
|
2388
2388
|
## Getting Started
|
|
2389
2389
|
`),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(`
|
|
2390
|
-
`)}}$0();class PAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:DMA,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}}}$0();class _AA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:IMA,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}}}$0();class kAA extends ow{directorySync;context;constructor(A,Q,B){super(A,{schema:fMA,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 H=$==="export"?10:60;await B.report({progress:H,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 H=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let Y=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}$0();class jAA extends ow{context;constructor(A,Q,B){super(A,{schema:OAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=OAA.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}}}$0();GA();var fj2=G.object({});class vAA extends ow{directorySync;constructor(A,Q){super(A,{schema:fj2,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}}$0();Bf();GA();E$();Bf();import{readFile as Ij2,writeFile as Dj2}from"fs/promises";var Hj2=HMA;class xAA extends ow{context;fetcher;constructor(A,Q,B=WH){super(Q,{schema:Hj2,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:vQ.INIT,message:`Reading file: ${w}`});let H;try{H=await Ij2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:y0(E)}),C$.failure(E)}let Y;try{Y=JF(H)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(E)}),C$.failure(E)}let W=Y.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:vQ.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:vQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:vQ.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(r)}),C$.failure(r)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let{base64:C}=uF(E),R=oN(C),k=cF(C);if(!R||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),C$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let P=`Cover image for ${f}`,o=D??P;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:E,metadata:{title:P,alt:o,format:R,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:vQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=$N(Z,Y.content);try{await Dj2(w,q,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:y0(E)}),C$.failure(E)}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}$0();Bf();GA();E$();import{readFile as Yj2,writeFile as Xj2}from"fs/promises";class hAA extends ow{converter;constructor(A,Q,B=WH){super(Q,{schema:YMA,jobTypeName:"inline-image-convert"});this.converter=new PT(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:vQ.INIT,message:`Reading file: ${w}`});let f;try{f=await Yj2(w,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:vQ.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:vQ.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:vQ.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:vQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:vQ.SAVE,message:"Writing updated file"});try{await Xj2(w,D.content,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:vQ.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=y0(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 rr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new kAA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new PAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new _AA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new jAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new vAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new xAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new hAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}$0();import{unlink as Wj2,access as Uj2}from"fs/promises";function dr0(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(H){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:H}=I.payload;try{let Y=await f.getEntity({entityType:D,id:H});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:H}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:H,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:H}=I.payload,Y=Q.fileOps.getFilePath(D,H);if(await Uj2(Y).then(()=>!0,()=>!1))await Wj2(Y),B.debug("Auto-deleted entity file",{id:D,entityType:H,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function nr0(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:Z5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();$0();import{readdir as ar0,mkdir as Gj2,copyFile as Fj2}from"fs/promises";import{join as sr0,resolve as XMA}from"path";import{join as Jj2}from"path";async function or0(A){if(!await w$(Jj2(A,".git")))return!1;try{return await gJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function Kj2(A,Q){if(!await w$(A))return!0;if((await ar0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await or0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function tr0(A,Q){let B=await ar0(A,{withFileTypes:!0});for(let w of B){let $=sr0(A,w.name),f=sr0(Q,w.name);if(w.isDirectory()){if(!await w$(f))await Gj2(f,{recursive:!0});await tr0($,f)}else await Fj2($,f)}}async function er0(A,Q,B){let w=XMA(process.cwd(),A);B=B?XMA(B):XMA(process.cwd(),"seed-content");let $=await Kj2(w,Q);if($&&await w$(B))Q.debug("Copying seed content to brain-data directory"),await tr0(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 Ad0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let H=B.syncPath??A.dataDir;await er0(H,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let H=await D.sync();w.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){w.error("Initial sync failed",H),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!1,error:y0(H)},...{broadcast:!0}})}};A.messaging.subscribe(CN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function Qd0(A,Q,B,w){let $=new UN(()=>{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 H=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(H)}return()=>{$.dispose();for(let D of I)D()}}function Bd0(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:Y,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(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},H=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(H)}}import{spawnSync as $d0}from"child_process";import{cpSync as Zj2,existsSync as wd0,mkdirSync as Nj2,mkdtempSync as zj2,rmSync as qj2}from"fs";import{tmpdir as Cj2}from"os";import{fileURLToPath as Ej2}from"url";import{join as Lj2,resolve as Mj2}from"path";function qZ(A,Q){let B=$d0("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 Vj2(A){return A.startsWith("file://")}function bj2(A){return Ej2(A)}function Oj2(A,Q){return $d0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function fd0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!Vj2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=bj2(A.gitUrl),w=Mj2(A.seedContentPath);if(!wd0(w))throw Error(`Seed content path not found: ${w}`);if(!wd0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),Nj2(B,{recursive:!0}),qZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(Oj2(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 $=zj2(Lj2(Cj2(),"directory-sync-seed-"));try{qZ($,["init",`--initial-branch=${Q}`]),qZ($,["config","user.name",A.authorName??"Brain"]),qZ($,["config","user.email",A.authorEmail??"brain@localhost"]),Zj2(w,$,{recursive:!0}),qZ($,["add","."]),qZ($,["commit","-m","seed content remote"]),qZ($,["remote","add","origin",A.gitUrl]),qZ($,["push","-u","origin",Q])}finally{qj2($,{recursive:!0,force:!0})}}function Id0(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(),H=I.payload.paths,Y=await D.importEntities(H);if(H&&H.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}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")}$0();GA();$0();GA();function Dd0(A,Q){return xQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",G.object({entityType:G.string().describe("Entity type (e.g. post, note, link)"),id:G.string().describe("Entity ID"),sha:G.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:G.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 _8({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 _8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return L$($ instanceof Error?$.message:"History lookup failed")}})}function Hd0(A,Q,B,w){let $=[xQ(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.",G.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,H={interfaceType:I.interfaceType,channelId:I.channelId},Y=w!==void 0,W=()=>A.queueSyncBatch(Q,D,H),F=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!F)return _8({gitPulled:Y},"No files to sync");return _8({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:Y},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${Y?" (pulled from git)":""}`)}catch(D){return L$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),xQ(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.",G.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 _8(I)}catch(f){return L$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Dd0(B,w));return $}var Yd0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.72",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 WMA extends RB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",Yd0,A,uT)}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:cT,basePrompt:"",formatter:new RAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new _T({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(dr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)nr0(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 fd0({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 $MA({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(Qd0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(Bd0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)Ad0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Id0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return Hd0(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 _T({...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){rr0(A,this.requireDirectorySync(),this.logger)}}function aq(A={}){return new WMA(A)}$0();GA();var Xd0={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.72",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 _j2=G.object({apiKey:G.string().min(1).optional(),from:G.string().min(1).optional()});class Wd0 extends RB{fetchImpl;constructor(A={},Q={}){super("email-resend",Xd0,A,_j2);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(Fs,async(B)=>{let w=iY0.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 Ud0(A={}){return new Wd0(A)}$0();import{render as YB1}from"preact-render-to-string";import{h as PC}from"preact";function Jd0(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=Jd0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function JR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=Jd0(A))&&(w&&(w+=" "),w+=Q);return w}var kj2=(A)=>{let Q=vj2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return Nd0(D,Q)||jj2(I)},getConflictingClassGroupIds:(I,D)=>{let H=B[I]||[];if(D&&w[I])return[...H,...w[I]];return H}}},Nd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?Nd0(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},Gd0=/^\[(.+)\]$/,jj2=(A)=>{if(Gd0.test(A)){let Q=Gd0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},vj2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return hj2(Object.entries(A.classGroups),B).forEach(([f,I])=>{JMA(I,w,f,Q)}),w},JMA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:Fd0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(xj2($)){JMA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{JMA(I,Fd0(Q,f),B,w)})})},Fd0=(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},xj2=(A)=>A.isThemeGetter,hj2=(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,$]})},yj2=(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 gj2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let H=[],Y=0,W=0,F;for(let C=0;C<D.length;C++){let R=D[C];if(Y===0){if(R===$&&(w||D.slice(C,C+f)===Q)){H.push(D.slice(W,C)),W=C+f;continue}if(R==="/"){F=C;continue}}if(R==="[")Y++;else if(R==="]")Y--}let K=H.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:H,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:E}};if(B)return(D)=>B({className:D,parseClassName:I});return I},Tj2=(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},Sj2=(A)=>({cache:yj2(A.cacheSize),parseClassName:gj2(A),...kj2(A)}),mj2=/\s+/,uj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(mj2),D="";for(let H=I.length-1;H>=0;H-=1){let Y=I[H],{modifiers:W,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(Y),q=Boolean(Z),E=w(q?K.substring(0,Z):K);if(!E){if(!q){D=Y+(D.length>0?" "+D:D);continue}if(E=w(K),!E){D=Y+(D.length>0?" "+D:D);continue}q=!1}let C=Tj2(W).join(":"),R=F?C+"!":C,k=R+E;if(f.includes(k))continue;f.push(k);let P=$(E,q);for(let o=0;o<P.length;++o){let r=P[o];f.push(R+r)}D=Y+(D.length>0?" "+D:D)}return D};function cj2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=zd0(Q))w&&(w+=" "),w+=B}return w}var zd0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=zd0(A[w]))B&&(B+=" "),B+=Q}return B};function Kd0(A,...Q){let B,w,$,f=I;function I(H){let Y=Q.reduce((W,F)=>F(W),A());return B=Sj2(Y),w=B.cache.get,$=B.cache.set,f=D,D(H)}function D(H){let Y=w(H);if(Y)return Y;let W=uj2(H,B);return $(H,W),W}return function(){return f(cj2.apply(null,arguments))}}var B8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},qd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,pj2=/^\d+\/\d+$/,lj2=new Set(["px","full","screen"]),ij2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,rj2=/\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$/,dj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,nj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,oj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,TJ=(A)=>GR(A)||lj2.has(A)||pj2.test(A),CZ=(A)=>FR(A,"length",wv2),GR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),UMA=(A)=>FR(A,"number",GR),pT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),sj2=(A)=>A.endsWith("%")&&GR(A.slice(0,-1)),_Q=(A)=>qd0.test(A),EZ=(A)=>ij2.test(A),aj2=new Set(["length","size","percentage"]),tj2=(A)=>FR(A,aj2,Cd0),ej2=(A)=>FR(A,"position",Cd0),Av2=new Set(["image","url"]),Qv2=(A)=>FR(A,Av2,fv2),Bv2=(A)=>FR(A,"",$v2),lT=()=>!0,FR=(A,Q,B)=>{let w=qd0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},wv2=(A)=>rj2.test(A)&&!dj2.test(A),Cd0=()=>!1,$v2=(A)=>nj2.test(A),fv2=(A)=>oj2.test(A);var Zd0=()=>{let A=B8("colors"),Q=B8("spacing"),B=B8("blur"),w=B8("brightness"),$=B8("borderColor"),f=B8("borderRadius"),I=B8("borderSpacing"),D=B8("borderWidth"),H=B8("contrast"),Y=B8("grayscale"),W=B8("hueRotate"),F=B8("invert"),K=B8("gap"),Z=B8("gradientColorStops"),q=B8("gradientColorStopPositions"),E=B8("inset"),C=B8("margin"),R=B8("opacity"),k=B8("padding"),P=B8("saturate"),o=B8("scale"),r=B8("sepia"),S=B8("skew"),x=B8("space"),y=B8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",_Q,Q],JA=()=>[_Q,Q],HA=()=>["",TJ,CZ],_=()=>["auto",GR,_Q],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],t=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],d=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",_Q],n=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[GR,_Q];return{cacheSize:500,separator:":",theme:{colors:[lT],spacing:[TJ,CZ],blur:["none","",EZ,_Q],brightness:UA(),borderColor:[A],borderRadius:["none","","full",EZ,_Q],borderSpacing:JA(),borderWidth:HA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:JA(),gradientColorStops:[A],gradientColorStopPositions:[sj2,CZ],inset:c(),margin:c(),opacity:UA(),padding:JA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:JA(),translate:JA()},classGroups:{aspect:[{aspect:["auto","square","video",_Q]}],container:["container"],columns:[{columns:[EZ]}],"break-after":[{"break-after":n()}],"break-before":[{"break-before":n()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...O(),_Q]}],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",pT,_Q]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",_Q]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",pT,_Q]}],"grid-cols":[{"grid-cols":[lT]}],"col-start-end":[{col:["auto",{span:["full",pT,_Q]},_Q]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[lT]}],"row-start-end":[{row:["auto",{span:[pT,_Q]},_Q]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",_Q]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",_Q]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...d()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...d(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...d(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[k]}],px:[{px:[k]}],py:[{py:[k]}],ps:[{ps:[k]}],pe:[{pe:[k]}],pt:[{pt:[k]}],pr:[{pr:[k]}],pb:[{pb:[k]}],pl:[{pl:[k]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",_Q,Q]}],"min-w":[{"min-w":[_Q,Q,"min","max","fit"]}],"max-w":[{"max-w":[_Q,Q,"none","full","min","max","fit","prose",{screen:[EZ]},EZ]}],h:[{h:[_Q,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[_Q,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",EZ,CZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",UMA]}],"font-family":[{font:[lT]}],"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",_Q]}],"line-clamp":[{"line-clamp":["none",GR,UMA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",TJ,_Q]}],"list-image":[{"list-image":["none",_Q]}],"list-style-type":[{list:["none","disc","decimal",_Q]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",TJ,CZ]}],"underline-offset":[{"underline-offset":["auto",TJ,_Q]}],"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:JA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_Q]}],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",_Q]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),ej2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",tj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Qv2]}],"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":[R]}],"border-style":[{border:[...j(),"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":[R]}],"divide-style":[{divide:j()}],"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:["",...j()]}],"outline-offset":[{"outline-offset":[TJ,_Q]}],"outline-w":[{outline:[TJ,CZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:HA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[TJ,CZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",EZ,Bv2]}],"shadow-color":[{shadow:[lT]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...t(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":t()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[H]}],"drop-shadow":[{"drop-shadow":["","none",EZ,_Q]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[F]}],saturate:[{saturate:[P]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[H]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[P]}],"backdrop-sepia":[{"backdrop-sepia":[r]}],"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",_Q]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",_Q]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",_Q]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[pT,_Q]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",_Q]}],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",_Q]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":JA()}],"scroll-mx":[{"scroll-mx":JA()}],"scroll-my":[{"scroll-my":JA()}],"scroll-ms":[{"scroll-ms":JA()}],"scroll-me":[{"scroll-me":JA()}],"scroll-mt":[{"scroll-mt":JA()}],"scroll-mr":[{"scroll-mr":JA()}],"scroll-mb":[{"scroll-mb":JA()}],"scroll-ml":[{"scroll-ml":JA()}],"scroll-p":[{"scroll-p":JA()}],"scroll-px":[{"scroll-px":JA()}],"scroll-py":[{"scroll-py":JA()}],"scroll-ps":[{"scroll-ps":JA()}],"scroll-pe":[{"scroll-pe":JA()}],"scroll-pt":[{"scroll-pt":JA()}],"scroll-pr":[{"scroll-pr":JA()}],"scroll-pb":[{"scroll-pb":JA()}],"scroll-pl":[{"scroll-pl":JA()}],"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",_Q]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[TJ,CZ,UMA]}],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"]}}},Iv2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{iT(A,"cacheSize",Q),iT(A,"prefix",B),iT(A,"separator",w),iT(A,"experimentalParseClassName",$);for(let D in I)Dv2(A[D],I[D]);for(let D in f)Hv2(A[D],f[D]);return A},iT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Dv2=(A,Q)=>{if(Q)for(let B in Q)iT(A,B,Q[B])},Hv2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},yAA=(A,...Q)=>typeof A==="function"?Kd0(Zd0,A,...Q):Kd0(()=>Iv2(Zd0(),A),...Q);var Yv2=yAA({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 s1(...A){return Yv2(JR(A))}var Ed0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,Ld0=JR,Zw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return Ld0(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((Y)=>{let W=B===null||B===void 0?void 0:B[Y],F=f===null||f===void 0?void 0:f[Y];if(W===null)return null;let K=Ed0(W)||Ed0(F);return $[Y][K]}),D=B&&Object.entries(B).reduce((Y,W)=>{let[F,K]=W;if(K===void 0)return Y;return Y[F]=K,Y},{}),H=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,W)=>{let{class:F,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[E,C]=q;return Array.isArray(C)?C.includes({...f,...D}[E]):{...f,...D}[E]===C})?[...Y,F,K]:Y},[]);return Ld0(A,I,H,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as GMA}from"preact/jsx-dev-runtime";var Md0=Zw("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 FMA({variant:A,title:Q,children:B,className:w}){return GMA("div",{className:s1(Md0({variant:A}),w),role:"alert",children:[Q&&GMA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),GMA("div",{className:s1(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 Xv2}from"preact/jsx-dev-runtime";var Vd0=Zw("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 tq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return Xv2("button",{type:f,className:s1(Vd0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as Wv2}from"preact/jsx-dev-runtime";var bd0=Zw("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 b5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return Wv2("a",{href:A,className:s1(bd0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as gAA}from"preact/jsx-dev-runtime";var Od0=Zw("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"}}),Uv2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function KR({variant:A,size:Q,className:B}){let w=Uv2[Q??"md"];return gAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Od0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:gAA("svg",{className:s1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[gAA("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),gAA("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 KMA}from"preact/jsx-dev-runtime";var Rd0=Zw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function TAA({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 KMA("ul",{className:s1(Rd0({orientation:w}),Q),children:[f.map((I)=>KMA("li",{children:KMA("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 ErB}from"preact/jsx-dev-runtime";import{jsxDEV as VrB}from"preact/jsx-dev-runtime";import{createContext as Gv2,h as Fv2}from"preact";import{useContext as Kv2}from"preact/hooks";BUA();var Jv2=new _x({gfm:!0,breaks:!0});function ZMA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new _x({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):Jv2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2390
|
+
`)}}$0();class PAA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:DMA,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}}}$0();class _AA extends ow{directorySync;constructor(A,Q,B){super(A,{schema:IMA,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}}}$0();class kAA extends ow{directorySync;context;constructor(A,Q,B){super(A,{schema:fMA,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 H=$==="export"?10:60;await B.report({progress:H,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 H=(await Promise.all(A.map((W)=>B.getAsyncJobStatus(W)))).filter((W)=>W&&(W.status==="completed"||W.status==="failed")).length;if(H===A.length){this.logger.debug("All import jobs completed");return}if(Date.now()-f>w){this.logger.warn(`Timeout waiting for import jobs (${H}/${A.length} completed)`);return}let Y=Math.round(H/A.length*100);return await Q.report({progress:50+Math.round(Y*0.05),message:`Processing ${H}/${A.length} entities`}),await new Promise((W)=>setTimeout(W,$)),I()};return I()}summarizeDataForLog(A){return{operation:A.operation,syncDirection:A.syncDirection}}}$0();class jAA extends ow{context;constructor(A,Q,B){super(A,{schema:OAA,jobTypeName:"directory-delete"});this.context=Q}async process(A,Q,B){let w=OAA.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}}}$0();GA();var fj2=G.object({});class vAA extends ow{directorySync;constructor(A,Q){super(A,{schema:fj2,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}}$0();Bf();GA();E$();Bf();import{readFile as Ij2,writeFile as Dj2}from"fs/promises";var Hj2=HMA;class xAA extends ow{context;fetcher;constructor(A,Q,B=WH){super(Q,{schema:Hj2,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:vQ.INIT,message:`Reading file: ${w}`});let H;try{H=await Ij2(w,"utf-8")}catch(E){return this.logger.error("Failed to read file",{filePath:w,error:y0(E)}),C$.failure(E)}let Y;try{Y=JF(H)}catch(E){return this.logger.warn("Failed to parse markdown",{filePath:w,error:y0(E)}),C$.failure(E)}let W=Y.frontmatter;if(W.coverImageId)return this.logger.debug("File already has coverImageId, skipping",{filePath:w}),await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Already converted"}),{success:!0,skipped:!0};await this.reportProgress(B,{progress:vQ.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:vQ.EXTRACT,message:`Reusing existing image: ${K}`});else{await this.reportProgress(B,{progress:vQ.PROCESS,message:`Fetching image from ${$}`});let E;try{E=await this.fetcher($)}catch(r){return this.logger.error("Failed to fetch image",{sourceUrl:$,error:y0(r)}),C$.failure(r)}await this.reportProgress(B,{progress:vQ.GENERATE,message:"Creating image entity"});let{base64:C}=uF(E),R=oN(C),k=cF(C);if(!R||!k)return this.logger.error("Could not detect image format or dimensions",{sourceUrl:$}),C$.failure(Error("Could not detect image format or dimensions"));K=`${I}-cover`;let P=`Cover image for ${f}`,o=D??P;await this.context.entityService.createEntity({entity:{id:K,entityType:"image",content:E,metadata:{title:P,alt:o,format:R,width:k.width,height:k.height,sourceUrl:$}}}),this.logger.debug("Created image entity",{imageId:K,sourceUrl:$}),await this.reportProgress(B,{progress:vQ.EXTRACT,message:`Created image: ${K}`})}await this.reportProgress(B,{progress:vQ.SAVE,message:"Updating file"});let Z={...W};delete Z.coverImageUrl,delete Z.coverImageAlt,Z.coverImageId=K;let q=$N(Z,Y.content);try{await Dj2(w,q,"utf-8")}catch(E){return this.logger.error("Failed to write file",{filePath:w,error:y0(E)}),C$.failure(E)}return await this.reportProgress(B,{progress:vQ.COMPLETE,message:"Conversion complete"}),this.logger.info("Image conversion complete",{filePath:w,imageId:K,sourceUrl:$}),{success:!0,imageId:K}}catch(H){return this.logger.error("Image conversion job failed",{jobId:Q,filePath:w,error:y0(H)}),C$.failure(H)}}summarizeDataForLog(A){return{filePath:A.filePath,sourceUrl:A.sourceUrl,postSlug:A.postSlug}}}$0();Bf();GA();E$();import{readFile as Yj2,writeFile as Xj2}from"fs/promises";class hAA extends ow{converter;constructor(A,Q,B=WH){super(Q,{schema:YMA,jobTypeName:"inline-image-convert"});this.converter=new PT(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:vQ.INIT,message:`Reading file: ${w}`});let f;try{f=await Yj2(w,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to read file",{filePath:w,error:Y}),{success:!1,error:Y}}await this.reportProgress(B,{progress:vQ.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:vQ.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:vQ.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:vQ.COMPLETE,message:"No images converted"}),{success:!0,skipped:!0,convertedCount:0};await this.reportProgress(B,{progress:vQ.SAVE,message:"Writing updated file"});try{await Xj2(w,D.content,"utf-8")}catch(H){let Y=y0(H);return this.logger.error("Failed to write file",{filePath:w,error:Y}),{success:!1,error:Y}}return await this.reportProgress(B,{progress:vQ.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=y0(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 rr0(A,Q,B){let w=($)=>B.child($);A.jobs.registerHandler("directory-sync",new kAA(w("DirectorySyncJobHandler"),A,Q)),A.jobs.registerHandler("directory-export",new PAA(w("DirectoryExportJobHandler"),A,Q)),A.jobs.registerHandler("directory-import",new _AA(w("DirectoryImportJobHandler"),A,Q)),A.jobs.registerHandler("directory-delete",new jAA(w("DirectoryDeleteJobHandler"),A,Q)),A.jobs.registerHandler("directory-cleanup",new vAA(w("DirectoryCleanupJobHandler"),Q)),A.jobs.registerHandler("cover-image-convert",new xAA(A,w("CoverImageConversionJobHandler"))),A.jobs.registerHandler("inline-image-convert",new hAA(A,w("InlineImageConversionJobHandler"))),B.debug("Registered async job handlers")}$0();import{unlink as Wj2,access as Uj2}from"fs/promises";function dr0(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(H){B.error("Auto-export FAILED for created entity",{id:D.id,entityType:D.entityType,error:H instanceof Error?H.message:String(H),stack:H instanceof Error?H.stack:void 0})}return{success:!0}}),$("entity:updated",async(I)=>{let{entityType:D,entityId:H}=I.payload;try{let Y=await f.getEntity({entityType:D,id:H});if(!Y)return B.debug("Entity not found in DB, skipping export",{entityType:D,entityId:H}),{success:!1};await Q.fileOps.writeEntity(Y),B.debug("Auto-exported updated entity",{id:Y.id,entityType:Y.entityType})}catch(Y){B.error("Auto-export FAILED for updated entity",{entityType:D,entityId:H,error:Y instanceof Error?Y.message:String(Y),stack:Y instanceof Error?Y.stack:void 0})}return{success:!0}}),$("entity:deleted",async(I)=>{let{entityId:D,entityType:H}=I.payload,Y=Q.fileOps.getFilePath(D,H);if(await Uj2(Y).then(()=>!0,()=>!1))await Wj2(Y),B.debug("Auto-deleted entity file",{id:D,entityType:H,path:Y});return{success:!0}}),B.debug("Setup auto-sync for entity events",{entityTypes:w})}function nr0(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:Z5(),metadata:{operationType:"file_operations",operationTarget:B,pluginId:"directory-sync"}})})}GA();$0();import{readdir as ar0,mkdir as Gj2,copyFile as Fj2}from"fs/promises";import{join as sr0,resolve as XMA}from"path";import{join as Jj2}from"path";async function or0(A){if(!await w$(Jj2(A,".git")))return!1;try{return await gJ(A).revparse(["--verify","HEAD"]),!0}catch{return!1}}async function Kj2(A,Q){if(!await w$(A))return!0;if((await ar0(A)).filter(($)=>!$.startsWith(".")&&!$.startsWith("_")).length>0)return!1;if(await or0(A))return Q.debug("Git repository with history detected - skipping seed content",{path:A}),!1;return!0}async function tr0(A,Q){let B=await ar0(A,{withFileTypes:!0});for(let w of B){let $=sr0(A,w.name),f=sr0(Q,w.name);if(w.isDirectory()){if(!await w$(f))await Gj2(f,{recursive:!0});await tr0($,f)}else await Fj2($,f)}}async function er0(A,Q,B){let w=XMA(process.cwd(),A);B=B?XMA(B):XMA(process.cwd(),"seed-content");let $=await Kj2(w,Q);if($&&await w$(B))Q.debug("Copying seed content to brain-data directory"),await tr0(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 Ad0(A,Q,B,w,$){let f=!1,I=async()=>{if(f)return;f=!0;let D=Q();if(B.seedContent){let H=B.syncPath??A.dataDir;await er0(H,w,B.seedContentPath)}try{if($){w.debug("Git enabled \u2014 pulling before import");let Y=await $.pull();if(Y.files.length>0)w.info("Pulled changes from remote",{filesChanged:Y.files.length})}w.debug("Starting initial sync");let H=await D.sync();w.debug("Initial sync completed",{imported:H.import.imported,failed:H.import.failed,duration:H.duration}),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!0},...{broadcast:!0}})}catch(H){w.error("Initial sync failed",H),await A.messaging.send({type:CN.initialSyncCompleted,payload:{success:!1,error:y0(H)},...{broadcast:!0}})}};A.messaging.subscribe(CN.pluginsRegistered,async()=>{return w.debug("Plugins registered, starting initial sync"),await I(),{success:!0}})}GA();function Qd0(A,Q,B,w){let $=new UN(()=>{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 H=A.subscribe(D,async()=>{return $.trigger(),{success:!0}});I.push(H)}return()=>{$.dispose();for(let D of I)D()}}function Bd0(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:Y,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(Y.length>0)$.info("Periodic sync: pulled changes",{filesChanged:Y.length});if(W)$.debug("Periodic sync: queued imports",{importOperations:W.importOperationsCount,totalFiles:W.totalFiles})}catch(Y){$.error("Periodic git sync failed",{error:Y})}finally{I=!1}},H=setInterval(()=>{D()},f);return $.info("Started periodic git sync",{intervalMinutes:w}),()=>{clearInterval(H)}}import{spawnSync as $d0}from"child_process";import{cpSync as Zj2,existsSync as wd0,mkdirSync as Nj2,mkdtempSync as zj2,rmSync as qj2}from"fs";import{tmpdir as Cj2}from"os";import{fileURLToPath as Ej2}from"url";import{join as Lj2,resolve as Mj2}from"path";function qZ(A,Q){let B=$d0("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 Vj2(A){return A.startsWith("file://")}function bj2(A){return Ej2(A)}function Oj2(A,Q){return $d0("git",["--git-dir",A,"show-ref","--verify","--quiet",`refs/heads/${Q}`]).status===0}async function fd0(A){if(!A.bootstrapFromSeed)return;if(!A.gitUrl||!Vj2(A.gitUrl))return;if(!A.seedContentPath)throw Error("directory-sync git.bootstrapFromSeed requires seedContentPath for local file:// remotes");let Q=A.branch??"main",B=bj2(A.gitUrl),w=Mj2(A.seedContentPath);if(!wd0(w))throw Error(`Seed content path not found: ${w}`);if(!wd0(B))A.logger.debug("Creating local bare content remote",{remotePath:B,branch:Q}),Nj2(B,{recursive:!0}),qZ(process.cwd(),["init","--bare",`--initial-branch=${Q}`,B]);if(Oj2(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 $=zj2(Lj2(Cj2(),"directory-sync-seed-"));try{qZ($,["init",`--initial-branch=${Q}`]),qZ($,["config","user.name",A.authorName??"Brain"]),qZ($,["config","user.email",A.authorEmail??"brain@localhost"]),Zj2(w,$,{recursive:!0}),qZ($,["add","."]),qZ($,["commit","-m","seed content remote"]),qZ($,["remote","add","origin",A.gitUrl]),qZ($,["push","-u","origin",Q])}finally{qj2($,{recursive:!0,force:!0})}}function Id0(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(),H=I.payload.paths,Y=await D.importEntities(H);if(H&&H.length>0)await D.removeOrphanedEntities();return{success:!0,data:Y}}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")}$0();GA();$0();GA();function Dd0(A,Q){return xQ(A,"history","Get version history for an entity from git. Without sha: returns commit list. With sha: returns entity content at that version.",G.object({entityType:G.string().describe("Entity type (e.g. post, note, link)"),id:G.string().describe("Entity ID"),sha:G.string().optional().describe("Commit SHA to retrieve content at. Omit to list commit history."),limit:G.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 _8({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 _8({commits:[]},`No history found for ${B.entityType}/${B.id}`);return _8({commits:$,entityType:B.entityType,id:B.id},`${$.length} version${$.length===1?"":"s"} found`)}catch($){return L$($ instanceof Error?$.message:"History lookup failed")}})}function Hd0(A,Q,B,w){let $=[xQ(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.",G.object({}),async(f,I)=>{try{let D=I.channelId?`${I.interfaceType}:${I.channelId}`:`plugin:${B}`,H={interfaceType:I.interfaceType,channelId:I.channelId},Y=w!==void 0,W=()=>A.queueSyncBatch(Q,D,H),F=w?await w.withLock(async()=>{return await w.pull(),W()}):await W();if(!F)return _8({gitPulled:Y},"No files to sync");return _8({batchId:F.batchId,importOperations:F.importOperationsCount,totalFiles:F.totalFiles,gitPulled:Y},`Sync started: ${F.importOperationsCount} import jobs queued for ${F.totalFiles} files${Y?" (pulled from git)":""}`)}catch(D){return L$(D instanceof Error?D.message:"Sync failed")}},{cli:{name:"sync"}}),xQ(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.",G.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 _8(I)}catch(f){return L$(f instanceof Error?f.message:"Status check failed")}},{visibility:"public"})];if(w)$.push(Dd0(B,w));return $}var Yd0={name:"@brains/directory-sync",private:!0,version:"0.2.0-alpha.73",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 WMA extends RB{directorySync;gitSync;gitCleanups=[];constructor(A={}){super("directory-sync",Yd0,A,uT)}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:cT,basePrompt:"",formatter:new RAA,requiredPermission:"anchor"}});let w=this.config.syncPath??A.dataDir;this.directorySync=new _T({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(dr0(A,$,this.logger,this.config.entityTypes),this.config.autoSync)nr0(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 fd0({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 $MA({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(Qd0(A.messaging,this.gitSync,this.config.commitDebounce,this.logger.child("GitAutoCommit"))),this.config.autoSync)this.gitCleanups.push(Bd0(this.gitSync,this.requireDirectorySync(),A,this.config.syncInterval,this.logger.child("GitPeriodicSync")))}if(this.config.initialSync)Ad0(A,()=>this.requireDirectorySync(),this.config,this.logger,this.gitSync);Id0(A,()=>this.requireDirectorySync(),(I)=>this.configure(I),this.logger,this.config.git)}async getTools(){let A=this.requireDirectorySync();return Hd0(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 _T({...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){rr0(A,this.requireDirectorySync(),this.logger)}}function aq(A={}){return new WMA(A)}$0();GA();var Xd0={name:"@brains/email-resend",private:!0,version:"0.2.0-alpha.73",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 _j2=G.object({apiKey:G.string().min(1).optional(),from:G.string().min(1).optional()});class Wd0 extends RB{fetchImpl;constructor(A={},Q={}){super("email-resend",Xd0,A,_j2);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(Fs,async(B)=>{let w=iY0.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 Ud0(A={}){return new Wd0(A)}$0();import{render as YB1}from"preact-render-to-string";import{h as PC}from"preact";function Jd0(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=Jd0(A[Q]))&&(w&&(w+=" "),w+=B)}else for(B in A)A[B]&&(w&&(w+=" "),w+=B);return w}function JR(){for(var A,Q,B=0,w="",$=arguments.length;B<$;B++)(A=arguments[B])&&(Q=Jd0(A))&&(w&&(w+=" "),w+=Q);return w}var kj2=(A)=>{let Q=vj2(A),{conflictingClassGroups:B,conflictingClassGroupModifiers:w}=A;return{getClassGroupId:(I)=>{let D=I.split("-");if(D[0]===""&&D.length!==1)D.shift();return Nd0(D,Q)||jj2(I)},getConflictingClassGroupIds:(I,D)=>{let H=B[I]||[];if(D&&w[I])return[...H,...w[I]];return H}}},Nd0=(A,Q)=>{if(A.length===0)return Q.classGroupId;let B=A[0],w=Q.nextPart.get(B),$=w?Nd0(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},Gd0=/^\[(.+)\]$/,jj2=(A)=>{if(Gd0.test(A)){let Q=Gd0.exec(A)[1],B=Q?.substring(0,Q.indexOf(":"));if(B)return"arbitrary.."+B}},vj2=(A)=>{let{theme:Q,prefix:B}=A,w={nextPart:new Map,validators:[]};return hj2(Object.entries(A.classGroups),B).forEach(([f,I])=>{JMA(I,w,f,Q)}),w},JMA=(A,Q,B,w)=>{A.forEach(($)=>{if(typeof $==="string"){let f=$===""?Q:Fd0(Q,$);f.classGroupId=B;return}if(typeof $==="function"){if(xj2($)){JMA($(w),Q,B,w);return}Q.validators.push({validator:$,classGroupId:B});return}Object.entries($).forEach(([f,I])=>{JMA(I,Fd0(Q,f),B,w)})})},Fd0=(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},xj2=(A)=>A.isThemeGetter,hj2=(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,$]})},yj2=(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 gj2=(A)=>{let{separator:Q,experimentalParseClassName:B}=A,w=Q.length===1,$=Q[0],f=Q.length,I=(D)=>{let H=[],Y=0,W=0,F;for(let C=0;C<D.length;C++){let R=D[C];if(Y===0){if(R===$&&(w||D.slice(C,C+f)===Q)){H.push(D.slice(W,C)),W=C+f;continue}if(R==="/"){F=C;continue}}if(R==="[")Y++;else if(R==="]")Y--}let K=H.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:H,hasImportantModifier:Z,baseClassName:q,maybePostfixModifierPosition:E}};if(B)return(D)=>B({className:D,parseClassName:I});return I},Tj2=(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},Sj2=(A)=>({cache:yj2(A.cacheSize),parseClassName:gj2(A),...kj2(A)}),mj2=/\s+/,uj2=(A,Q)=>{let{parseClassName:B,getClassGroupId:w,getConflictingClassGroupIds:$}=Q,f=[],I=A.trim().split(mj2),D="";for(let H=I.length-1;H>=0;H-=1){let Y=I[H],{modifiers:W,hasImportantModifier:F,baseClassName:K,maybePostfixModifierPosition:Z}=B(Y),q=Boolean(Z),E=w(q?K.substring(0,Z):K);if(!E){if(!q){D=Y+(D.length>0?" "+D:D);continue}if(E=w(K),!E){D=Y+(D.length>0?" "+D:D);continue}q=!1}let C=Tj2(W).join(":"),R=F?C+"!":C,k=R+E;if(f.includes(k))continue;f.push(k);let P=$(E,q);for(let o=0;o<P.length;++o){let r=P[o];f.push(R+r)}D=Y+(D.length>0?" "+D:D)}return D};function cj2(){let A=0,Q,B,w="";while(A<arguments.length)if(Q=arguments[A++]){if(B=zd0(Q))w&&(w+=" "),w+=B}return w}var zd0=(A)=>{if(typeof A==="string")return A;let Q,B="";for(let w=0;w<A.length;w++)if(A[w]){if(Q=zd0(A[w]))B&&(B+=" "),B+=Q}return B};function Kd0(A,...Q){let B,w,$,f=I;function I(H){let Y=Q.reduce((W,F)=>F(W),A());return B=Sj2(Y),w=B.cache.get,$=B.cache.set,f=D,D(H)}function D(H){let Y=w(H);if(Y)return Y;let W=uj2(H,B);return $(H,W),W}return function(){return f(cj2.apply(null,arguments))}}var B8=(A)=>{let Q=(B)=>B[A]||[];return Q.isThemeGetter=!0,Q},qd0=/^\[(?:([a-z-]+):)?(.+)\]$/i,pj2=/^\d+\/\d+$/,lj2=new Set(["px","full","screen"]),ij2=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,rj2=/\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$/,dj2=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,nj2=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,oj2=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,TJ=(A)=>GR(A)||lj2.has(A)||pj2.test(A),CZ=(A)=>FR(A,"length",wv2),GR=(A)=>Boolean(A)&&!Number.isNaN(Number(A)),UMA=(A)=>FR(A,"number",GR),pT=(A)=>Boolean(A)&&Number.isInteger(Number(A)),sj2=(A)=>A.endsWith("%")&&GR(A.slice(0,-1)),_Q=(A)=>qd0.test(A),EZ=(A)=>ij2.test(A),aj2=new Set(["length","size","percentage"]),tj2=(A)=>FR(A,aj2,Cd0),ej2=(A)=>FR(A,"position",Cd0),Av2=new Set(["image","url"]),Qv2=(A)=>FR(A,Av2,fv2),Bv2=(A)=>FR(A,"",$v2),lT=()=>!0,FR=(A,Q,B)=>{let w=qd0.exec(A);if(w){if(w[1])return typeof Q==="string"?w[1]===Q:Q.has(w[1]);return B(w[2])}return!1},wv2=(A)=>rj2.test(A)&&!dj2.test(A),Cd0=()=>!1,$v2=(A)=>nj2.test(A),fv2=(A)=>oj2.test(A);var Zd0=()=>{let A=B8("colors"),Q=B8("spacing"),B=B8("blur"),w=B8("brightness"),$=B8("borderColor"),f=B8("borderRadius"),I=B8("borderSpacing"),D=B8("borderWidth"),H=B8("contrast"),Y=B8("grayscale"),W=B8("hueRotate"),F=B8("invert"),K=B8("gap"),Z=B8("gradientColorStops"),q=B8("gradientColorStopPositions"),E=B8("inset"),C=B8("margin"),R=B8("opacity"),k=B8("padding"),P=B8("saturate"),o=B8("scale"),r=B8("sepia"),S=B8("skew"),x=B8("space"),y=B8("translate"),g=()=>["auto","contain","none"],AA=()=>["auto","hidden","clip","visible","scroll"],c=()=>["auto",_Q,Q],JA=()=>[_Q,Q],HA=()=>["",TJ,CZ],_=()=>["auto",GR,_Q],O=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],j=()=>["solid","dashed","dotted","double","none"],t=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],d=()=>["start","end","center","between","around","evenly","stretch"],BA=()=>["","0",_Q],n=()=>["auto","avoid","all","avoid-page","page","left","right","column"],UA=()=>[GR,_Q];return{cacheSize:500,separator:":",theme:{colors:[lT],spacing:[TJ,CZ],blur:["none","",EZ,_Q],brightness:UA(),borderColor:[A],borderRadius:["none","","full",EZ,_Q],borderSpacing:JA(),borderWidth:HA(),contrast:UA(),grayscale:BA(),hueRotate:UA(),invert:BA(),gap:JA(),gradientColorStops:[A],gradientColorStopPositions:[sj2,CZ],inset:c(),margin:c(),opacity:UA(),padding:JA(),saturate:UA(),scale:UA(),sepia:BA(),skew:UA(),space:JA(),translate:JA()},classGroups:{aspect:[{aspect:["auto","square","video",_Q]}],container:["container"],columns:[{columns:[EZ]}],"break-after":[{"break-after":n()}],"break-before":[{"break-before":n()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...O(),_Q]}],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",pT,_Q]}],basis:[{basis:c()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",_Q]}],grow:[{grow:BA()}],shrink:[{shrink:BA()}],order:[{order:["first","last","none",pT,_Q]}],"grid-cols":[{"grid-cols":[lT]}],"col-start-end":[{col:["auto",{span:["full",pT,_Q]},_Q]}],"col-start":[{"col-start":_()}],"col-end":[{"col-end":_()}],"grid-rows":[{"grid-rows":[lT]}],"row-start-end":[{row:["auto",{span:[pT,_Q]},_Q]}],"row-start":[{"row-start":_()}],"row-end":[{"row-end":_()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",_Q]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",_Q]}],gap:[{gap:[K]}],"gap-x":[{"gap-x":[K]}],"gap-y":[{"gap-y":[K]}],"justify-content":[{justify:["normal",...d()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...d(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...d(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[k]}],px:[{px:[k]}],py:[{py:[k]}],ps:[{ps:[k]}],pe:[{pe:[k]}],pt:[{pt:[k]}],pr:[{pr:[k]}],pb:[{pb:[k]}],pl:[{pl:[k]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],"space-x":[{"space-x":[x]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[x]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",_Q,Q]}],"min-w":[{"min-w":[_Q,Q,"min","max","fit"]}],"max-w":[{"max-w":[_Q,Q,"none","full","min","max","fit","prose",{screen:[EZ]},EZ]}],h:[{h:[_Q,Q,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[_Q,Q,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[_Q,Q,"auto","min","max","fit"]}],"font-size":[{text:["base",EZ,CZ]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",UMA]}],"font-family":[{font:[lT]}],"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",_Q]}],"line-clamp":[{"line-clamp":["none",GR,UMA]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",TJ,_Q]}],"list-image":[{"list-image":["none",_Q]}],"list-style-type":[{list:["none","disc","decimal",_Q]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[A]}],"placeholder-opacity":[{"placeholder-opacity":[R]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[A]}],"text-opacity":[{"text-opacity":[R]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...j(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",TJ,CZ]}],"underline-offset":[{"underline-offset":["auto",TJ,_Q]}],"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:JA()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",_Q]}],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",_Q]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[R]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...O(),ej2]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",tj2]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},Qv2]}],"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":[R]}],"border-style":[{border:[...j(),"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":[R]}],"divide-style":[{divide:j()}],"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:["",...j()]}],"outline-offset":[{"outline-offset":[TJ,_Q]}],"outline-w":[{outline:[TJ,CZ]}],"outline-color":[{outline:[A]}],"ring-w":[{ring:HA()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[A]}],"ring-opacity":[{"ring-opacity":[R]}],"ring-offset-w":[{"ring-offset":[TJ,CZ]}],"ring-offset-color":[{"ring-offset":[A]}],shadow:[{shadow:["","inner","none",EZ,Bv2]}],"shadow-color":[{shadow:[lT]}],opacity:[{opacity:[R]}],"mix-blend":[{"mix-blend":[...t(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":t()}],filter:[{filter:["","none"]}],blur:[{blur:[B]}],brightness:[{brightness:[w]}],contrast:[{contrast:[H]}],"drop-shadow":[{"drop-shadow":["","none",EZ,_Q]}],grayscale:[{grayscale:[Y]}],"hue-rotate":[{"hue-rotate":[W]}],invert:[{invert:[F]}],saturate:[{saturate:[P]}],sepia:[{sepia:[r]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[B]}],"backdrop-brightness":[{"backdrop-brightness":[w]}],"backdrop-contrast":[{"backdrop-contrast":[H]}],"backdrop-grayscale":[{"backdrop-grayscale":[Y]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[W]}],"backdrop-invert":[{"backdrop-invert":[F]}],"backdrop-opacity":[{"backdrop-opacity":[R]}],"backdrop-saturate":[{"backdrop-saturate":[P]}],"backdrop-sepia":[{"backdrop-sepia":[r]}],"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",_Q]}],duration:[{duration:UA()}],ease:[{ease:["linear","in","out","in-out",_Q]}],delay:[{delay:UA()}],animate:[{animate:["none","spin","ping","pulse","bounce",_Q]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[o]}],"scale-x":[{"scale-x":[o]}],"scale-y":[{"scale-y":[o]}],rotate:[{rotate:[pT,_Q]}],"translate-x":[{"translate-x":[y]}],"translate-y":[{"translate-y":[y]}],"skew-x":[{"skew-x":[S]}],"skew-y":[{"skew-y":[S]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",_Q]}],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",_Q]}],"caret-color":[{caret:[A]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":JA()}],"scroll-mx":[{"scroll-mx":JA()}],"scroll-my":[{"scroll-my":JA()}],"scroll-ms":[{"scroll-ms":JA()}],"scroll-me":[{"scroll-me":JA()}],"scroll-mt":[{"scroll-mt":JA()}],"scroll-mr":[{"scroll-mr":JA()}],"scroll-mb":[{"scroll-mb":JA()}],"scroll-ml":[{"scroll-ml":JA()}],"scroll-p":[{"scroll-p":JA()}],"scroll-px":[{"scroll-px":JA()}],"scroll-py":[{"scroll-py":JA()}],"scroll-ps":[{"scroll-ps":JA()}],"scroll-pe":[{"scroll-pe":JA()}],"scroll-pt":[{"scroll-pt":JA()}],"scroll-pr":[{"scroll-pr":JA()}],"scroll-pb":[{"scroll-pb":JA()}],"scroll-pl":[{"scroll-pl":JA()}],"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",_Q]}],fill:[{fill:[A,"none"]}],"stroke-w":[{stroke:[TJ,CZ,UMA]}],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"]}}},Iv2=(A,{cacheSize:Q,prefix:B,separator:w,experimentalParseClassName:$,extend:f={},override:I={}})=>{iT(A,"cacheSize",Q),iT(A,"prefix",B),iT(A,"separator",w),iT(A,"experimentalParseClassName",$);for(let D in I)Dv2(A[D],I[D]);for(let D in f)Hv2(A[D],f[D]);return A},iT=(A,Q,B)=>{if(B!==void 0)A[Q]=B},Dv2=(A,Q)=>{if(Q)for(let B in Q)iT(A,B,Q[B])},Hv2=(A,Q)=>{if(Q)for(let B in Q){let w=Q[B];if(w!==void 0)A[B]=(A[B]||[]).concat(w)}},yAA=(A,...Q)=>typeof A==="function"?Kd0(Zd0,A,...Q):Kd0(()=>Iv2(Zd0(),A),...Q);var Yv2=yAA({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 s1(...A){return Yv2(JR(A))}var Ed0=(A)=>typeof A==="boolean"?`${A}`:A===0?"0":A,Ld0=JR,Zw=(A,Q)=>(B)=>{var w;if((Q===null||Q===void 0?void 0:Q.variants)==null)return Ld0(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((Y)=>{let W=B===null||B===void 0?void 0:B[Y],F=f===null||f===void 0?void 0:f[Y];if(W===null)return null;let K=Ed0(W)||Ed0(F);return $[Y][K]}),D=B&&Object.entries(B).reduce((Y,W)=>{let[F,K]=W;if(K===void 0)return Y;return Y[F]=K,Y},{}),H=Q===null||Q===void 0?void 0:(w=Q.compoundVariants)===null||w===void 0?void 0:w.reduce((Y,W)=>{let{class:F,className:K,...Z}=W;return Object.entries(Z).every((q)=>{let[E,C]=q;return Array.isArray(C)?C.includes({...f,...D}[E]):{...f,...D}[E]===C})?[...Y,F,K]:Y},[]);return Ld0(A,I,H,B===null||B===void 0?void 0:B.class,B===null||B===void 0?void 0:B.className)};import{jsxDEV as GMA}from"preact/jsx-dev-runtime";var Md0=Zw("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 FMA({variant:A,title:Q,children:B,className:w}){return GMA("div",{className:s1(Md0({variant:A}),w),role:"alert",children:[Q&&GMA("p",{className:"font-medium text-current opacity-90",children:Q},void 0,!1,void 0,this),GMA("div",{className:s1(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 Xv2}from"preact/jsx-dev-runtime";var Vd0=Zw("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 tq({variant:A,size:Q,className:B,children:w,ssrOnClick:$,type:f="button",...I}){return Xv2("button",{type:f,className:s1(Vd0({variant:A,size:Q}),B),...I,...$&&{onclick:$},children:w},void 0,!1,void 0,this)}import{jsxDEV as Wv2}from"preact/jsx-dev-runtime";var bd0=Zw("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 b5({href:A,children:Q,variant:B,size:w,external:$=!1,className:f,"aria-label":I}){let D=$?{target:"_blank",rel:"noopener noreferrer"}:{};return Wv2("a",{href:A,className:s1(bd0({variant:B,size:w}),f),"aria-label":I,...D,children:Q},void 0,!1,void 0,this)}import{jsxDEV as gAA}from"preact/jsx-dev-runtime";var Od0=Zw("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"}}),Uv2={sm:"w-4 h-4",md:"w-5 h-5",lg:"w-6 h-6"};function KR({variant:A,size:Q,className:B}){let w=Uv2[Q??"md"];return gAA("button",{onclick:"toggleTheme()",type:"button",className:s1(Od0({variant:A,size:Q}),B),"aria-label":"Toggle dark mode",children:gAA("svg",{className:s1(w,"transition-colors"),fill:"none",stroke:"currentColor",strokeWidth:1.6,viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:[gAA("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),gAA("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 KMA}from"preact/jsx-dev-runtime";var Rd0=Zw("flex flex-wrap",{variants:{orientation:{horizontal:"justify-center gap-6 items-center",vertical:"flex-col gap-2.5"}},defaultVariants:{orientation:"horizontal"}});function TAA({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 KMA("ul",{className:s1(Rd0({orientation:w}),Q),children:[f.map((I)=>KMA("li",{children:KMA("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 ErB}from"preact/jsx-dev-runtime";import{jsxDEV as VrB}from"preact/jsx-dev-runtime";import{createContext as Gv2,h as Fv2}from"preact";import{useContext as Kv2}from"preact/hooks";BUA();var Jv2=new _x({gfm:!0,breaks:!0});function ZMA(A,Q){let{imageRenderer:B}=Q??{},$=(B?new _x({gfm:!0,breaks:!0}).use({renderer:{image(f,I,D){return B(f,I,D)??!1}}}):Jv2).parse(A);return $=$.replace(/<\/blockquote>\s*<p>(\u2014|--|\u2013)([\s\S]*?)<\/p>/g,`</blockquote>
|
|
2391
2391
|
<cite class="block-attribution"><span class="emdash">$1</span>$2</cite>`),$}var Pd0=Gv2(null);function SAA({imageRenderer:A,children:Q}){return Fv2(Pd0.Provider,{value:A??null},Q)}function _d0(){return Kv2(Pd0)}function eq(){let A=_d0();return(Q)=>ZMA(Q,A?{imageRenderer:A}:void 0)}var Zv2=/<pre><code class="language-mermaid">([\s\S]*?)<\/code><\/pre>/g,Nv2={"&":"&","<":"<",">":">",""":'"',"'":"'"},zv2=/&(?:amp|lt|gt|quot|#39);/g;function qv2(A){return A.replace(zv2,(Q)=>Nv2[Q]??Q)}function NMA(A){return A.replace(Zv2,(Q,B)=>{return`<div class="mermaid">${qv2(B)}</div>`})}var kd0=/<!--\s*\.slide:\s*(.*?)\s*-->/g;function jd0(A){let Q={};for(let w of A.matchAll(kd0)){let $=w[1]??"";for(let I of $.matchAll(/([\w-]+)=["']([^"']*?)["']/g)){let D=I[1],H=I[2];if(D&&H!==void 0)Q[D]=H}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(kd0,"").replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
2392
2392
|
|
|
2393
2393
|
`).trim();return{attributes:Q,markdown:B}}var Cv2=/<!--\s*\.break\s*-->/;function vd0(A){let Q=A.split(Cv2);return Q.length>1?Q:null}import{jsxDEV as SJ}from"preact/jsx-dev-runtime";var zMA=({markdown:A})=>{let Q=eq(),w=A.split(/^---$/gm).map((I)=>I.trim()).map((I)=>{let{attributes:D,markdown:H}=jd0(I),Y=vd0(H),W;if(Y)W=`<div class="slide-columns">${Y.map((K)=>`<div class="slide-column">${NMA(Q(K.trim()))}</div>`).join("")}</div>`;else W=NMA(Q(H));return{attributes:D,htmlContent:W}}),$=w.some((I)=>I.htmlContent.includes('class="mermaid"')),f=w.map(({attributes:I,htmlContent:D},H)=>SJ("section",{...I,dangerouslySetInnerHTML:{__html:D}},H,!1,void 0,this));return SJ("section",{className:"presentation-section",children:[SJ("link",{rel:"stylesheet",href:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.css"},void 0,!1,void 0,this),SJ("div",{className:"reveal",children:SJ("div",{className:"slides",children:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),SJ("script",{src:"https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.min.js",defer:!0},void 0,!1,void 0,this),$&&SJ("script",{src:"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",defer:!0},void 0,!1,void 0,this),SJ("script",{dangerouslySetInnerHTML:{__html:`
|
|
@@ -3231,13 +3231,13 @@ ${A.map((f)=>({url:`${Q}${f.path}`,lastmod:B,changefreq:f.path==="/"?"daily":"we
|
|
|
3231
3231
|
`+$:B,I=XW(this.outputDir,"styles","main.css");await this.cssProcessor.process(f,I,this.workingDir,this.outputDir,this.logger);let D=await u$.readFile(I,"utf-8"),H=w.length>0?w:Q;if(H.length>0){let Y=H.join(`
|
|
3232
3232
|
`)+`
|
|
3233
3233
|
|
|
3234
|
-
`+D;await u$.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=XW(process.cwd(),"public");try{await u$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await u$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=XW(A,B.name),$=XW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await u$.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=XW(this.outputDir,$);await u$.mkdir(Za2(f),{recursive:!0}),await u$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await u$.mkdir(Q,{recursive:!0});let B=await u$.readdir(A,{withFileTypes:!0});for(let w of B){let $=XW(A,w.name),f=XW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await u$.copyFile($,f)}}}function xOA(A){return new XB1(A)}G6();GA();GA();G6();var WB1=G.object({environment:G.enum(["preview","production"]),outputDir:G.string(),workingDir:G.string().optional(),sharedImagesDir:G.string().default("./dist/images"),enableContentGeneration:G.boolean().default(!1),cleanBeforeBuild:G.boolean().default(!0),siteConfig:BI,layouts:G.record(G.any()),themeCSS:G.string().optional()}),Z2w=G.object({success:G.boolean(),outputDir:G.string(),filesGenerated:G.number(),routesBuilt:G.number(),errors:G.array(G.string()).optional(),warnings:G.array(G.string()).optional()});function UB1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function JB1(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"}}G6();Bf();G6();GA();var Na2=G.object({id:G.string(),entityType:G.string(),content:G.string(),metadata:G.object({slug:G.string()}).passthrough()}).passthrough(),za2=G.object({content:G.string(),metadata:G.object({width:G.number().optional(),height:G.number().optional()}).passthrough()});async function A2A(A,Q){let B=Q.urlGenerator??I9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((P)=>A2A(P,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,P])=>A2A(P,{...Q,urlGenerator:B})));for(let P=0;P<$.length;P++){let o=$[P];if(o)w[o[0]]=f[P]}let I=Na2.safeParse(A);if(!I.success)return w;let D=I.data,H=D.entityType,Y=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[H],F=W?W.label:H.charAt(0).toUpperCase()+H.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":ef(H),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),E=Tv(D),C=E?Q.imageBuildService?.get(E):void 0,R={};if(C)R={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let P=await qa2(E,Q.pipelineContext.services.entityService);if(P)R={coverImageUrl:P.url,...P.width&&{coverImageWidth:P.width},...P.height&&{coverImageHeight:P.height}}}return{...w,...D,url:B.generateUrl(H,Y),typeLabel:F,listUrl:Z,listLabel:q,...R}}async function qa2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=za2.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 GB1(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=Tv(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function FB1(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 A2A(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:I9.getInstance()})}function KB1(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 FB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return JB1(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 Ca2}from"path";async function ZB1(A){let Q=A.parsedOptions.workingDir??Ca2(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 NB1(A){await new t1A({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 zB1(A){let Q=new a1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await GB1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function qB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function CB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function EB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function LB1(A){let Q=WB1.parse(A.buildOptions),B=z$.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 NB1({pipelineContext:A.pipelineContext});let $=await ZB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=UB1(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 zB1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=KB1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await qB1({staticSiteBuilder:$,buildContext:H,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),CB1({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:$}),EB1({outputDir:Q.outputDir,errorMessage:f.message})}}class pI{static instance=null;static defaultStaticSiteBuilderFactory=xOA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){pI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return pI.instance??=new pI(A,pI.defaultStaticSiteBuilderFactory,Q,B,w,$),pI.instance}static resetInstance(){pI.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new pI(A,$??pI.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,I9.getInstance().configure(f)}async build(A,Q){return LB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class hOA{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 UN(()=>{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})}}}G6();function Ea2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function Q2A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?Ea2(w.sections,Q):[]})}function MB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=up.parse(w.payload),{routes:f,pluginId:I}=$;return Q2A(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 $=cp.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 $=pp.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 $=lp.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 VB1}from"fs";import{join as bB1}from"path";async function La2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=jOA(w,A.environment);await VB1.writeFile(bB1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=vOA($,w);await VB1.writeFile(bB1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function OB1(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 La2(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}$0();GA();G6();var RB1=G.object({environment:G.enum(["preview","production"]).optional(),outputDir:G.string(),workingDir:G.string().optional(),enableContentGeneration:G.boolean().optional(),siteConfig:BI.optional()});G6();G6();async function fm(A,Q){try{let B=await A({type:kk,payload:void 0});if("success"in B&&B.success&&B.data){let w=BI.safeParse(B.data);if(w.success)return BI.parse({...Q,...w.data})}}catch{}return Q}class yOA extends ow{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:RB1,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 fm(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 H=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:H},generateEntityUrl:(Y,W)=>I9.getInstance().generateUrl(Y,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();G6();var Ma2=G.object({slot:G.enum(GN).optional().default("primary"),limit:G.number().optional()});class gOA{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=Ma2.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((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}G6();$0();GA();var Va2=G.object({environment:G.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function PB1(A,Q){return[xQ(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'.",Va2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();G6();var _B1=G.object({previewOutputDir:G.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:G.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:G.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:G.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:BI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:G.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:G.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:G.any().optional().describe("Template definitions to register"),routes:G.array(FN).optional().describe("Routes to register"),layouts:G.record(G.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:G.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:G.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:G.record(G.object({label:G.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:G.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:G.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:G.boolean().optional().describe("Enable pagination for list pages"),pageSize:G.number().optional().describe("Items per page (default: 10)"),navigation:G.object({show:G.boolean().optional().describe("Show in navigation"),slot:G.enum(GN).optional().describe("Navigation slot (primary or secondary)"),priority:G.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:G.record(G.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 kB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.72",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 TOA extends RB{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",kB1,{...A,layouts:Q},_B1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new e1A(A.logger),this._slotRegistry=new k1A,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 gOA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=f7.getInstance(A.entityService,A.logger),MB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)Q2A(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=pI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new yOA(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 hOA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(jk,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),OB1({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 PB1(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 fm(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 fm(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3234
|
+
`+D;await u$.writeFile(I,Y,"utf-8")}this.logger.debug("CSS processed successfully with font imports")}async copyStaticAssets(){this.logger.debug("Copying static assets from public/ directory");let A=XW(process.cwd(),"public");try{await u$.access(A)}catch{this.logger.debug("No public/ directory found, skipping static assets");return}let Q=await u$.readdir(A,{withFileTypes:!0});for(let B of Q){let w=XW(A,B.name),$=XW(this.outputDir,B.name);if(B.isDirectory())await this.copyDirectory(w,$);else await u$.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=XW(this.outputDir,$);await u$.mkdir(Za2(f),{recursive:!0}),await u$.writeFile(f,w,"utf-8"),this.logger.debug(`Wrote inline static asset: ${$}`)}))}async copyDirectory(A,Q){await u$.mkdir(Q,{recursive:!0});let B=await u$.readdir(A,{withFileTypes:!0});for(let w of B){let $=XW(A,w.name),f=XW(Q,w.name);if(w.isDirectory())await this.copyDirectory($,f);else await u$.copyFile($,f)}}}function xOA(A){return new XB1(A)}G6();GA();GA();G6();var WB1=G.object({environment:G.enum(["preview","production"]),outputDir:G.string(),workingDir:G.string().optional(),sharedImagesDir:G.string().default("./dist/images"),enableContentGeneration:G.boolean().default(!1),cleanBeforeBuild:G.boolean().default(!0),siteConfig:BI,layouts:G.record(G.any()),themeCSS:G.string().optional()}),Z2w=G.object({success:G.boolean(),outputDir:G.string(),filesGenerated:G.number(),routesBuilt:G.number(),errors:G.array(G.string()).optional(),warnings:G.array(G.string()).optional()});function UB1(A){let Q=A.list(),B=Q.length===0?["No routes registered for site build"]:[];return{routes:Q,warnings:B}}function JB1(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"}}G6();Bf();G6();GA();var Na2=G.object({id:G.string(),entityType:G.string(),content:G.string(),metadata:G.object({slug:G.string()}).passthrough()}).passthrough(),za2=G.object({content:G.string(),metadata:G.object({width:G.number().optional(),height:G.number().optional()}).passthrough()});async function A2A(A,Q){let B=Q.urlGenerator??I9.getInstance();if(A===null||A===void 0)return A;if(Array.isArray(A))return Promise.all(A.map((P)=>A2A(P,{...Q,urlGenerator:B})));if(typeof A!=="object")return A;let w={},$=Object.entries(A),f=await Promise.all($.map(([,P])=>A2A(P,{...Q,urlGenerator:B})));for(let P=0;P<$.length;P++){let o=$[P];if(o)w[o[0]]=f[P]}let I=Na2.safeParse(A);if(!I.success)return w;let D=I.data,H=D.entityType,Y=D.metadata.slug,W=Q.pipelineContext.entityDisplay?.[H],F=W?W.label:H.charAt(0).toUpperCase()+H.slice(1),K=W?W.pluralName??W.label.toLowerCase()+"s":ef(H),Z=`/${K}`,q=K.charAt(0).toUpperCase()+K.slice(1),E=Tv(D),C=E?Q.imageBuildService?.get(E):void 0,R={};if(C)R={coverImageUrl:C.src,coverImageWidth:C.width,coverImageHeight:C.height,...C.srcset&&{coverImageSrcset:C.srcset,coverImageSizes:C.sizes}};else{let P=await qa2(E,Q.pipelineContext.services.entityService);if(P)R={coverImageUrl:P.url,...P.width&&{coverImageWidth:P.width},...P.height&&{coverImageHeight:P.height}}}return{...w,...D,url:B.generateUrl(H,Y),typeLabel:F,listUrl:Z,listLabel:q,...R}}async function qa2(A,Q){if(!A)return;let B=await Q.getEntity({entityType:"image",id:A}),w=za2.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 GB1(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=Tv(I);if(D)B.add(D)}}}catch(w){Q.warn("Failed to collect image IDs for pre-resolution",{error:y0(w)})}return[...B]}async function FB1(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 A2A(I,{pipelineContext:w.pipelineContext,imageBuildService:w.imageBuildService,urlGenerator:I9.getInstance()})}function KB1(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 FB1(B,Q,w,{pipelineContext:A.pipelineContext,imageBuildService:A.imageBuildService})},getViewTemplate:(Q)=>{return A.pipelineContext.services.getViewTemplate(Q)},layouts:A.parsedOptions.layouts,getSiteLayoutInfo:async()=>{return JB1(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 Ca2}from"path";async function ZB1(A){let Q=A.parsedOptions.workingDir??Ca2(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 NB1(A){await new t1A({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 zB1(A){let Q=new a1A(A.pipelineContext.services.entityService,A.pipelineContext.logger,A.sharedImagesDir),B=await GB1(A.pipelineContext.services.entityService,A.pipelineContext.logger);if(B.length>0)await Q.resolveAll(B);return Q}async function qB1(A){let Q=A.reporter?.createSub({scale:{start:85,end:95}});await A.staticSiteBuilder.build(A.buildContext,(B)=>{Q?.report(B).catch(()=>{})})}function CB1(A){return{success:!0,outputDir:A.outputDir,filesGenerated:A.routesBuilt+1,routesBuilt:A.routesBuilt,...A.warnings.length>0&&{warnings:A.warnings}}}function EB1(A){return{success:!1,outputDir:A.outputDir,filesGenerated:0,routesBuilt:0,errors:[A.errorMessage]}}async function LB1(A){let Q=WB1.parse(A.buildOptions),B=z$.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 NB1({pipelineContext:A.pipelineContext});let $=await ZB1({logger:A.pipelineContext.logger,parsedOptions:Q,staticSiteBuilderFactory:A.staticSiteBuilderFactory}),f=UB1(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 zB1({pipelineContext:A.pipelineContext,sharedImagesDir:Q.sharedImagesDir}),H=KB1({routes:I,parsedOptions:Q,buildOptions:A.buildOptions,pipelineContext:A.pipelineContext,imageBuildService:D,siteMetadata:Q.siteConfig});return await qB1({staticSiteBuilder:$,buildContext:H,reporter:B}),await B?.report({message:"Site build complete",progress:100,total:100}),CB1({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:$}),EB1({outputDir:Q.outputDir,errorMessage:f.message})}}class pI{static instance=null;static defaultStaticSiteBuilderFactory=xOA;pipelineContext;staticSiteBuilderFactory;static setDefaultStaticSiteBuilderFactory(A){pI.defaultStaticSiteBuilderFactory=A}static getInstance(A,Q,B,w,$=void 0){return pI.instance??=new pI(A,pI.defaultStaticSiteBuilderFactory,Q,B,w,$),pI.instance}static resetInstance(){pI.instance=null}static createFresh(A,Q,B,w,$,f=void 0){return new pI(A,$??pI.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,I9.getInstance().configure(f)}async build(A,Q){return LB1({buildOptions:A,progress:Q,pipelineContext:this.pipelineContext,staticSiteBuilderFactory:this.staticSiteBuilderFactory})}}GA();class hOA{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 UN(()=>{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})}}}G6();function Ea2(A,Q){return A.map((B)=>({...B,template:B.template.includes(":")?B.template:`${Q}:${B.template}`}))}function Q2A(A,Q,B){for(let w of A)B.register({...w,pluginId:Q,sections:w.sections?Ea2(w.sections,Q):[]})}function MB1(A,Q,B){A.messaging.subscribe("plugin:site-builder:route:register",async(w)=>{try{let $=up.parse(w.payload),{routes:f,pluginId:I}=$;return Q2A(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 $=cp.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 $=pp.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 $=lp.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 VB1}from"fs";import{join as bB1}from"path";async function La2(A,Q,B){let w=A.siteConfig.url??"https://example.com",$=Q.list(),f=jOA(w,A.environment);await VB1.writeFile(bB1(A.outputDir,"robots.txt"),f,"utf-8"),B.info(`Generated robots.txt for ${A.environment} environment`);let I=vOA($,w);await VB1.writeFile(bB1(A.outputDir,"sitemap.xml"),I,"utf-8"),B.info(`Generated sitemap.xml with ${$.length} URLs`)}function OB1(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 La2(f,B,w),{success:!0}}catch(f){return w.error("Failed to generate SEO files",f),{success:!1}}})}$0();GA();G6();var RB1=G.object({environment:G.enum(["preview","production"]).optional(),outputDir:G.string(),workingDir:G.string().optional(),enableContentGeneration:G.boolean().optional(),siteConfig:BI.optional()});G6();G6();async function fm(A,Q){try{let B=await A({type:kk,payload:void 0});if("success"in B&&B.success&&B.data){let w=BI.safeParse(B.data);if(w.success)return BI.parse({...Q,...w.data})}}catch{}return Q}class yOA extends ow{sendMessage;cfg;constructor(A,Q,B){super(A,{schema:RB1,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 fm(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 H=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:H},generateEntityUrl:(Y,W)=>I9.getInstance().generateUrl(Y,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();G6();var Ma2=G.object({slot:G.enum(GN).optional().default("primary"),limit:G.number().optional()});class gOA{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=Ma2.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((H)=>({label:H.label,href:H.href}));this.logger.debug("NavigationDataSource returning",{slot:w.slot,itemCount:f.length,items:I});let D={navigation:I};return Q.parse(D)}}G6();$0();GA();var Va2=G.object({environment:G.enum(["preview","production"]).optional().describe("Build environment (defaults to production, or preview if configured)")});function PB1(A,Q){return[xQ(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'.",Va2,async(B)=>{return Q(B.environment),{success:!0,message:`Site build requested${B.environment?` for ${B.environment}`:""} (debounced)`,data:{}}},{cli:{name:"build"}})]}GA();G6();var _B1=G.object({previewOutputDir:G.string().describe("Output directory for preview builds").default("./dist/site-preview"),productionOutputDir:G.string().describe("Output directory for production builds").default("./dist/site-production"),sharedImagesDir:G.string().describe("Shared directory for optimized images (used by both preview and production)").default("./dist/images"),workingDir:G.string().optional().describe("Working directory for builds").default("./.preact-work"),siteInfo:BI.default({title:"Brain",description:"A knowledge management system"}),themeCSS:G.string().describe("Custom CSS theme overrides to inject into builds").optional(),analyticsScript:G.string().describe("Analytics tracking script to inject into page head (e.g., Cloudflare Web Analytics)").optional(),templates:G.any().optional().describe("Template definitions to register"),routes:G.array(FN).optional().describe("Routes to register"),layouts:G.record(G.any()).optional().describe("Layout components (at least 'default' required)"),autoRebuild:G.boolean().default(!0).describe("Automatically rebuild site when content changes"),rebuildDebounce:G.number().min(100).describe("Debounce time in ms before triggering site rebuild after content changes").default(5000),entityDisplay:G.record(G.object({label:G.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:G.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')"),layout:G.string().optional().describe("Layout name for this entity type's generated routes (defaults to 'default')"),paginate:G.boolean().optional().describe("Enable pagination for list pages"),pageSize:G.number().optional().describe("Items per page (default: 10)"),navigation:G.object({show:G.boolean().optional().describe("Show in navigation"),slot:G.enum(GN).optional().describe("Navigation slot (primary or secondary)"),priority:G.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:G.record(G.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 kB1={name:"@brains/site-builder-plugin",private:!0,version:"0.2.0-alpha.73",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 TOA extends RB{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",kB1,{...A,layouts:Q},_B1);this.layouts=Q}async onRegister(A){if(this.pluginContext=A,this._routeRegistry=new e1A(A.logger),this._slotRegistry=new k1A,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 gOA(this._routeRegistry,A.logger.child("NavigationDataSource"))),this.profileService=f7.getInstance(A.entityService,A.logger),MB1(A,this._routeRegistry,this.logger),this.config.templates)A.templates.register(this.config.templates);if(this.config.routes)Q2A(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=pI.getInstance(A.logger.child("SiteBuilder"),Q,this.routeRegistry,this.profileService,this.config.entityDisplay),A.jobs.registerHandler("site-build",new yOA(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 hOA(this.config,A,this.id,this.logger),this.config.autoRebuild)this.logger.debug("Auto-rebuild enabled"),this.rebuildManager.setupAutoRebuild();A.messaging.subscribe(jk,async()=>{let B=await this.getInstructions();if(B)A.registerInstructions(B);return{success:!0}}),OB1({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 PB1(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 fm(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 fm(A.messaging.send,this.config.siteInfo);return`## Your Site
|
|
3235
3235
|
${[`**Title:** ${B.title}`,`**Description:** ${B.description}`,A.domain&&`**Domain:** ${A.domain}`,A.siteUrl&&`**URL:** ${A.siteUrl}`].filter(Boolean).join(`
|
|
3236
3236
|
`)}
|
|
3237
3237
|
|
|
3238
3238
|
## Site Builder Actions
|
|
3239
3239
|
- When the user asks to build, rebuild, publish, or build the website/site again, call \`site-builder_build-site\` immediately.
|
|
3240
|
-
- 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(),pI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function _C(A={}){return new TOA(A)}$0();G6();GA();$0();G6();var jB1=G.object({}),Im=B2.extend({id:G.literal("site-info"),entityType:G.literal("site-info"),metadata:jB1}),SOA=rp,eR=BI.omit({url:!0,analyticsScript:!0});$0();class WW extends W2{constructor(){super({entityType:"site-info",schema:Im,frontmatterSchema:eR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=eR.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 UW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return UW.instance??=new UW(A,Q,B),UW.instance}static resetInstance(){UW.instance=null}static createFresh(A,Q,B){return new UW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new WW;let w=UW.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 Oa2=new WW;class B2A{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?Oa2.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 vB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.
|
|
3240
|
+
- 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(),pI.resetInstance(),this.logger.debug("Cleaned up all event subscriptions")}}function _C(A={}){return new TOA(A)}$0();G6();GA();$0();G6();var jB1=G.object({}),Im=B2.extend({id:G.literal("site-info"),entityType:G.literal("site-info"),metadata:jB1}),SOA=rp,eR=BI.omit({url:!0,analyticsScript:!0});$0();class WW extends W2{constructor(){super({entityType:"site-info",schema:Im,frontmatterSchema:eR,isSingleton:!0,hasBody:!1})}createSiteInfoContent(A){let Q=eR.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 UW{static instance=null;logger;entityService;adapter;defaultSiteInfo;static getDefaultSiteInfo(){return{title:"Brain",description:"A knowledge management system"}}static getInstance(A,Q,B){return UW.instance??=new UW(A,Q,B),UW.instance}static resetInstance(){UW.instance=null}static createFresh(A,Q,B){return new UW(A,Q,B)}constructor(A,Q,B){this.entityService=A,this.logger=Q.child("SiteInfoService"),this.adapter=new WW;let w=UW.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 Oa2=new WW;class B2A{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?Oa2.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 vB1={name:"@brains/site-info",private:!0,version:"0.2.0-alpha.73",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 Pa2=new WW;class mOA extends KQ{entityType="site-info";schema=Im;adapter=Pa2;defaultSiteInfo;constructor(A){super("site-info",vB1);this.defaultSiteInfo=A?.siteInfo??{}}getEntityTypeConfig(){return{embeddable:!1}}getDataSources(){return[new B2A(this.logger.child("SiteInfoDataSource"))]}async onRegister(A){let Q=UW.createFresh(A.entityService,this.logger,this.defaultSiteInfo);A.messaging.subscribe(kk,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:jk,payload:$,broadcast:!0})}return{success:!0}}),A.messaging.subscribe("sync:initial:completed",async()=>{return await Q.initialize(),{success:!0}})}}function kC(A){return new mOA(A)}var _a2=new WW;async function uOA(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 _a2.parseSiteInfoBody(B.content)}GA();var ka2=eR.extend({navigation:G.object({primary:G.array(G.object({label:G.string(),href:G.string(),priority:G.number()})),secondary:G.array(G.object({label:G.string(),href:G.string(),priority:G.number()}))}),copyright:G.string(),socialLinks:G.array(G.object({platform:G.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:G.string().describe("Profile or contact URL"),label:G.string().optional().describe("Optional display label")})).optional().describe("Social media links from profile entity")});$0();JW();Ym();GA();var cOA=G.object({defaultPrompt:G.string().default("Write a blog post about my recent work and insights"),paginate:G.boolean().default(!0),pageSize:G.number().default(10)});$0();GA();E$();var xa2=G.object({prompt:G.string().optional(),title:G.string().optional(),content:G.string().optional(),excerpt:G.string().optional(),coverImageId:G.string().optional(),seriesName:G.string().optional(),seriesIndex:G.number().optional(),skipAi:G.boolean().optional()}),SBw=AI.extend({title:G.string().optional(),slug:G.string().optional()});class pOA extends X9{constructor(A,Q){super(A,Q,{schema:xa2,jobTypeName:"blog-generation",entityType:"post"})}async generate(A,Q){let{prompt:B,coverImageId:w,seriesName:$,seriesIndex:f,skipAi:I}=A,{title:D,content:H,excerpt:Y}=A;if(I){if(!D)this.failEarly("Title is required when skipAi is true");H=H??`## Introduction
|
|
3241
3241
|
|
|
3242
3242
|
Add your introduction here.
|
|
3243
3243
|
|
|
@@ -3282,7 +3282,7 @@ The excerpt should be clear, concise, and compelling.`});GA();Rw();JW();import{j
|
|
|
3282
3282
|
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=Bt2.parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3283
3283
|
|
|
3284
3284
|
Content:
|
|
3285
|
-
${B.content}`,templateName:"blog:excerpt"})})}var lB1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.
|
|
3285
|
+
${B.content}`,templateName:"blog:excerpt"})})}var lB1={name:"@brains/blog",private:!0,version:"0.2.0-alpha.73",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 nOA extends KQ{entityType=jC.entityType;schema=AP;adapter=jC;constructor(A={}){super("blog",lB1,A,cOA)}getEntityTypeConfig(){return{weight:2}}createGenerationHandler(A){return new pOA(this.logger.child("BlogGenerationJobHandler"),A)}getTemplates(){return TB1()}getDataSources(){return[new iOA(this.logger.child("BlogDataSource"))]}async onRegister(A){let{RSSDataSource:Q}=await Promise.resolve().then(() => (dB1(),rB1));A.entities.registerDataSource(new Q(this.logger.child("RSSDataSource"))),await SB1(A,this.logger),mB1(A,this.logger),cB1(A,this.logger),pB1(A),this.logger.info("Blog plugin registered (routes auto-generated at /posts/)")}}function oOA(A={}){return new nOA(A)}JW();Ym();$0();GA();GA();d5();Ew();var I4=G.object({title:G.string(),slug:G.string(),coverImageId:G.string().optional()}),nB1=I4.pick({title:!0,slug:!0}),BP=B2.extend({metadata:nB1}),f2A=BP.extend({frontmatter:I4}),I2A=f2A.extend({description:G.string().optional(),postCount:G.number(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()}),oB1=G.object({description:G.string().optional()});function vC(A){return new PB(oB1,{title:A,mappings:[{key:"description",label:"Description",type:"string"}]})}Ew();class sOA extends W2{constructor(){super({entityType:"series",schema:BP,frontmatterSchema:I4,supportsCoverImage:!0,bodyFormatter:vC("")})}toMarkdown(A){let Q,B={};try{Q=this.parseFrontMatter(A.content,I4).coverImageId,B=vC(A.metadata.title).parse(this.extractBody(A.content))}catch{}let w={title:A.metadata.title,slug:A.metadata.slug,...Q&&{coverImageId:Q}},f=vC(A.metadata.title).format(B);return this.buildMarkdown(f,w)}fromMarkdown(A){let Q=this.parseFrontMatter(A,I4);return{content:A,entityType:"series",metadata:{title:Q.title,slug:Q.slug}}}parseBody(A){try{let Q=this.parseFrontMatter(A,I4);return vC(Q.title).parse(this.extractBody(A))}catch{return{}}}generateFrontMatter(){return""}}var wP=new sOA;$0();GA();ED();class aOA{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=U2($);w.add(f);let I=B.get(f),D=I?.content??this.createSeriesContent($),H=hB(D);if(I?.contentHash===H)continue;let Y={id:f,entityType:"series",content:D,contentHash:H,created:I?.created??new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:$,slug:U2($)}};await this.entityService.upsertEntity({entity:Y}),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=U2(A);if(await this.entityService.getEntity({entityType:"series",id:Q}))return;let w=this.createSeriesContent(A),$={id:Q,entityType:"series",content:w,contentHash:hB(w),created:new Date().toISOString(),updated:new Date().toISOString(),metadata:{title:A,slug:U2(A)}};await this.entityService.upsertEntity({entity:$}),this.logger.debug(`Created series: ${A}`)}async cleanupOrphanedSeries(A){let Q=U2(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:U2(A)};return H9("",Q)}}$0();GA();var ft2=G.object({entityType:G.literal("series"),query:G.object({id:G.string().optional(),limit:G.number().optional(),page:G.number().optional(),pageSize:G.number().optional()}).passthrough()}),It2=G.object({type:G.enum(["list","detail"]),seriesName:G.string().optional()});function Dt2(A){let Q=It2.safeParse(A);if(Q.success)return{type:Q.data.type,seriesName:Q.data.seriesName};let B=ft2.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 sB1(A){let Q=t2(A.content,I4);return f2A.parse({...A,frontmatter:Q.metadata})}class tOA{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=Dt2(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=sB1(f),D=wP.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 $=sB1(w),f=wP.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}}$0();GA();ED();var Ht2=G.object({prompt:G.string().optional(),title:G.string().optional(),seriesId:G.string().optional()});class D2A{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}
|
|
3286
3286
|
|
|
3287
3287
|
Content in this series:
|
|
3288
3288
|
${w.join(`
|
|
@@ -3294,7 +3294,7 @@ Your task is to write a series description (2-3 sentences) that:
|
|
|
3294
3294
|
3. Is engaging and makes readers want to explore the content
|
|
3295
3295
|
4. Works well as a series overview on a website
|
|
3296
3296
|
|
|
3297
|
-
Be concise and focus on what makes this series unique and valuable.`});var ww1={name:"@brains/series",private:!0,version:"0.2.0-alpha.
|
|
3297
|
+
Be concise and focus on what makes this series unique and valuable.`});var ww1={name:"@brains/series",private:!0,version:"0.2.0-alpha.73",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 $w1=G.discriminatedUnion("mode",[G.object({mode:G.literal("derive"),reason:G.string().optional()}),G.object({mode:G.literal("source"),entityId:G.string(),entityType:G.string(),seriesName:G.string()})]);class eOA extends KQ{entityType="series";schema=BP;adapter=wP;manager;constructor(){super("series",ww1)}getEntityTypeConfig(){return{weight:0.5}}createGenerationHandler(A){return new D2A(this.logger.child("SeriesGenerationHandler"),A)}getTemplates(){return{...Qw1(),description:Bw1}}getDataSources(){return[new tOA(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 aOA(A.entityService,this.logger.child("SeriesManager"))}createSeriesProjectionHandler(A){return{process:async(Q)=>{let B=$w1.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=$w1.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 D2A(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 ARA(){return new eOA}$0();GA();$0();GA();GA();$0();var Jt2=G.enum(["draft","queued","published"]),fw1="publishedAt is required when deck status is published",Iw1=(A)=>A.status==="published"&&!A.publishedAt,QRA=(A)=>{if(Iw1(A))throw Error(fw1)},cZ=G.object({title:G.string(),slug:G.string().optional(),description:G.string().optional(),author:G.string().optional(),status:Jt2,publishedAt:G.string().datetime().optional(),event:G.string().optional(),coverImageId:G.string().optional()}),Gt2=cZ.pick({title:!0,description:!0,status:!0,publishedAt:!0,coverImageId:!0}).extend({slug:G.string()}).superRefine((A,Q)=>{if(!Iw1(A))return;Q.addIssue({code:G.ZodIssueCode.custom,path:["publishedAt"],message:fw1})}),H2A=B2.extend({entityType:G.literal("deck"),metadata:Gt2}),Y2A=H2A.extend({frontmatter:cZ,body:G.string()}),Jm=Y2A.extend({url:G.string().optional(),typeLabel:G.string().optional(),listUrl:G.string().optional(),listLabel:G.string().optional(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()});class BRA extends W2{constructor(){super({entityType:"deck",schema:H2A,frontmatterSchema:cZ,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,cZ);QRA(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);QRA(Q),this.validateSlideStructure(B);let w=Q.slug??U2(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 Gm=new BRA;GA();Rw();var Ft2=G.object({markdown:G.string().describe("Markdown content with slide separators (---)")}),wRA=O1({name:"deck-detail",description:"Render a presentation deck as Reveal.js slides",schema:Ft2,dataSourceId:"decks:entities",requiredPermission:"public",layout:{component:zMA,fullscreen:!0}});Rw();GA();var $RA=G.object({decks:G.array(Y2A)}),fRA=G.object({decks:G.array(Jm),pageTitle:G.string().optional(),pageLabel:G.string().optional()});import{jsxDEV as IRA}from"preact/jsx-dev-runtime";var Kt2="Presentations",DRA=({decks:A,pageLabel:Q})=>{let B=A.map(($)=>({id:$.id,url:$.url,title:$.frontmatter.title,date:$.frontmatter.publishedAt??$.created,description:$.frontmatter.description}));return IRA("div",{className:"deck-list bg-theme",children:IRA("div",{className:"container mx-auto max-w-[1100px] px-6 py-16 md:px-12 md:py-24",children:IRA(dT,{label:Q&&Q!=="Decks"?Q:Kt2,items:B},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)};d5();class X2A extends PB{constructor(){super($RA,{title:"Deck List",mappings:[{key:"decks",label:"Decks",type:"array",itemType:"object"}]})}}var HRA=O1({name:"deck-list",description:"List view of all presentation decks",schema:fRA,dataSourceId:"decks:entities",requiredPermission:"public",formatter:new X2A,layout:{component:DRA}});GA();$0();var Zt2=G.object({title:G.string().max(80).describe("A short, punchy title (2-5 words) that's memorable and evocative"),content:G.string().describe("Full slide deck content in markdown format with slide separators (---). Each slide should have a header and focused content."),description:G.string().describe("A concise 1-2 sentence summary that captures the essence of the talk")}),Dw1=O1({name:"decks:generation",description:"Template for AI to generate complete slide decks from prompts",schema:Zt2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are creating slide decks in a distinctive voice that blends philosophy, technology, and culture.
|
|
3298
3298
|
|
|
3299
3299
|
Your task is to generate a complete slide deck based on the user's prompt.
|
|
3300
3300
|
|
|
@@ -3363,7 +3363,7 @@ Add your conclusion here`,H=H??`Presentation: ${I}`,await this.reportProgress(Q,
|
|
|
3363
3363
|
Note: This presentation is for "${$}".`:""}`,R=await this.context.ai.generate({prompt:C,templateName:"decks:generation"});I=I??R.title,D=D??R.content,H=H??R.description,await this.reportProgress(Q,{progress:50,message:`Generated deck: "${I}"`})}else if(!H)await this.reportProgress(Q,{progress:30,message:"Generating description with AI"}),H=(await this.context.ai.generate({prompt:`Title: ${I}
|
|
3364
3364
|
|
|
3365
3365
|
Content:
|
|
3366
|
-
${D}`,templateName:"decks:description"})).description,await this.reportProgress(Q,{progress:50,message:"Description generated"});else await this.reportProgress(Q,{progress:50,message:"Using provided content"});if(!I||!D)this.failEarly("Title and content are required");let W={slug:U2(I),title:I,status:"draft"},F=await VU({entityType:"deck",title:I,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(F!==I)W.title=F,W.slug=U2(F);let K={title:W.title,status:W.status,slug:W.slug,description:H,author:w,event:$},Z=H9(D,K);return{id:F,content:Z,metadata:W,title:F,resultExtras:{title:F,slug:W.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Yw1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.
|
|
3366
|
+
${D}`,templateName:"decks:description"})).description,await this.reportProgress(Q,{progress:50,message:"Description generated"});else await this.reportProgress(Q,{progress:50,message:"Using provided content"});if(!I||!D)this.failEarly("Title and content are required");let W={slug:U2(I),title:I,status:"draft"},F=await VU({entityType:"deck",title:I,deriveId:(q)=>q,regeneratePrompt:"Generate a different presentation deck title on the same topic.",context:this.context});if(F!==I)W.title=F,W.slug=U2(F);let K={title:W.title,status:W.status,slug:W.slug,description:H,author:w,event:$},Z=H9(D,K);return{id:F,content:Z,metadata:W,title:F,resultExtras:{title:F,slug:W.slug},createOptions:{deduplicateId:!0}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Yw1={name:"@brains/decks",private:!0,version:"0.2.0-alpha.73",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/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 WRA extends KQ{entityType=Gm.entityType;schema=Gm.schema;adapter=Gm;constructor(){super("decks",Yw1)}createGenerationHandler(A){return new XRA(this.logger.child("DeckGenerationJobHandler"),A)}getTemplates(){return{"deck-detail":wRA,"deck-list":HRA,generation:Dw1,description:Hw1}}getDataSources(){return[new YRA(this.logger)]}getEntityTypeConfig(){return{weight:1.5}}async onRegister(A){await this.registerWithPublishPipeline(A),this.subscribeToPublishExecute(A),this.registerEvalHandlers(A),this.logger.info("Decks plugin registered")}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:y0($)}})}return{success:!0}})}registerEvalHandlers(A){A.eval.registerHandler("generateDeck",async(Q)=>{let B=G.object({prompt:G.string(),event:G.string().optional()}).parse(Q);return A.ai.generate({prompt:`${B.prompt}${B.event?`
|
|
3367
3367
|
|
|
3368
3368
|
Note: This presentation is for "${B.event}".`:""}`,templateName:"decks:generation"})}),A.eval.registerHandler("generateDescription",async(Q)=>{let B=G.object({title:G.string(),content:G.string()}).parse(Q);return A.ai.generate({prompt:`Title: ${B.title}
|
|
3369
3369
|
|
|
@@ -3378,7 +3378,7 @@ Guidelines:
|
|
|
3378
3378
|
3. Depth: Provide enough detail to be useful as a reference, but stay focused on the topic.
|
|
3379
3379
|
4. Style: Informative and educational. Write as if explaining to yourself for future reference.
|
|
3380
3380
|
5. Length: Adjust based on topic complexity - concise for simple topics, more detailed for complex ones.
|
|
3381
|
-
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});$0();GA();E$();var Uw1=G.object({prompt:G.string(),title:G.string().optional()}),Et2=AI.extend({title:G.string().optional()});class W2A extends X9{constructor(A,Q){super(A,Q,{schema:Uw1,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:fP.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Jw1={name:"@brains/note",private:!0,version:"0.2.0-alpha.
|
|
3381
|
+
6. No meta-commentary: Just provide the content directly without phrases like "Here is..." or "This note covers..."`});$0();GA();E$();var Uw1=G.object({prompt:G.string(),title:G.string().optional()}),Et2=AI.extend({title:G.string().optional()});class W2A extends X9{constructor(A,Q){super(A,Q,{schema:Uw1,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:fP.createNoteContent(w,B.body),metadata:{title:w},title:w,resultExtras:{title:w}}}summarizeDataForLog(A){return{prompt:A.prompt,title:A.title}}}var Jw1={name:"@brains/note",private:!0,version:"0.2.0-alpha.73",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 FRA extends KQ{entityType=fP.entityType;schema=$P;adapter=fP;constructor(A={}){super("note",Jw1,A,JRA)}createGenerationHandler(A){return new W2A(this.logger.child("NoteGenerationJobHandler"),A)}getTemplates(){return{generation:GRA}}async onRegister(A){A.eval.registerHandler("generateNote",async(Q)=>{let B=G.object({prompt:G.string()}).parse(Q);return A.ai.generate({prompt:B.prompt,templateName:"note:generation"})})}}function xC(A={}){return new FRA(A)}$0();GA();GA();$0();var Gw1=G.object({ref:G.string(),label:G.string()}),Fw1=G.enum(["pending","draft","published"]),IG=G.object({status:Fw1,title:G.string(),url:G.string().url(),description:G.string().optional(),domain:G.string(),capturedAt:G.string().datetime(),source:Gw1}),Kw1=IG.pick({title:!0,status:!0}),Zm=B2.extend({entityType:G.literal("link"),metadata:Kw1}),KRA=G.object({enableSummarization:G.boolean().default(!0).describe("Generate AI summaries for captured links"),jinaApiKey:G.string().optional().describe("Jina Reader API key for higher rate limits (500 RPM vs 20 RPM without key)")});$0();class lZ extends W2{constructor(){super({entityType:"link",schema:Zm,frontmatterSchema:IG})}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,IG),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 ZRA=new lZ;$0();GA();var Mt2=G.object({success:G.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:G.string().describe("If success is false, explain why content could not be extracted. Use an empty string when success is true."),title:G.string().max(80).describe("The page title - extract from the content or create a descriptive one. Leave empty string if success is false."),description:G.string().describe("A one-sentence description of what the page is about. Leave empty string if success is false."),summary:G.string().describe("A 1-2 paragraph summary of the main content. Leave empty string if success is false.")}),Zw1=O1({name:"link:extraction",description:"Extract structured content from webpage markdown",dataSourceId:"shell:ai-content",schema:Mt2,basePrompt:`You are an expert at extracting key information from webpage content.
|
|
3382
3382
|
|
|
3383
3383
|
You will receive webpage content in markdown format. Your job is to extract structured information from it.
|
|
3384
3384
|
|
|
@@ -3400,7 +3400,7 @@ Accuracy rules:
|
|
|
3400
3400
|
|
|
3401
3401
|
`))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 Rt2}from"crypto";class hC{static URL_PATTERN=/https?:\/\/[^\s<>"{}|\\^`[\]]+?(?=[,;:\s]|$)/gi;static extractUrls(A){let Q=A.match(hC.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=Rt2("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}}}$0();GA();E$();var Pt2=G.object({url:G.string().url(),metadata:G.object({interfaceId:G.string().optional(),userId:G.string().optional(),channelId:G.string().optional(),channelName:G.string().optional(),timestamp:G.string().optional()}).optional()}),s$w=G.object({success:G.boolean(),entityId:G.string().optional(),title:G.string().optional(),url:G.string().optional(),status:G.enum(["pending","draft","published"]).optional(),error:G.string().optional()});class J2A extends ow{context;linkAdapter;urlFetcher;constructor(A,Q,B){super(A,{schema:Pt2,jobTypeName:"link-capture"});this.context=Q,this.linkAdapter=new lZ,this.urlFetcher=new IP(B?.jinaApiKey?{jinaApiKey:B.jinaApiKey}:void 0)}async process(A,Q,B){let{url:w,metadata:$}=A;try{await B.report({progress:vQ.START,total:100,message:"Starting link capture"});let f=hC.generateEntityId(w);await B.report({progress:vQ.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:vQ.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:vQ.PROCESS,total:100,message:"Extracting content with AI"});let H=await this.context.ai.generate({templateName:"link:extraction",prompt:D.success?`Extract structured information from this webpage content:
|
|
3402
3402
|
|
|
3403
|
-
${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:H}),await B.report({progress:vQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),W=new Date().toISOString();if(H.success===!1||!H.title||!H.description||!H.summary){let Z=H.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:vQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),E=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:vQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:vQ.SAVE,total:100,message:`Saving link: "${H.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:H.title,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:F,metadata:{status:"draft",title:H.title}}});return await B.report({progress:vQ.COMPLETE,total:100,message:`Link captured: "${H.title}"`}),{success:!0,entityId:K.entityId,title:H.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),C$.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 qw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.
|
|
3403
|
+
${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:H}),await B.report({progress:vQ.EXTRACT,total:100,message:"Processing extraction results"});let Y=this.resolveSource($),W=new Date().toISOString();if(H.success===!1||!H.title||!H.description||!H.summary){let Z=H.title||new URL(w).hostname;this.logger.info("Incomplete extraction, saving as pending",{url:w}),await B.report({progress:vQ.SAVE,total:100,message:"Saving link as pending"});let q=this.linkAdapter.createLinkContent({status:"pending",title:Z,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),E=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:q,metadata:{status:"pending",title:Z}}});return await B.report({progress:vQ.COMPLETE,total:100,message:"Link saved (pending)"}),{success:!0,entityId:E.entityId,title:Z,url:w,status:"pending"}}await B.report({progress:vQ.SAVE,total:100,message:`Saving link: "${H.title}"`});let F=this.linkAdapter.createLinkContent({status:"draft",title:H.title,url:w,description:H.description,summary:H.summary,domain:new URL(w).hostname,capturedAt:W,source:Y}),K=await this.context.entityService.createEntity({entity:{id:f,entityType:"link",content:F,metadata:{status:"draft",title:H.title}}});return await B.report({progress:vQ.COMPLETE,total:100,message:`Link captured: "${H.title}"`}),{success:!0,entityId:K.entityId,title:H.title,url:w,status:"draft"}}catch(f){return this.logger.error("Link capture job failed",{error:f,jobId:Q,data:A}),C$.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 qw1={name:"@brains/link",private:!0,version:"0.2.0-alpha.73",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 LRA extends KQ{entityType=ZRA.entityType;schema=Zm;adapter=ZRA;shell;constructor(A={}){super("link",qw1,A,KRA)}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 J2A(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,H=this.extractFirstUrl(A.content);if(I&&D&&H){let Y=U2(H)||U2(I)||`${A.entityType}-${Date.now()}`,W=new Date().toISOString();return{kind:"handled",result:{success:!0,data:{entityId:(await B.entityService.createEntity({entity:{id:Y,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 J2A(this.logger.child("LinkCaptureJobHandler"),A,this.config.jinaApiKey?{jinaApiKey:this.config.jinaApiKey}:void 0)}getTemplates(){return{extraction:Zw1,"link-list":Nw1,"link-detail":zw1}}getDataSources(){return[new ERA(this.logger.child("LinksDataSource"))]}async onRegister(A){A.eval.registerHandler("extractContent",async(Q)=>{let{url:B}=G.object({url:G.string().url()}).parse(Q),$=await new IP(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:
|
|
3404
3404
|
|
|
3405
3405
|
${$.content}`,data:{url:B,hasContent:!0},interfacePermissionGrant:"public"})})}extractFirstUrl(...A){for(let Q of A){if(!Q)continue;let[B]=hC.extractUrls(Q);if(B)return B}return}}function Cw1(A={}){return new LRA(A)}var yC=Cw1;GA();var K9w=G.object({id:G.string().optional(),metadata:G.object({conversationId:G.string().optional(),interfaceId:G.string().optional(),userId:G.string().optional(),messageId:G.string().optional(),timestamp:G.string().optional()}).optional()});$0();GA();Rw();GA();$0();var Ew1=G.enum(["draft","published"]),D4=G.object({title:G.string(),slug:G.string().optional(),status:Ew1,publishedAt:G.string().datetime().optional(),description:G.string(),year:G.number(),coverImageId:G.string().optional(),url:G.string().url().optional()}),Lw1=D4.pick({title:!0,status:!0,publishedAt:!0,year:!0}).extend({slug:G.string()}),DP=B2.extend({entityType:G.literal("project"),metadata:Lw1}),G2A=G.object({context:G.string(),problem:G.string(),solution:G.string(),outcome:G.string()}),zm=DP.extend({frontmatter:D4,body:G.string(),structuredContent:G2A.optional(),coverImageUrl:G.string().optional()}),HP=zm.extend({url:G.string().optional(),typeLabel:G.string().optional(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()}),kt2=zm.extend({url:G.string(),typeLabel:G.string(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()});$0();GA();d5();class MRA extends PB{constructor(){super(G2A,{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 VRA=new MRA;class bRA extends W2{constructor(){super({entityType:"project",schema:DP,frontmatterSchema:D4,supportsCoverImage:!0,bodyFormatter:VRA})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,D4),w={...B,slug:B.slug??A.metadata.slug};return this.buildMarkdown(Q,w)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,D4),B=Q.slug??U2(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,D4)}parseStructuredContent(A){return VRA.parse(this.extractBody(A.content))}createProjectContent(A,Q){let B=VRA.format(Q);return this.buildMarkdown(B,A)}}var iZ=new bRA;GA();var ORA=G.object({});import{jsxDEV as iI,Fragment as vt2}from"preact/jsx-dev-runtime";var jt2=({project:A})=>{let{frontmatter:Q,url:B,coverImageUrl:w}=A;return iI(UB,{href:B,children:[w&&iI("img",{src:w,alt:Q.title,className:"w-full h-56 object-cover rounded-md mb-4"},void 0,!1,void 0,this),iI(f$,{children:Q.title},void 0,!1,void 0,this),iI("p",{className:"text-theme leading-relaxed",children:Q.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},RRA=({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 iI(vt2,{children:[iI(XQ,{title:$,description:I},void 0,!1,void 0,this),iI("div",{className:"project-list bg-theme",children:iI("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[iI("h1",{className:"text-4xl font-bold text-heading mb-12",children:$},void 0,!1,void 0,this),iI("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:A.map((D)=>iI(jt2,{project:D},D.id,!1,void 0,this))},void 0,!1,void 0,this),B&&B.totalPages>1&&iI("div",{className:"mt-12",children:iI(cJ,{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 cB,Fragment as Mw1}from"preact/jsx-dev-runtime";var xt2=({prevProject:A,nextProject:Q})=>{if(!A&&!Q)return null;return cB("nav",{className:"pt-12 mt-12 border-t border-theme-muted",children:cB("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[A?cB(UB,{href:A.url,variant:"compact",children:[cB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Previous"},void 0,!1,void 0,this),cB("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):cB("div",{},void 0,!1,void 0,this),Q&&cB(UB,{href:Q.url,variant:"compact",className:"md:text-right",children:[cB("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Next"},void 0,!1,void 0,this),cB("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)},F2A=({title:A,content:Q})=>{if(!Q)return null;return cB("section",{className:"mb-12",children:[cB("h2",{className:"text-2xl font-bold text-heading mb-4",children:A},void 0,!1,void 0,this),cB(mI,{markdown:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},PRA=({project:A,prevProject:Q,nextProject:B})=>{let{frontmatter:w,structuredContent:$,metadata:f,coverImageUrl:I}=A;return cB(Mw1,{children:[cB(XQ,{title:w.title,description:w.description,...I&&{ogImage:I},ogType:"article"},void 0,!1,void 0,this),cB("article",{className:"project-detail",children:cB("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:cB("div",{className:"max-w-3xl mx-auto",children:[I&&A.coverImageWidth&&A.coverImageHeight&&cB(mJ,{src:I,alt:w.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8 shadow-lg"},void 0,!1,void 0,this),cB("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),cB("div",{className:"flex flex-wrap items-center gap-4 text-theme-muted mb-8",children:[cB("span",{className:"text-sm",children:f.year},void 0,!1,void 0,this),w.url&&cB(Mw1,{children:[cB("span",{className:"text-theme-muted",children:"|"},void 0,!1,void 0,this),cB("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),cB("p",{className:"text-lg text-theme mb-12 leading-relaxed",children:w.description},void 0,!1,void 0,this),$&&cB("div",{className:"case-study",children:[cB(F2A,{title:"Context",content:$.context},void 0,!1,void 0,this),cB(F2A,{title:"Problem",content:$.problem},void 0,!1,void 0,this),cB(F2A,{title:"Solution",content:$.solution},void 0,!1,void 0,this),cB(F2A,{title:"Outcome",content:$.outcome},void 0,!1,void 0,this)]},void 0,!0,void 0,this),cB(xt2,{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();$0();var ht2=G.object({title:G.string().max(80).describe("A clear, compelling project title (3-8 words). Should capture the essence of the project."),description:G.string().describe("A 1-2 sentence summary of the project for portfolio cards. Focus on the core value delivered."),context:G.string().describe("Background information: Who was the client/user? What was the situation? What constraints existed? (2-4 paragraphs)"),problem:G.string().describe("The challenge: What specific problem needed solving? What were the pain points? (2-3 paragraphs)"),solution:G.string().describe("The approach: What was built? What technologies/methods were used? How did it work? (3-5 paragraphs)"),outcome:G.string().describe("The results: What impact did this have? What metrics improved? What was learned? (2-3 paragraphs)")}),_RA=O1({name:"portfolio:generation",description:"Template for AI to generate portfolio project case studies",schema:ht2,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,basePrompt:`You are helping to create a professional portfolio case study based on REAL project information.
|
|
3406
3406
|
|
|
@@ -3424,7 +3424,7 @@ ${A.prompt}
|
|
|
3424
3424
|
|
|
3425
3425
|
Project year: ${A.year}
|
|
3426
3426
|
|
|
3427
|
-
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 K2A extends X9{constructor(A,Q){super(A,Q,{schema:yt2,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:kRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=U2($);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:iZ.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}}}$0();$0();function gt2(A){let Q=t2(A.content,D4),B=iZ.parseStructuredContent(A);return zm.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class Z2A extends r6{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 gt2(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 Vw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.
|
|
3427
|
+
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 K2A extends X9{constructor(A,Q){super(A,Q,{schema:yt2,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:kRA(A),templateName:"portfolio:generation"}),$=A.title??w.title,f=U2($);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:iZ.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}}}$0();$0();function gt2(A){let Q=t2(A.content,D4),B=iZ.parseStructuredContent(A);return zm.parse({...A,frontmatter:Q.metadata,body:Q.content,structuredContent:B})}class Z2A extends r6{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 gt2(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 Vw1={name:"@brains/portfolio",private:!0,version:"0.2.0-alpha.73",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 St2=G.object({projects:G.array(HP),pageTitle:G.string().optional(),pagination:Y9.nullable(),baseUrl:G.string().optional()});function mt2(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 jRA extends KQ{entityType=iZ.entityType;schema=DP;adapter=iZ;constructor(A={}){super("portfolio",Vw1,A,ORA)}async interceptCreate(A,Q,B){if(!A.prompt||A.content)return{kind:"continue",input:A};let w=mt2(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 K2A(this.logger.child("ProjectGenerationJobHandler"),A)}getTemplates(){return{"project-list":O1({name:"project-list",description:"Portfolio project list page template",schema:St2,dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:RRA}}),"project-detail":O1({name:"project-detail",description:"Individual project case study template",schema:G.object({project:HP,prevProject:HP.nullable(),nextProject:HP.nullable()}),dataSourceId:"portfolio:entities",requiredPermission:"public",layout:{component:PRA}}),generation:_RA}}getDataSources(){return[new Z2A(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=G.object({prompt:G.string(),year:G.number()}).parse(Q);return A.ai.generate({prompt:kRA(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=t2($.content,D4),I=new Date().toISOString(),D=H9(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:y0($)}})}return{success:!0}})}}function vRA(A={}){return new jRA(A)}$0();GA();var bw1=G.object({includeEntityTypes:G.array(G.string()).default([]),minRelevanceScore:G.number().min(0).max(1).default(0.5),mergeSimilarityThreshold:G.number().min(0).max(1).default(0.85),autoMerge:G.boolean().default(!0),extractableStatuses:G.array(G.string()).default(["published"]),enableAutoExtraction:G.boolean().default(!0),sourceChangeBatchDelayMs:G.number().int().min(0).default(1000)});$0();GA();$0();var ut2=G.object({}),N2A=B2.extend({entityType:G.literal("topic"),metadata:ut2}),k7w=G.object({content:G.string()}),Ow1=G.object({title:G.string().describe("Topic title")});var gC="topics",pB="topic",xRA="topics-projection",Rw1="topic:project",z2A="topics-plugin",Pw1="topics:batch-completed",_w1="topics-source-batch";class DG extends W2{constructor(){super({entityType:pB,schema:N2A,frontmatterSchema:Ow1})}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:pB}}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))}}$0();GA();GA();var ct2=G.object({title:G.string().max(100),content:G.string(),relevanceScore:G.number().min(0).max(1)}),kw1=G.array(ct2);var pt2=G.object({topics:kw1}),jw1=O1({name:"topics:extraction",description:"Extract topics from conversation text",dataSourceId:"shell:ai-content",schema:pt2,basePrompt:`You are an expert at analyzing content and extracting key topics.
|
|
3428
3428
|
|
|
3429
3429
|
Analyze the provided content and extract meaningful topics discussed.
|
|
3430
3430
|
|
|
@@ -3527,13 +3527,13 @@ ${A.incomingTopic.content}`})}}function Ae2(A){if(A.length===0)return"";return A
|
|
|
3527
3527
|
|
|
3528
3528
|
${Q.content}`}).join(`
|
|
3529
3529
|
|
|
3530
|
-
`)}async function TC(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=pw1(A),H=new $Y(Q.entityService,B),Y=w.topicMergeSynthesizer??new mRA(Q,B),W=await M2A(Q.entityService),F=new Map,K=0,Z=0,q=0;for(let C of D){B.info(`Processing batch of ${C.length} entities`);let R=Ae2(C),k=V2A({entityTitle:`Batch of ${C.length} entities`,entityType:"batch",content:R,existingTopicTitles:W});try{let o=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((r)=>r.relevanceScore>=$);for(let r of o)try{if(f){let y=await H.findMergeCandidate({incoming:r,threshold:I,additionalCandidates:Array.from(F.values())});if(y){let g=await Y.synthesize({existingTopic:y.topic,incomingTopic:r}),AA=await H.applySynthesizedMerge({existingId:y.topic.id,synthesized:{...g,title:y.title}});if(!AA)throw Error(`Failed to merge topic: ${r.title}`);F.set(AA.id,AA),Z++;continue}}let S=SY(r.title);if(F.has(S)){q++;continue}let x=await H.createTopicOptimistic({title:r.title,content:r.content});if(x.topic)F.set(x.topic.id,x.topic);if(x.created)K++;else q++}catch(S){B.error("Topic batch item failed",{title:r.title,error:y0(S)})}}catch(P){B.error("Batch topic extraction failed",{batchSize:C.length,promptChars:k.length,error:y0(P)})}}let E={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:Pw1,payload:E,broadcast:!0});return E}GA();var Qe2=G.discriminatedUnion("mode",[G.object({mode:G.literal("derive"),reason:G.string().optional()}),G.object({mode:G.literal("rebuild"),reason:G.string().optional()}),G.object({mode:G.literal("source-batch"),minRelevanceScore:G.number().min(0).max(1).optional()})]);class uRA{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 ow1(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 Be2({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=Qe2.safeParse($??{});return f.success?f.data:null}}}async function Be2(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(H)=>({ref:H,entity:await A.context.entityService.getEntity({entityType:H.entityType,id:H.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:H,entity:Y}of B){if(!Y){$++;continue}if(Y.contentHash!==H.contentHash){w++;continue}if(!A.isEntityPublished(Y)){f++;continue}I.push(Y)}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 TC(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 sw1(){return{priority:5,source:z2A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:gC}}}async function aw1(A){let Q=await ew1(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 TC(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 tw1(A){let Q=await ew1(A),B=await cRA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function cRA(A,Q,B,w){let $=new $Y(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 TC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function ew1(A){let Q=we2(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 we2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var WP=G.object({entityType:G.string(),content:G.string(),metadata:G.record(G.unknown()).optional()}),$e2=WP.extend({minRelevanceScore:G.number().optional()}),fe2=G.object({contentA:WP,contentB:WP,minRelevanceScore:G.number().optional(),threshold:G.number().min(0).max(1).optional()}),Lm=G.object({title:G.string(),content:G.string()}),Ie2=G.object({existingTopics:G.array(Lm),incomingTopic:Lm,threshold:G.number().optional()}),De2=G.object({existingTopics:G.array(Lm).default([]),incomingTopic:Lm.extend({relevanceScore:G.number().min(0).max(1).optional()}),threshold:G.number().optional()}),He2=G.object({entities:G.array(WP).min(1),minRelevanceScore:G.number().optional()}),Ye2=G.object({existingTopics:G.array(Lm).optional(),entities:G.array(WP)}),Xe2=G.object({entities:G.array(WP)});function XP(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:hB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function A81(A){return{title:A.title,relevanceScore:A.relevanceScore}}function We2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Ue2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:We2(Q)}]}}async function SC(A){let Q=await A.entityService.listEntities({entityType:pB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:pB,id:B.id})))}async function Je2(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function Q81(A){let{context:Q,logger:B,config:w}=A,$=new SRA(Q,B),f=async(I,D,H="")=>{let Y=XP(I,H);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await SC(Q);let D=$e2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=XP(D);return(await $.extractFromEntity(Y,H)).map((F)=>Ue2(F,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await SC(Q);let D=fe2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[W,F]=await Promise.all([f(D.contentA,H,"-a"),f(D.contentB,H,"-b")]),K=new $Y(Q.entityService,B),Z=[];for(let C of W){let R=await K.createTopic(C);if(R)Z.push(R)}let q=(await Promise.all(F.map(async(C)=>{let R=await K.findMergeCandidate({incoming:C,threshold:Y,additionalCandidates:Z});if(!R)return null;return{incomingTitle:C.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((C)=>C!==null),E=q.map((C)=>C.candidateTitle);return{topicsA:W.map(A81),topicsB:F.map(A81),matchingTitles:E,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await SC(Q);let D=Ie2.parse(I),H=D.threshold??w.mergeSimilarityThreshold,Y=new $Y(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await Y.createTopic(K);if(Z)W.push(Z)}let F=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:H,additionalCandidates:W});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await SC(Q);let D=De2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics)await H.createTopic({title:K.title,content:K.content});await Je2(Q);let Y=XP({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await TC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:pB});return{...W,topicCount:F.length,topics:F.map(gRA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await SC(Q);let D=Ye2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics??[])await H.createTopic(K);let Y=D.entities.map((K,Z)=>XP(K,`-rebuild-${Z}`)),W=await cRA(Y,Q,B,w),F=await Q.entityService.listEntities({entityType:pB});return{...W,topicCount:F.length,topics:F.map(gRA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await SC(Q);let D=He2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=new $Y(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=XP(Z,`-sequential-${K}`),E=await $.extractFromEntity(q,H);for(let C of E)await Y.createTopic({title:C.title,content:C.content});W.push({extractedTitles:E.map((C)=>C.title)})}let F=await Q.entityService.listEntities({entityType:pB});return{totalTopics:F.length,perEntity:W,topics:F.map(YP)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await SC(Q);let H=Xe2.parse(I).entities.map((F,K)=>XP(F,`-batch-${K}`)),Y=await TC(H,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:pB});return{...Y,topics:W.map(YP)}})}var B81={name:"@brains/topics",private:!0,version:"0.2.0-alpha.72",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 Fe2=new DG;class w81 extends KQ{entityType=pB;schema=N2A;adapter=Fe2;sourceBatch=new uRA;constructor(A={}){super(gC,B81,A,bw1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:jw1,"merge-synthesis":vw1,"topic-list":xw1,"topic-detail":hw1}}getDataSources(){return[new TRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:xRA,targetType:pB,job:{type:Rw1,handler:ow1({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 qN(A,pB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:sw1()},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:z2A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:_w1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:gC}})}}]}async onRegister(A){A.insights.register("topic-distribution",Tw1()),Sw1({context:A,pluginId:this.id}),Q81({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(xRA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===pB)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 aw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await tw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function b2A(A){return new w81(A)}$0();GA();$0();var $81=G.enum(["linkedin"]),f81=G.enum(["draft","queued","published","failed"]),I81=G.enum(["post","deck"]),H4=G.object({title:G.string().describe("Short descriptive title (3-6 words) for file naming"),platform:$81.describe("Target platform"),status:f81,coverImageId:G.string().optional().describe("Image entity ID for post image"),publishedAt:G.string().datetime().optional(),platformPostId:G.string().optional().describe("ID from platform after publishing"),sourceEntityId:G.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:I81.optional().describe("Source entity type (post, deck)")}),D81=H4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:G.string().describe("URL-friendly identifier: {platform}-{title}")}),UP=B2.extend({entityType:G.literal("social-post"),metadata:D81}),O2A=UP.extend({frontmatter:H4,body:G.string()}),R2A=O2A.extend({url:G.string().optional(),listUrl:G.string().optional(),listLabel:G.string().optional(),typeLabel:G.string().optional(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()});$0();GA();class pRA extends W2{constructor(){super({entityType:"social-post",schema:UP,frontmatterSchema:H4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,H4),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,H4),B=`${Q.platform}-${U2(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,H4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var Vf=new pRA;$0();$0();GA();var Ke2=tY.extend({platform:G.enum(["linkedin"]).optional(),status:G.enum(["draft","queued","published","failed"]).optional(),sortByQueue:G.boolean().optional(),nextInQueue:G.boolean().optional()}),Ze2=eY.extend({query:Ke2.optional()});function H81(A){let Q=t2(A.content,H4);return O2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class P2A extends r6{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=Ze2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return H81(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:H,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(H,Y,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?H81(w):null;return A.parse({post:$})}}GA();var Y81=G.object({accessToken:G.string().optional(),refreshToken:G.string().optional(),organizationId:G.string().optional()}),lRA=G.object({linkedin:Y81.optional(),publishInterval:G.number().default(3600000),enabled:G.boolean().default(!0),defaultPrompt:G.string().default("Create an engaging social media post that drives engagement"),maxRetries:G.number().default(3),autoGenerateOnBlogPublish:G.boolean().default(!1)});$0();GA();E$();rRA();import{jsxDEV as b6,Fragment as qe2}from"preact/jsx-dev-runtime";function Ne2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function ze2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var k2A=({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 b6(qe2,{children:[b6(XQ,{title:$,description:I},void 0,!1,void 0,this),b6("div",{className:"social-post-list bg-theme",children:b6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?b6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b6("ul",{className:"space-y-6",children:A.map((D)=>b6("li",{children:b6(UB,{href:D.url,variant:"horizontal",children:b6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&b6("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),b6("div",{className:"flex-1 min-w-0",children:[b6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),b6("time",{className:"text-sm text-theme-muted shrink-0",children:ze2(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("div",{className:"flex items-center gap-2 mb-3",children:[b6(Ef,{status:D.frontmatter.status},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("p",{className:"text-theme leading-relaxed",children:Ne2(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&&b6(cJ,{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 O6,Fragment as Ce2}from"preact/jsx-dev-runtime";function X81(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var j2A=({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 O6(Ce2,{children:[O6(XQ,{title:Q,description:B},void 0,!1,void 0,this),O6("section",{className:"social-post-detail",children:O6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:O6("div",{className:"max-w-3xl mx-auto",children:[O6(tX,{items:w},void 0,!1,void 0,this),O6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),O6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[O6(Ef,{status:A.frontmatter.status},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),O6("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&&O6(mJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),O6(UB,{className:"p-8 mb-8",children:O6("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),O6("div",{className:"space-y-4 text-sm text-theme-muted",children:[O6("div",{children:[O6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",X81(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&O6("div",{children:[O6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",X81(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&O6("div",{children:O6("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 Mm(A){return`social-media:${A}`}var Ee2=G.union([G.boolean(),G.object({generate:G.boolean().optional(),prompt:G.string().optional()})]),dRA=G.object({prompt:G.string().optional(),platform:G.enum(["linkedin"]).optional(),sourceEntityType:G.enum(["post","deck"]).optional(),sourceEntityId:G.string().optional(),title:G.string().optional().describe("Required when content is provided directly"),content:G.string().optional(),addToQueue:G.boolean().optional(),generateImage:G.boolean().optional().describe("Auto-generate cover image for post"),coverImage:Ee2.optional().describe("Generic cover image generation request")}),Le2=AI.extend({slug:G.string().optional()});class mC extends X9{constructor(A,Q){super(A,Q,{schema:dRA,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:H}=A;if(D&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Mm(B)});H=C.title,D=C.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 C=await this.context.entityService.getEntity({entityType:f,id:I});if(!C)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let k=G.object({slug:G.string()}).safeParse(C.metadata),P=k.success?k.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3530
|
+
`)}async function TC(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=pw1(A),H=new $Y(Q.entityService,B),Y=w.topicMergeSynthesizer??new mRA(Q,B),W=await M2A(Q.entityService),F=new Map,K=0,Z=0,q=0;for(let C of D){B.info(`Processing batch of ${C.length} entities`);let R=Ae2(C),k=V2A({entityTitle:`Batch of ${C.length} entities`,entityType:"batch",content:R,existingTopicTitles:W});try{let o=(await Q.ai.generate({prompt:k,templateName:"topics:extraction"})).topics.filter((r)=>r.relevanceScore>=$);for(let r of o)try{if(f){let y=await H.findMergeCandidate({incoming:r,threshold:I,additionalCandidates:Array.from(F.values())});if(y){let g=await Y.synthesize({existingTopic:y.topic,incomingTopic:r}),AA=await H.applySynthesizedMerge({existingId:y.topic.id,synthesized:{...g,title:y.title}});if(!AA)throw Error(`Failed to merge topic: ${r.title}`);F.set(AA.id,AA),Z++;continue}}let S=SY(r.title);if(F.has(S)){q++;continue}let x=await H.createTopicOptimistic({title:r.title,content:r.content});if(x.topic)F.set(x.topic.id,x.topic);if(x.created)K++;else q++}catch(S){B.error("Topic batch item failed",{title:r.title,error:y0(S)})}}catch(P){B.error("Batch topic extraction failed",{batchSize:C.length,promptChars:k.length,error:y0(P)})}}let E={created:K,merged:Z,skipped:q,batches:D.length};if(K>0||Z>0)await Q.messaging.send({type:Pw1,payload:E,broadcast:!0});return E}GA();var Qe2=G.discriminatedUnion("mode",[G.object({mode:G.literal("derive"),reason:G.string().optional()}),G.object({mode:G.literal("rebuild"),reason:G.string().optional()}),G.object({mode:G.literal("source-batch"),minRelevanceScore:G.number().min(0).max(1).optional()})]);class uRA{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 ow1(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 Be2({context:Q,logger:B,config:w,sourceBatch:A.sourceBatch,isEntityPublished:A.isEntityPublished,minRelevanceScore:$.minRelevanceScore??w.minRelevanceScore})},validateAndParse:($)=>{let f=Qe2.safeParse($??{});return f.success?f.data:null}}}async function Be2(A){let Q=A.sourceBatch.drain(),B=await Promise.all(Q.map(async(H)=>({ref:H,entity:await A.context.entityService.getEntity({entityType:H.entityType,id:H.entityId})}))),w=0,$=0,f=0,I=[];for(let{ref:H,entity:Y}of B){if(!Y){$++;continue}if(Y.contentHash!==H.contentHash){w++;continue}if(!A.isEntityPublished(Y)){f++;continue}I.push(Y)}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 TC(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 sw1(){return{priority:5,source:z2A,deduplication:"coalesce",deduplicationKey:"topics-initial-derivation",metadata:{operationType:"data_processing",operationTarget:"topics-initial-derivation",pluginId:gC}}}async function aw1(A){let Q=await ew1(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 TC(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 tw1(A){let Q=await ew1(A),B=await cRA(Q,A.context,A.logger,A.config);A.logger.info("Topic rebuild complete",B)}async function cRA(A,Q,B,w){let $=new $Y(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 TC(A,Q,B,{minRelevanceScore:w.minRelevanceScore,autoMerge:w.autoMerge,mergeSimilarityThreshold:w.mergeSimilarityThreshold});return{deleted:f.length,...I}}async function ew1(A){let Q=we2(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 we2(A){return A.context.entityService.getEntityTypes().filter((B)=>A.shouldProcessEntityType(B))}var WP=G.object({entityType:G.string(),content:G.string(),metadata:G.record(G.unknown()).optional()}),$e2=WP.extend({minRelevanceScore:G.number().optional()}),fe2=G.object({contentA:WP,contentB:WP,minRelevanceScore:G.number().optional(),threshold:G.number().min(0).max(1).optional()}),Lm=G.object({title:G.string(),content:G.string()}),Ie2=G.object({existingTopics:G.array(Lm),incomingTopic:Lm,threshold:G.number().optional()}),De2=G.object({existingTopics:G.array(Lm).default([]),incomingTopic:Lm.extend({relevanceScore:G.number().min(0).max(1).optional()}),threshold:G.number().optional()}),He2=G.object({entities:G.array(WP).min(1),minRelevanceScore:G.number().optional()}),Ye2=G.object({existingTopics:G.array(Lm).optional(),entities:G.array(WP)}),Xe2=G.object({entities:G.array(WP)});function XP(A,Q=""){return{id:`eval${Q}-${Date.now()}`,entityType:A.entityType,content:A.content,contentHash:hB(A.content),metadata:A.metadata??{},created:new Date().toISOString(),updated:new Date().toISOString()}}function A81(A){return{title:A.title,relevanceScore:A.relevanceScore}}function We2(A){let Q=A.metadata.title;return typeof Q==="string"?Q:A.id}function Ue2(A,Q){return{...A,sources:[{id:Q.id,type:Q.entityType,title:We2(Q)}]}}async function SC(A){let Q=await A.entityService.listEntities({entityType:pB});await Promise.all(Q.map((B)=>A.entityService.deleteEntity({entityType:pB,id:B.id})))}async function Je2(A){for(;;){if((await A.jobs.getActiveJobs(["shell:embedding"])).length===0)return;await new Promise((B)=>setTimeout(B,100))}}function Q81(A){let{context:Q,logger:B,config:w}=A,$=new SRA(Q,B),f=async(I,D,H="")=>{let Y=XP(I,H);return $.extractFromEntity(Y,D)};Q.eval.registerHandler("extractFromEntity",async(I)=>{await SC(Q);let D=$e2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=XP(D);return(await $.extractFromEntity(Y,H)).map((F)=>Ue2(F,Y))}),Q.eval.registerHandler("checkMergeSimilarity",async(I)=>{await SC(Q);let D=fe2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=D.threshold??w.mergeSimilarityThreshold,[W,F]=await Promise.all([f(D.contentA,H,"-a"),f(D.contentB,H,"-b")]),K=new $Y(Q.entityService,B),Z=[];for(let C of W){let R=await K.createTopic(C);if(R)Z.push(R)}let q=(await Promise.all(F.map(async(C)=>{let R=await K.findMergeCandidate({incoming:C,threshold:Y,additionalCandidates:Z});if(!R)return null;return{incomingTitle:C.title,candidateTitle:R.title,candidateScore:R.score}}))).filter((C)=>C!==null),E=q.map((C)=>C.candidateTitle);return{topicsA:W.map(A81),topicsB:F.map(A81),matchingTitles:E,mergeCandidates:q,wouldMerge:q.length>0}}),Q.eval.registerHandler("detectMergeCandidate",async(I)=>{await SC(Q);let D=Ie2.parse(I),H=D.threshold??w.mergeSimilarityThreshold,Y=new $Y(Q.entityService,B),W=[];for(let K of D.existingTopics){let Z=await Y.createTopic(K);if(Z)W.push(Z)}let F=await Y.findMergeCandidate({incoming:{title:D.incomingTopic.title},threshold:H,additionalCandidates:W});return{found:F!==null,candidateTitle:F?.title,candidateScore:F?.score}}),Q.eval.registerHandler("processTopicWithAutoMerge",async(I)=>{await SC(Q);let D=De2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics)await H.createTopic({title:K.title,content:K.content});await Je2(Q);let Y=XP({entityType:"post",content:D.incomingTopic.content,metadata:{title:D.incomingTopic.title}},"-source"),W=await TC([Y],Q,B,{minRelevanceScore:0,autoMerge:!0,mergeSimilarityThreshold:D.threshold??w.mergeSimilarityThreshold}),F=await Q.entityService.listEntities({entityType:pB});return{...W,topicCount:F.length,topics:F.map(gRA)}}),Q.eval.registerHandler("rebuildTopics",async(I)=>{await SC(Q);let D=Ye2.parse(I),H=new $Y(Q.entityService,B);for(let K of D.existingTopics??[])await H.createTopic(K);let Y=D.entities.map((K,Z)=>XP(K,`-rebuild-${Z}`)),W=await cRA(Y,Q,B,w),F=await Q.entityService.listEntities({entityType:pB});return{...W,topicCount:F.length,topics:F.map(gRA)}}),Q.eval.registerHandler("extractSequentially",async(I)=>{await SC(Q);let D=He2.parse(I),H=D.minRelevanceScore??w.minRelevanceScore,Y=new $Y(Q.entityService,B),W=[];for(let[K,Z]of D.entities.entries()){let q=XP(Z,`-sequential-${K}`),E=await $.extractFromEntity(q,H);for(let C of E)await Y.createTopic({title:C.title,content:C.content});W.push({extractedTitles:E.map((C)=>C.title)})}let F=await Q.entityService.listEntities({entityType:pB});return{totalTopics:F.length,perEntity:W,topics:F.map(YP)}}),Q.eval.registerHandler("batchExtract",async(I)=>{await SC(Q);let H=Xe2.parse(I).entities.map((F,K)=>XP(F,`-batch-${K}`)),Y=await TC(H,Q,B,{minRelevanceScore:w.minRelevanceScore}),W=await Q.entityService.listEntities({entityType:pB});return{...Y,topics:W.map(YP)}})}var B81={name:"@brains/topics",private:!0,version:"0.2.0-alpha.73",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 Fe2=new DG;class w81 extends KQ{entityType=pB;schema=N2A;adapter=Fe2;sourceBatch=new uRA;constructor(A={}){super(gC,B81,A,bw1)}getEntityTypeConfig(){return{weight:0.5,projectionSource:!1}}getTemplates(){return{extraction:jw1,"merge-synthesis":vw1,"topic-list":xw1,"topic-detail":hw1}}getDataSources(){return[new TRA(this.logger.child("TopicsDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableAutoExtraction)return[];return[{id:xRA,targetType:pB,job:{type:Rw1,handler:ow1({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 qN(A,pB),jobData:{mode:"derive",reason:"initial-sync"},jobOptions:sw1()},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:z2A,delayMs:this.config.sourceChangeBatchDelayMs,deduplication:"skip",deduplicationKey:_w1,metadata:{operationType:"data_processing",operationTarget:"topic-source-batch",pluginId:gC}})}}]}async onRegister(A){A.insights.register("topic-distribution",Tw1()),Sw1({context:A,pluginId:this.id}),Q81({context:A,logger:this.logger,config:this.config})}hasRunInitialDerivation(){return this.getDerivedEntityProjectionController(xRA)?.hasQueuedInitialSync()??!1}shouldProcessEntityType(A,Q){if(A===pB)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 aw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}async rebuildAllTopics(A){await tw1({context:A,logger:this.logger,config:this.config,shouldProcessEntityType:(Q)=>this.shouldProcessEntityType(Q,A.entityService),isEntityPublished:(Q)=>this.isEntityPublished(Q)})}}function b2A(A){return new w81(A)}$0();GA();$0();var $81=G.enum(["linkedin"]),f81=G.enum(["draft","queued","published","failed"]),I81=G.enum(["post","deck"]),H4=G.object({title:G.string().describe("Short descriptive title (3-6 words) for file naming"),platform:$81.describe("Target platform"),status:f81,coverImageId:G.string().optional().describe("Image entity ID for post image"),publishedAt:G.string().datetime().optional(),platformPostId:G.string().optional().describe("ID from platform after publishing"),sourceEntityId:G.string().optional().describe("Source entity ID if auto-generated"),sourceEntityType:I81.optional().describe("Source entity type (post, deck)")}),D81=H4.pick({title:!0,platform:!0,status:!0,publishedAt:!0,platformPostId:!0}).extend({slug:G.string().describe("URL-friendly identifier: {platform}-{title}")}),UP=B2.extend({entityType:G.literal("social-post"),metadata:D81}),O2A=UP.extend({frontmatter:H4,body:G.string()}),R2A=O2A.extend({url:G.string().optional(),listUrl:G.string().optional(),listLabel:G.string().optional(),typeLabel:G.string().optional(),coverImageUrl:G.string().optional(),coverImageWidth:G.number().optional(),coverImageHeight:G.number().optional()});$0();GA();class pRA extends W2{constructor(){super({entityType:"social-post",schema:UP,frontmatterSchema:H4,supportsCoverImage:!0})}toMarkdown(A){let Q="",B={};try{B=this.parseFrontMatter(A.content,H4),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,H4),B=`${Q.platform}-${U2(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,H4)}getPostContent(A){return this.extractBody(A.content)}createPostContent(A,Q){return this.buildMarkdown(Q,A)}}var Vf=new pRA;$0();$0();GA();var Ke2=tY.extend({platform:G.enum(["linkedin"]).optional(),status:G.enum(["draft","queued","published","failed"]).optional(),sortByQueue:G.boolean().optional(),nextInQueue:G.boolean().optional()}),Ze2=eY.extend({query:Ke2.optional()});function H81(A){let Q=t2(A.content,H4);return O2A.parse({...A,frontmatter:Q.metadata,body:Q.content})}class P2A extends r6{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=Ze2.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){return H81(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:H,pagination:Y}=await this.fetchList(w,$,{...I&&{filter:{metadata:f}},sortFields:D});return Q.parse(this.buildListResult(H,Y,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?H81(w):null;return A.parse({post:$})}}GA();var Y81=G.object({accessToken:G.string().optional(),refreshToken:G.string().optional(),organizationId:G.string().optional()}),lRA=G.object({linkedin:Y81.optional(),publishInterval:G.number().default(3600000),enabled:G.boolean().default(!0),defaultPrompt:G.string().default("Create an engaging social media post that drives engagement"),maxRetries:G.number().default(3),autoGenerateOnBlogPublish:G.boolean().default(!1)});$0();GA();E$();rRA();import{jsxDEV as b6,Fragment as qe2}from"preact/jsx-dev-runtime";function Ne2(A,Q){if(A.length<=Q)return A;return A.slice(0,Q).trim()+"..."}function ze2(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}var k2A=({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 b6(qe2,{children:[b6(XQ,{title:$,description:I},void 0,!1,void 0,this),b6("div",{className:"social-post-list bg-theme",children:b6("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[b6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:$},void 0,!1,void 0,this),A.length===0?b6("p",{className:"text-theme-muted italic",children:"No social posts yet."},void 0,!1,void 0,this):b6("ul",{className:"space-y-6",children:A.map((D)=>b6("li",{children:b6(UB,{href:D.url,variant:"horizontal",children:b6("div",{className:"flex flex-col sm:flex-row gap-4",children:[D.coverImageUrl&&b6("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),b6("div",{className:"flex-1 min-w-0",children:[b6("div",{className:"flex items-start justify-between gap-4 mb-2",children:[b6("h2",{className:"text-lg font-semibold text-heading",children:D.frontmatter.title},void 0,!1,void 0,this),b6("time",{className:"text-sm text-theme-muted shrink-0",children:ze2(D.frontmatter.publishedAt??D.created)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("div",{className:"flex items-center gap-2 mb-3",children:[b6(Ef,{status:D.frontmatter.status},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted uppercase",children:D.frontmatter.platform},void 0,!1,void 0,this),b6("span",{className:"text-xs text-theme-muted font-mono",children:D.id},void 0,!1,void 0,this)]},void 0,!0,void 0,this),b6("p",{className:"text-theme leading-relaxed",children:Ne2(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&&b6(cJ,{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 O6,Fragment as Ce2}from"preact/jsx-dev-runtime";function X81(A){return new Date(A).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric",hour:"numeric",minute:"2-digit"})}var j2A=({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 O6(Ce2,{children:[O6(XQ,{title:Q,description:B},void 0,!1,void 0,this),O6("section",{className:"social-post-detail",children:O6("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:O6("div",{className:"max-w-3xl mx-auto",children:[O6(tX,{items:w},void 0,!1,void 0,this),O6("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-4",children:A.frontmatter.title},void 0,!1,void 0,this),O6("div",{className:"flex flex-wrap items-center gap-3 mb-6",children:[O6(Ef,{status:A.frontmatter.status},void 0,!1,void 0,this),O6("span",{className:"text-sm text-theme-muted uppercase",children:A.frontmatter.platform},void 0,!1,void 0,this),O6("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&&O6(mJ,{src:A.coverImageUrl,alt:A.frontmatter.title,width:A.coverImageWidth,height:A.coverImageHeight,className:"mb-8"},void 0,!1,void 0,this),O6(UB,{className:"p-8 mb-8",children:O6("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),O6("div",{className:"space-y-4 text-sm text-theme-muted",children:[O6("div",{children:[O6("span",{className:"font-medium",children:"Created:"},void 0,!1,void 0,this)," ",X81(A.created)]},void 0,!0,void 0,this),A.frontmatter.publishedAt&&O6("div",{children:[O6("span",{className:"font-medium",children:"Published:"},void 0,!1,void 0,this)," ",X81(A.frontmatter.publishedAt)]},void 0,!0,void 0,this),A.frontmatter.platformPostId&&O6("div",{children:O6("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 Mm(A){return`social-media:${A}`}var Ee2=G.union([G.boolean(),G.object({generate:G.boolean().optional(),prompt:G.string().optional()})]),dRA=G.object({prompt:G.string().optional(),platform:G.enum(["linkedin"]).optional(),sourceEntityType:G.enum(["post","deck"]).optional(),sourceEntityId:G.string().optional(),title:G.string().optional().describe("Required when content is provided directly"),content:G.string().optional(),addToQueue:G.boolean().optional(),generateImage:G.boolean().optional().describe("Auto-generate cover image for post"),coverImage:Ee2.optional().describe("Generic cover image generation request")}),Le2=AI.extend({slug:G.string().optional()});class mC extends X9{constructor(A,Q){super(A,Q,{schema:dRA,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:H}=A;if(D&&H)await this.reportProgress(Q,{progress:50,message:"Using provided content"});else if(D&&!H){await this.reportProgress(Q,{progress:10,message:"Shaping content with AI"});let C=await this.context.ai.generate({prompt:D,templateName:Mm(B)});H=C.title,D=C.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 C=await this.context.entityService.getEntity({entityType:f,id:I});if(!C)this.failEarly(`Source entity not found: ${f}/${I}`);await this.reportProgress(Q,{progress:30,message:"Generating social post from source content"});let k=G.object({slug:G.string()}).safeParse(C.metadata),P=k.success?k.data.slug:I,o=await this.context.ai.generate({prompt:`Create an engaging ${B} post to promote this ${f}:
|
|
3531
3531
|
|
|
3532
3532
|
Source: ${f}/${P}
|
|
3533
3533
|
|
|
3534
3534
|
${C.content}`,templateName:Mm(B)});H=o.title,D=o.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 C=await this.context.ai.generate({prompt:$,templateName:Mm(B)});H=C.title,D=C.content,await this.reportProgress(Q,{progress:50,message:"Social post generated"})}else this.failEarly("No content source provided (prompt, sourceEntityId, or content)");if(!D||!H)this.failEarly("Content or title was not generated");let W={title:H,platform:B,status:w?"queued":"draft",...I&&{sourceEntityId:I},...f&&{sourceEntityType:f}},F=Vf.createPostContent(W,D),Z=Vf.fromMarkdown(F).metadata;if(!Z)this.failEarly("Failed to parse social post metadata");let q=await VU({entityType:"social-post",title:H,deriveId:(C)=>`${B}-${U2(C)}`,regeneratePrompt:"Generate a different social media post title on the same topic.",context:this.context}),E=F;if(q!==H){Z.title=q,Z.slug=`${B}-${U2(q)}`;let C={...W,title:q};E=Vf.createPostContent(C,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}}}class nRA{config;logger;name="linkedin";apiBaseUrl="https://api.linkedin.com/v2";cachedUserId=null;constructor(A,Q){this.config=A;this.logger=Q}async publish(A,Q,B){if(!this.config.accessToken)throw Error("LinkedIn access token not configured");let w=await this.getAuthor(),$=null;if(B)$=await this.uploadImage(w,B);let f={shareCommentary:{text:A},shareMediaCategory:$?"IMAGE":"NONE",...$&&{media:[{status:"READY",media:$}]}},I=await 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:w,lifecycleState:"PUBLISHED",specificContent:{"com.linkedin.ugc.ShareContent":f},visibility:{"com.linkedin.ugc.MemberNetworkVisibility":"PUBLIC"}})});if(!I.ok){let Y=await I.text();throw this.logger.error("LinkedIn API error",{status:I.status,error:Y}),Error(`LinkedIn API error: ${I.status} - ${Y}`)}let D=I.headers.get("X-RestLi-Id")??"";this.logger.info("LinkedIn post created",{postId:D,hasImage:!!$});let H={id:D};if(D)H.url=`https://www.linkedin.com/feed/update/${D}`;return H}async uploadImage(A,Q){try{let B=await 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=await B.text();return this.logger.warn("LinkedIn image upload registration failed",{status:B.status,error:D}),null}let w=await B.json(),$=w.value.uploadMechanism["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"].uploadUrl,f=w.value.asset,I=await 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 validateCredentials(){if(!this.config.accessToken)return!1;try{if(this.config.organizationId)return(await 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 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 fetch("https://api.linkedin.com/v2/me",{headers:{Authorization:`Bearer ${this.config.accessToken}`}});if(!A.ok){let B=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 oRA(A,Q){return new nRA(A,Q)}$0();GA();Rw();rRA();var Me2=G.object({posts:G.array(R2A),totalCount:G.number().optional(),pagination:Y9.nullable(),baseUrl:G.string().optional()}),Ve2=G.object({post:R2A});function W81(){return{linkedin:_2A,"social-post-list":O1({name:"social-post-list",description:"Social post list page template",schema:Me2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:k2A}}),"social-post-detail":O1({name:"social-post-detail",description:"Individual social post template",schema:Ve2,dataSourceId:"social-media:posts",requiredPermission:"public",layout:{component:j2A}})}}GA();var be2=G.object({prompt:G.string().optional(),content:G.string().optional(),platform:G.enum(["linkedin"]).default("linkedin")}),Oe2=G.object({prompt:G.string().optional(),content:G.string().optional(),title:G.string().optional(),platform:G.enum(["linkedin"]).optional()});function U81(A){A.eval.registerHandler("generation",async(Q)=>{let B=be2.parse(Q),w=B.content?`Create an engaging LinkedIn post to share this content:
|
|
3535
3535
|
|
|
3536
|
-
${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=Oe2.parse(Q),w=[],$=z$.from(async(Y)=>{let W={progress:Y.progress};if(Y.message!==void 0)W.message=Y.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new mC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,H;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,H=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:H,progressSteps:w}})}GA();$0();class Vm{sendMessage;logger;entityService;providers;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers}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=t2(w.content,H4),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);try{let H=await f.publish(I.content,w.metadata,D),Y=new Date().toISOString(),W=H.id||void 0,F={...I.metadata,status:"published",publishedAt:Y,...W&&{platformPostId:W}},K=Vf.createPostContent(F,I.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:Y,platformPostId:W}}}),await this.reportSuccess(Q,B,H.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(H){let Y=H instanceof Error?H.message:String(H),W={...I.metadata,status:"failed"},F=Vf.createPostContent(W,I.content);await this.entityService.updateEntity({entity:{...w,content:F,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,Y),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:Y})}}catch(w){let $=y0(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 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 J81(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 G81(A,Q,B){let w=new Vm({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function F81(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 H=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function K81(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:`${Vf.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=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function Z81(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:`${Vf.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=y0($);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 N81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.72",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 sRA extends KQ{entityType=Vf.entityType;schema=UP;adapter=Vf;providers=new Map;constructor(A){super("social-media",N81,A,lRA)}createGenerationHandler(A){return new mC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return W81()}getDataSources(){return[new P2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),J81(A,this.providers,this.logger),G81(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)F81(A,this.logger),K81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");Z81(A,this.logger),U81(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=oRA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function bm(A){return new sRA(A)}GA();var Pe2=G.enum(["draft","queued","published","failed"]),J4w=G.object({status:Pe2.default("draft"),queueOrder:G.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:G.string().datetime().optional()});class aRA{name="internal";async publish(A,Q){return{id:"internal"}}}var k9={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"},rZ={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 _e2=G.object({skipIfDraftExists:G.boolean().optional(),minSourceEntities:G.number().optional(),maxUnpublishedDrafts:G.number().optional(),sourceEntityType:G.string().optional()}),z81=G.object({entitySchedules:G.record(G.string(),G.string()).optional(),generationSchedules:G.record(G.string(),G.string()).optional(),generationConditions:G.record(G.string(),_e2).optional(),maxRetries:G.number().optional().default(3),retryBaseDelayMs:G.number().optional().default(5000)});class FW{static instance=null;queues=new Map;static getInstance(){return FW.instance??=new FW,FW.instance}static resetInstance(){FW.instance=null}static createFresh(){return new FW}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 KW{static instance=null;providers=new Map;defaultProvider=new aRA;static getInstance(){return KW.instance??=new KW,KW.instance}static resetInstance(){KW.instance=null}static createFresh(){return new KW}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 q81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:k9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function C81(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=y0($);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 E81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:k9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function L81(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:k9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function M81(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:rZ.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:rZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function V81(A,Q,B){if(B)B.send({type:rZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function b81(A,Q,B){if(B)B.send({type:rZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var ke2=1000;class tRA{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(ke2,()=>this.processUnscheduledTypes())}stop(){if(je2(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 q81(A,this.deps.getPublishDeps());else await C81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function je2(A){for(let Q of A.values())Q.stop();A.clear()}class eRA{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(){ve2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await M81(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 ve2(A){for(let Q of A.values())Q.stop();A.clear()}class fY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return fY.instance??=new fY(A),fY.instance}static resetInstance(){if(fY.instance)fY.instance.stop();fY.instance=null}static createFresh(A){return new fY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new tRA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new eRA({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){E81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){L81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){V81(A,Q,this.config.messageBus)}failGeneration(A,Q){b81(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}" - ${y0(w)}`)}}}var O81={maxRetries:3,baseDelayMs:5000};class ZW{static instance=null;retries=new Map;config;static getInstance(A){return ZW.instance??=new ZW(A??O81),ZW.instance}static resetInstance(){ZW.instance=null}static createFresh(A){return new ZW(A??O81)}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 j9(A,Q,B,w,$,f,I,D){return j9.fromTZ(j9.tp(A,Q,B,w,$,f,I),D)}j9.fromTZISO=(A,Q,B)=>j9.fromTZ(xe2(A,Q),B);j9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=APA(A.tz,B),$=new Date(B.getTime()-w),f=APA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=APA(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 $}};j9.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}};j9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function APA(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 xe2(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("+")?j9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):j9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}j9.minitz=j9;var QPA=32,Rm=31|QPA,k81=[1,2,4,8,16],R81=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 Y4(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,Rm),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,H]=f,Y=parseInt(I,10)+B,W=parseInt(D,10)+B,F=parseInt(H,10);if(isNaN(Y))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(Y>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=Y;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 H=I;H<=D;H++)this.setPart(Q,H,$[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 H=I;H<this[Q].length;H+=D)this.setPart(Q,H,$[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]|QPA;else if(Q===Rm)this.dayOfWeek[A]=Rm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|k81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},P81=[31,28,31,30,31,30,31,31,30,31,30,31],HG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],Y4=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($&Rm&&k81[I-1]&$)return!0;if($&QPA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let H=w+1;H<=D;H++)if(new Date(Date.UTC(Q,B,H)).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=j9.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>P81[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=j9.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(j9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=P81[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 H=this[B]+$;H<w[B].length;H++){let Y=w[B][H];if(B==="day"&&w.lastDayOfMonth&&H-$==I&&(Y=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(H-$-1))%7];if(W&&W&Rm)W=this.isNthWeekdayOfMonth(this.year,this.month,H-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?Y=Y||W:Y=Y&&W}if(Y)return this[B]=H-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,HG[w][0],Q,HG[w][2]);if($>1){let f=w+1;for(;f<HG.length;)this[HG[f][0]]=-HG[f][2],f++;if($===3)return this[HG[w][1]]++,this[HG[w][0]]=-HG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=HG.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)):j9.fromTZ(j9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function he2(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 Y4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new Y4(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 Om(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function ye2(A){return Om(A)}function ge2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var _81=30000,v2A=[],BPA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Om(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(Om(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=he2(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 R81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new Y4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new R81(A,this.options.timezone),this.name){if(v2A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");v2A.push(this)}return $!==void 0&&ye2($)&&(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 Y4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new Y4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=v2A.indexOf(this);A>=0&&v2A.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>_81&&(Q=_81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&ge2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new Y4(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){Om(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new Y4(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&&Om(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 Y4(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 Y4(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 Y4(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 Y4(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 x2A{scheduleCron(A,Q){let B=new BPA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new BPA(A).stop()}}$0();GA();var wPA=G.object({action:G.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:G.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:G.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:G.number().optional().describe("New position for reorder action (1-based)")}),$PA=G.object({position:G.number(),entityType:G.string(),entityId:G.string(),queuedAt:G.string()}),Te2=G.object({success:G.literal(!0),message:G.string().optional(),data:G.object({queue:G.array($PA).optional(),entityType:G.string().optional(),entityId:G.string().optional(),position:G.number().optional()}).optional()}),Se2=G.object({success:G.literal(!1),error:G.string(),code:G.string().optional()}),fPA=G.union([Te2,Se2]);function h2A(A,Q,B){return{...xQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",wPA,async($)=>{let{action:f,entityType:I,entityId:D,position:H}=$;switch(f){case"list":return me2(B,I);case"add":return ue2(B,I,D);case"remove":return ce2(B,I,D);case"reorder":return pe2(B,I,D,H);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:fPA}}async function me2(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 ue2(A,Q,B){let w=IPA("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 ce2(A,Q,B){let w=IPA("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 pe2(A,Q,B,w){let $=IPA("reorder",Q,B);if(!$.success)return $.error;let f=le2(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 IPA(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 le2(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}}$0();GA();$0();GA();async function j81(A,Q){let{bodyContent:B,coverImageId:w}=ie2(Q.content),$=w?await re2(A,w):void 0,f={bodyContent:B};if($)f.imageData=$;return f}function ie2(A){try{let Q=t2(A,G.record(G.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0;return w?{bodyContent:Q.content,coverImageId:w}:{bodyContent:Q.content}}catch{return{bodyContent:A}}}async function re2(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=B.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2])return;return{data:Buffer.from(w[2],"base64"),mimeType:w[1]}}var DPA=G.object({entityType:G.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:G.string().optional().describe("Entity ID to publish"),slug:G.string().optional().describe("Entity slug to publish")}),de2=G.object({success:G.literal(!0),message:G.string().optional(),data:G.object({entityType:G.string().optional(),entityId:G.string().optional(),platformId:G.string().optional(),url:G.string().optional()}).optional()}),ne2=G.object({success:G.literal(!1),error:G.string(),code:G.string().optional()}),HPA=G.union([de2,ne2]);function y2A(A,Q,B){return{...xQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",DPA,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let H=await oe2(A,f,I,D);if(!H)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(H.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 Y=B.get(f),{bodyContent:W,imageData:F}=await j81(A,H),K=await Y.publish(W,H.metadata,F);return await A.entityService.updateEntity({entity:{...H,metadata:{...H.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:f,entityId:H.id,platformId:K.id,url:K.url},message:`Published ${f}:${H.id}`}}),outputSchema:HPA}}async function oe2(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}$0();GA();function v81(A,Q){se2(A,Q),ae2(A,Q)}function se2(A,Q){A.messaging.subscribe(k9.REGISTER,async(B)=>te2(Q,B.payload)),A.messaging.subscribe(k9.QUEUE,async(B)=>ee2(A,Q,B.payload)),A.messaging.subscribe(k9.DIRECT,async(B)=>AAQ(A,Q,B.payload)),A.messaging.subscribe(k9.REMOVE,async(B)=>QAQ(Q,B.payload)),A.messaging.subscribe(k9.REORDER,async(B)=>BAQ(Q,B.payload)),A.messaging.subscribe(k9.LIST,async(B)=>wAQ(A,Q,B.payload)),A.messaging.subscribe(k9.REPORT_SUCCESS,async(B)=>$AQ(Q,B.payload)),A.messaging.subscribe(k9.REPORT_FAILURE,async(B)=>fAQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function ae2(A,Q){A.messaging.subscribe(rZ.REPORT_SUCCESS,async(B)=>IAQ(Q,B.payload)),A.messaging.subscribe(rZ.REPORT_FAILURE,async(B)=>DAQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function te2(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=y0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function ee2(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:k9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function AAQ(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:k9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function QAQ(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=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function BAQ(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=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function wAQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:k9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function $AQ(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 fAQ(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 IAQ(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 DAQ(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 x81(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:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function h81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=HAQ(Q);return fY.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new x2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(H,Y)=>x81(Q.entityService,I,H,Y)})}function HAQ(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 y81(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 YAQ=["draft","queued","published","failed"];async function g81(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:()=>XAQ(A)}})}async function XAQ(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=WAQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:UAQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function WAQ(A){return YAQ.find((Q)=>Q===A)}function UAQ(A,Q){return typeof Q==="string"?Q:A}var T81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.72",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 YPA extends RB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",T81,A??{},z81)}async onRegister(A){this.pluginContext=A,this.queueManager=FW.createFresh(),this.providerRegistry=KW.createFresh(),this.retryTracker=ZW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=h81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),v81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await y81(A.entityService,this.queueManager,this.logger),await g81(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[h2A(this.pluginContext,this.id,this.queueManager),y2A(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(),FW.resetInstance(),KW.resetInstance(),ZW.resetInstance()}}function XPA(A){return new YPA(A)}$0();GA();var S81=G.object({accountId:G.string().describe("Cloudflare account ID"),apiToken:G.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:G.string().describe("Cloudflare Web Analytics site tag")}),WPA=G.object({cloudflare:S81.optional()});$0();GA();var GAQ=G.object({date:G.string().describe("Single date in YYYY-MM-DD format").optional(),days:G.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:G.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:G.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:G.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function FAQ(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 m81(A,Q,B){let w=[];if(!B)return w;return w.push(xQ(A,"query",`Query website analytics from Cloudflare.
|
|
3536
|
+
${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=Oe2.parse(Q),w=[],$=z$.from(async(Y)=>{let W={progress:Y.progress};if(Y.message!==void 0)W.message=Y.message;w.push(W)});if(!$)throw Error("Failed to create progress reporter");let I=await new mC(A.logger,A).process(B,`eval-${Date.now()}`,$),D=!1,H;if(I.success&&I.entityId){let Y=await A.entityService.getEntity({entityType:"social-post",id:I.entityId});D=!!Y,H=Y?.content.slice(0,300)}return{...I,entityExists:D,entityPreview:H,progressSteps:w}})}GA();$0();class Vm{sendMessage;logger;entityService;providers;constructor(A){this.sendMessage=A.sendMessage,this.logger=A.logger,this.entityService=A.entityService,this.providers=A.providers}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=t2(w.content,H4),D;if(I.metadata.coverImageId)D=await this.fetchImageData(I.metadata.coverImageId);try{let H=await f.publish(I.content,w.metadata,D),Y=new Date().toISOString(),W=H.id||void 0,F={...I.metadata,status:"published",publishedAt:Y,...W&&{platformPostId:W}},K=Vf.createPostContent(F,I.content);await this.entityService.updateEntity({entity:{...w,content:K,metadata:{...w.metadata,status:"published",publishedAt:Y,platformPostId:W}}}),await this.reportSuccess(Q,B,H.id),this.logger.info(`Post published successfully: ${B}`,{platform:$,platformPostId:W})}catch(H){let Y=H instanceof Error?H.message:String(H),W={...I.metadata,status:"failed"},F=Vf.createPostContent(W,I.content);await this.entityService.updateEntity({entity:{...w,content:F,metadata:{...w.metadata,status:"failed"}}}),await this.reportFailure(Q,B,Y),this.logger.error(`Post publish failed: ${B}`,{platform:$,error:Y})}}catch(w){let $=y0(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 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 J81(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 G81(A,Q,B){let w=new Vm({sendMessage:A.messaging.send,logger:B.child("PublishExecuteHandler"),entityService:A.entityService,providers:Q});A.messaging.subscribe("publish:execute",async($)=>{return await w.handle($.payload),{success:!0}}),B.debug("Subscribed to publish:execute messages")}GA();function F81(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 H=y0(D);return Q.error(`Failed to trigger auto-generate for ${$}:`,{error:H}),{success:!0}}}),Q.debug("Subscribed to entity:updated for auto-generation")}function K81(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:`${Vf.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=y0(I);return Q.error(`Failed to enqueue social post generation for ${$}:`,{error:D}),{success:!1}}}),Q.debug("Subscribed to social:auto-generate messages")}function Z81(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:`${Vf.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=y0($);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 N81={name:"@brains/social-media",private:!0,version:"0.2.0-alpha.73",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 sRA extends KQ{entityType=Vf.entityType;schema=UP;adapter=Vf;providers=new Map;constructor(A){super("social-media",N81,A,lRA)}createGenerationHandler(A){return new mC(this.logger.child("GenerationJobHandler"),A)}getTemplates(){return W81()}getDataSources(){return[new P2A(this.logger.child("SocialPostDataSource"))]}async onRegister(A){if(this.initializeProviders(),J81(A,this.providers,this.logger),G81(A,this.providers,this.logger),this.config.autoGenerateOnBlogPublish)F81(A,this.logger),K81(A,this.logger),this.logger.info("Auto-generate on blog publish enabled");Z81(A,this.logger),U81(A),this.logger.info("Social media plugin registered successfully")}initializeProviders(){if(this.config.linkedin?.accessToken){let A=oRA(this.config.linkedin,this.logger.child("LinkedInClient"));this.providers.set("linkedin",A),this.logger.info("LinkedIn provider initialized")}}}function bm(A){return new sRA(A)}GA();var Pe2=G.enum(["draft","queued","published","failed"]),J4w=G.object({status:Pe2.default("draft"),queueOrder:G.number().optional().describe("Position in publish queue (lower = sooner)"),publishedAt:G.string().datetime().optional()});class aRA{name="internal";async publish(A,Q){return{id:"internal"}}}var k9={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"},rZ={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 _e2=G.object({skipIfDraftExists:G.boolean().optional(),minSourceEntities:G.number().optional(),maxUnpublishedDrafts:G.number().optional(),sourceEntityType:G.string().optional()}),z81=G.object({entitySchedules:G.record(G.string(),G.string()).optional(),generationSchedules:G.record(G.string(),G.string()).optional(),generationConditions:G.record(G.string(),_e2).optional(),maxRetries:G.number().optional().default(3),retryBaseDelayMs:G.number().optional().default(5000)});class FW{static instance=null;queues=new Map;static getInstance(){return FW.instance??=new FW,FW.instance}static resetInstance(){FW.instance=null}static createFresh(){return new FW}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 KW{static instance=null;providers=new Map;defaultProvider=new aRA;static getInstance(){return KW.instance??=new KW,KW.instance}static resetInstance(){KW.instance=null}static createFresh(){return new KW}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 q81(A,Q){let B={entityType:A.entityType,entityId:A.entityId};if(Q.messageBus)await Q.messageBus.send({type:k9.EXECUTE,payload:B,sender:"publish-service"});Q.onExecute?.(B)}async function C81(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=y0($);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 E81(A,Q,B,w){if(w.retryTracker.clearRetries(Q),w.messageBus)w.messageBus.send({type:k9.COMPLETED,payload:{entityType:A,entityId:Q,result:B},sender:"publish-service"});w.onPublish?.({entityType:A,entityId:Q,result:B})}function L81(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:k9.FAILED,payload:f,sender:"publish-service"});w.onFailed?.(f)}async function M81(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:rZ.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:rZ.EXECUTE,payload:w,sender:"content-pipeline"});Q.onGenerate?.(w)}function V81(A,Q,B){if(B)B.send({type:rZ.COMPLETED,payload:{entityType:A,entityId:Q},sender:"content-pipeline"})}function b81(A,Q,B){if(B)B.send({type:rZ.FAILED,payload:{entityType:A,error:Q},sender:"content-pipeline"})}var ke2=1000;class tRA{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(ke2,()=>this.processUnscheduledTypes())}stop(){if(je2(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 q81(A,this.deps.getPublishDeps());else await C81(A,this.deps.getPublishDeps())}get entitySchedules(){return this.deps.config.entitySchedules}}function je2(A){for(let Q of A.values())Q.stop();A.clear()}class eRA{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(){ve2(this.generationJobs)}async handleTriggerGeneration(A){if(!this.deps.isRunning())return;try{await M81(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 ve2(A){for(let Q of A.values())Q.stop();A.clear()}class fY{static instance=null;config;publishRunner;generationRunner;running=!1;static getInstance(A){return fY.instance??=new fY(A),fY.instance}static resetInstance(){if(fY.instance)fY.instance.stop();fY.instance=null}static createFresh(A){return new fY(A)}constructor(A){this.config={...A,entitySchedules:A.entitySchedules??{},generationSchedules:A.generationSchedules??{},generationConditions:A.generationConditions??{}},this.validateCronExpressions(),this.publishRunner=new tRA({config:this.config,getPublishDeps:()=>this.publishDeps,isRunning:()=>this.running}),this.generationRunner=new eRA({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){E81(A,Q,B,this.publishDeps)}failPublish(A,Q,B){L81(A,Q,B,this.publishDeps)}async publishDirect(A,Q,B,w){return this.config.providerRegistry.get(A).publish(B,w)}completeGeneration(A,Q){V81(A,Q,this.config.messageBus)}failGeneration(A,Q){b81(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}" - ${y0(w)}`)}}}var O81={maxRetries:3,baseDelayMs:5000};class ZW{static instance=null;retries=new Map;config;static getInstance(A){return ZW.instance??=new ZW(A??O81),ZW.instance}static resetInstance(){ZW.instance=null}static createFresh(A){return new ZW(A??O81)}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 j9(A,Q,B,w,$,f,I,D){return j9.fromTZ(j9.tp(A,Q,B,w,$,f,I),D)}j9.fromTZISO=(A,Q,B)=>j9.fromTZ(xe2(A,Q),B);j9.fromTZ=function(A,Q){let B=new Date(Date.UTC(A.y,A.m-1,A.d,A.h,A.i,A.s)),w=APA(A.tz,B),$=new Date(B.getTime()-w),f=APA(A.tz,$);if(f-w===0)return $;{let I=new Date(B.getTime()-f),D=APA(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 $}};j9.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}};j9.tp=(A,Q,B,w,$,f,I)=>({y:A,m:Q,d:B,h:w,i:$,s:f,tz:I});function APA(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 xe2(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("+")?j9.tp(B.getUTCFullYear(),B.getUTCMonth()+1,B.getUTCDate(),B.getUTCHours(),B.getUTCMinutes(),B.getUTCSeconds(),"Etc/UTC"):j9.tp(B.getFullYear(),B.getMonth()+1,B.getDate(),B.getHours(),B.getMinutes(),B.getSeconds(),Q)}j9.minitz=j9;var QPA=32,Rm=31|QPA,k81=[1,2,4,8,16],R81=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 Y4(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,Rm),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,H]=f,Y=parseInt(I,10)+B,W=parseInt(D,10)+B,F=parseInt(H,10);if(isNaN(Y))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(Y>W)throw TypeError("CronPattern: From value is larger than to value: '"+A+"'");for(let K=Y;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 H=I;H<=D;H++)this.setPart(Q,H,$[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 H=I;H<this[Q].length;H+=D)this.setPart(Q,H,$[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]|QPA;else if(Q===Rm)this.dayOfWeek[A]=Rm;else if(Q<6&&Q>0)this.dayOfWeek[A]=this.dayOfWeek[A]|k81[Q-1];else throw TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${Q}, Type: ${typeof Q}`)}},P81=[31,28,31,30,31,30,31,31,30,31,30,31],HG=[["month","year",0],["day","month",-1],["hour","day",0],["minute","hour",0],["second","minute",0]],Y4=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($&Rm&&k81[I-1]&$)return!0;if($&QPA){let D=new Date(Date.UTC(Q,B+1,0)).getUTCDate();for(let H=w+1;H<=D;H++)if(new Date(Date.UTC(Q,B,H)).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=j9.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>P81[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=j9.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(j9.fromTZISO(Q,this.tz))}findNext(Q,B,w,$){let f=this[B],I;w.lastDayOfMonth&&(this.month!==1?I=P81[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 H=this[B]+$;H<w[B].length;H++){let Y=w[B][H];if(B==="day"&&w.lastDayOfMonth&&H-$==I&&(Y=1),B==="day"&&!w.starDOW){let W=w.dayOfWeek[(D+(H-$-1))%7];if(W&&W&Rm)W=this.isNthWeekdayOfMonth(this.year,this.month,H-$,W)?1:0;else if(W)throw Error(`CronDate: Invalid value for dayOfWeek encountered. ${W}`);Q.legacyMode&&!w.starDOM?Y=Y||W:Y=Y&&W}if(Y)return this[B]=H-$,f!==this[B]?2:1}return 3}recurse(Q,B,w){let $=this.findNext(B,HG[w][0],Q,HG[w][2]);if($>1){let f=w+1;for(;f<HG.length;)this[HG[f][0]]=-HG[f][2],f++;if($===3)return this[HG[w][1]]++,this[HG[w][0]]=-HG[w][2],this.apply(),this.recurse(Q,B,0);if(this.apply())return this.recurse(Q,B,w-1)}return w+=1,w>=HG.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)):j9.fromTZ(j9.tp(this.year,this.month+1,this.day,this.hour,this.minute,this.second,this.tz),!1)}getTime(){return this.getDate(!1).getTime()}};function he2(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 Y4(A.startAt,A.timezone)),A.stopAt&&(A.stopAt=new Y4(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 Om(A){return Object.prototype.toString.call(A)==="[object Function]"||typeof A=="function"||A instanceof Function}function ye2(A){return Om(A)}function ge2(A){typeof Deno<"u"&&typeof Deno.unrefTimer<"u"?Deno.unrefTimer(A):A&&typeof A.unref<"u"&&A.unref()}var _81=30000,v2A=[],BPA=class{name;options;_states;fn;constructor(A,Q,B){let w,$;if(Om(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(Om(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=he2(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 R81("* * * * *")},A&&(A instanceof Date||typeof A=="string"&&A.indexOf(":")>0)?this._states.once=new Y4(A,this.options.timezone||this.options.utcOffset):this._states.pattern=new R81(A,this.options.timezone),this.name){if(v2A.find((f)=>f.name===this.name))throw Error("Cron: Tried to initialize new named job '"+this.name+"', but name already taken.");v2A.push(this)}return $!==void 0&&ye2($)&&(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 Y4||A instanceof Date?Q.getTime()-A.getTime():Q.getTime()-new Y4(A).getTime():null}stop(){this._states.kill=!0,this._states.currentTimeout&&clearTimeout(this._states.currentTimeout);let A=v2A.indexOf(this);A>=0&&v2A.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>_81&&(Q=_81),this._states.currentTimeout=setTimeout(()=>this._checkTrigger(B),Q),this._states.currentTimeout&&this.options.unref&&ge2(this._states.currentTimeout),this)}async _trigger(A){if(this._states.blocking=!0,this._states.currentRun=new Y4(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){Om(this.options.catch)&&this.options.catch(Q,this)}else this.fn!==void 0&&await this.fn(this,this.options.context);this._states.previousRun=new Y4(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&&Om(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 Y4(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 Y4(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 Y4(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 Y4(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 x2A{scheduleCron(A,Q){let B=new BPA(A,()=>{Q()});return{stop:()=>B.stop()}}scheduleInterval(A,Q){let B=setInterval(()=>{Q()},A);return{stop:()=>clearInterval(B)}}validateCron(A){new BPA(A).stop()}}$0();GA();var wPA=G.object({action:G.enum(["list","add","remove","reorder"]).describe("Queue action to perform"),entityType:G.string().optional().describe("Entity type (required for add/remove/reorder, optional for list)"),entityId:G.string().optional().describe("Entity ID (required for add/remove/reorder)"),position:G.number().optional().describe("New position for reorder action (1-based)")}),$PA=G.object({position:G.number(),entityType:G.string(),entityId:G.string(),queuedAt:G.string()}),Te2=G.object({success:G.literal(!0),message:G.string().optional(),data:G.object({queue:G.array($PA).optional(),entityType:G.string().optional(),entityId:G.string().optional(),position:G.number().optional()}).optional()}),Se2=G.object({success:G.literal(!1),error:G.string(),code:G.string().optional()}),fPA=G.union([Te2,Se2]);function h2A(A,Q,B){return{...xQ(Q,"queue","Manage the publish queue for all entity types (list, add, remove, reorder)",wPA,async($)=>{let{action:f,entityType:I,entityId:D,position:H}=$;switch(f){case"list":return me2(B,I);case"add":return ue2(B,I,D);case"remove":return ce2(B,I,D);case"reorder":return pe2(B,I,D,H);default:return{success:!1,error:`Unknown action: ${f}`}}}),outputSchema:fPA}}async function me2(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 ue2(A,Q,B){let w=IPA("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 ce2(A,Q,B){let w=IPA("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 pe2(A,Q,B,w){let $=IPA("reorder",Q,B);if(!$.success)return $.error;let f=le2(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 IPA(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 le2(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}}$0();GA();$0();GA();async function j81(A,Q){let{bodyContent:B,coverImageId:w}=ie2(Q.content),$=w?await re2(A,w):void 0,f={bodyContent:B};if($)f.imageData=$;return f}function ie2(A){try{let Q=t2(A,G.record(G.unknown())),B=Q.metadata.coverImageId,w=typeof B==="string"?B:void 0;return w?{bodyContent:Q.content,coverImageId:w}:{bodyContent:Q.content}}catch{return{bodyContent:A}}}async function re2(A,Q){let B=await A.entityService.getEntity({entityType:"image",id:Q});if(!B?.content)return;let w=B.content.match(/^data:([^;]+);base64,(.+)$/);if(!w?.[1]||!w[2])return;return{data:Buffer.from(w[2],"base64"),mimeType:w[1]}}var DPA=G.object({entityType:G.string().describe("Entity type to publish (e.g., social-post, post, deck)"),id:G.string().optional().describe("Entity ID to publish"),slug:G.string().optional().describe("Entity slug to publish")}),de2=G.object({success:G.literal(!0),message:G.string().optional(),data:G.object({entityType:G.string().optional(),entityId:G.string().optional(),platformId:G.string().optional(),url:G.string().optional()}).optional()}),ne2=G.object({success:G.literal(!1),error:G.string(),code:G.string().optional()}),HPA=G.union([de2,ne2]);function y2A(A,Q,B){return{...xQ(Q,"publish","Publish an entity directly to its platform. Works with any registered entity type (social-post, post, deck, etc.)",DPA,async($)=>{let{entityType:f,id:I,slug:D}=$;if(!I&&!D)return{success:!1,error:"Either 'id' or 'slug' must be provided"};let H=await oe2(A,f,I,D);if(!H)return{success:!1,error:`Entity not found: ${f}:${I??D}`};if(H.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 Y=B.get(f),{bodyContent:W,imageData:F}=await j81(A,H),K=await Y.publish(W,H.metadata,F);return await A.entityService.updateEntity({entity:{...H,metadata:{...H.metadata,status:"published",publishedAt:new Date().toISOString(),platformId:K.id}}}),{success:!0,data:{entityType:f,entityId:H.id,platformId:K.id,url:K.url},message:`Published ${f}:${H.id}`}}),outputSchema:HPA}}async function oe2(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}$0();GA();function v81(A,Q){se2(A,Q),ae2(A,Q)}function se2(A,Q){A.messaging.subscribe(k9.REGISTER,async(B)=>te2(Q,B.payload)),A.messaging.subscribe(k9.QUEUE,async(B)=>ee2(A,Q,B.payload)),A.messaging.subscribe(k9.DIRECT,async(B)=>AAQ(A,Q,B.payload)),A.messaging.subscribe(k9.REMOVE,async(B)=>QAQ(Q,B.payload)),A.messaging.subscribe(k9.REORDER,async(B)=>BAQ(Q,B.payload)),A.messaging.subscribe(k9.LIST,async(B)=>wAQ(A,Q,B.payload)),A.messaging.subscribe(k9.REPORT_SUCCESS,async(B)=>$AQ(Q,B.payload)),A.messaging.subscribe(k9.REPORT_FAILURE,async(B)=>fAQ(Q,B.payload)),Q.logger.debug("Subscribed to publish messages")}function ae2(A,Q){A.messaging.subscribe(rZ.REPORT_SUCCESS,async(B)=>IAQ(Q,B.payload)),A.messaging.subscribe(rZ.REPORT_FAILURE,async(B)=>DAQ(Q,B.payload)),Q.logger.debug("Subscribed to generation messages")}async function te2(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=y0($);return A.logger.error(`Failed to register provider: ${f}`),{success:!1}}}async function ee2(A,Q,B){let{entityType:w,entityId:$}=B;try{let f=await Q.queueManager.add(w,$);return await A.messaging.send({type:k9.QUEUED,payload:{entityType:w,entityId:$,position:f.position}}),Q.logger.debug(`Entity queued: ${$}`,{entityType:w,position:f.position}),{success:!0}}catch(f){let I=y0(f);return Q.logger.error(`Failed to queue entity: ${I}`),{success:!1}}}async function AAQ(A,Q,B){let{entityType:w,entityId:$}=B;return await A.messaging.send({type:k9.EXECUTE,payload:{entityType:w,entityId:$}}),Q.logger.debug(`Direct publish requested: ${$}`,{entityType:w}),{success:!0}}async function QAQ(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=y0($);return A.logger.error(`Failed to remove entity: ${f}`),{success:!1}}}async function BAQ(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=y0(f);return A.logger.error(`Failed to reorder entity: ${I}`),{success:!1}}}async function wAQ(A,Q,B){let{entityType:w}=B;try{let $=await Q.queueManager.list(w);return await A.messaging.send({type:k9.LIST_RESPONSE,payload:{entityType:w,queue:$.map((f)=>({entityId:f.entityId,position:f.position,queuedAt:f.queuedAt}))}}),{success:!0}}catch($){let f=y0($);return Q.logger.error(`Failed to list queue: ${f}`),{success:!1}}}async function $AQ(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 fAQ(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 IAQ(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 DAQ(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 x81(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:y0($)}),{shouldGenerate:!1,reason:`Condition check failed: ${y0($)}`}}}function h81(A){let{context:Q,config:B,queueManager:w,providerRegistry:$,retryTracker:f,logger:I}=A,D=HAQ(Q);return fY.createFresh({queueManager:w,providerRegistry:$,retryTracker:f,logger:I,backend:new x2A,...B.entitySchedules&&{entitySchedules:B.entitySchedules},...B.generationSchedules&&{generationSchedules:B.generationSchedules},...B.generationConditions&&{generationConditions:B.generationConditions},messageBus:D,entityService:Q.entityService,onCheckGenerationConditions:(H,Y)=>x81(Q.entityService,I,H,Y)})}function HAQ(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 y81(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 YAQ=["draft","queued","published","failed"];async function g81(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:()=>XAQ(A)}})}async function XAQ(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=WAQ(I.metadata.status);if(!D)continue;w[D]++,B.push({id:I.id,title:UAQ(I.id,I.metadata.title),type:$,status:D})}}return{summary:w,items:B}}function WAQ(A){return YAQ.find((Q)=>Q===A)}function UAQ(A,Q){return typeof Q==="string"?Q:A}var T81={name:"@brains/content-pipeline",private:!0,version:"0.2.0-alpha.73",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 YPA extends RB{pluginContext;queueManager;providerRegistry;retryTracker;scheduler;constructor(A){super("content-pipeline",T81,A??{},z81)}async onRegister(A){this.pluginContext=A,this.queueManager=FW.createFresh(),this.providerRegistry=KW.createFresh(),this.retryTracker=ZW.createFresh({maxRetries:this.config.maxRetries,baseDelayMs:this.config.retryBaseDelayMs}),this.scheduler=h81({context:A,config:this.config,queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,logger:this.logger}),v81(A,{queueManager:this.queueManager,providerRegistry:this.providerRegistry,retryTracker:this.retryTracker,scheduler:this.scheduler,logger:this.logger})}async onReady(A){await y81(A.entityService,this.queueManager,this.logger),await g81(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[h2A(this.pluginContext,this.id,this.queueManager),y2A(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(),FW.resetInstance(),KW.resetInstance(),ZW.resetInstance()}}function XPA(A){return new YPA(A)}$0();GA();var S81=G.object({accountId:G.string().describe("Cloudflare account ID"),apiToken:G.string().describe("Cloudflare API token with Analytics:Read permission"),siteTag:G.string().describe("Cloudflare Web Analytics site tag")}),WPA=G.object({cloudflare:S81.optional()});$0();GA();var GAQ=G.object({date:G.string().describe("Single date in YYYY-MM-DD format").optional(),days:G.number().min(1).max(365).describe("Number of days back from yesterday (e.g., 7 for last week)").optional(),startDate:G.string().describe("Start date in YYYY-MM-DD format (use with endDate)").optional(),endDate:G.string().describe("End date in YYYY-MM-DD format (use with startDate)").optional(),limit:G.number().min(1).max(100).default(20).describe("Maximum items for breakdowns (pages, referrers, countries)")});function FAQ(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 m81(A,Q,B){let w=[];if(!B)return w;return w.push(xQ(A,"query",`Query website analytics from Cloudflare.
|
|
3537
3537
|
|
|
3538
3538
|
Date range options (use only one):
|
|
3539
3539
|
- No params: yesterday only
|
|
@@ -3671,7 +3671,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,GAQ,
|
|
|
3671
3671
|
}
|
|
3672
3672
|
}
|
|
3673
3673
|
}
|
|
3674
|
-
`,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 JPA=7,KAQ=10;function c81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=ZL(),B=Rp(JPA),w=NF(B),$=NF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:KAQ})]);return{days:JPA,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:JPA}}}}var p81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.
|
|
3674
|
+
`,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 JPA=7,KAQ=10;function c81(A){return async()=>{if(!A)return{unavailable:!0,reason:"Cloudflare analytics not configured"};let Q=ZL(),B=Rp(JPA),w=NF(B),$=NF(Q);try{let[f,I]=await Promise.all([A.getWebsiteStats({startDate:w,endDate:$}),A.getTopPages({startDate:w,endDate:$,limit:KAQ})]);return{days:JPA,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:JPA}}}}var p81={name:"@brains/analytics",private:!0,version:"0.2.0-alpha.73",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 l81 extends RB{cloudflareClient;constructor(A={}){super("analytics",p81,A,WPA)}async onRegister(A){this.cloudflareClient=this.config.cloudflare?new UPA(this.config.cloudflare):void 0,A.insights.register("traffic-overview",c81(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:u81(Q)}})}async getTools(){return m81(this.id,this.getContext(),this.cloudflareClient)}}function NAQ(A={}){return new l81(A)}var g2A=NAQ;$0();GA();Ew();var zAQ=new Set(["description","excerpt","summary","tagline","story"]);function qAQ(A){if(A.endsWith("s"))return A;return ef(A)}function GPA(A,Q=!1,B){let w=A._def.typeName;if(w==="ZodOptional"||w==="ZodNullable")return GPA(A._def.innerType,!0,B);if(w==="ZodDefault")return GPA(A._def.innerType,Q,A._def.defaultValue());return{inner:A,isOptional:Q,defaultValue:B}}function FPA(A,Q){let{inner:B,isOptional:w,defaultValue:$}=GPA(Q),f=B._def.typeName,I={name:A,label:mY(A),widget:"string",...w&&{required:!1},...$!==void 0&&{default:$}};switch(f){case"ZodString":{if((B._def.checks??[]).some((H)=>H.kind==="datetime"))return{...I,widget:"datetime"};if(zAQ.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,H=FPA("item",D);if(H.widget==="object"&&H.fields)return{...I,widget:"list",fields:H.fields};return{...I,widget:"list",field:{name:A,label:mY(A),widget:H.widget}}}case"ZodObject":{let D=B.shape,H=Object.entries(D).map(([Y,W])=>FPA(Y,W));return{...I,widget:"object",fields:H}}default:return{...I,widget:"string"}}}function i81(A,Q){let B=Object.entries(A.shape).map(([w,$])=>FPA(w,$));if(Q)B.push({name:"body",label:"Body",widget:"markdown"});return B}function r81(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],H=w===_l?"Note":mY(w),Y=D?.label??H,W=D?.pluralName??qAQ(Y);if(f?.isSingleton){B.push({name:w,label:Y,file:`${w}/${w}.md`,fields:i81($,I)});continue}if(w===_l){Q.push({name:w,label:W,folder:".",create:!0,extension:"md",format:"frontmatter",fields:[{name:"body",label:"Body",widget:"markdown"}]});continue}Q.push({name:w,label:W,folder:w,create:!0,extension:"md",format:"frontmatter",fields:i81($,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 KPA(A){return`<!doctype html>
|
|
3675
3675
|
<html>
|
|
3676
3676
|
<head>
|
|
3677
3677
|
<meta charset="utf-8" />
|
|
@@ -3682,7 +3682,7 @@ Returns pageviews, visitors, top pages, referrers, devices, and countries.`,GAQ,
|
|
|
3682
3682
|
</head>
|
|
3683
3683
|
<body></body>
|
|
3684
3684
|
</html>
|
|
3685
|
-
`}GA();var d81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.
|
|
3685
|
+
`}GA();var d81={name:"@brains/cms",private:!0,version:"0.2.0-alpha.73",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 EAQ=G.object({label:G.string().optional(),pluralName:G.string().optional()}).passthrough(),LAQ=G.object({entityDisplay:G.record(EAQ).optional(),routePath:G.string().default("/cms")});function MAQ(A){return`${A.endsWith("/")?A:`${A}/`}config.yml`}function VAQ(A,Q){let B=A.entityDisplay??Q?.entityDisplay;return B?{entityDisplay:B}:{}}async function bAQ(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 OAQ(A,Q={}){let{repo:B,branch:w}=await bAQ(A);return r81({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 n81(A,Q={}){return TY(await OAQ(A,Q))}class ZPA extends RB{constructor(A={}){super("cms",d81,A,LAQ)}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=MAQ(this.config.routePath);return[{path:this.config.routePath,method:"GET",public:!0,handler:async()=>{return new Response(KPA({cmsConfigPath:A}),{headers:{"Content-Type":"text/html; charset=utf-8"}})}},{path:A,method:"GET",public:!0,handler:async()=>{try{let Q=await n81(this.getContext(),VAQ(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 uC(A){return new ZPA(A)}$0();GA();$0();GA();var T2A=["StatsWidget","ListWidget","CustomWidget","PipelineWidget","IdentityWidget","ProfileWidget","SystemWidget"],RAQ=new Set(T2A);function NPA(A){return RAQ.has(A)}var o81=G.object({id:G.string(),pluginId:G.string(),title:G.string(),description:G.string().optional(),priority:G.number().default(50),section:G.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:G.string(),visibility:A7.default("public")});class S2A{widgets=new Map;logger;constructor(A){this.logger=A.child("DashboardWidgetRegistry")}register(A){let Q={...A,...o81.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)=>Q7.hasPermission(B,w.visibility)).sort((w,$)=>w.priority-$.priority)}get size(){return this.widgets.size}}GA();class m2A{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:H,visibility:Y="public",...W}=$;return{key:`${$.pluginId}:${$.id}`,widget:{...W,visibility:Y},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:y0(f.reason)})}return{widgets:Q}}async fetch(A,Q,B){return await this.getDashboardData()}}import{render as w0Q}from"preact-render-to-string";var s81=`
|
|
3686
3686
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
3687
3687
|
html, body { min-height: 100%; max-width: 100%; }
|
|
3688
3688
|
body {
|
|
@@ -4922,7 +4922,7 @@ ${s81}`;import{jsxDEV as IY,Fragment as e81}from"preact/jsx-dev-runtime";functio
|
|
|
4922
4922
|
}
|
|
4923
4923
|
});
|
|
4924
4924
|
})();`;function H0Q({input:A}){let Q=A.appInfo.entities,B=A.appInfo.entityCounts,w=f0Q(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,H=new Date;return oQ("html",{lang:"en","data-theme":"dark",children:[oQ("head",{children:[oQ("meta",{charSet:"utf-8"},void 0,!1,void 0,this),oQ("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"},void 0,!1,void 0,this),oQ("title",{children:A.title},void 0,!1,void 0,this),oQ("link",{rel:"preconnect",href:"https://fonts.googleapis.com"},void 0,!1,void 0,this),oQ("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"},void 0,!1,void 0,this),oQ("link",{href:$0Q,rel:"stylesheet"},void 0,!1,void 0,this),A.themeCSS!==void 0&&oQ("style",{"data-dashboard-theme":!0,dangerouslySetInnerHTML:{__html:A.themeCSS}},void 0,!1,void 0,this),oQ("style",{"data-dashboard-styles":!0,dangerouslySetInnerHTML:{__html:t81}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("body",{children:[oQ("main",{class:"console","data-component":"dashboard:dashboard",children:[oQ(A61,{title:A.title,tagline:A.profile.description,operatorAccess:A.operatorAccess},void 0,!1,void 0,this),oQ("section",{class:I,children:[$&&oQ("div",{class:"identity-column",children:[oQ(B61,{character:A.character},void 0,!1,void 0,this),oQ(zPA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),D&&A.operatorAccess&&oQ(Y61,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("div",{class:"main-column",children:[oQ(Q61,{total:Q,entityCounts:B},void 0,!1,void 0,this),!$&&D&&A.operatorAccess&&oQ(Y61,{hiddenWidgetCount:A.operatorAccess.hiddenWidgetCount,loginUrl:A.operatorAccess.loginUrl},void 0,!1,void 0,this),w.primary.map((Y)=>oQ(u2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),w.secondary.map((Y)=>oQ(u2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this))]},void 0,!0,void 0,this),oQ("div",{class:"sidebar-column",children:[!$&&oQ(zPA,{interactions:f,baseUrl:A.baseUrl},void 0,!1,void 0,this),w.sidebar.map((Y)=>oQ(u2A,{widget:Y},`${Y.widget.pluginId}:${Y.widget.id}`,!1,void 0,this)),oQ(w61,{endpoints:A.appInfo.endpoints,baseUrl:A.baseUrl},void 0,!1,void 0,this),oQ(D61,{appInfo:A.appInfo,now:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),oQ(H61,{title:A.title,appInfo:A.appInfo,baseUrl:A.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),oQ("script",{dangerouslySetInnerHTML:{__html:I0Q}},void 0,!1,void 0,this),oQ("script",{dangerouslySetInnerHTML:{__html:D0Q}},void 0,!1,void 0,this),A.widgetScripts.map((Y,W)=>oQ("script",{dangerouslySetInnerHTML:{__html:Y}},`widget-script:${W}`,!1,void 0,this))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function X61(A){return`<!doctype html>
|
|
4925
|
-
${w0Q(oQ(H0Q,{input:A},void 0,!1,void 0,this))}`}function W61(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 U61={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.
|
|
4925
|
+
${w0Q(oQ(H0Q,{input:A},void 0,!1,void 0,this))}`}function W61(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 U61={name:"@brains/dashboard",private:!0,version:"0.2.0-alpha.73",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 X0Q=G.object({version:G.string().default("1.0.0"),routePath:G.string().default("/dashboard"),themeCSS:G.string().optional()}),W0Q=G.object({id:G.string(),pluginId:G.string(),title:G.string(),description:G.string().optional(),priority:G.number().default(50),section:G.enum(["primary","secondary","sidebar"]).default("primary"),rendererName:G.string(),visibility:A7.default("public"),component:G.custom().optional(),clientScript:G.string().optional(),dataProvider:G.function().returns(G.promise(G.unknown()))}).superRefine((A,Q)=>{if(!NPA(A.rendererName)&&!A.component)Q.addIssue({code:G.ZodIssueCode.custom,message:"Custom dashboard widgets must register a Preact component.",path:["component"]})}),U0Q=G.object({pluginId:G.string(),widgetId:G.string().optional()});function J0Q(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 CPA extends RB{widgetRegistry=null;datasource=null;siteUrl;ctx;constructor(A){super("dashboard",U61,A??{},X0Q)}async onRegister(A){this.siteUrl=A.siteUrl,this.ctx=A,this.widgetRegistry=new S2A(this.logger),this.datasource=new m2A(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=W0Q.parse(Q.payload),w=J0Q(B);return this.widgetRegistry?.register(w),this.logger.debug("Widget registered via messaging",{widgetId:B.id,pluginId:B.pluginId,rendererName:B.rendererName,builtIn:T2A.includes(B.rendererName)}),{success:!0}}catch(B){return this.logger.error("Failed to register widget",{error:y0(B),payload:Q.payload}),{success:!1,error:"Widget registration failed"}}}),A.messaging.subscribe("dashboard:unregister-widget",async(Q)=>{let B=U0Q.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 nb()?.getOperatorSession(A),w=Boolean(B),$=w?"anchor":"public",f=this.widgetRegistry?.list({permissionLevel:"anchor"})??[],I=f.filter((o)=>Q7.hasPermission($,o.visibility)),D=f.length-I.length,[H,Y]=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={...Y,endpoints:Y.endpoints.filter((o)=>Q7.hasPermission($,o.visibility)),interactions:Y.interactions.filter((o)=>Q7.hasPermission($,o.visibility))},q=F.name||Y.model||"Brain Dashboard",E=new URL(A.url),C=`${E.pathname}${E.search}`,R=encodeURIComponent(C),k=W61(H.widgets,this.widgetRegistry),P={title:q,baseUrl:K,widgets:k.widgets,widgetScripts:k.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=${R}`,logoutUrl:`/logout?return_to=${R}`}};return new Response(X61(P),{headers:{"Content-Type":"text/html; charset=utf-8"}})}}]}async getTools(){return[]}getWidgetRegistry(){return this.widgetRegistry}}function nZ(A){return new CPA(A)}$0();GA();var G0Q=G.object({id:G.string(),pluginId:G.string(),title:G.string(),description:G.string().optional(),priority:G.number(),section:G.enum(["primary","secondary","sidebar"]),rendererName:G.string(),visibility:A7,component:G.custom().optional()}),F0Q=G.object({widget:G0Q,data:G.unknown()}),K0Q=G.object({widgets:G.record(F0Q)});GA();$0();GA();import{h as _0Q}from"preact";GA();ED();$0();var JP=G.enum(["draft","queued","published","failed"]),_m=G.object({subject:G.string(),status:JP,entityIds:G.array(G.string()).optional(),scheduledFor:G.string().datetime().optional(),sentAt:G.string().datetime().optional(),buttondownId:G.string().optional(),sourceEntityType:G.string().optional()}),J61=_m.pick({subject:!0,status:!0,entityIds:!0,scheduledFor:!0,sentAt:!0,buttondownId:!0,sourceEntityType:!0}),km=B2.extend({entityType:G.literal("newsletter"),metadata:J61});$0();class G61 extends W2{constructor(){super({entityType:"newsletter",schema:km,frontmatterSchema:_m})}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 F61=new G61;$0();$0();GA();var Z0Q=tY.extend({status:G.enum(["draft","queued","published","failed"]).optional()}),N0Q=eY.extend({query:Z0Q.optional()});function K61(A){try{let{content:Q}=t2(A.content,_m);return Q}catch{return A.content}}class EPA extends r6{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=N0Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}transformEntity(A){let Q=K61(A),B={id:A.id,subject:A.metadata.subject,status:A.metadata.status,excerpt:cY(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:H}=await this.fetchList(w,$,I);return Q.parse(this.buildListResult(D,H,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 H=w.metadata.sourceEntityType??"post";f=(await Promise.all(w.metadata.entityIds.map(async(W)=>{let F=await B.getEntity({entityType:H,id:W});if(F){let K=F.metadata;return{id:W,title:K.title??W,url:`/${H}s/${K.slug??W}`}}return null}))).filter((W)=>W!==null)}let I=K61(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)}}$0();GA();var z0Q=G.object({prompt:G.string().optional().describe("AI generation prompt"),sourceEntityIds:G.array(G.string()).optional().describe("Entity IDs to include in newsletter (e.g., blog posts)"),sourceEntityType:G.enum(["post"]).optional().describe("Type of source entities"),content:G.string().optional().describe("Direct content (skip AI)"),subject:G.string().optional().describe("Newsletter subject (AI-generated if not provided)"),addToQueue:G.boolean().optional().describe("Create as queued (true) or draft (false)")});class LPA extends X9{constructor(A,Q){super(A,Q,{schema:z0Q,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((P)=>this.context.entityService.getEntity({entityType:K,id:P})))).filter((P)=>P!=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 C=`Create an engaging newsletter that highlights these blog posts:
|
|
4926
4926
|
|
|
4927
4927
|
${q.map((P)=>`## ${P.metadata.title}
|
|
4928
4928
|
|
|
@@ -4991,14 +4991,14 @@ Newsletter-specific guidelines:
|
|
|
4991
4991
|
- "Reply and let me know..."
|
|
4992
4992
|
- "Until next time..."
|
|
4993
4993
|
|
|
4994
|
-
The goal is to build a relationship with readers through valuable, authentic content.`});GA();$0();import{jsxDEV as j7,Fragment as M0Q}from"preact/jsx-dev-runtime";var C0Q=G.object({id:G.string(),subject:G.string(),status:JP,excerpt:G.string(),created:G.string(),sentAt:G.string().optional(),url:G.string()}),E0Q=G.object({newsletters:G.array(C0Q),totalCount:G.number(),pagination:Y9.nullable()}),L0Q=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return j7(M0Q,{children:[j7(XQ,{title:f,description:I},void 0,!1,void 0,this),j7("div",{className:"newsletter-list bg-theme",children:j7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[j7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?j7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):j7("div",{className:"space-y-4",children:A.map((D)=>j7(UB,{href:D.url,children:[j7(f$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),j7(h$,{children:j7("div",{className:"flex items-center gap-3",children:[j7(Ef,{status:D.status},void 0,!1,void 0,this),j7("span",{className:"text-sm text-theme-muted",children:Q6(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&&j7("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&&j7(cJ,{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)},N61=O1({name:"newsletter-list",description:"Newsletter list page template",schema:E0Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:L0Q}});GA();$0();import{jsxDEV as gw,Fragment as R0Q}from"preact/jsx-dev-runtime";var V0Q=G.object({id:G.string(),title:G.string(),url:G.string()}),z61=G.object({id:G.string(),subject:G.string(),url:G.string()}),b0Q=G.object({id:G.string(),subject:G.string(),status:JP,content:G.string(),created:G.string(),updated:G.string(),sentAt:G.string().optional(),scheduledFor:G.string().optional(),sourceEntities:G.array(V0Q).optional(),prevNewsletter:z61.nullable().optional(),nextNewsletter:z61.nullable().optional()}),O0Q=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:H})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,F=$?"Sent":"Created";return gw(R0Q,{children:[gw(XQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),gw("section",{className:"newsletter-detail-section",children:gw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:gw("div",{className:"max-w-3xl mx-auto",children:[gw(tX,{items:Y},void 0,!1,void 0,this),gw("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),gw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[gw(Ef,{status:Q},void 0,!1,void 0,this),gw("span",{children:[F,": ",Q6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&gw("span",{children:["Scheduled for: ",Q6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&gw(UB,{variant:"compact",className:"mb-8",children:[gw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),gw("ul",{className:"space-y-1",children:I.map((K)=>gw("li",{children:gw("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),gw(mI,{markdown:B},void 0,!1,void 0,this),(D??H)&&gw("nav",{className:"mt-12 pt-8 border-t border-theme",children:gw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?gw(UB,{href:D.url,variant:"compact",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),gw("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):gw("div",{},void 0,!1,void 0,this),H&&gw(UB,{href:H.url,variant:"compact",className:"md:text-right",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.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)},q61=O1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:b0Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:O0Q}});var C61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.
|
|
4994
|
+
The goal is to build a relationship with readers through valuable, authentic content.`});GA();$0();import{jsxDEV as j7,Fragment as M0Q}from"preact/jsx-dev-runtime";var C0Q=G.object({id:G.string(),subject:G.string(),status:JP,excerpt:G.string(),created:G.string(),sentAt:G.string().optional(),url:G.string()}),E0Q=G.object({newsletters:G.array(C0Q),totalCount:G.number(),pagination:Y9.nullable()}),L0Q=({newsletters:A,totalCount:Q,pageTitle:B,pagination:w,baseUrl:$="/newsletters"})=>{let f=B??"Newsletters",I=`Browse all ${Q} ${Q===1?"newsletter":"newsletters"}`;return j7(M0Q,{children:[j7(XQ,{title:f,description:I},void 0,!1,void 0,this),j7("div",{className:"newsletter-list bg-theme",children:j7("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-16 md:py-24",children:[j7("h1",{className:"text-3xl md:text-4xl font-bold text-heading mb-8",children:f},void 0,!1,void 0,this),A.length===0?j7("p",{className:"text-theme-muted italic",children:"No newsletters yet."},void 0,!1,void 0,this):j7("div",{className:"space-y-4",children:A.map((D)=>j7(UB,{href:D.url,children:[j7(f$,{className:"text-lg",children:D.subject},void 0,!1,void 0,this),j7(h$,{children:j7("div",{className:"flex items-center gap-3",children:[j7(Ef,{status:D.status},void 0,!1,void 0,this),j7("span",{className:"text-sm text-theme-muted",children:Q6(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&&j7("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&&j7(cJ,{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)},N61=O1({name:"newsletter-list",description:"Newsletter list page template",schema:E0Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:L0Q}});GA();$0();import{jsxDEV as gw,Fragment as R0Q}from"preact/jsx-dev-runtime";var V0Q=G.object({id:G.string(),title:G.string(),url:G.string()}),z61=G.object({id:G.string(),subject:G.string(),url:G.string()}),b0Q=G.object({id:G.string(),subject:G.string(),status:JP,content:G.string(),created:G.string(),updated:G.string(),sentAt:G.string().optional(),scheduledFor:G.string().optional(),sourceEntities:G.array(V0Q).optional(),prevNewsletter:z61.nullable().optional(),nextNewsletter:z61.nullable().optional()}),O0Q=({subject:A,status:Q,content:B,created:w,sentAt:$,scheduledFor:f,sourceEntities:I,prevNewsletter:D,nextNewsletter:H})=>{let Y=[{label:"Home",href:"/"},{label:"Newsletters",href:"/newsletters"},{label:A}],W=$??w,F=$?"Sent":"Created";return gw(R0Q,{children:[gw(XQ,{title:A,description:`Newsletter: ${A}`},void 0,!1,void 0,this),gw("section",{className:"newsletter-detail-section",children:gw("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:gw("div",{className:"max-w-3xl mx-auto",children:[gw(tX,{items:Y},void 0,!1,void 0,this),gw("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),gw("div",{className:"flex flex-wrap items-center gap-3 mb-8 text-sm text-theme-muted",children:[gw(Ef,{status:Q},void 0,!1,void 0,this),gw("span",{children:[F,": ",Q6(W,{style:"long"})]},void 0,!0,void 0,this),f&&Q==="queued"&&gw("span",{children:["Scheduled for: ",Q6(f,{style:"long"})]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I&&I.length>0&&gw(UB,{variant:"compact",className:"mb-8",children:[gw("h3",{className:"text-sm font-medium text-heading mb-2",children:"Related Content"},void 0,!1,void 0,this),gw("ul",{className:"space-y-1",children:I.map((K)=>gw("li",{children:gw("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),gw(mI,{markdown:B},void 0,!1,void 0,this),(D??H)&&gw("nav",{className:"mt-12 pt-8 border-t border-theme",children:gw("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[D?gw(UB,{href:D.url,variant:"compact",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Newer"},void 0,!1,void 0,this),gw("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):gw("div",{},void 0,!1,void 0,this),H&&gw(UB,{href:H.url,variant:"compact",className:"md:text-right",children:[gw("span",{className:"text-xs text-theme-muted uppercase tracking-wide",children:"Older"},void 0,!1,void 0,this),gw("span",{className:"block mt-1 font-medium text-heading group-hover:text-brand transition-colors truncate",children:H.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)},q61=O1({name:"newsletter-detail",description:"Individual newsletter detail template",schema:b0Q,dataSourceId:"newsletter:entities",requiredPermission:"public",layout:{component:O0Q}});var C61={name:"@brains/newsletter-entity",private:!0,version:"0.2.0-alpha.73",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 k0Q=G.object({});class MPA extends KQ{entityType="newsletter";schema=km;adapter=F61;constructor(A={}){super("newsletter",C61,A,k0Q)}createGenerationHandler(A){return new LPA(this.logger,A)}getTemplates(){return{generation:Z61,"newsletter-list":N61,"newsletter-detail":q61}}getDataSources(){return[new EPA(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:()=>_0Q(cMA,{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=y0($);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:y0(B)}}),{success:!0}}})}registerEvalHandlers(A){let Q=G.object({prompt:G.string().optional(),content:G.string().optional()});A.eval.registerHandler("generation",async(B)=>{let w=Q.parse(B),$=w.content?`Create an engaging newsletter based on this content:
|
|
4995
4995
|
|
|
4996
|
-
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function VPA(A={}){return new MPA(A)}$0();GA();class GP{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}}}$0();GA();var j0Q=G.object({email:G.string().email().describe("Email address to subscribe"),name:G.string().optional().describe("Subscriber name (optional)"),tags:G.array(G.string()).optional().describe("Tags to apply to subscriber (optional)")}),v0Q=G.object({email:G.string().email().describe("Email address to unsubscribe")}),x0Q=G.object({type:G.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:G.number().optional().describe("Maximum number of results")});function E61(A,Q,B){let w=new GP(Q,B);return[xQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",j0Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return _8({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 L$(y0(f))}}),xQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",v0Q,async($)=>{try{return await w.unsubscribe($.email),_8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return L$(y0(f))}}),xQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",x0Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _8({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 L$(y0(f))}})]}GA();async function L61(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=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var M61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.
|
|
4996
|
+
${w.content}`:w.prompt??"Write an engaging newsletter";return A.ai.generate({prompt:$,templateName:"newsletter:generation"})})}}function VPA(A={}){return new MPA(A)}$0();GA();class GP{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}}}$0();GA();var j0Q=G.object({email:G.string().email().describe("Email address to subscribe"),name:G.string().optional().describe("Subscriber name (optional)"),tags:G.array(G.string()).optional().describe("Tags to apply to subscriber (optional)")}),v0Q=G.object({email:G.string().email().describe("Email address to unsubscribe")}),x0Q=G.object({type:G.enum(["unactivated","regular","unsubscribed"]).optional().describe("Filter by subscriber status"),limit:G.number().optional().describe("Maximum number of results")});function E61(A,Q,B){let w=new GP(Q,B);return[xQ(A,"subscribe","Subscribe an email address to the newsletter. Uses double opt-in by default.",j0Q,async($)=>{try{let f=await w.createSubscriber({email:$.email,...$.name&&{name:$.name},...$.tags&&{tags:$.tags}}),I=f.subscriber_type==="already_subscribed";return _8({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 L$(y0(f))}}),xQ(A,"unsubscribe","Unsubscribe an email address from the newsletter.",v0Q,async($)=>{try{return await w.unsubscribe($.email),_8({email:$.email},`Unsubscribed ${$.email} successfully`)}catch(f){return L$(y0(f))}}),xQ(A,"list_subscribers","List newsletter subscribers with optional filtering by status.",x0Q,async($)=>{try{let f=await w.listSubscribers({...$.type&&{type:$.type},...$.limit&&{limit:$.limit}});return _8({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 L$(y0(f))}})]}GA();async function L61(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=y0(f);return w.error("Failed to send newsletter for post",{postId:$.id,error:I}),{success:!1,error:I}}}var M61={name:"@brains/buttondown",private:!0,version:"0.2.0-alpha.73",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 y0Q=G.object({apiKey:G.string().optional().describe("Buttondown API key"),doubleOptIn:G.boolean().default(!0).describe("Require email confirmation for new subscribers"),autoSendOnPublish:G.boolean().default(!1).describe("Automatically send newsletter when a blog post is published")});class bPA extends RB{constructor(A={}){super("buttondown",M61,A,y0Q)}async onRegister(A){if(A.messaging.subscribe("buttondown:is-configured",async()=>{return{success:!!this.config.apiKey}}),this.config.apiKey){let Q=new GP({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:y0(w)}),{success:!1}}}),this.config.autoSendOnPublish)A.messaging.subscribe("publish:completed",async(B)=>{return await L61(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 E61(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 OPA(A={}){return new bPA(A)}var g0Q=G.object({apiKey:G.string().optional().describe("Buttondown API key"),doubleOptIn:G.boolean().optional().describe("Require email confirmation for new subscribers"),autoSendOnPublish:G.boolean().optional().describe("Automatically send newsletter when a blog post is published")});function V61(A={}){let Q=g0Q.parse(A);return[VPA({}),OPA({...Q.apiKey!==void 0&&{apiKey:Q.apiKey},...Q.doubleOptIn!==void 0&&{doubleOptIn:Q.doubleOptIn},...Q.autoSendOnPublish!==void 0&&{autoSendOnPublish:Q.autoSendOnPublish}})]}$0();GA();import{existsSync as o0Q,mkdirSync as s0Q,writeFileSync as a0Q}from"fs";import{join as XG}from"path";GA();var RPA=G.object({baseFolder:G.string().default("_obsidian")});GA();function T0Q(A){let Q=A,B=!0,w=void 0,$=!1,f=!0;while(f){if(f=!1,Q instanceof G.ZodOptional)B=!1,Q=Q._def.innerType,f=!0;if(Q instanceof G.ZodDefault)B=!1,$=!0,w=Q._def.defaultValue(),Q=Q._def.innerType,f=!0;if(Q instanceof G.ZodNullable)B=!1,Q=Q._def.innerType,f=!0}let I={inner:Q,required:B};if($)I.defaultValue=w;return I}function S0Q(A){if(A instanceof G.ZodEnum)return{type:"enum",enumValues:A._def.values};if(A instanceof G.ZodLiteral)return{type:"string",defaultValue:A._def.value};if(A instanceof G.ZodString)return{type:"string"};if(A instanceof G.ZodNumber)return{type:"number"};if(A instanceof G.ZodBoolean)return{type:"boolean"};if(A instanceof G.ZodArray)return{type:"array"};if(A instanceof G.ZodDate)return{type:"date"};if(A instanceof G.ZodPipeline){if(A._def.out instanceof G.ZodDate)return{type:"date"}}return{type:"unknown"}}function b61(A){let Q=A.shape,B=[];for(let[w,$]of Object.entries(Q)){let{inner:f,required:I,defaultValue:D}=T0Q($),H=S0Q(f),Y={name:w,type:H.type,required:I},W=D!==void 0?D:H.defaultValue;if(W!==void 0)Y.defaultValue=W;if(H.enumValues)Y.enumValues=H.enumValues;B.push(Y)}return B}function m0Q(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 O61(A,Q,B=""){let w=["---"];for(let $ of Q){let f=m0Q($,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(`
|
|
4997
4997
|
`)}GA();var u0Q={string:"Input",number:"Number",boolean:"Boolean",date:"Date",enum:"Select",array:"Multi",unknown:"Input"};function c0Q(A){let Q={name:A.name,id:A.name,type:u0Q[A.type]};if(A.type==="enum"&&A.enumValues){let B={};A.enumValues.forEach((w,$)=>{B[String($)]=w}),Q.options=B}return Q}function R61(A,Q){let B={filesPaths:A,fields:Q.map(c0Q)};return`---
|
|
4998
4998
|
${TY(B)}---
|
|
4999
|
-
`}GA();var p0Q=new Set(["entityType"]),l0Q={base:"Notes"},i0Q=new Set(["base"]);function r0Q(A){let Q=["file.name"];for(let B of A)if(!p0Q.has(B.name))Q.push(B.name);return Q}function d0Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function P61(A,Q){let B=l0Q[A]??bp(A),w=d0Q(Q),$=r0Q(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:[i0Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:TY(D),hasStatus:w}}function _61(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 TY(B)}function k61(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 TY(B)}var j61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.72",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 t0Q={mkdir:s0Q,writeFile:a0Q,existsFile:o0Q},e0Q=G.object({entityTypes:G.array(G.string()).optional().describe("Entity types to generate templates for (default: all)")});class PPA extends RB{deps;constructor(A={},Q={}){super("obsidian-vault",j61,A,RPA);this.deps={...t0Q,...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[xQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",e0Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((C)=>Q.includes(C)):B,$=XG(A.dataDir,this.config.baseFolder),f=XG($,"templates"),I=XG($,"fileClasses"),D=XG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let H=[],Y=[],W=[],F=[],K=[],Z=[];for(let C of w){let R=A.entities.getEffectiveFrontmatterSchema(C);if(!R){this.logger.debug(`Skipping ${C}: no frontmatter schema`),Y.push(C);continue}let k=b61(R),P=A.entities.getAdapter(C),o=P?.isSingleton===!0,r=R61(C,k);if(this.deps.writeFile(XG(I,`${C}.md`),r),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=P?.getBodyTemplate()??"",x=O61(C,k,S);this.deps.writeFile(XG(f,`${C}.md`),x),H.push(C);let y=P61(C,k),g=XG(D,y.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,y.content),F.push(C),this.logger.debug(`Generated base: ${y.filename}`);if(y.hasStatus)Z.push({entityType:C,fields:k});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=_61(K);if(q){let C=XG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=k61(Z);if(E){let C=XG(D,"Pipeline.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,E),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${W.length} fileClasses, ${F.length} bases (${Y.length} skipped)`),_8({generated:H,skipped:Y,fileClasses:W,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),L$(B instanceof Error?B.message:"Unknown error")}}}function _PA(A,Q){return new PPA(A,Q)}$0();GA();$0();var kPA=G.enum(["new","planned","in-progress","done","declined"]),jPA=G.enum(["low","medium","high","critical"]),jm=G.object({title:G.string(),status:kPA,priority:jPA.default("medium"),requested:G.number().int().default(1),declinedReason:G.string().optional()}),v61=G.object({title:G.string(),status:kPA,priority:jPA,requested:G.number().int(),slug:G.string()}),vm=B2.extend({entityType:G.literal("wish"),metadata:v61}),vPA=G.object({});$0();GA();class xm extends W2{constructor(){super({entityType:"wish",schema:vm,frontmatterSchema:jm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,jm);return{frontmatter:jm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=U2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var xPA=new xm;GA();GA();async function x61(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=U2(Q.title);return A.getEntity({entityType:"wish",id:f})}class c2A{logger;context;adapter=new xm;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 x61({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:W}=this.adapter.parseWishContent(f.content),F=Y.requested+1,K=this.adapter.createWishContent({...Y,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=U2(w),D=A.options?.priority??"medium",H=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:H,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 h61={critical:0,high:1,medium:2,low:3};function y61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return h61[Q.metadata.priority]-h61[B.metadata.priority]})}var g61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.72",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 T61 extends KQ{entityType=xPA.entityType;schema=vm;adapter=xPA;constructor(A={}){super("wishlist",g61,A,vPA)}async interceptCreate(A,Q,B){let w=await new c2A(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 y61(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 c2A(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 Q1Q(A={}){return new T61(A)}var p2A=Q1Q;$0();GA();$0();var hm=G.object({title:G.string(),target:G.string()}),S61=G.object({title:G.string(),target:G.string(),slug:G.string().optional()}),ym=B2.extend({entityType:G.literal("prompt"),metadata:S61});$0();GA();class hPA extends W2{constructor(){super({entityType:"prompt",schema:ym,frontmatterSchema:hm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,hm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,hm),B=U2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var l2A=new hPA;var m61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.72",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 yPA extends KQ{entityType=l2A.entityType;schema=ym;adapter=l2A;constructor(){super("prompt",m61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function cC(){return new yPA}$0();GA();class i2A{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(w1Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function w1Q(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();Bf();var u61={query:G.string().describe("Search terms for stock photos"),perPage:G.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:G.number().min(1).default(1).describe("Page number")},c61={photoId:G.string().describe("Photo ID from search results"),downloadLocation:G.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:G.string().describe("Photographer name for attribution"),photographerUrl:G.string().url().describe("Photographer profile URL for attribution"),sourceUrl:G.string().url().describe("Photo page URL on provider"),imageUrl:G.string().url().describe("Image URL to download"),title:G.string().optional().describe("Image entity title"),alt:G.string().optional().describe("Alt text for the image"),targetEntityType:G.string().optional().describe("Entity type to set cover image on"),targetEntityId:G.string().optional().describe("Entity ID to set cover image on")};function l61(A,Q){return[$1Q(A,Q),f1Q(A,Q)]}function $1Q(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:u61,handler:async(B)=>{let w=G.object(u61).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 f1Q(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:c61,handler:async(B)=>{let w=G.object(c61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:H,imageUrl:Y,title:W,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:H},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(E[0]){let S={imageEntityId:E[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await p61(Q.entityService,K,Z,E[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(f).catch(()=>{});let C;try{C=await Q.fetchImage(Y)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,k=pF.createImageEntity({dataUrl:C,title:R,alt:F??R}),P={id:$,...k,metadata:{...k.metadata,sourceUrl:Y}},{entityId:o}=await Q.entityService.createEntity({entity:P}),r={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await p61(Q.entityService,K,Z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function p61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Bf();var i61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.72",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 D1Q=G.object({provider:G.enum(["unsplash"]).default("unsplash"),apiKey:G.string().optional().describe("Stock photo provider API key")});class gPA extends RB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",i61,A,D1Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new i2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=l61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WH}),this.cachedTools}}function TPA(A={},Q={}){return new gPA(A,Q)}$0();GA();$0();$0();GA();var r61=G.enum(["ai","foundation","work"]),d61=G.object({suffix:r61,title:G.string(),body:G.string(),linkLabel:G.string(),linkHref:G.string()}),gm=G.object({eyebrow:G.string(),headline:G.string(),cards:G.array(d61).min(1)}),r2A=G.object({title:G.string(),slug:G.string(),status:G.enum(["draft","published"])}),Tm=B2.extend({entityType:G.literal("ecosystem-section"),metadata:r2A});class n61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Tm,frontmatterSchema:r2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var SPA=new n61;GA();function H1Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function mPA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Sm(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function d2A(A){let Q=H1Q(A),w=mPA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return gm.parse({eyebrow:mPA(Q,"Eyebrow"),headline:mPA(Q,"Headline"),cards:w.map(($)=>({suffix:Sm($,"Suffix"),title:Sm($,"Title"),body:Sm($,"Body"),linkLabel:Sm($,"Link Label"),linkHref:Sm($,"Link Href")}))})}function o61(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(`
|
|
4999
|
+
`}GA();var p0Q=new Set(["entityType"]),l0Q={base:"Notes"},i0Q=new Set(["base"]);function r0Q(A){let Q=["file.name"];for(let B of A)if(!p0Q.has(B.name))Q.push(B.name);return Q}function d0Q(A){return A.some((Q)=>Q.name==="status"&&Q.type==="enum")}function P61(A,Q){let B=l0Q[A]??bp(A),w=d0Q(Q),$=r0Q(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:[i0Q.has(A)?'file.folder == "/"':`file.inFolder("${A}")`]},views:f};return{filename:`${B}.base`,content:TY(D),hasStatus:w}}function _61(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 TY(B)}function k61(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 TY(B)}var j61={name:"@brains/obsidian-vault",private:!0,version:"0.2.0-alpha.73",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 t0Q={mkdir:s0Q,writeFile:a0Q,existsFile:o0Q},e0Q=G.object({entityTypes:G.array(G.string()).optional().describe("Entity types to generate templates for (default: all)")});class PPA extends RB{deps;constructor(A={},Q={}){super("obsidian-vault",j61,A,RPA);this.deps={...t0Q,...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[xQ(this.id,"sync-templates","Generate Obsidian templates, Metadata Menu fileClass definitions, and Bases views for all registered entity types.",e0Q,async(Q)=>{return this.sync(A,Q.entityTypes)})]}async sync(A,Q){try{let B=A.entityService.getEntityTypes(),w=Q?B.filter((C)=>Q.includes(C)):B,$=XG(A.dataDir,this.config.baseFolder),f=XG($,"templates"),I=XG($,"fileClasses"),D=XG($,"bases");this.deps.mkdir(f,{recursive:!0}),this.deps.mkdir(I,{recursive:!0}),this.deps.mkdir(D,{recursive:!0});let H=[],Y=[],W=[],F=[],K=[],Z=[];for(let C of w){let R=A.entities.getEffectiveFrontmatterSchema(C);if(!R){this.logger.debug(`Skipping ${C}: no frontmatter schema`),Y.push(C);continue}let k=b61(R),P=A.entities.getAdapter(C),o=P?.isSingleton===!0,r=R61(C,k);if(this.deps.writeFile(XG(I,`${C}.md`),r),W.push(C),o){K.push(C),this.logger.debug(`Generated fileClass (singleton): ${C}`);continue}let S=P?.getBodyTemplate()??"",x=O61(C,k,S);this.deps.writeFile(XG(f,`${C}.md`),x),H.push(C);let y=P61(C,k),g=XG(D,y.filename);if(!this.deps.existsFile(g))this.deps.writeFile(g,y.content),F.push(C),this.logger.debug(`Generated base: ${y.filename}`);if(y.hasStatus)Z.push({entityType:C,fields:k});this.logger.debug(`Generated template + fileClass: ${C}`)}let q=_61(K);if(q){let C=XG(D,"Settings.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,q),F.push("Settings"),this.logger.debug("Generated Settings.base")}let E=k61(Z);if(E){let C=XG(D,"Pipeline.base");if(!this.deps.existsFile(C))this.deps.writeFile(C,E),F.push("Pipeline"),this.logger.debug("Generated Pipeline.base")}return this.logger.info(`Synced ${H.length} templates, ${W.length} fileClasses, ${F.length} bases (${Y.length} skipped)`),_8({generated:H,skipped:Y,fileClasses:W,bases:F})}catch(B){return this.logger.error("Failed to sync",{error:B}),L$(B instanceof Error?B.message:"Unknown error")}}}function _PA(A,Q){return new PPA(A,Q)}$0();GA();$0();var kPA=G.enum(["new","planned","in-progress","done","declined"]),jPA=G.enum(["low","medium","high","critical"]),jm=G.object({title:G.string(),status:kPA,priority:jPA.default("medium"),requested:G.number().int().default(1),declinedReason:G.string().optional()}),v61=G.object({title:G.string(),status:kPA,priority:jPA,requested:G.number().int(),slug:G.string()}),vm=B2.extend({entityType:G.literal("wish"),metadata:v61}),vPA=G.object({});$0();GA();class xm extends W2{constructor(){super({entityType:"wish",schema:vm,frontmatterSchema:jm})}createWishContent(A,Q){return this.buildMarkdown(Q,A)}parseWishContent(A){let Q=this.parseFrontMatter(A,jm);return{frontmatter:jm.parse(Q),description:this.extractBody(A).trim()}}fromMarkdown(A){let{frontmatter:Q}=this.parseWishContent(A),B=U2(Q.title);return{content:A,entityType:"wish",metadata:{title:Q.title,status:Q.status,priority:Q.priority,requested:Q.requested,slug:B}}}}var xPA=new xm;GA();GA();async function x61(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=U2(Q.title);return A.getEntity({entityType:"wish",id:f})}class c2A{logger;context;adapter=new xm;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 x61({search:(Y)=>this.context.entityService.search(Y),getEntity:(Y)=>this.context.entityService.getEntity(Y),similarityThreshold:0.85},{title:w,description:$});if(f){let{frontmatter:Y,description:W}=this.adapter.parseWishContent(f.content),F=Y.requested+1,K=this.adapter.createWishContent({...Y,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=U2(w),D=A.options?.priority??"medium",H=this.adapter.createWishContent({title:w,status:"new",priority:D,requested:1},$);return await this.context.entityService.createEntity({entity:{id:I,entityType:"wish",content:H,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 h61={critical:0,high:1,medium:2,low:3};function y61(A){A.sort((Q,B)=>{let w=B.metadata.requested-Q.metadata.requested;if(w!==0)return w;return h61[Q.metadata.priority]-h61[B.metadata.priority]})}var g61={name:"@brains/wishlist",private:!0,version:"0.2.0-alpha.73",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 T61 extends KQ{entityType=xPA.entityType;schema=vm;adapter=xPA;constructor(A={}){super("wishlist",g61,A,vPA)}async interceptCreate(A,Q,B){let w=await new c2A(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 y61(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 c2A(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 Q1Q(A={}){return new T61(A)}var p2A=Q1Q;$0();GA();$0();var hm=G.object({title:G.string(),target:G.string()}),S61=G.object({title:G.string(),target:G.string(),slug:G.string().optional()}),ym=B2.extend({entityType:G.literal("prompt"),metadata:S61});$0();GA();class hPA extends W2{constructor(){super({entityType:"prompt",schema:ym,frontmatterSchema:hm})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,hm);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,hm),B=U2(Q.target.replace(/:/g,"-"));return{content:A,entityType:"prompt",metadata:{title:Q.title,target:Q.target,slug:B}}}}var l2A=new hPA;var m61={name:"@brains/prompt",private:!0,version:"0.2.0-alpha.73",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 yPA extends KQ{entityType=l2A.entityType;schema=ym;adapter=l2A;constructor(){super("prompt",m61,{},void 0)}getEntityTypeConfig(){return{embeddable:!1}}}function cC(){return new yPA}$0();GA();class i2A{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(w1Q),total:$.total,totalPages:$.total_pages,page:Q.page}}async triggerDownload(A){try{await this.fetchFn(A,{headers:{Authorization:`Client-ID ${this.apiKey}`}})}catch{}}}function w1Q(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();Bf();var u61={query:G.string().describe("Search terms for stock photos"),perPage:G.number().min(1).max(30).default(10).describe("Results per page (1-30)"),page:G.number().min(1).default(1).describe("Page number")},c61={photoId:G.string().describe("Photo ID from search results"),downloadLocation:G.string().url().describe("Download tracking URL (required by provider ToS)"),photographerName:G.string().describe("Photographer name for attribution"),photographerUrl:G.string().url().describe("Photographer profile URL for attribution"),sourceUrl:G.string().url().describe("Photo page URL on provider"),imageUrl:G.string().url().describe("Image URL to download"),title:G.string().optional().describe("Image entity title"),alt:G.string().optional().describe("Alt text for the image"),targetEntityType:G.string().optional().describe("Entity type to set cover image on"),targetEntityId:G.string().optional().describe("Entity ID to set cover image on")};function l61(A,Q){return[$1Q(A,Q),f1Q(A,Q)]}function $1Q(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:u61,handler:async(B)=>{let w=G.object(u61).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 f1Q(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:c61,handler:async(B)=>{let w=G.object(c61).safeParse(B);if(!w.success)return{success:!1,error:`Invalid input: ${w.error.message}`};let{photoId:$,downloadLocation:f,photographerName:I,photographerUrl:D,sourceUrl:H,imageUrl:Y,title:W,alt:F,targetEntityType:K,targetEntityId:Z}=w.data,q={photographerName:I,photographerUrl:D,sourceUrl:H},E=await Q.entityService.listEntities({entityType:"image",options:{limit:1,filter:{metadata:{sourceUrl:Y}}}});if(E[0]){let S={imageEntityId:E[0].id,alreadyExisted:!0,attribution:q};if(K&&Z)await p61(Q.entityService,K,Z,E[0].id),S.coverSet=!0;return{success:!0,data:S}}Q.provider.triggerDownload(f).catch(()=>{});let C;try{C=await Q.fetchImage(Y)}catch(S){return{success:!1,error:S instanceof Error?S.message:"Image download failed"}}let R=W??`Stock photo ${$}`,k=pF.createImageEntity({dataUrl:C,title:R,alt:F??R}),P={id:$,...k,metadata:{...k.metadata,sourceUrl:Y}},{entityId:o}=await Q.entityService.createEntity({entity:P}),r={imageEntityId:o,alreadyExisted:!1,attribution:q};if(K&&Z)await p61(Q.entityService,K,Z,o),r.coverSet=!0;return{success:!0,data:r}}}}async function p61(A,Q,B,w){let $=await A.getEntity({entityType:Q,id:B});if(!$)return;await A.updateEntity({entity:{...$,metadata:{...$.metadata,coverImageId:w}}})}Bf();var i61={name:"@brains/stock-photo",private:!0,version:"0.2.0-alpha.73",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 D1Q=G.object({provider:G.enum(["unsplash"]).default("unsplash"),apiKey:G.string().optional().describe("Stock photo provider API key")});class gPA extends RB{deps;cachedTools=null;constructor(A={},Q={}){super("stock-photo",i61,A,D1Q);this.deps=Q}async getTools(){if(!this.config.apiKey)return[];if(this.cachedTools)return this.cachedTools;let A=this.getContext(),Q=new i2A(this.config.apiKey,this.deps.fetch??globalThis.fetch);return this.cachedTools=l61(this.id,{provider:Q,entityService:A.entityService,fetchImage:this.deps.fetchImage??WH}),this.cachedTools}}function TPA(A={},Q={}){return new gPA(A,Q)}$0();GA();$0();$0();GA();var r61=G.enum(["ai","foundation","work"]),d61=G.object({suffix:r61,title:G.string(),body:G.string(),linkLabel:G.string(),linkHref:G.string()}),gm=G.object({eyebrow:G.string(),headline:G.string(),cards:G.array(d61).min(1)}),r2A=G.object({title:G.string(),slug:G.string(),status:G.enum(["draft","published"])}),Tm=B2.extend({entityType:G.literal("ecosystem-section"),metadata:r2A});class n61 extends W2{constructor(){super({entityType:"ecosystem-section",schema:Tm,frontmatterSchema:r2A})}fromMarkdown(A){return{content:A,entityType:"ecosystem-section",metadata:this.parseFrontmatter(A)}}}var SPA=new n61;GA();function H1Q(A){return A.replace(/^---\n[\s\S]*?\n---\n?/,"")}function mPA(A,Q){return new RegExp(`(?:^|\\n)## ${Q}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`).exec(A)?.[1]?.trim()??""}function Sm(A,Q){return new RegExp(`(?:^|\\n)#### ${Q}\\s*\\n([\\s\\S]*?)(?=\\n#### |\\n### |$)`).exec(A)?.[1]?.trim()??""}function d2A(A){let Q=H1Q(A),w=mPA(Q,"Cards").split(/^### Card \d+\s*$/m).map(($)=>$.trim()).filter(Boolean);return gm.parse({eyebrow:mPA(Q,"Eyebrow"),headline:mPA(Q,"Headline"),cards:w.map(($)=>({suffix:Sm($,"Suffix"),title:Sm($,"Title"),body:Sm($,"Body"),linkLabel:Sm($,"Link Label"),linkHref:Sm($,"Link Href")}))})}function o61(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(`
|
|
5000
5000
|
`)}var Y1Q=G.object({query:G.object({id:G.string().optional()}).optional()}).passthrough();class n2A{id="rizom-ecosystem:entities";name="Rizom Ecosystem";description="Fetches an ecosystem-section entity for rendering";async fetch(A,Q,B){let $=Y1Q.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(d2A(f.content))}}$0();var X1Q=yAA({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 NW(...A){return X1Q(JR(A))}import{jsxDEV as _Jw}from"preact/jsx-dev-runtime";import{jsxDEV as xJw}from"preact/jsx-dev-runtime";import{jsxDEV as TJw}from"preact/jsx-dev-runtime";import{jsxDEV as U1Q}from"preact/jsx-dev-runtime";var uPA="px-6 md:px-10 xl:px-20",W1Q=`${uPA} relative z-[1]`,cPA=({id:A,className:Q,children:B})=>U1Q("section",{id:A,className:NW(W1Q,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as o2A}from"preact/jsx-dev-runtime";var J1Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},mm=({name:A="rizom",brandSuffix:Q,className:B,dotClassName:w,suffixClassName:$})=>{let f=J1Q[Q];return o2A("span",{className:NW("inline-flex items-baseline gap-0 font-display font-medium tracking-[-0.015em] [font-variation-settings:'opsz'_24]",B),children:[o2A("span",{className:"text-theme",children:A},void 0,!1,void 0,this),o2A("span",{className:NW(f??"text-accent",w),children:"."},void 0,!1,void 0,this),o2A("span",{className:NW("italic font-normal text-theme-muted",$),children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as sJw}from"preact/jsx-dev-runtime";import{jsxDEV as AGw}from"preact/jsx-dev-runtime";import{jsxDEV as $Gw,Fragment as wGw}from"preact/jsx-dev-runtime";import{jsxDEV as DGw}from"preact/jsx-dev-runtime";import{Fragment as pPA}from"preact";import{jsxDEV as um}from"preact/jsx-dev-runtime";var G1Q=/(\*[^*]+\*)/;function lPA(A,Q){let B=A.split(`
|
|
5001
|
-
`);return um(pPA,{children:B.map((w,$)=>um(pPA,{children:[$>0&&um("br",{},void 0,!1,void 0,this),w.split(G1Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return um("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return um(pPA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as Of,Fragment as V1Q}from"preact/jsx-dev-runtime";var F1Q="italic text-accent font-normal",K1Q="You are here",Z1Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},N1Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},z1Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},q1Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",C1Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",E1Q="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",L1Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",M1Q=({card:A})=>{let Q=A.linkLabel===K1Q,B=A.linkHref.trim().length===0,w=Of(V1Q,{children:[Of(mm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),Of("span",{className:`${q1Q} ${Z1Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),Of("p",{className:C1Q,children:A.body},void 0,!1,void 0,this),Q?Of("span",{className:L1Q,children:A.linkLabel},void 0,!1,void 0,this):Of("span",{className:E1Q,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?N1Q[A.suffix]:"border-white/10"}`;return Q||B?Of("div",{className:$,children:w},void 0,!1,void 0,this):Of("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${z1Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},iPA=({eyebrow:A,headline:Q,cards:B})=>Of(cPA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[Of("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[Of("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),Of("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:lPA(Q,F1Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Of("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)=>Of(M1Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var b1Q=[{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 s61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:b1Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var O1Q=s61();var rPA=O1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:gm,formatter:{parse:d2A,format:o61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:iPA}});var a61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.
|
|
5001
|
+
`);return um(pPA,{children:B.map((w,$)=>um(pPA,{children:[$>0&&um("br",{},void 0,!1,void 0,this),w.split(G1Q).map((f,I)=>{if(f.length>=3&&f.startsWith("*")&&f.endsWith("*"))return um("span",{className:Q,children:f.slice(1,-1)},I,!1,void 0,this);return um(pPA,{children:f},I,!1,void 0,this)})]},$,!0,void 0,this))},void 0,!1,void 0,this)}import{jsxDEV as Of,Fragment as V1Q}from"preact/jsx-dev-runtime";var F1Q="italic text-accent font-normal",K1Q="You are here",Z1Q={work:"text-accent",foundation:"text-secondary",ai:"text-accent-bright"},N1Q={work:"border-t-accent/60",foundation:"border-t-secondary/60",ai:"border-t-accent-bright/60"},z1Q={work:"hover:border-t-accent",foundation:"hover:border-t-secondary",ai:"hover:border-t-accent-bright"},q1Q="font-label text-[10.5px] uppercase tracking-[0.26em] mt-1",C1Q="font-body text-[15px] leading-[1.6] text-theme-muted mt-2",E1Q="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",L1Q="font-label text-[10.5px] uppercase tracking-[0.22em] text-accent self-start mt-[18px] pb-1",M1Q=({card:A})=>{let Q=A.linkLabel===K1Q,B=A.linkHref.trim().length===0,w=Of(V1Q,{children:[Of(mm,{brandSuffix:A.suffix,className:"text-[clamp(28px,3vw,40px)] [font-variation-settings:'opsz'_96]"},void 0,!1,void 0,this),Of("span",{className:`${q1Q} ${Z1Q[A.suffix]}`,children:A.title},void 0,!1,void 0,this),Of("p",{className:C1Q,children:A.body},void 0,!1,void 0,this),Q?Of("span",{className:L1Q,children:A.linkLabel},void 0,!1,void 0,this):Of("span",{className:E1Q,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?N1Q[A.suffix]:"border-white/10"}`;return Q||B?Of("div",{className:$,children:w},void 0,!1,void 0,this):Of("a",{href:A.linkHref,className:`${$} text-inherit no-underline transition-colors ${z1Q[A.suffix]}`,children:w},void 0,!1,void 0,this)},iPA=({eyebrow:A,headline:Q,cards:B})=>Of(cPA,{id:"ecosystem",className:"pt-[112px] pb-[144px] border-t border-white/5",children:[Of("div",{className:"mx-auto mb-[88px] max-w-[1180px] text-center",children:[Of("span",{className:"font-label text-[11px] font-semibold uppercase tracking-[0.24em] text-accent",children:A},void 0,!1,void 0,this),Of("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:lPA(Q,F1Q)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Of("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)=>Of(M1Q,{card:w},w.suffix,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this);var b1Q=[{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 s61(A){return{eyebrow:"The Ecosystem",headline:"One practice. *Three faces.*",cards:b1Q.map((Q)=>Q.suffix===A?{...Q,linkLabel:"You are here",linkHref:""}:Q)}}var O1Q=s61();var rPA=O1({name:"ecosystem",description:"Rizom ecosystem sibling-site section",schema:gm,formatter:{parse:d2A,format:o61},dataSourceId:"rizom-ecosystem:entities",requiredPermission:"public",layout:{component:iPA}});var a61={name:"@brains/rizom-ecosystem",private:!0,version:"0.2.0-alpha.73",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 dPA extends KQ{entityType="ecosystem-section";schema=Tm;adapter=SPA;constructor(A={}){super("rizom-ecosystem",a61,A,G.object({}).default({}))}getTemplates(){return{ecosystem:rPA}}getDataSources(){return[new n2A]}}function pC(A={}){return new dPA(A)}GA();$0();$0();GA();d5();GA();$0();var c$="agent",t61="agent-discovery",e61="agent:generation",A51="agent-network",Q51="AgentNetworkWidget",cm="agent-discovery:entities",nPA="agent-list",oPA="agent-detail",w6="skill",B51="skill",s2A="skill-derivation",w51="skill:project",$51="skill-derivation",f51="skill:skill-derivation",I51="skills";var FP=G.object({name:G.string(),description:G.string(),tags:G.array(G.string())}),X4=G.enum(["discovered","approved"]).describe("Discovered for review or approved for calling"),DY=AH.pick({name:!0,kind:!0,organization:!0}).extend({brainName:G.string().describe("Name of the brain instance"),url:G.string().url().describe("Brain endpoint URL"),did:G.string().optional().describe("Decentralized identifier (public)"),status:X4,discoveredAt:G.string().datetime().describe("When this agent was first discovered")}),D51=DY.pick({name:!0,url:!0,status:!0}).extend({discoveredAt:G.string().datetime().optional(),slug:G.string()}),KP=B2.extend({entityType:G.literal(c$),metadata:D51}),pm=KP.extend({frontmatter:DY,about:G.string(),skills:G.array(FP),notes:G.string()}),ZP=pm.extend({url:G.string().optional(),typeLabel:G.string().optional()}),P1Q=pm.extend({url:G.string(),typeLabel:G.string()});GA();var _1Q=G.array(FP);function H51(A){let Q=_1Q.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(`
|
|
5002
5002
|
`)}function Y51(A){if(!A.trim())return[];let Q=[];for(let B of A.split(`
|
|
5003
5003
|
`)){let w=B.match(/^- (.+?): (.+?)(?:\s+\[(.+?)\])?$/);if(!w)continue;let $=w[1]??"",f=w[2]??"",I=w[3],D=I?I.split(",").map((H)=>H.trim()).filter(Boolean):[];Q.push({name:$,description:f,tags:D})}return Q}var k1Q=G.object({about:G.string(),skills:G.array(FP),notes:G.string()}),X51=new PB(k1Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:H51,parser:Y51},{key:"notes",label:"Notes",type:"string"}]});class W4 extends W2{constructor(){super({entityType:c$,schema:KP,frontmatterSchema:DY})}fromMarkdown(A){let Q=this.parseFrontMatter(A,DY),B=FL(Q.url);return{content:A,entityType:c$,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:X4.parse(A.status),discoveredAt:A.discoveredAt},B=X51.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=X51.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,DY),body:this.parseAgentContent(A.content)}}}$0();var j1Q=new W4,v1Q=tY.extend({status:X4.optional()}),x1Q=eY.extend({query:v1Q.optional()});function h1Q(A){let Q=t2(A.content,DY),B=j1Q.parseAgentContent(A.content);return pm.parse({...A,frontmatter:Q.metadata,about:B.about,skills:B.skills,notes:B.notes})}class a2A extends r6{id=cm;name="Agent Directory DataSource";description="Fetches and transforms agent entities for rendering";config={entityType:c$,defaultSort:[{field:"discoveredAt",direction:"desc"}],defaultLimit:50,lookupField:"slug",enableNavigation:!0};constructor(A){super(A)}transformEntity(A){return h1Q(A)}buildDetailResult(A,Q){return{agent:A,prevAgent:Q?.prev??null,nextAgent:Q?.next??null}}parseQuery(A){let Q=x1Q.parse(A);return{entityType:Q.entityType??this.config.entityType,query:Q.query??{}}}buildListResult(A,Q,B){let w=X4.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))}}$0();GA();E$();$0();async function W51(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 Xj(f)}catch{return null}}function t2A(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 y1Q=new W4;function U51(A){return A.trim().toLowerCase().replace(/[_\s]+/g,"-")}function oZ(A){let Q=new Set,B=[];for(let w of A){let $=U51(w);if(!$||Q.has($))continue;Q.add($),B.push($)}return B}function g1Q(A,Q){if(Q.count!==A.count)return Q.count-A.count;return A.tag.localeCompare(Q.tag)}async function J51(A,Q={}){let B=Q.minCount??1,w=Q.topN??12,$=new Map,[f,I]=await Promise.all([A.entityService.listEntities({entityType:w6}),A.entityService.listEntities({entityType:c$})]),D=(H)=>{for(let Y of oZ(H))$.set(Y,($.get(Y)??0)+1)};for(let H of f)D(H.metadata.tags);for(let H of I){let Y=y1Q.parseAgentContent(H.content);D(Y.skills.flatMap((W)=>W.tags))}return Array.from($.entries()).map(([H,Y])=>({tag:H,count:Y})).filter((H)=>H.count>=B).sort(g1Q).slice(0,w)}function G51(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(`
|
|
5004
5004
|
`)}var T1Q=new W4;function F51(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:T1Q.createAgentContent({name:B,kind:w,...A.anchor?.organization&&{organization:A.anchor.organization},brainName:A.brainName,url:A.url,status:f,discoveredAt:I,about:$.join(`
|
|
@@ -5098,7 +5098,7 @@ ${TY(B)}---
|
|
|
5098
5098
|
setView("agents");
|
|
5099
5099
|
setTagFilter("all");
|
|
5100
5100
|
});
|
|
5101
|
-
})();`;import{jsxDEV as jQ}from"preact/jsx-dev-runtime";function d1Q({item:A}){return jQ("li",{class:"list-item",children:[jQ("div",{class:"list-main",children:[jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),jQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&jQ("div",{class:"list-tags",children:A.tags.map((Q)=>jQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"list-meta",children:A.status==="discovered"&&jQ("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 n1Q({item:A}){return jQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[jQ("div",{class:"list-main",children:jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),jQ("div",{class:"list-meta",children:jQ("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 o1Q({kind:A,items:Q,active:B}){return jQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?jQ("ul",{class:"list agent-network-list",children:Q.map((w)=>jQ(d1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function s1Q({skills:A,count:Q,filters:B}){return jQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[jQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[jQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[jQ("span",{class:"count",children:Q},void 0,!1,void 0,this),jQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>jQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[jQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),jQ("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?jQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>jQ(n1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function tPA({data:A}){let Q=C51.safeParse(A);if(!Q.success)return jQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return jQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[jQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[jQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",jQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",jQ("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),jQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:aPA.map((w)=>{let $=w==="all";return jQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[jQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),jQ("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),aPA.map((w)=>jQ(o1Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),jQ(s1Q,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function L51(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:A51,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:Q51,component:tPA,clientScript:AQA,dataProvider:async()=>E51(A)}}),{success:!0}})}function M51(){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.'}$0();Rw();GA();import{jsxDEV as V51}from"preact/jsx-dev-runtime";function QQA(A){try{return new URL(A).hostname}catch{return A}}var BQA=({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 V51("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)},wQA=({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 V51("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 F2,Fragment as e1Q}from"preact/jsx-dev-runtime";var a1Q=({skills:A})=>{if(A.length===0)return null;return F2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>F2("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 t1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function b51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var ePA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return F2("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:[F2(BQA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),F2("div",{className:"flex-1 min-w-0",children:[F2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[F2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),F2(wQA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&F2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&F2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&F2(a1Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[F2("span",{className:"text-xs text-theme-muted",children:QQA(Q.url)},void 0,!1,void 0,this),F2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${t1Q(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)},O51=({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"),H=A.filter((K)=>K.frontmatter.status==="discovered"),Y=D.length,W=H.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return F2(e1Q,{children:[F2(XQ,{title:f,description:F},void 0,!1,void 0,this),F2("div",{className:"agent-list bg-theme",children:F2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[F2("div",{className:"mb-8 pb-6 border-b border-theme",children:[F2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),F2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),F2("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),F2("div",{className:"flex flex-wrap gap-2 text-sm",children:[F2("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),F2("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),F2("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&&F2("section",{className:"mb-10",children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:D.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("div",{children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),F2("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),F2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:H.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:A.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&F2("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"&&F2("div",{className:"mt-12",children:F2(cJ,{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"&&F2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?F2("a",{href:b51(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):F2("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),F2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?F2("a",{href:b51(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):F2("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 f2,Fragment as w2Q}from"preact/jsx-dev-runtime";function A2Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var lm=({children:A})=>f2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),Q2Q=({skill:A})=>f2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[f2("div",{className:"flex-1",children:[f2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),f2("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&&f2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>f2("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),B2Q=({label:A,value:Q,valueClassName:B})=>f2("div",{className:"flex justify-between text-[13px]",children:[f2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),f2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=QQA(w.url),H=w.status==="approved";return f2(w2Q,{children:[f2(XQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),f2("article",{className:"agent-detail",children:f2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[f2("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),f2("div",{className:"flex items-start gap-6 mb-8",children:[f2(BQA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),f2("div",{children:[f2("div",{className:"flex items-center gap-3 mb-1",children:[f2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),f2(wQA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),f2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&f2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&f2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),f2("span",{className:"text-sm",children:["Discovered ",A2Q(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),f2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&f2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[f2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),f2("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),f2("div",{className:"flex flex-col md:flex-row gap-12",children:[f2("div",{className:"flex-[2] min-w-0",children:[$&&f2("section",{className:"mb-8",children:[f2(lm,{children:"About"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Skills"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>f2(Q2Q,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Notes"},void 0,!1,void 0,this),f2("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),f2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[f2("section",{className:"mb-8",children:[f2(lm,{children:"Brain"},void 0,!1,void 0,this),f2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[f2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&f2("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),f2("section",{className:"mb-8",children:[f2(lm,{children:"Connection"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-3",children:[f2("div",{children:[f2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),f2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2(B2Q,{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),f2("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)&&f2("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:[f2("div",{className:"min-h-[1px]",children:Q&&f2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),f2("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),f2("div",{className:"min-h-[1px] md:text-right",children:B&&f2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"Next \u2192"},void 0,!1,void 0,this),f2("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 $2Q=G.object({agents:G.array(ZP),pageTitle:G.string().optional(),pagination:Y9.nullable(),baseUrl:G.string().optional(),selectedStatus:G.union([G.literal("all"),X4])});function P51(){return{[nPA]:O1({name:nPA,description:"Agent directory list page template",schema:$2Q,dataSourceId:cm,requiredPermission:"public",layout:{component:O51}}),[oPA]:O1({name:oPA,description:"Individual agent profile template",schema:G.object({agent:ZP,prevAgent:ZP.nullable(),nextAgent:ZP.nullable()}),dataSourceId:cm,requiredPermission:"public",layout:{component:R51}})}}var $QA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.72",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 I2Q=new W4;class A_A extends KQ{entityType=c$;schema=KP;adapter=I2Q;constructor(){super(t61,$QA)}interceptCreate(A,Q,B){return K51(A,Q,B,this.id)}createGenerationHandler(A){return new sPA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return P51()}getDataSources(){return[new a2A(this.logger.child("AgentDataSource"))]}async onRegister(A){L51(A,this.id)}async getInstructions(){return M51()}}function Q_A(){return new A_A}$0();GA();$0();var NP=HI,_51=HI,im=B2.extend({entityType:G.literal(w6),metadata:_51});$0();class zP extends W2{constructor(){super({entityType:w6,schema:im,frontmatterSchema:NP})}fromMarkdown(A){let Q=this.parseFrontMatter(A,NP);return{content:A,entityType:w6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}$0();GA();var D2Q=G.object({skills:G.array(NP).max(8)}),k51=O1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:D2Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5101
|
+
})();`;import{jsxDEV as jQ}from"preact/jsx-dev-runtime";function d1Q({item:A}){return jQ("li",{class:"list-item",children:[jQ("div",{class:"list-main",children:[jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this),jQ("span",{class:"list-desc",children:A.description},void 0,!1,void 0,this),A.tags.length>0&&jQ("div",{class:"list-tags",children:A.tags.map((Q)=>jQ("span",{class:"tag",children:Q},`${A.id}:${Q}`,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("div",{class:"list-meta",children:A.status==="discovered"&&jQ("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 n1Q({item:A}){return jQ("li",{class:"list-item agent-network-skill-row","data-agent-network-skill-row":!0,"data-agent-network-tags":JSON.stringify(A.tags),children:[jQ("div",{class:"list-main",children:jQ("span",{class:"list-name",children:A.name},void 0,!1,void 0,this)},void 0,!1,void 0,this),jQ("div",{class:"list-meta",children:jQ("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 o1Q({kind:A,items:Q,active:B}){return jQ("div",{class:`agent-network-panel${B?" is-active":""}`,"data-agent-network-panel":A,children:Q.length>0?jQ("ul",{class:"list agent-network-list",children:Q.map((w)=>jQ(d1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)},void 0,!1,void 0,this)}function s1Q({skills:A,count:Q,filters:B}){return jQ("div",{class:"agent-network-panel","data-agent-network-panel":"skills",children:[jQ("div",{class:"agent-network-filter-row",role:"tablist","aria-label":"Filter skills by tag",children:[jQ("button",{class:"agent-network-filter is-active",type:"button","data-agent-network-tag-filter":"all","aria-pressed":"true",children:[jQ("span",{class:"count",children:Q},void 0,!1,void 0,this),jQ("span",{class:"label",children:"all"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),B.map((w)=>jQ("button",{class:`agent-network-filter${w.variant==="gap"?" is-gap":""}`,type:"button","data-agent-network-tag-filter":w.tag,"aria-pressed":"false",children:[jQ("span",{class:"count",children:w.count},void 0,!1,void 0,this),jQ("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?jQ("ul",{class:"list agent-network-list agent-network-skills-list",children:A.map((w)=>jQ(n1Q,{item:w},w.id,!1,void 0,this))},void 0,!1,void 0,this):jQ("p",{class:"agent-network-empty",children:"Nothing to show yet."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function tPA({data:A}){let Q=C51.safeParse(A);if(!Q.success)return jQ("p",{class:"muted",children:"Nothing to show yet."},void 0,!1,void 0,this);let B=Q.data;return jQ("div",{"data-agent-network-widget":!0,"data-agent-network-view":"agents",children:[jQ("div",{class:"agent-network-view-tabs",role:"tablist","aria-label":"Browse the agent network",children:[jQ("button",{class:"agent-network-view-tab is-active",type:"button","data-agent-network-view-tab":"agents","aria-pressed":"true",children:["Agents",jQ("span",{class:"agent-network-view-count",children:B.counts.agents},void 0,!1,void 0,this)]},void 0,!0,void 0,this),jQ("button",{class:"agent-network-view-tab",type:"button","data-agent-network-view-tab":"skills","aria-pressed":"false",children:["Skills",jQ("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),jQ("div",{class:"agent-network-kind-tabs",role:"tablist","aria-label":"Filter agents by kind",children:aPA.map((w)=>{let $=w==="all";return jQ("button",{class:`agent-network-kind-tab${$?" is-active":""}`,type:"button","data-agent-network-kind-tab":w,"aria-pressed":$?"true":"false",children:[jQ("span",{class:"agent-network-kind-count",children:B.agents[w].length},void 0,!1,void 0,this),jQ("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),aPA.map((w)=>jQ(o1Q,{kind:w,items:B.agents[w],active:w==="all"},w,!1,void 0,this)),jQ(s1Q,{skills:B.skills,count:B.counts.skills,filters:B.skillFilters},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function L51(A,Q){A.messaging.subscribe("system:plugins:ready",async()=>{return await A.messaging.send({type:"dashboard:register-widget",payload:{id:A51,pluginId:Q,title:"Agent Network",section:"secondary",priority:15,rendererName:Q51,component:tPA,clientScript:AQA,dataProvider:async()=>E51(A)}}),{success:!0}})}function M51(){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.'}$0();Rw();GA();import{jsxDEV as V51}from"preact/jsx-dev-runtime";function QQA(A){try{return new URL(A).hostname}catch{return A}}var BQA=({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 V51("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)},wQA=({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 V51("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 F2,Fragment as e1Q}from"preact/jsx-dev-runtime";var a1Q=({skills:A})=>{if(A.length===0)return null;return F2("div",{className:"flex gap-1.5 flex-wrap mt-2",children:A.map((Q)=>F2("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 t1Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric"})}function b51(A,Q,B){let w=new URLSearchParams({status:Q});if(B>1)w.set("page",String(B));return`${A}?${w.toString()}`}var ePA=({agent:A})=>{let{frontmatter:Q,about:B,skills:w,url:$}=A,f=Q.status==="approved";return F2("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:[F2(BQA,{name:Q.name,className:"w-12 h-12 text-lg"},void 0,!1,void 0,this),F2("div",{className:"flex-1 min-w-0",children:[F2("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[F2("span",{className:"text-lg font-semibold text-heading",children:Q.name},void 0,!1,void 0,this),F2(wQA,{kind:Q.kind,size:"sm"},void 0,!1,void 0,this),Q.organization&&F2("span",{className:"text-xs text-theme-muted",children:["\xB7 ",Q.organization]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"text-sm text-theme-muted mb-1",children:Q.brainName},void 0,!1,void 0,this),B&&F2("p",{className:"text-sm text-theme-muted line-clamp-2 mb-0",children:B},void 0,!1,void 0,this),f&&F2(a1Q,{skills:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col items-end gap-1 flex-shrink-0 text-right",children:[F2("span",{className:"text-xs text-theme-muted",children:QQA(Q.url)},void 0,!1,void 0,this),F2("span",{className:"text-[11px] text-theme-muted opacity-60",children:f?`Discovered ${t1Q(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)},O51=({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"),H=A.filter((K)=>K.frontmatter.status==="discovered"),Y=D.length,W=H.length,F=`Your network of ${I} ${I===1?"brain":"brains"} and their anchors`;return F2(e1Q,{children:[F2(XQ,{title:f,description:F},void 0,!1,void 0,this),F2("div",{className:"agent-list bg-theme",children:F2("div",{className:"container mx-auto px-6 md:px-12 max-w-5xl py-16 md:py-24",children:[F2("div",{className:"mb-8 pb-6 border-b border-theme",children:[F2("h1",{className:"text-4xl font-bold text-heading mb-2",children:f},void 0,!1,void 0,this),F2("p",{className:"text-theme-muted mb-4",children:F},void 0,!1,void 0,this),F2("div",{className:"flex flex-wrap gap-2 text-sm mb-4",children:[F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-heading",children:[I," total"]},void 0,!0,void 0,this),F2("span",{className:"px-3 py-1 rounded-full bg-theme-subtle text-status-success",children:[Y," approved"]},void 0,!0,void 0,this),F2("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),F2("div",{className:"flex flex-wrap gap-2 text-sm",children:[F2("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),F2("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),F2("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&&F2("section",{className:"mb-10",children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Approved brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:D.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:D.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$==="all"&&H.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("div",{children:[F2("h2",{className:"text-lg font-semibold text-heading",children:"Discovered brains"},void 0,!1,void 0,this),F2("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),F2("span",{className:"text-sm text-theme-muted",children:H.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:H.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="all"&&A.length>0&&F2("section",{children:[F2("div",{className:"flex items-center justify-between mb-4",children:[F2("h2",{className:"text-lg font-semibold text-heading",children:$==="approved"?"Approved brains":"Discovered brains"},void 0,!1,void 0,this),F2("span",{className:"text-sm text-theme-muted",children:A.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F2("div",{className:"flex flex-col gap-4",children:A.map((K)=>F2(ePA,{agent:K},K.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.length===0&&F2("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"&&F2("div",{className:"mt-12",children:F2(cJ,{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"&&F2("nav",{"aria-label":"Pagination",className:"flex items-center justify-center gap-3 mt-12",children:[B.hasPrevPage?F2("a",{href:b51(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):F2("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),F2("span",{className:"text-sm text-theme-muted",children:["Page ",B.currentPage," of ",B.totalPages]},void 0,!0,void 0,this),B.hasNextPage?F2("a",{href:b51(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):F2("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 f2,Fragment as w2Q}from"preact/jsx-dev-runtime";function A2Q(A){return new Date(A).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}var lm=({children:A})=>f2("h2",{className:"text-sm font-semibold text-theme-muted uppercase tracking-wide mb-3",children:A},void 0,!1,void 0,this),Q2Q=({skill:A})=>f2("div",{className:"flex items-start gap-3 px-4 py-3 bg-theme-subtle rounded-lg",children:[f2("div",{className:"flex-1",children:[f2("div",{className:"text-sm font-semibold text-heading",children:A.name},void 0,!1,void 0,this),f2("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&&f2("div",{className:"flex gap-1 flex-shrink-0",children:A.tags.map((Q)=>f2("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),B2Q=({label:A,value:Q,valueClassName:B})=>f2("div",{className:"flex justify-between text-[13px]",children:[f2("span",{className:"text-theme-muted",children:A},void 0,!1,void 0,this),f2("span",{className:B??"text-heading",children:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R51=({agent:A,prevAgent:Q,nextAgent:B})=>{let{frontmatter:w,about:$,skills:f,notes:I}=A,D=QQA(w.url),H=w.status==="approved";return f2(w2Q,{children:[f2(XQ,{title:w.name,description:$||`Agent profile for ${w.name}`},void 0,!1,void 0,this),f2("article",{className:"agent-detail",children:f2("div",{className:"container mx-auto px-6 md:px-8 py-12 md:py-20",children:[f2("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),f2("div",{className:"flex items-start gap-6 mb-8",children:[f2(BQA,{name:w.name,className:"w-[72px] h-[72px] text-3xl"},void 0,!1,void 0,this),f2("div",{children:[f2("div",{className:"flex items-center gap-3 mb-1",children:[f2("h1",{className:"text-3xl md:text-4xl font-bold text-heading",children:w.name},void 0,!1,void 0,this),f2(wQA,{kind:w.kind},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2("div",{className:"text-base text-theme-muted mb-2",children:w.brainName},void 0,!1,void 0,this),f2("div",{className:"flex items-center gap-3 text-theme-muted",children:[w.organization&&f2("span",{className:"text-[15px]",children:w.organization},void 0,!1,void 0,this),w.organization&&f2("span",{className:"text-theme-muted opacity-40",children:"\xB7"},void 0,!1,void 0,this),f2("span",{className:"text-sm",children:["Discovered ",A2Q(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),f2("div",{className:"border-b border-theme mb-8"},void 0,!1,void 0,this),!H&&f2("div",{className:"mb-8 rounded-xl border border-theme bg-theme-subtle px-5 py-4",children:[f2("div",{className:"text-sm font-semibold text-heading mb-1",children:"Saved for review"},void 0,!1,void 0,this),f2("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),f2("div",{className:"flex flex-col md:flex-row gap-12",children:[f2("div",{className:"flex-[2] min-w-0",children:[$&&f2("section",{className:"mb-8",children:[f2(lm,{children:"About"},void 0,!1,void 0,this),f2("p",{className:"text-[15px] text-theme leading-relaxed",children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f.length>0&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Skills"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-2.5",children:f.map((Y)=>f2(Q2Q,{skill:Y},Y.name,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),I&&f2("section",{className:"mb-8",children:[f2(lm,{children:"Notes"},void 0,!1,void 0,this),f2("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),f2("aside",{className:"flex-1 md:pl-8 md:border-l border-theme-muted/20",children:[f2("section",{className:"mb-8",children:[f2(lm,{children:"Brain"},void 0,!1,void 0,this),f2("div",{className:"p-4 bg-theme-subtle rounded-xl",children:[f2("div",{className:"text-[15px] font-semibold text-heading mb-1",children:w.brainName},void 0,!1,void 0,this),w.did&&f2("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),f2("section",{className:"mb-8",children:[f2(lm,{children:"Connection"},void 0,!1,void 0,this),f2("div",{className:"flex flex-col gap-3",children:[f2("div",{children:[f2("div",{className:"text-[13px] text-theme-muted mb-0.5",children:"Endpoint"},void 0,!1,void 0,this),f2("div",{className:"text-xs text-heading font-mono",children:w.url},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f2(B2Q,{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),f2("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)&&f2("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:[f2("div",{className:"min-h-[1px]",children:Q&&f2("a",{href:Q.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"\u2190 Previous"},void 0,!1,void 0,this),f2("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),f2("div",{className:"min-h-[1px] md:text-right",children:B&&f2("a",{href:B.url,className:"inline-flex flex-col text-sm text-theme-muted hover:text-heading transition-colors",children:[f2("span",{children:"Next \u2192"},void 0,!1,void 0,this),f2("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 $2Q=G.object({agents:G.array(ZP),pageTitle:G.string().optional(),pagination:Y9.nullable(),baseUrl:G.string().optional(),selectedStatus:G.union([G.literal("all"),X4])});function P51(){return{[nPA]:O1({name:nPA,description:"Agent directory list page template",schema:$2Q,dataSourceId:cm,requiredPermission:"public",layout:{component:O51}}),[oPA]:O1({name:oPA,description:"Individual agent profile template",schema:G.object({agent:ZP,prevAgent:ZP.nullable(),nextAgent:ZP.nullable()}),dataSourceId:cm,requiredPermission:"public",layout:{component:R51}})}}var $QA={name:"@brains/agent-discovery",private:!0,version:"0.2.0-alpha.73",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 I2Q=new W4;class A_A extends KQ{entityType=c$;schema=KP;adapter=I2Q;constructor(){super(t61,$QA)}interceptCreate(A,Q,B){return K51(A,Q,B,this.id)}createGenerationHandler(A){return new sPA(this.logger.child("AgentGenerationJobHandler"),A)}getTemplates(){return P51()}getDataSources(){return[new a2A(this.logger.child("AgentDataSource"))]}async onRegister(A){L51(A,this.id)}async getInstructions(){return M51()}}function Q_A(){return new A_A}$0();GA();$0();var NP=HI,_51=HI,im=B2.extend({entityType:G.literal(w6),metadata:_51});$0();class zP extends W2{constructor(){super({entityType:w6,schema:im,frontmatterSchema:NP})}fromMarkdown(A){let Q=this.parseFrontMatter(A,NP);return{content:A,entityType:w6,metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}$0();GA();var D2Q=G.object({skills:G.array(NP).max(8)}),k51=O1({name:"skill:skill-derivation",description:"Derive skills from topic titles and brain capabilities",dataSourceId:"shell:ai-content",schema:D2Q,useKnowledgeContext:!0,basePrompt:`You are analyzing a brain's content to identify its high-level capabilities.
|
|
5102
5102
|
|
|
5103
5103
|
Given knowledge domains, CONSOLIDATE related topics into broader skills.
|
|
5104
5104
|
There should be FEWER skills than topics \u2014 combine related domains.
|
|
@@ -5248,9 +5248,9 @@ Context:
|
|
|
5248
5248
|
${JSON.stringify(w,null,2)}
|
|
5249
5249
|
|
|
5250
5250
|
Draft SWOT:
|
|
5251
|
-
${JSON.stringify(B,null,2)}`}function UQA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function P2Q(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 JQA{logger;context;adapter=new WG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=$_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 Y_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:Y}=await this.context.ai.generateObject(await b2Q(this.context,w),f_A),W=f_A.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await R2Q(this.context,w,W),YQA);$=YQA.parse(F.object),P2Q(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:UQA($.strengths),weaknesses:UQA($.weaknesses),opportunities:UQA($.opportunities),threats:UQA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,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 v9}from"preact/jsx-dev-runtime";var GQA=G.object({title:G.string(),detail:G.string().optional()}),_2Q=G.discriminatedUnion("status",[G.object({status:G.literal("generating")}),G.object({status:G.literal("ready"),strengths:G.array(GQA).default([]),weaknesses:G.array(GQA).default([]),opportunities:G.array(GQA).default([]),threats:G.array(GQA).default([]),derivedAt:G.string()})]);function k2Q({items:A}){if(A.length===0)return v9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return v9("ul",{class:"swot-list",children:A.map((Q)=>v9("li",{class:"swot-item",children:[v9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?v9("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 FQA({title:A,tone:Q,items:B}){return v9("section",{class:`swot-cell is-${Q}`,children:[v9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),v9(k2Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function U_A({data:A}){let Q=_2Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return v9("div",{"data-swot-widget":!0,children:v9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return v9("div",{"data-swot-widget":!0,children:v9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[v9(FQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),v9(FQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),v9(FQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),v9(FQA,{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 J_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.
|
|
5251
|
+
${JSON.stringify(B,null,2)}`}function UQA(A){return A.map((Q)=>Q.detail===null?{title:Q.title}:{title:Q.title,detail:Q.detail})}function P2Q(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 JQA{logger;context;adapter=new WG;constructor(A,Q){this.logger=A;this.context=Q}validateAndParse(A){let Q=$_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 Y_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:Y}=await this.context.ai.generateObject(await b2Q(this.context,w),f_A),W=f_A.parse(Y);await B.report({progress:0.75,message:"Refining SWOT language"});let F=await this.context.ai.generateObject(await R2Q(this.context,w,W),YQA);$=YQA.parse(F.object),P2Q(W,$)}let I=new Date().toISOString(),D=this.adapter.createSwotContent({strengths:UQA($.strengths),weaknesses:UQA($.weaknesses),opportunities:UQA($.opportunities),threats:UQA($.threats),derivedAt:I});await B.report({progress:0.9,message:"Saving SWOT entity"});let H=await this.context.entityService.getEntity({entityType:"swot",id:"swot"});if(H)await this.context.entityService.updateEntity({entity:{...H,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 v9}from"preact/jsx-dev-runtime";var GQA=G.object({title:G.string(),detail:G.string().optional()}),_2Q=G.discriminatedUnion("status",[G.object({status:G.literal("generating")}),G.object({status:G.literal("ready"),strengths:G.array(GQA).default([]),weaknesses:G.array(GQA).default([]),opportunities:G.array(GQA).default([]),threats:G.array(GQA).default([]),derivedAt:G.string()})]);function k2Q({items:A}){if(A.length===0)return v9("p",{class:"swot-empty",children:"\u2014"},void 0,!1,void 0,this);return v9("ul",{class:"swot-list",children:A.map((Q)=>v9("li",{class:"swot-item",children:[v9("b",{children:Q.title},void 0,!1,void 0,this),Q.detail?v9("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 FQA({title:A,tone:Q,items:B}){return v9("section",{class:`swot-cell is-${Q}`,children:[v9("div",{class:"swot-head",children:A},void 0,!1,void 0,this),v9(k2Q,{items:B},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function U_A({data:A}){let Q=_2Q.safeParse(A);if(!Q.success||Q.data.status==="generating")return v9("div",{"data-swot-widget":!0,children:v9("p",{class:"muted",children:"generating assessment\u2026"},void 0,!1,void 0,this)},void 0,!1,void 0,this);let B=Q.data;return v9("div",{"data-swot-widget":!0,children:v9("div",{class:"swot",role:"grid","aria-label":"SWOT analysis of agent network",children:[v9(FQA,{title:"Strengths",tone:"s",items:B.strengths},void 0,!1,void 0,this),v9(FQA,{title:"Weaknesses",tone:"w",items:B.weaknesses},void 0,!1,void 0,this),v9(FQA,{title:"Opportunities",tone:"o",items:B.opportunities},void 0,!1,void 0,this),v9(FQA,{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 J_A={name:"@brains/assessment",private:!0,version:"0.2.0-alpha.73",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 G_A=new WG;class F_A extends KQ{entityType="swot";schema=qP;adapter=G_A;initialSyncComplete=!1;constructor(){super("swot",J_A)}async onRegister(A){let Q=new JQA(this.logger.child("SwotDerivationHandler"),A);A.jobs.registerHandler("derive",Q),A.eval.registerHandler("deriveSwot",async()=>{let f=z$.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 G_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:U_A,dataProvider:async()=>{let f=await A.entityService.getEntity({entityType:"swot",id:"swot"});if(!f)return{status:"generating"};let{frontmatter:I}=G_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 K_A(){return new F_A}$0();d5();GA();var E3w=new WG,i51=G.object({name:G.string(),description:G.string(),tags:G.array(G.string())}),Z_A=G.enum(["discovered","approved"]),v2Q=G.object({name:G.string(),kind:G.enum(["professional","team","collective"]),organization:G.string().optional(),brainName:G.string(),url:G.string().url(),did:G.string().optional(),status:Z_A,discoveredAt:G.string().datetime()}),x2Q=B2.extend({entityType:G.literal("agent"),metadata:G.object({name:G.string(),url:G.string().url(),status:Z_A,slug:G.string()})}),h2Q=B2.extend({entityType:G.literal("skill"),metadata:HI}),y2Q=G.object({about:G.string(),skills:G.array(i51),notes:G.string()});function g2Q(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(`
|
|
5252
5252
|
`)}function T2Q(A){if(!A.trim())return[];return A.split(`
|
|
5253
|
-
`).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 S2Q=new PB(y2Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:g2Q,parser:T2Q},{key:"notes",label:"Notes",type:"string"}]});class r51 extends W2{constructor(){super({entityType:"agent",schema:x2Q,frontmatterSchema:v2Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=S2Q.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 d51 extends W2{constructor(){super({entityType:"skill",schema:h2Q,frontmatterSchema:HI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,HI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var L3w=new r51,M3w=new d51,V3w=G.object({skills:G.array(HI),agents:G.array(G.object({id:G.string().optional(),name:G.string(),kind:G.enum(["professional","team","collective"]),organization:G.string().optional(),brainName:G.string(),url:G.string().url(),did:G.string().optional(),status:Z_A,discoveredAt:G.string().datetime().optional(),about:G.string(),skills:G.array(i51),notes:G.string().default("")}))});var m2Q=G.object({}).strict();function KQA(A={}){return m2Q.parse(A),[K_A()]}$0();GA();Rw();G6();GA();$0();var ZQA=Tl.extend({expertise:G.array(G.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:G.string().optional().describe("What you're currently working on"),availability:G.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),sZ=AH.extend(ZQA.shape);$0();OU();GA();var u2Q=new AX;class NQA{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([eL(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),uOA(w)]),H=u2Q.parseProfileBody($,sZ),Y=f.sort(Fk).slice(0,3).map(Xm),W=I.sort(Fk).slice(0,3).map(Fm);if(!D.cta)throw Error("CTA not configured in site-info");let F={profile:H,posts:Y,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(F)}}$0();OU();var c2Q=new AX;class zQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await eL(B.entityService),f={profile:c2Q.parseProfileBody(w,sZ)};return Q.parse(f)}}import{jsxDEV as Vw,Fragment as i2Q}from"preact/jsx-dev-runtime";var p2Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",l2Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",N_A=({number:A,title:Q,blurb:B,children:w})=>Vw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Vw("div",{className:"max-w-6xl mx-auto",children:Vw("div",{className:p2Q,children:[Vw(yMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Vw("div",{className:l2Q,"aria-hidden":"true"},void 0,!1,void 0,this),Vw("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),z_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,H=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})),Y=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 Vw(i2Q,{children:[Vw(XQ,{title:W,description:F,ogType:"website"},void 0,!1,void 0,this),Vw("div",{className:"homepage-list bg-theme",children:[Vw("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:Vw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Vw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Vw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Vw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Vw("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:pAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Vw("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:pAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(N_A,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:Vw(cAA,{items:H,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&Vw(N_A,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:Vw(cAA,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Vw(N_A,{number:"03",title:"About",blurb:I.about?.blurb,children:Vw("div",{className:"flex flex-col gap-8",children:[A.description&&Vw("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&&Vw(gMA,{subjects:A.expertise},void 0,!1,void 0,this),Vw("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",Vw("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),Vw(CMA,{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 sB,Fragment as r2Q}from"preact/jsx-dev-runtime";var q_A=({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 sB(r2Q,{children:[sB(XQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),sB("div",{className:"about-page bg-theme",children:[sB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:sB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[sB("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&&sB("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),sB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&sB("section",{className:"content-section-reveal mb-20 md:mb-28",children:sB(mI,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&sB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),sB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>sB("li",{className:rT({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),sB("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&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),sB("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)&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),sB("div",{className:"space-y-4",children:[A.email&&sB("p",{className:"text-lg",children:sB("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&&sB("p",{className:"text-lg",children:sB("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&&sB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>sB(b5,{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 x9,Fragment as n51}from"preact/jsx-dev-runtime";var C_A=()=>{return x9(n51,{children:[x9(XQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),x9("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),x9(b5,{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)},E_A=()=>{return x9(n51,{children:[x9(XQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),x9("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),x9(b5,{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 o51=G.object({label:G.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:G.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),s51=G.object({entityDisplay:G.object({post:o51,deck:o51}).describe("Display metadata for post and deck entity types (required for homepage)")});var a51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.72",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 L_A extends RB{dependencies=["blog","decks"];constructor(A){super("professional-site",a51,A,s51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",ZQA);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 NQA(w,$);A.entities.registerDataSource(f);let I=new zQA;A.entities.registerDataSource(I);let D=G.object({profile:sZ,posts:G.array(fG),decks:G.array(Jm),postsListUrl:G.string(),decksListUrl:G.string(),cta:SOA,sections:G.record(G.string(),dp)}),H=G.object({profile:sZ}),Y=G.object({});A.templates.register({"homepage-list":O1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:z_A}}),about:O1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:q_A}}),"subscribe-thanks":O1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:C_A}}),"subscribe-error":O1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:E_A}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function t51(A){return new L_A(A??{})}var e51=[{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 qQA}from"preact/jsx-dev-runtime";function A$1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return qQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[qQA(VMA,{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),qQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),qQA(LMA,{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 n2Q={layouts:{default:A$1},routes:e51,plugin:t51,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"}}}},dm=n2Q;var Q$1=`/*
|
|
5253
|
+
`).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 S2Q=new PB(y2Q,{title:"Agent",mappings:[{key:"about",label:"About",type:"string"},{key:"skills",label:"Skills",type:"custom",formatter:g2Q,parser:T2Q},{key:"notes",label:"Notes",type:"string"}]});class r51 extends W2{constructor(){super({entityType:"agent",schema:x2Q,frontmatterSchema:v2Q})}fromMarkdown(A){return{content:A,entityType:"agent"}}createAgentContent(A){let Q=S2Q.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 d51 extends W2{constructor(){super({entityType:"skill",schema:h2Q,frontmatterSchema:HI})}fromMarkdown(A){let Q=this.parseFrontMatter(A,HI);return{content:A,entityType:"skill",metadata:Q}}createSkillContent(A){return this.buildMarkdown("",A)}}var L3w=new r51,M3w=new d51,V3w=G.object({skills:G.array(HI),agents:G.array(G.object({id:G.string().optional(),name:G.string(),kind:G.enum(["professional","team","collective"]),organization:G.string().optional(),brainName:G.string(),url:G.string().url(),did:G.string().optional(),status:Z_A,discoveredAt:G.string().datetime().optional(),about:G.string(),skills:G.array(i51),notes:G.string().default("")}))});var m2Q=G.object({}).strict();function KQA(A={}){return m2Q.parse(A),[K_A()]}$0();GA();Rw();G6();GA();$0();var ZQA=Tl.extend({expertise:G.array(G.string()).optional().describe("Skills, domains, areas of focus"),currentFocus:G.string().optional().describe("What you're currently working on"),availability:G.string().optional().describe("What you're open to (consulting, speaking, etc.)")}),sZ=AH.extend(ZQA.shape);$0();OU();GA();var u2Q=new AX;class NQA{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([eL(w),w.listEntities({entityType:"post",options:{limit:20}}),w.listEntities({entityType:"deck",options:{limit:20}}),uOA(w)]),H=u2Q.parseProfileBody($,sZ),Y=f.sort(Fk).slice(0,3).map(Xm),W=I.sort(Fk).slice(0,3).map(Fm);if(!D.cta)throw Error("CTA not configured in site-info");let F={profile:H,posts:Y,decks:W,postsListUrl:this.postsListUrl,decksListUrl:this.decksListUrl,cta:D.cta,sections:D.sections??{}};return Q.parse(F)}}$0();OU();var c2Q=new AX;class zQA{id="professional:about";name="About Page DataSource";description="Fetches full profile data for the about page";async fetch(A,Q,B){let w=await eL(B.entityService),f={profile:c2Q.parseProfileBody(w,sZ)};return Q.parse(f)}}import{jsxDEV as Vw,Fragment as i2Q}from"preact/jsx-dev-runtime";var p2Q="grid md:grid-cols-[14rem_1px_1fr] gap-y-2 gap-x-0 md:gap-16 items-start",l2Q="border-t md:border-t-0 md:border-l border-rule-strong md:self-stretch",N_A=({number:A,title:Q,blurb:B,children:w})=>Vw("section",{className:"py-20 border-b border-rule px-6 md:px-12",children:Vw("div",{className:"max-w-6xl mx-auto",children:Vw("div",{className:p2Q,children:[Vw(yMA,{title:Q,number:A,blurb:B},void 0,!1,void 0,this),Vw("div",{className:l2Q,"aria-hidden":"true"},void 0,!1,void 0,this),Vw("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),z_A=({profile:A,posts:Q,decks:B,postsListUrl:w,decksListUrl:$,cta:f,sections:I})=>{let D=A.tagline||A.description,H=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})),Y=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 Vw(i2Q,{children:[Vw(XQ,{title:W,description:F,ogType:"website"},void 0,!1,void 0,this),Vw("div",{className:"homepage-list bg-theme",children:[Vw("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:Vw("div",{className:"relative z-10 max-w-6xl mx-auto w-full",children:[A.name&&Vw("div",{className:"flex items-center gap-[0.6rem] mb-6 font-mono text-[0.7rem] font-medium uppercase tracking-[0.22em] text-accent",children:[Vw("span",{className:"w-[18px] h-px bg-accent","aria-hidden":"true"},void 0,!1,void 0,this),Vw("span",{children:A.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D&&Vw("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:pAA(D,"italic font-normal text-accent [font-variation-settings:'opsz'_144,'SOFT'_80]")},void 0,!1,void 0,this),A.intro&&Vw("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:pAA(A.intro,"italic text-accent")},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Vw(N_A,{number:"01",title:"Essays",blurb:I.essays?.blurb,children:Vw(cAA,{items:H,viewAllUrl:w,viewAllLabel:"View all essays"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Y.length>0&&Vw(N_A,{number:"02",title:"Presentations",blurb:I.presentations?.blurb,children:Vw(cAA,{items:Y,viewAllUrl:$,viewAllLabel:"View all presentations"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K&&Vw(N_A,{number:"03",title:"About",blurb:I.about?.blurb,children:Vw("div",{className:"flex flex-col gap-8",children:[A.description&&Vw("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&&Vw(gMA,{subjects:A.expertise},void 0,!1,void 0,this),Vw("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",Vw("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),Vw(CMA,{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 sB,Fragment as r2Q}from"preact/jsx-dev-runtime";var q_A=({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 sB(r2Q,{children:[sB(XQ,{title:Q,description:B,ogType:"profile"},void 0,!1,void 0,this),sB("div",{className:"about-page bg-theme",children:[sB("header",{className:"hero-bg-pattern relative w-full py-16 md:py-24 px-6 md:px-12 bg-theme overflow-hidden",children:sB("div",{className:"relative z-10 max-w-4xl mx-auto",children:[sB("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&&sB("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),sB("div",{className:"container mx-auto px-6 md:px-12 max-w-4xl py-12 md:py-16",children:[A.story&&sB("section",{className:"content-section-reveal mb-20 md:mb-28",children:sB(mI,{markdown:A.story},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&sB("div",{className:"content-section-reveal grid md:grid-cols-2 gap-x-16 gap-y-12",children:[A.expertise&&A.expertise.length>0&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Expertise"},void 0,!1,void 0,this),sB("ul",{className:"flex flex-wrap gap-3",children:A.expertise.map(($,f)=>sB("li",{className:rT({variant:"accent",size:"lg"}),children:$},f,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A.currentFocus&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Current Focus"},void 0,!1,void 0,this),sB("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&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Availability"},void 0,!1,void 0,this),sB("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)&&sB("section",{children:[sB("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:"Contact"},void 0,!1,void 0,this),sB("div",{className:"space-y-4",children:[A.email&&sB("p",{className:"text-lg",children:sB("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&&sB("p",{className:"text-lg",children:sB("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&&sB("div",{className:"flex flex-wrap gap-4 mt-4",children:A.socialLinks.map(($,f)=>sB(b5,{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 x9,Fragment as n51}from"preact/jsx-dev-runtime";var C_A=()=>{return x9(n51,{children:[x9(XQ,{title:"Thanks for subscribing!",description:"You've successfully subscribed to the newsletter."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83C\uDF89"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Thanks for subscribing!"},void 0,!1,void 0,this),x9("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),x9(b5,{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)},E_A=()=>{return x9(n51,{children:[x9(XQ,{title:"Subscription failed",description:"There was a problem with your subscription."},void 0,!1,void 0,this),x9("div",{className:"min-h-[60vh] flex items-center justify-center px-6",children:x9("div",{className:"text-center max-w-md",children:[x9("div",{className:"text-6xl mb-6",children:"\uD83D\uDE22"},void 0,!1,void 0,this),x9("h1",{className:"text-3xl font-semibold mb-4 text-heading",children:"Something went wrong"},void 0,!1,void 0,this),x9("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),x9(b5,{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 o51=G.object({label:G.string().describe("Display label for entity type (e.g., 'Essay')"),pluralName:G.string().optional().describe("URL path segment (defaults to label.toLowerCase() + 's')")}),s51=G.object({entityDisplay:G.object({post:o51,deck:o51}).describe("Display metadata for post and deck entity types (required for homepage)")});var a51={name:"@brains/site-professional",private:!0,version:"0.2.0-alpha.73",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 L_A extends RB{dependencies=["blog","decks"];constructor(A){super("professional-site",a51,A,s51)}async onRegister(A){A.entities.extendFrontmatterSchema("anchor-profile",ZQA);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 NQA(w,$);A.entities.registerDataSource(f);let I=new zQA;A.entities.registerDataSource(I);let D=G.object({profile:sZ,posts:G.array(fG),decks:G.array(Jm),postsListUrl:G.string(),decksListUrl:G.string(),cta:SOA,sections:G.record(G.string(),dp)}),H=G.object({profile:sZ}),Y=G.object({});A.templates.register({"homepage-list":O1({name:"homepage-list",description:"Professional homepage with essays and presentations",schema:D,dataSourceId:"professional:homepage-list",requiredPermission:"public",layout:{component:z_A}}),about:O1({name:"about",description:"About page with full profile information",schema:H,dataSourceId:"professional:about",requiredPermission:"public",layout:{component:q_A}}),"subscribe-thanks":O1({name:"subscribe-thanks",description:"Newsletter subscription success page",schema:Y,requiredPermission:"public",layout:{component:C_A}}),"subscribe-error":O1({name:"subscribe-error",description:"Newsletter subscription error page",schema:Y,requiredPermission:"public",layout:{component:E_A}})}),this.logger.info("Professional site plugin registered successfully")}async getTools(){return[]}async getResources(){return[]}}function t51(A){return new L_A(A??{})}var e51=[{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 qQA}from"preact/jsx-dev-runtime";function A$1({sections:A,siteInfo:Q,slots:B,wordmark:w}){return qQA("div",{className:"flex flex-col min-h-screen bg-theme overflow-x-clip",children:[qQA(VMA,{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),qQA("main",{className:"flex-grow flex flex-col bg-theme",children:A},void 0,!1,void 0,this),qQA(LMA,{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 n2Q={layouts:{default:A$1},routes:e51,plugin:t51,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"}}}},dm=n2Q;var Q$1=`/*
|
|
5254
5254
|
* Default theme \u2014 simplified editorial base inspired by the Rizom family.
|
|
5255
5255
|
*
|
|
5256
5256
|
* This theme is intentionally less branded than @brains/theme-rizom. It
|
|
@@ -5638,7 +5638,7 @@ ${JSON.stringify(B,null,2)}`}function UQA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5638
5638
|
|
|
5639
5639
|
.btn-primary:disabled { opacity: 0.5; }
|
|
5640
5640
|
}
|
|
5641
|
-
`;var EP=Q$1;import{join as a2Q}from"path";var B$1={name:"@brains/rover",version:"0.2.0-alpha.72",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/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/topics":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var w$1=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","discord","a2a"],$$1=[...w$1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],t2Q=[...$$1,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],e2Q=["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."],f$1=QK({name:"rover",version:B$1.version,model:"gpt-5.4-mini",site:dm,theme:EP,presets:{core:w$1,default:$$1,full:t2Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:e2Q,capabilities:[["prompt",cC,void 0],["image",yx,void 0],["cms",uC,{}],["auth-service",Vy,void 0],["notifications",oY0,void 0],["email-resend",Ud0,void 0],["dashboard",nZ,void 0],["dashboard-root",nZ,{routePath:"/"}],["blog",oOA,{}],["series",ARA,void 0],["decks",Km,void 0],["note",xC,{}],["link",yC,{}],["portfolio",vRA,{}],["topics",b2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",XPA,{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",bm,{autoGenerateOnBlogPublish:!0}],["newsletter",V61,{doubleOptIn:!0}],["obsidian-vault",_PA,{autoSync:!0}],["wishlist",p2A,{}],["stock-photo",TPA,{}],["agents",IQA,void 0],["assessment",KQA,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:a2Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",g2A,{}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",_C,{cms:{}}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({})],["webserver",ZZ,()=>({})],["a2a",AR,()=>({})]],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"}}});$K();$0();GA();GA();$0();var CQA=G.object({routeId:G.string(),sectionId:G.string()}),nm=B2.extend({entityType:G.literal("site-content"),template:G.string().optional(),content:G.string(),metadata:CQA});$0();class I$1 extends W2{constructor(){super({entityType:"site-content",schema:nm,frontmatterSchema:CQA})}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 M_A=new I$1;GA();var EQA=G.object({routeId:G.string().optional().describe("Optional: specific route filter"),sectionId:G.string().optional().describe("Optional: specific section filter"),dryRun:G.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:G.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),Szw=G.object({jobs:G.array(G.object({jobId:G.string(),routeId:G.string(),sectionId:G.string()})),totalSections:G.number(),queuedSections:G.number(),skippedSections:G.number().optional(),batchId:G.string().optional()});class V_A{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 H=[],Y=[];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};Y.push({type:"shell:content-generation",data:q})}if(Y.length>0){let W=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(Y,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)H.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:H,totalSections:D,queuedSections:H.length,batchId:F}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class b_A{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new V_A(A)}async generateContent(A,Q){let B=EQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}d5();GA();function om(A,Q){return Q?A.optional():A}function R_A(A){switch(A.type){case"string":return om(G.string(),A.optional);case"number":return om(G.number(),A.optional);case"enum":{let Q=[...A.options];return om(G.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=R_A(w);return om(G.object(Q),A.optional)}case"array":{let Q=G.array(AQQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return om(Q,A.optional)}}}function AQQ(A){let{items:Q}=A;switch(Q.type){case"string":return G.string();case"number":return G.number();case"enum":{let B=[...Q.options];return G.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=R_A($);return G.object(B)}}}function O_A(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])=>O_A(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,$])=>O_A(w,$)),B}}}}function QQQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=R_A(I);let w=G.object(B),$=new PB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>O_A(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 P_A(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,QQQ(Q,B)]))}GA();var D$1=G.object({namespace:G.string(),sections:G.record(G.any())}),H$1=G.object({definitions:G.union([D$1,G.array(D$1)]).optional()});$0();function Y$1(A,Q){return[xQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",EQA,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 X$1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.72",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 __A extends RB{siteContentService;constructor(A={}){super("site-content",X$1,A,H$1)}async onRegister(A){A.entities.register("site-content",nm,M_A);for(let Q of pY(this.config.definitions))A.templates.register(P_A(Q),Q.namespace);this.siteContentService=new b_A(A)}async getTools(){return Y$1(()=>this.siteContentService,this.id)}}function sm(A={}){return new __A(A)}$0();GA();Rw();GA();$0();var W$1=G.enum(["available","early access","coming soon","planned"]),U$1=G.object({title:G.string(),description:G.string()}),UG=G.object({name:G.string(),availability:W$1,order:G.number()}),LQA=G.object({tagline:G.string(),promise:G.string(),role:G.string(),purpose:G.string(),audience:G.string(),values:G.array(G.string()).min(1),features:G.array(U$1).min(1).max(6),story:G.string()}),wQQ=UG.pick({name:!0,availability:!0,order:!0}).extend({slug:G.string()}),LP=B2.extend({entityType:G.literal("product"),metadata:wQQ}),MQA=LP.extend({frontmatter:UG,body:LQA,labels:G.record(G.string(),G.string())}),VQA=MQA.extend({url:G.string().optional(),typeLabel:G.string().optional(),listUrl:G.string().optional(),listLabel:G.string().optional()});$0();GA();d5();class MP extends PB{constructor(){super(LQA,{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 k_A extends W2{constructor(){super({entityType:"product",schema:LP,frontmatterSchema:UG,bodyFormatter:new MP})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,UG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,UG),B=U2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var bQA=new k_A;GA();$0();var J$1=G.object({title:G.string(),description:G.string()}),G$1=G.object({title:G.string(),description:G.string()}),$QQ=G.object({title:G.string(),description:G.string()}),F$1=G.object({heading:G.string(),buttonText:G.string(),link:G.string()}),JG=G.object({headline:G.string(),tagline:G.string()}),fQQ=G.object({title:G.string(),description:G.string()}),OQA=G.object({vision:G.string(),pillars:G.array(J$1).min(1).max(6),approach:G.array(fQQ).min(1).max(6),productsIntro:G.string(),technologies:G.array($QQ).min(1).max(6),benefits:G.array(G$1).min(1).max(6),cta:F$1}),K$1=JG.pick({headline:!0}).extend({slug:G.string()}),VP=B2.extend({entityType:G.literal("products-overview"),metadata:K$1}),am=VP.extend({frontmatter:JG,body:OQA,labels:G.record(G.string(),G.string())});$0();GA();d5();class bP extends PB{constructor(){super(OQA,{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 j_A extends W2{constructor(){super({entityType:"products-overview",schema:VP,frontmatterSchema:JG,bodyFormatter:new bP})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,JG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,JG),B=U2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var v_A=new j_A;$0();GA();var IQQ=G.object({entityType:G.string(),query:G.object({id:G.string().optional()}).optional()});function Z$1(A,Q){let B=t2(A.content,UG),w=Q.parse(B.content),$=Q.getLabels();return MQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function N$1(A,Q){let B=t2(A.content,JG),w=Q.parse(B.content),$=Q.getLabels();return am.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class RQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new bP;productFormatter=new MP;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=IQQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let W=N$1(Y,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:Z$1(Y,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:N$1(D,this.overviewFormatter),products:I.map((H)=>Z$1(H,this.productFormatter))})}}import{jsxDEV as B1,Fragment as YQQ}from"preact/jsx-dev-runtime";var z$1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(YQQ,{children:[B1(XQ,{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:`
|
|
5641
|
+
`;var EP=Q$1;import{join as a2Q}from"path";var B$1={name:"@brains/rover",version:"0.2.0-alpha.73",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/email-resend":"workspace:*","@brains/image-plugin":"workspace:*","@brains/link":"workspace:*","@brains/mcp":"workspace:*","@brains/newsletter":"workspace:*","@brains/note":"workspace:*","@brains/notifications":"workspace:*","@brains/obsidian-vault":"workspace:*","@brains/portfolio":"workspace:*","@brains/prompt":"workspace:*","@brains/rizom-ecosystem":"workspace:*","@brains/series":"workspace:*","@brains/site-builder-plugin":"workspace:*","@brains/site-default":"workspace:*","@brains/site-info":"workspace:*","@brains/social-media":"workspace:*","@brains/stock-photo":"workspace:*","@brains/topics":"workspace:*","@brains/webserver":"workspace:*","@brains/wishlist":"workspace:*"},devDependencies:{"@brains/ai-evaluation":"workspace:*","@brains/typescript-config":"workspace:*",typescript:"^5.3.3"}};var w$1=["prompt","note","link","wishlist","topics","directory-sync","agents","assessment","auth-service","notifications","email-resend","cms","dashboard-root","mcp","webserver","discord","a2a"],$$1=[...w$1.filter((A)=>A!=="dashboard-root"),"image","dashboard","blog","series","decks","analytics","obsidian-vault","site-info","site-builder"],t2Q=[...$$1,"portfolio","topics","content-pipeline","social-media","newsletter","stock-photo"],e2Q=["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."],f$1=QK({name:"rover",version:B$1.version,model:"gpt-5.4-mini",site:dm,theme:EP,presets:{core:w$1,default:$$1,full:t2Q},evalDisable:["discord","webserver","mcp","analytics","dashboard","dashboard-root","email-resend"],agentInstructions:e2Q,capabilities:[["prompt",cC,void 0],["image",yx,void 0],["cms",uC,{}],["auth-service",Vy,void 0],["notifications",oY0,void 0],["email-resend",Ud0,void 0],["dashboard",nZ,void 0],["dashboard-root",nZ,{routePath:"/"}],["blog",oOA,{}],["series",ARA,void 0],["decks",Km,void 0],["note",xC,{}],["link",yC,{}],["portfolio",vRA,{}],["topics",b2A,{includeEntityTypes:["post","deck","project","link","anchor-profile"]}],["content-pipeline",XPA,{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",bm,{autoGenerateOnBlogPublish:!0}],["newsletter",V61,{doubleOptIn:!0}],["obsidian-vault",_PA,{autoSync:!0}],["wishlist",p2A,{}],["stock-photo",TPA,{}],["agents",IQA,void 0],["assessment",KQA,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:a2Q(import.meta.dir,"..","seed-content"),initialSync:!0}],["analytics",g2A,{}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",_C,{cms:{}}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({})],["webserver",ZZ,()=>({})],["a2a",AR,()=>({})]],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"}}});$K();$0();GA();GA();$0();var CQA=G.object({routeId:G.string(),sectionId:G.string()}),nm=B2.extend({entityType:G.literal("site-content"),template:G.string().optional(),content:G.string(),metadata:CQA});$0();class I$1 extends W2{constructor(){super({entityType:"site-content",schema:nm,frontmatterSchema:CQA})}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 M_A=new I$1;GA();var EQA=G.object({routeId:G.string().optional().describe("Optional: specific route filter"),sectionId:G.string().optional().describe("Optional: specific section filter"),dryRun:G.boolean().optional().default(!1).describe("Optional: preview changes without executing"),force:G.boolean().optional().default(!1).describe("Force regeneration even if content exists")}),Szw=G.object({jobs:G.array(G.object({jobId:G.string(),routeId:G.string(),sectionId:G.string()})),totalSections:G.number(),queuedSections:G.number(),skippedSections:G.number().optional(),batchId:G.string().optional()});class V_A{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 H=[],Y=[];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};Y.push({type:"shell:content-generation",data:q})}if(Y.length>0){let W=this.createJobOptions(B,"site:content-generation"),F=await this.context.jobs.enqueueBatch(Y,W);for(let K=0;K<I.length;K++){let Z=I[K];if(Z)H.push({jobId:`${F}-${K}`,routeId:Z.route.id,sectionId:Z.section.id})}return{jobs:H,totalSections:D,queuedSections:H.length,batchId:F}}return{jobs:[],totalSections:D,queuedSections:0,batchId:`empty-${Date.now()}`}}}class b_A{siteConfig;operations;constructor(A,Q){this.siteConfig=Q;this.operations=new V_A(A)}async generateContent(A,Q){let B=EQA.parse(A);return this.operations.generate(B,this.siteConfig,Q)}}d5();GA();function om(A,Q){return Q?A.optional():A}function R_A(A){switch(A.type){case"string":return om(G.string(),A.optional);case"number":return om(G.number(),A.optional);case"enum":{let Q=[...A.options];return om(G.enum(Q),A.optional)}case"object":{let Q={};for(let[B,w]of Object.entries(A.fields))Q[B]=R_A(w);return om(G.object(Q),A.optional)}case"array":{let Q=G.array(AQQ(A));if(A.minItems!==void 0)Q=Q.min(A.minItems);if(A.length!==void 0)Q=Q.length(A.length);return om(Q,A.optional)}}}function AQQ(A){let{items:Q}=A;switch(Q.type){case"string":return G.string();case"number":return G.number();case"enum":{let B=[...Q.options];return G.enum(B)}case"object":{let B={};for(let[w,$]of Object.entries(Q.fields))B[w]=R_A($);return G.object(B)}}}function O_A(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])=>O_A(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,$])=>O_A(w,$)),B}}}}function QQQ(A,Q){let B={};for(let[f,I]of Object.entries(Q.fields))B[f]=R_A(I);let w=G.object(B),$=new PB(w,{title:Q.title,mappings:Object.entries(Q.fields).map(([f,I])=>O_A(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 P_A(A){return Object.fromEntries(Object.entries(A.sections).map(([Q,B])=>[Q,QQQ(Q,B)]))}GA();var D$1=G.object({namespace:G.string(),sections:G.record(G.any())}),H$1=G.object({definitions:G.union([D$1,G.array(D$1)]).optional()});$0();function Y$1(A,Q){return[xQ(Q,"generate","Generate content for all routes, a specific route, or a specific section",EQA,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 X$1={name:"@brains/site-content",private:!0,version:"0.2.0-alpha.73",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 __A extends RB{siteContentService;constructor(A={}){super("site-content",X$1,A,H$1)}async onRegister(A){A.entities.register("site-content",nm,M_A);for(let Q of pY(this.config.definitions))A.templates.register(P_A(Q),Q.namespace);this.siteContentService=new b_A(A)}async getTools(){return Y$1(()=>this.siteContentService,this.id)}}function sm(A={}){return new __A(A)}$0();GA();Rw();GA();$0();var W$1=G.enum(["available","early access","coming soon","planned"]),U$1=G.object({title:G.string(),description:G.string()}),UG=G.object({name:G.string(),availability:W$1,order:G.number()}),LQA=G.object({tagline:G.string(),promise:G.string(),role:G.string(),purpose:G.string(),audience:G.string(),values:G.array(G.string()).min(1),features:G.array(U$1).min(1).max(6),story:G.string()}),wQQ=UG.pick({name:!0,availability:!0,order:!0}).extend({slug:G.string()}),LP=B2.extend({entityType:G.literal("product"),metadata:wQQ}),MQA=LP.extend({frontmatter:UG,body:LQA,labels:G.record(G.string(),G.string())}),VQA=MQA.extend({url:G.string().optional(),typeLabel:G.string().optional(),listUrl:G.string().optional(),listLabel:G.string().optional()});$0();GA();d5();class MP extends PB{constructor(){super(LQA,{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 k_A extends W2{constructor(){super({entityType:"product",schema:LP,frontmatterSchema:UG,bodyFormatter:new MP})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,UG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,UG),B=U2(Q.name);return{content:A,entityType:"product",metadata:{name:Q.name,slug:B,availability:Q.availability,order:Q.order}}}}var bQA=new k_A;GA();$0();var J$1=G.object({title:G.string(),description:G.string()}),G$1=G.object({title:G.string(),description:G.string()}),$QQ=G.object({title:G.string(),description:G.string()}),F$1=G.object({heading:G.string(),buttonText:G.string(),link:G.string()}),JG=G.object({headline:G.string(),tagline:G.string()}),fQQ=G.object({title:G.string(),description:G.string()}),OQA=G.object({vision:G.string(),pillars:G.array(J$1).min(1).max(6),approach:G.array(fQQ).min(1).max(6),productsIntro:G.string(),technologies:G.array($QQ).min(1).max(6),benefits:G.array(G$1).min(1).max(6),cta:F$1}),K$1=JG.pick({headline:!0}).extend({slug:G.string()}),VP=B2.extend({entityType:G.literal("products-overview"),metadata:K$1}),am=VP.extend({frontmatter:JG,body:OQA,labels:G.record(G.string(),G.string())});$0();GA();d5();class bP extends PB{constructor(){super(OQA,{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 j_A extends W2{constructor(){super({entityType:"products-overview",schema:VP,frontmatterSchema:JG,bodyFormatter:new bP})}toMarkdown(A){let Q=this.extractBody(A.content);try{let B=this.parseFrontMatter(A.content,JG);return this.buildMarkdown(Q,B)}catch{return Q}}fromMarkdown(A){let Q=this.parseFrontMatter(A,JG),B=U2(Q.headline);return{content:A,entityType:"products-overview",metadata:{headline:Q.headline,slug:B}}}}var v_A=new j_A;$0();GA();var IQQ=G.object({entityType:G.string(),query:G.object({id:G.string().optional()}).optional()});function Z$1(A,Q){let B=t2(A.content,UG),w=Q.parse(B.content),$=Q.getLabels();return MQA.parse({...A,frontmatter:B.metadata,body:w,labels:$})}function N$1(A,Q){let B=t2(A.content,JG),w=Q.parse(B.content),$=Q.getLabels();return am.parse({...A,frontmatter:B.metadata,body:w,labels:$})}class RQA{logger;id="products:entities";name="Products Entity DataSource";description="Fetches products and overview for the products page";overviewFormatter=new bP;productFormatter=new MP;constructor(A){this.logger=A;this.logger.debug("ProductsDataSource initialized")}async fetch(A,Q,B){let w=IQQ.parse(A),$=B.entityService;if(w.entityType==="products-overview"){let Y=(await $.listEntities({entityType:"products-overview",options:{limit:1}}))[0];if(!Y)throw Error("Products overview entity not found");let W=N$1(Y,this.overviewFormatter);return Q.parse(W)}if(w.query?.id){let Y=(await $.listEntities({entityType:"product",options:{filter:{metadata:{slug:w.query.id}},limit:1}}))[0];if(!Y)throw Error(`Product not found: ${w.query.id}`);return Q.parse({product:Z$1(Y,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:N$1(D,this.overviewFormatter),products:I.map((H)=>Z$1(H,this.productFormatter))})}}import{jsxDEV as B1,Fragment as YQQ}from"preact/jsx-dev-runtime";var z$1=({overview:A,products:Q})=>{let{frontmatter:B,body:w,labels:$}=A;return B1(YQQ,{children:[B1(XQ,{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:`
|
|
5642
5642
|
@keyframes wave-drift {
|
|
5643
5643
|
from { transform: translateX(0); }
|
|
5644
5644
|
to { transform: translateX(-50%); }
|
|
@@ -5666,7 +5666,7 @@ ${JSON.stringify(B,null,2)}`}function UQA(A){return A.map((Q)=>Q.detail===null?{
|
|
|
5666
5666
|
@media (prefers-reduced-motion: reduce) {
|
|
5667
5667
|
.detail-wave { animation: none; }
|
|
5668
5668
|
}
|
|
5669
|
-
`},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:n1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[n1("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),n1("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),n1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),n1("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:[n1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:n1("ol",{className:"flex flex-wrap items-center gap-1",children:[n1("li",{className:"flex items-center gap-1",children:n1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("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),n1("div",{className:"mb-6 hero-stagger-1",children:n1(Ef,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("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),n1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),n1("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),n1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto space-y-16",children:[n1("div",{children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),n1("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),n1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),n1("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),n1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),n1(NR,{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),n1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"container mx-auto max-w-5xl",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,H)=>n1("div",{children:n1("div",{className:"flex items-start gap-6",children:[n1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this),n1("div",{className:"pt-2",children:[n1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),n1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),n1("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),n1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"max-w-3xl mx-auto",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),n1("div",{className:"space-y-6",children:I.map((D,H)=>n1("p",{className:H===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},H,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("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:n1("div",{className:"max-w-4xl mx-auto",children:[n1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),n1("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),n1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),n1(b5,{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 x_A=G.object({route:G.string().default("/products")});var C$1={name:"@brains/products",private:!0,version:"0.2.0-alpha.72",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 UQQ=G.object({overview:am,products:G.array(VQA)}),JQQ=G.object({product:VQA});class h_A extends KQ{entityType=bQA.entityType;schema=LP;adapter=bQA;constructor(A={}){super("products",C$1,A,x_A)}getTemplates(){return{"product-list":O1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:UQQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:z$1}}),"product-detail":O1({name:"product-detail",description:"Individual product detail page",schema:JQQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:q$1}})}}getDataSources(){return[new RQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",VP,v_A)}}function y_A(A={}){return new h_A(A)}import{join as TQQ}from"path";import{jsxDEV as PQA,Fragment as GQQ}from"preact/jsx-dev-runtime";var OP=({children:A})=>PQA(GQQ,{children:[PQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:PQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),PQA("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 VCw}from"preact/jsx-dev-runtime";import{jsxDEV as KQQ}from"preact/jsx-dev-runtime";var _QA="px-6 md:px-10 xl:px-20",FQQ=`${_QA} relative z-[1]`,aZ=({id:A,className:Q,children:B})=>KQQ("section",{id:A,className:s1(FQQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as vCw}from"preact/jsx-dev-runtime";import{jsxDEV as yCw}from"preact/jsx-dev-runtime";import{jsxDEV as CQQ}from"preact/jsx-dev-runtime";var ZQQ="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)]",NQQ={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)]"},zQQ={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)]"},qQQ="w-full md:w-auto",iC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>CQQ("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",ZQQ,NQQ[Q],zQQ[B],w&&qQQ,$),children:f},void 0,!1,void 0,this);import{jsxDEV as pCw}from"preact/jsx-dev-runtime";import{jsxDEV as dCw}from"preact/jsx-dev-runtime";import{Fragment as sCw}from"preact";import{jsxDEV as tCw}from"preact/jsx-dev-runtime";import{jsxDEV as E$1}from"preact/jsx-dev-runtime";var kQA=({sections:A})=>E$1(OP,{children:E$1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);$0();GA();var L$1=`/*
|
|
5669
|
+
`},void 0,!1,void 0,this),n1("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:n1("svg",{preserveAspectRatio:"none",width:"200%",height:"100%",viewBox:"0 0 1600 400",className:"block absolute inset-0 detail-wave",children:[n1("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),n1("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),n1("div",{className:"absolute inset-0 cta-bg-pattern pointer-events-none"},void 0,!1,void 0,this),n1("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:[n1("nav",{"aria-label":"Breadcrumb",className:"text-sm text-white/50 mb-8 hero-stagger-1",children:n1("ol",{className:"flex flex-wrap items-center gap-1",children:[n1("li",{className:"flex items-center gap-1",children:n1("a",{href:"/",className:"hover:text-white transition-colors",children:"Home"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("a",{href:$,className:"hover:text-white transition-colors",children:f},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("li",{className:"flex items-center gap-1",children:[n1("span",{className:"mx-1","aria-hidden":"true",children:"/"},void 0,!1,void 0,this),n1("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),n1("div",{className:"mb-6 hero-stagger-1",children:n1(Ef,{status:Q.availability},void 0,!1,void 0,this)},void 0,!1,void 0,this),n1("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),n1("div",{className:"w-20 h-1.5 bg-accent mb-6 md:mb-8 hero-stagger-2"},void 0,!1,void 0,this),n1("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),n1("section",{className:"bg-theme-subtle py-20 md:py-28 px-6 md:px-12",children:n1("div",{className:"max-w-4xl mx-auto space-y-16",children:[n1("div",{children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-6",children:w.promise},void 0,!1,void 0,this),n1("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),n1("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-16",children:[n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.role},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.role},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.purpose},void 0,!1,void 0,this),n1("p",{className:"text-lg leading-relaxed text-theme-muted",children:B.purpose},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n1("div",{children:[n1("div",{className:"w-8 h-1 bg-accent mb-6"},void 0,!1,void 0,this),n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-4",children:w.audience},void 0,!1,void 0,this),n1("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),n1("div",{className:"flex flex-col md:flex-row md:items-center gap-6 md:gap-12",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted whitespace-nowrap",children:w.values},void 0,!1,void 0,this),n1(NR,{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),n1("section",{className:"cta-bg-pattern bg-brand py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"container mx-auto max-w-5xl",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-white/50 mb-16",children:w.features},void 0,!1,void 0,this),n1("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-16",children:B.features.map((D,H)=>n1("div",{children:n1("div",{className:"flex items-start gap-6",children:[n1("span",{className:"text-5xl md:text-6xl font-black text-white/10 leading-none shrink-0",children:String(H+1).padStart(2,"0")},void 0,!1,void 0,this),n1("div",{className:"pt-2",children:[n1("div",{className:"w-8 h-1 bg-accent mb-4"},void 0,!1,void 0,this),n1("h3",{className:"text-xl font-bold text-white mb-3",children:D.title},void 0,!1,void 0,this),n1("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),n1("section",{className:"py-20 md:py-32 px-6 md:px-12",children:n1("div",{className:"max-w-3xl mx-auto",children:[n1("h2",{className:"text-sm tracking-widest uppercase text-theme-muted mb-12",children:w.story},void 0,!1,void 0,this),n1("div",{className:"space-y-6",children:I.map((D,H)=>n1("p",{className:H===0?"text-2xl md:text-3xl leading-relaxed text-heading font-light":"text-lg leading-relaxed text-theme-muted",children:D},H,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n1("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:n1("div",{className:"max-w-4xl mx-auto",children:[n1("p",{className:"text-sm tracking-widest uppercase text-white/60 mb-4",children:Q.name},void 0,!1,void 0,this),n1("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),n1("p",{className:"text-lg text-white/60 mb-10 max-w-xl",children:B.promise},void 0,!1,void 0,this),n1(b5,{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 x_A=G.object({route:G.string().default("/products")});var C$1={name:"@brains/products",private:!0,version:"0.2.0-alpha.73",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 UQQ=G.object({overview:am,products:G.array(VQA)}),JQQ=G.object({product:VQA});class h_A extends KQ{entityType=bQA.entityType;schema=LP;adapter=bQA;constructor(A={}){super("products",C$1,A,x_A)}getTemplates(){return{"product-list":O1({name:"product-list",description:"Products page \u2014 overview + brain model cards",schema:UQQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:z$1}}),"product-detail":O1({name:"product-detail",description:"Individual product detail page",schema:JQQ,dataSourceId:"products:entities",requiredPermission:"public",layout:{component:q$1}})}}getDataSources(){return[new RQA(this.logger.child("ProductsDataSource"))]}async onRegister(A){A.entities.register("products-overview",VP,v_A)}}function y_A(A={}){return new h_A(A)}import{join as TQQ}from"path";import{jsxDEV as PQA,Fragment as GQQ}from"preact/jsx-dev-runtime";var OP=({children:A})=>PQA(GQQ,{children:[PQA("div",{id:"bgCanvasWrap",className:"rizom-frame-canvas-wrap fixed top-0 left-0 w-full h-full pointer-events-none",children:PQA("canvas",{id:"heroCanvas",className:"w-full h-full block"},void 0,!1,void 0,this)},void 0,!1,void 0,this),PQA("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 VCw}from"preact/jsx-dev-runtime";import{jsxDEV as KQQ}from"preact/jsx-dev-runtime";var _QA="px-6 md:px-10 xl:px-20",FQQ=`${_QA} relative z-[1]`,aZ=({id:A,className:Q,children:B})=>KQQ("section",{id:A,className:s1(FQQ,Q),children:B},void 0,!1,void 0,this);import{jsxDEV as vCw}from"preact/jsx-dev-runtime";import{jsxDEV as yCw}from"preact/jsx-dev-runtime";import{jsxDEV as CQQ}from"preact/jsx-dev-runtime";var ZQQ="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)]",NQQ={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)]"},zQQ={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)]"},qQQ="w-full md:w-auto",iC=({href:A,variant:Q="primary",size:B="md",block:w=!1,className:$,children:f})=>CQQ("a",{href:A,className:s1("rizom-btn",`rizom-btn-${Q}`,`rizom-btn-${B}`,w&&"rizom-btn-block",ZQQ,NQQ[Q],zQQ[B],w&&qQQ,$),children:f},void 0,!1,void 0,this);import{jsxDEV as pCw}from"preact/jsx-dev-runtime";import{jsxDEV as dCw}from"preact/jsx-dev-runtime";import{Fragment as sCw}from"preact";import{jsxDEV as tCw}from"preact/jsx-dev-runtime";import{jsxDEV as E$1}from"preact/jsx-dev-runtime";var kQA=({sections:A})=>E$1(OP,{children:E$1("main",{children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this);$0();GA();var L$1=`/*
|
|
5670
5670
|
* Shared globals + helpers used by tree / constellation / roots canvas
|
|
5671
5671
|
* scripts. Loaded as a shared static asset by the Rizom runtime package
|
|
5672
5672
|
* so the variant canvases
|
|
@@ -8152,7 +8152,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var a
|
|
|
8152
8152
|
`).map((Q)=>Q.trim()).find((Q)=>Q.length>0&&!Q.startsWith("#"))??""}var ZBQ=5,NBQ=4,f91=[$6,rI,U4];class lQA{context;constructor(A){this.context=A}async retrieve(A){let Q=A.query?.trim()??"",B=Math.max(1,A.limit??ZBQ),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,H)=>{let Y=w?this.getEntitySpaceId(D.entity)===w:!1,W=w?this.getEntitySpaceId(H.entity)===w:!1;if(Y!==W)return Y?-1:1;if(H.score!==D.score)return H.score-D.score;return Date.parse(H.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 HY({interfaceType:A.interfaceType,channelId:A.channelId});if(!A.conversationId)return;let Q=await this.context.conversations.get(A.conversationId);return Q?HY(Q):void 0}async loadCandidates(A,Q){let B=Q*NBQ;if(A.length>0)return(await this.context.entityService.search({query:A,options:{types:f91,limit:B}})).map((f)=>({entity:f.entity,score:f.score,excerpt:f.excerpt}));return(await Promise.all(f91.map(($)=>this.context.entityService.listEntities({entityType:$,options:{limit:B,sortFields:[{field:"updated",direction:"desc"}]}})))).flat().map(($)=>({entity:$,score:0,excerpt:$u($)}))}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||$u(Q),...Q.entityType===$6?{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===$6}isDecisionEntity(A){return A.entityType===rI}getEntitySpaceId(A){let Q=A.metadata;if("spaceId"in Q&&typeof Q.spaceId==="string")return Q.spaceId;return HY(Q)}}var d_A=G.object({role:G.enum(["user","assistant","system"]),content:G.string(),timestamp:G.string().datetime().optional(),actor:nL.optional(),source:oL.optional()}),zBQ=G.object({conversationId:G.string().default("eval-conversation"),messages:G.array(d_A)}),qBQ=G.object({conversationId:G.string()}),CBQ=G.object({conversationId:G.string().default("eval-conversation"),interfaceType:G.string().default("eval"),channelId:G.string().default("eval-channel"),channelName:G.string().optional(),projectionDecision:G.enum(["update","append"]).default("update"),existingSummary:G.string().optional(),existingMessageCount:G.number().int().min(0).default(0),messages:G.array(d_A)}),iQA=G.object({actorId:G.string(),canonicalId:G.string().optional(),displayName:G.string().optional()}),EBQ=iQA.extend({roles:G.array(G.enum(["user","assistant","system"])).default(["user"]),sourceActorIds:G.array(G.string()).optional()}),LBQ=G.object({actorId:G.string().optional(),canonicalId:G.string().optional(),displayName:G.string()}),MBQ=G.object({id:G.string(),entityType:G.enum(["summary","decision","action-item"]),content:G.string(),excerpt:G.string().optional(),score:G.number().optional(),conversationId:G.string(),interfaceType:G.string(),channelId:G.string(),channelName:G.string().optional(),updated:G.string().datetime().optional(),status:G.string().optional(),participants:G.array(EBQ).optional(),decidedBy:G.array(iQA).optional(),mentionedBy:G.array(iQA).optional(),assignedTo:G.array(LBQ).optional(),requestedBy:G.array(iQA).optional()}),VBQ=G.object({query:G.string().optional(),conversationId:G.string().optional(),interfaceType:G.string().optional(),channelId:G.string().optional(),limit:G.number().int().min(1).optional(),includeOtherSpaces:G.boolean().optional(),actorId:G.string().optional(),canonicalId:G.string().optional(),memory:G.array(MBQ).optional()}),bBQ=G.object({conversationId:G.string().default("eval-conversation"),existingSummary:G.string().optional(),existingMessageCount:G.number().int().min(0).default(0),messages:G.array(d_A)});function D91(A){let{context:Q,logger:B,config:w}=A;Q.eval.registerHandler("summarizeMessages",async($)=>{let f=zBQ.parse($),I=r_A(f.messages,f.conversationId),H=await new vP(Q,B,w).extract(I);return H.entries.map((Y)=>{let W=H.decisions.filter((K)=>K.timeRange.start>=Y.timeRange.start).filter((K)=>K.timeRange.end<=Y.timeRange.end).map((K)=>K.text),F=H.actionItems.filter((K)=>K.timeRange.start>=Y.timeRange.start).filter((K)=>K.timeRange.end<=Y.timeRange.end).map((K)=>K.text);return{...Y,decisions:W,actionItems:F,keyPointsText:Y.keyPoints.join(`
|
|
8153
8153
|
`),decisionsText:W.join(`
|
|
8154
8154
|
`),actionItemsText:F.join(`
|
|
8155
|
-
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=bBQ.parse($),I=r_A(f.messages,f.conversationId),D=f.existingSummary?I91({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new eZ(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=VBQ.parse($),I=f.memory?PBQ(Q,f.memory):Q;return new lQA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=CBQ.parse($),I=r_A(f.messages,f.conversationId),D=OBQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),H=f.existingSummary?I91({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,Y=[],W=[],F=RBQ({context:Q,conversation:D,messages:I,existing:H,upserted:Y,deleted:W,projectionDecision:f.projectionDecision});return{result:await new eZ(F,B,w).projectConversation(f.conversationId),summaries:Y.filter((q)=>q.entityType==="summary"),decisions:Y.filter((q)=>q.entityType==="decision"),actionItems:Y.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=qBQ.parse($);return new eZ(Q,B,w).projectConversation(f.conversationId)})}function I91(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 r_A(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 OBQ(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 RBQ(A){let Q=HY(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 PBQ(A,Q){let B=Q.map(_BQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??$u($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function _BQ(A){if(A.entityType==="summary")return kBQ(A);if(A.entityType==="decision")return jBQ(A);return vBQ(A)}function n_A(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:hB(A.content),created:Q,updated:Q}}function kBQ(A){return{...n_A(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 jBQ(A){return{...n_A(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(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 vBQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...n_A(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(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 H91={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.72",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 hBQ=new zW,yBQ=new _P,gBQ=new kP,TBQ=G.object({conversationId:G.string()});class o_A extends KQ{entityType=$6;schema=em;adapter=hBQ;constructor(A={}){super(vQA,H91,A,m_A)}getConfig(){return this.config}getTemplates(){return{"summary-list":T$1,"summary-detail":S$1,"ai-response":m$1}}getDataSources(){return[new i_A(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:$6,job:{type:k$1,handler:new SQA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qN(A,$6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:S_A,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:vQA}}},sourceChange:{sourceKind:yl,sourceTypes:[yl],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Dj],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:S_A,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:vQA}}}}}]}parseConversationMessagePayload(A){return TBQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return nC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(rI,Au,yBQ),A.entities.register(U4,Qu,gBQ),p$1({context:A,pluginId:this.id}),i$1({context:A,pluginId:this.id}),Q91({context:A,pluginId:this.id}),$91({context:A,pluginId:this.id,config:this.config}),D91({context:A,logger:this.logger,config:this.config})}}function s_A(A){return new o_A(A)}$0();GA();$0();var GG=G.object({title:G.string(),section:G.string(),order:G.number().int(),sourcePath:G.string(),description:G.string().optional(),slug:G.string().optional()}),Y91=GG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:G.string()}),yP=B2.extend({entityType:G.literal("doc"),metadata:Y91}),FG=yP.extend({frontmatter:GG,body:G.string()});$0();GA();class a_A extends W2{constructor(){super({entityType:"doc",schema:yP,frontmatterSchema:GG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,GG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,GG),B=Q.slug??U2(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 rQA=new a_A;$0();function X91(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 W91(A){let Q=t2(A.content,GG);return FG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class dQA extends r6{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 W91(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=X91(f.items),D=I.findIndex((W)=>W.id===$.item.id),H=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:H,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:X91(A),pagination:Q,baseUrl:B.baseUrl}}}$0();Rw();GA();import{jsxDEV as H5}from"preact/jsx-dev-runtime";var SBQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function fu(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 nQA(A){let Q=new Map;for(let B of fu(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function gP(A){return`/docs/${A.metadata.slug}`}function oQA(A){return`section-${A+1}`}function TP(A){return SBQ[A]??String(A+1)}var G91="text-[var(--docs-text)] font-bold",F91="text-[var(--docs-accent)] font-bold",K91="text-[var(--docs-text-muted)]",mBQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",uBQ="docs-font-display text-[var(--docs-heading)]",U91="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",J91="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",t_A="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",qW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:mBQ,display:uBQ,button:`${U91} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${U91} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},Z91=()=>H5("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:[H5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[H5("span",{className:G91,children:"brains"},void 0,!1,void 0,this),H5("span",{className:F91,children:"."},void 0,!1,void 0,this),H5("span",{className:K91,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[H5("a",{className:J91,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:J91,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("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),N91=()=>H5("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:[H5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[H5("span",{className:G91,children:"rizom"},void 0,!1,void 0,this),H5("span",{className:F91,children:"."},void 0,!1,void 0,this),H5("span",{className:K91,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[H5("a",{className:t_A,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:t_A,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{className:t_A,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),H5("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),cBQ=`
|
|
8155
|
+
`)}})}),Q.eval.registerHandler("decideProjection",async($)=>{let f=bBQ.parse($),I=r_A(f.messages,f.conversationId),D=f.existingSummary?I91({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null;return new eZ(Q,B,w).decideProjection(I,D)}),Q.eval.registerHandler("retrieveMemory",async($)=>{let f=VBQ.parse($),I=f.memory?PBQ(Q,f.memory):Q;return new lQA(I).retrieve(f)}),Q.eval.registerHandler("projectMessages",async($)=>{let f=CBQ.parse($),I=r_A(f.messages,f.conversationId),D=OBQ({conversationId:f.conversationId,interfaceType:f.interfaceType,channelId:f.channelId,channelName:f.channelName,messages:I}),H=f.existingSummary?I91({conversationId:f.conversationId,content:f.existingSummary,messageCount:f.existingMessageCount,projectionVersion:w.projectionVersion}):null,Y=[],W=[],F=RBQ({context:Q,conversation:D,messages:I,existing:H,upserted:Y,deleted:W,projectionDecision:f.projectionDecision});return{result:await new eZ(F,B,w).projectConversation(f.conversationId),summaries:Y.filter((q)=>q.entityType==="summary"),decisions:Y.filter((q)=>q.entityType==="decision"),actionItems:Y.filter((q)=>q.entityType==="action-item"),deleted:W}}),Q.eval.registerHandler("projectConversation",async($)=>{let f=qBQ.parse($);return new eZ(Q,B,w).projectConversation(f.conversationId)})}function I91(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 r_A(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 OBQ(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 RBQ(A){let Q=HY(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 PBQ(A,Q){let B=Q.map(_BQ),w=B.map(($,f)=>({entity:$,score:Q[f]?.score??1,excerpt:Q[f]?.excerpt??$u($)}));return{...A,entityService:{...A.entityService,search:async()=>w,listEntities:async({entityType:$})=>B.filter((f)=>f.entityType===$)}}}function _BQ(A){if(A.entityType==="summary")return kBQ(A);if(A.entityType==="decision")return jBQ(A);return vBQ(A)}function n_A(A){let Q=A.updated??"2026-01-01T00:00:00.000Z";return{id:A.id,content:A.content,contentHash:hB(A.content),created:Q,updated:Q}}function kBQ(A){return{...n_A(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 jBQ(A){return{...n_A(A),entityType:"decision",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(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 vBQ(A){let Q=A.status==="done"||A.status==="dropped"?A.status:"open";return{...n_A(A),entityType:"action-item",metadata:{conversationId:A.conversationId,channelId:A.channelId,...A.channelName?{channelName:A.channelName}:{},interfaceType:A.interfaceType,spaceId:HY(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 H91={name:"@brains/conversation-memory",private:!0,version:"0.2.0-alpha.73",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 hBQ=new zW,yBQ=new _P,gBQ=new kP,TBQ=G.object({conversationId:G.string()});class o_A extends KQ{entityType=$6;schema=em;adapter=hBQ;constructor(A={}){super(vQA,H91,A,m_A)}getConfig(){return this.config}getTemplates(){return{"summary-list":T$1,"summary-detail":S$1,"ai-response":m$1}}getDataSources(){return[new i_A(this.logger.child("SummaryDataSource"))]}getDerivedEntityProjections(A){if(!this.config.enableProjection)return[];return[{id:"conversation-memory-projection",targetType:$6,job:{type:k$1,handler:new SQA(A,this.logger,this.config)},initialSync:{shouldEnqueue:async()=>A.spaces.length>0&&!await qN(A,$6),jobData:{mode:"rebuild-all",reason:"initial-sync"},jobOptions:{source:S_A,deduplication:"coalesce",deduplicationKey:"conversation-memory:rebuild-all:initial-sync",metadata:{operationType:"data_processing",operationTarget:"conversation-memory:rebuild-all",pluginId:vQA}}},sourceChange:{sourceKind:yl,sourceTypes:[yl],shouldEnqueue:(Q)=>this.shouldEnqueueConversationProjection(A,Q),events:[Dj],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:S_A,deduplication:"skip",deduplicationKey:`conversation-memory:${B}`,metadata:{operationType:"data_processing",operationTarget:`conversation-memory:${B}`,pluginId:vQA}}}}}]}parseConversationMessagePayload(A){return TBQ.parse(A)}async shouldEnqueueConversationProjection(A,Q){let{conversationId:B}=this.parseConversationMessagePayload(Q),w=await A.conversations.get(B);if(!w)return!1;return nC({conversation:w,spaces:A.spaces}).eligible}async onRegister(A){A.entities.register(rI,Au,yBQ),A.entities.register(U4,Qu,gBQ),p$1({context:A,pluginId:this.id}),i$1({context:A,pluginId:this.id}),Q91({context:A,pluginId:this.id}),$91({context:A,pluginId:this.id,config:this.config}),D91({context:A,logger:this.logger,config:this.config})}}function s_A(A){return new o_A(A)}$0();GA();$0();var GG=G.object({title:G.string(),section:G.string(),order:G.number().int(),sourcePath:G.string(),description:G.string().optional(),slug:G.string().optional()}),Y91=GG.pick({title:!0,section:!0,order:!0,description:!0}).extend({slug:G.string()}),yP=B2.extend({entityType:G.literal("doc"),metadata:Y91}),FG=yP.extend({frontmatter:GG,body:G.string()});$0();GA();class a_A extends W2{constructor(){super({entityType:"doc",schema:yP,frontmatterSchema:GG})}toMarkdown(A){let Q=this.extractBody(A.content),B=this.parseFrontMatter(A.content,GG);return this.buildMarkdown(Q,B)}fromMarkdown(A){let Q=this.parseFrontMatter(A,GG),B=Q.slug??U2(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 rQA=new a_A;$0();function X91(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 W91(A){let Q=t2(A.content,GG);return FG.parse({...A,frontmatter:Q.metadata,body:Q.content})}class dQA extends r6{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 W91(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=X91(f.items),D=I.findIndex((W)=>W.id===$.item.id),H=D>0?I[D-1]:null,Y=D>=0&&D<I.length-1?I[D+1]:null;return Q.parse({doc:$.item,docs:I,prevDoc:H,nextDoc:Y})}buildDetailResult(A,Q){return{doc:A,docs:[A],prevDoc:Q?.prev??null,nextDoc:Q?.next??null}}buildListResult(A,Q,B){return{docs:X91(A),pagination:Q,baseUrl:B.baseUrl}}}$0();Rw();GA();import{jsxDEV as H5}from"preact/jsx-dev-runtime";var SBQ=["I","II","III","IV","V","VI","VII","VIII","IX","X"];function fu(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 nQA(A){let Q=new Map;for(let B of fu(A)){let w=B.metadata.section;Q.set(w,[...Q.get(w)??[],B])}return[...Q.entries()].map(([B,w])=>({section:B,docs:w}))}function gP(A){return`/docs/${A.metadata.slug}`}function oQA(A){return`section-${A+1}`}function TP(A){return SBQ[A]??String(A+1)}var G91="text-[var(--docs-text)] font-bold",F91="text-[var(--docs-accent)] font-bold",K91="text-[var(--docs-text-muted)]",mBQ="docs-font-label text-xs uppercase tracking-[0.18em] text-[var(--docs-accent)]",uBQ="docs-font-display text-[var(--docs-heading)]",U91="inline-flex items-center justify-center rounded-lg border px-[18px] py-2.5 text-sm font-semibold transition-colors duration-150",J91="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",t_A="docs-font-label text-[13px] text-[var(--docs-text-light)] transition-colors duration-150 hover:text-[var(--docs-text)]",qW={wrap:"mx-auto max-w-6xl px-6 pt-20 md:px-12 md:pt-24",label:mBQ,display:uBQ,button:`${U91} border-[var(--docs-text)] text-[var(--docs-text)] hover:border-[var(--docs-accent)] hover:text-[var(--docs-accent)]`,primaryButton:`${U91} border-[var(--docs-accent)] bg-[var(--docs-accent)] text-white hover:bg-transparent hover:text-[var(--docs-accent)]`},Z91=()=>H5("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:[H5("a",{href:"/docs",className:"docs-font-body text-xl font-bold","aria-label":"Brains docs",children:[H5("span",{className:G91,children:"brains"},void 0,!1,void 0,this),H5("span",{className:F91,children:"."},void 0,!1,void 0,this),H5("span",{className:K91,children:"docs"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"docs-header__nav flex items-center gap-4 md:gap-8",children:[H5("a",{className:J91,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:J91,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("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),N91=()=>H5("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:[H5("a",{href:"https://rizom.ai",className:"docs-font-body text-[15px] font-bold",children:[H5("span",{className:G91,children:"rizom"},void 0,!1,void 0,this),H5("span",{className:F91,children:"."},void 0,!1,void 0,this),H5("span",{className:K91,children:"ai"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H5("div",{className:"flex flex-wrap items-center justify-center gap-6 md:justify-end",children:[H5("a",{className:t_A,href:"/docs/roadmap",children:"Roadmap"},void 0,!1,void 0,this),H5("a",{className:t_A,href:"https://github.com/rizom-ai/brains",children:"GitHub"},void 0,!1,void 0,this),H5("a",{className:t_A,href:"https://rizom.ai",children:"Rizom"},void 0,!1,void 0,this),H5("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),cBQ=`
|
|
8156
8156
|
.docs-handbook {
|
|
8157
8157
|
--docs-bg: var(--color-bg, #0d0a1a);
|
|
8158
8158
|
--docs-bg-card: var(--color-bg-card, #1a0a3e);
|
|
@@ -8304,7 +8304,7 @@ facts, owners, or tasks. Return only the required structured JSON.`});GA();var a
|
|
|
8304
8304
|
background: transparent;
|
|
8305
8305
|
}
|
|
8306
8306
|
|
|
8307
|
-
`,z91=()=>H5("style",{children:cBQ},void 0,!1,void 0,this);import{jsxDEV as Y2,Fragment as pBQ}from"preact/jsx-dev-runtime";var sQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>Y2(pBQ,{children:[Y2(XQ,{title:A,description:Q},void 0,!1,void 0,this),Y2(z91,{},void 0,!1,void 0,this),Y2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[Y2(Z91,{},void 0,!1,void 0,this),Y2("div",{className:`${qW.wrap} ${f}`.trim(),children:[B,$&&Y2(N91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q91=({docsCount:A,sectionsCount:Q,startDoc:B})=>Y2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[Y2("p",{className:`${qW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),Y2("h1",{className:`${qW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",Y2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("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),Y2("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:[Y2("div",{children:[Y2("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),Y2("div",{children:[Y2("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),Y2("div",{children:[Y2("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),Y2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&Y2("a",{className:qW.primaryButton,href:gP(B),children:"Start reading"},void 0,!1,void 0,this),Y2("a",{className:qW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C91=({groups:A})=>Y2("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:[Y2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>Y2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[Y2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[TP(B),"."]},void 0,!0,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${oQA(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),E91=({group:A,index:Q})=>Y2("article",{className:"mb-16 last:mb-0",id:oQA(Q),children:[Y2("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:[Y2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[TP(Q),"."]},void 0,!0,void 0,this),Y2("h2",{className:`${qW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),Y2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>Y2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:Y2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:gP(B),children:[Y2("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&&Y2("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),L91=({title:A})=>Y2("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:[Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>Y2("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:Y2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[Y2("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),Y2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return Y2("li",{className:f?"mb-[22px]":"mb-3.5",children:[Y2("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#${oQA($)}`,children:[Y2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[TP($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&Y2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return Y2("li",{children:Y2("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:gP(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),V91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return Y2("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?Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:gP(A),children:[Y2("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),Y2("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):Y2("span",{},void 0,!1,void 0,this),Q&&Y2("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:gP(Q),children:[Y2("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),Y2("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 SP}from"preact/jsx-dev-runtime";var e_A=({docs:A})=>{let Q=fu(A),B=nQA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return SP(sQA,{title:"Documentation",description:"Brains documentation",children:[SP(q91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),SP("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:[SP(C91,{groups:B},void 0,!1,void 0,this),SP("div",{children:B.map((f,I)=>SP(E91,{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 dI}from"preact/jsx-dev-runtime";var AkA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=nQA(Q.length>0?Q:[A]),f=fu(Q.length>0?Q:[A]),I=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((H)=>H.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return dI(sQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(L91,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(M91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${qW.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[TP(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${qW.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&dI("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),dI("div",{className:"docs-article__body",children:dI(mI,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(V91,{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 lBQ=G.object({docs:G.array(FG),pagination:Y9.nullable(),baseUrl:G.string().optional()}),iBQ=G.object({doc:FG,docs:G.array(FG),prevDoc:FG.nullable(),nextDoc:FG.nullable()});function b91(){return{"doc-list":O1({name:"doc-list",description:"Documentation index template",schema:lBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:e_A}}),"doc-detail":O1({name:"doc-detail",description:"Documentation page template",schema:iBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:AkA}})}}var O91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.72",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 QkA extends KQ{entityType=rQA.entityType;schema=yP;adapter=rQA;constructor(){super("docs",O91,{},void 0)}getTemplates(){return b91()}getDataSources(){return[new dQA(this.logger.child("DocDataSource"))]}}function BkA(){return new QkA}$0();GA();GA();d5();var R91=G.object({label:G.string(),href:G.string()}),P91=G.object({label:G.string(),title:G.string(),detail:G.string()}),dBQ=G.object({eyebrow:G.string(),name:G.string(),sub:G.string()}),nBQ=G.object({tone:G.enum(["capture","synthesis","share"]),title:G.string(),text:G.string()}),wkA=G.object({captures:G.number(),links:G.number(),topics:G.number(),summaries:G.number(),peers:G.number()}),mP=G.object({eyebrow:G.string(),headline:G.string(),intro:G.string(),primaryCta:R91,secondaryCta:R91,inputs:G.array(P91).min(1),outputs:G.array(P91).min(1),core:dBQ,legend:G.array(nBQ).min(1)}),$kA=mP.extend({counts:wkA}),_91={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."}]},k91=new PB(mP,{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 aQA(A){return k91.parse(A)}function j91(A){return k91.format(A)}GA();var oBQ=G.object({query:G.object({routeId:G.string().default("home"),sectionId:G.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),sBQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class fkA{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=oBQ.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 _91;return mP.parse(aQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(sBQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return wkA.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 v91=G.object({label:G.string(),href:G.string()}),aBQ=G.object({eyebrow:G.string(),headline:G.string(),intro:G.string(),primaryCta:v91,secondaryCta:v91,signals:G.array(G.object({label:G.string(),value:G.string(),note:G.string()}))}),tBQ=G.object({eyebrow:G.string(),title:G.string(),intro:G.string(),steps:G.array(G.object({phase:G.string(),title:G.string(),text:G.string()}))}),eBQ=G.object({title:G.string(),intro:G.string(),cards:G.array(G.object({label:G.string(),title:G.string(),text:G.string()}))}),AwQ=G.object({title:G.string(),intro:G.string(),points:G.array(G.string())}),QwQ={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."]},BwQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function x91({href:A,label:Q}){return w1("a",{href:A,className:BwQ,children:Q},void 0,!1,void 0,this)}function wwQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(OP,{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(x91,{...$},`${$.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(x91,{...$},`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 $wQ=({sections:A,siteInfo:Q})=>w1(wwQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function fwQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(aZ,{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(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{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 IwQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(aZ,{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 DwQ({title:A,intro:Q,cards:B}){return w1(aZ,{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 HwQ({title:A,intro:Q,points:B}){return w1(aZ,{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 YwQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},XwQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Iu=(A,Q,B=`${Q}s`)=>`${XwQ(A)} ${A===1?Q:B}`;function WwQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:H,counts:Y}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Iu(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Iu(Y.summaries,"summary","summaries")}];return w1(aZ,{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(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{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:[Iu(Y.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:H.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 ${YwQ(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 UwQ=O1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:$kA,formatter:{parse:(A)=>$kA.parse({...aQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>j91(mP.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:WwQ}}),JwQ=(A)=>fwQ(aBQ.parse(A)),GwQ=(A)=>IwQ(tBQ.parse(A)),FwQ=(A)=>DwQ(eBQ.parse(A)),KwQ=(A)=>HwQ(AwQ.parse(A)),h91={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},y91={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:JwQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...h91,label:"Primary CTA"},secondaryCta:{...h91,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:GwQ,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:FwQ,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:KwQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},ZwQ=[{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:QwQ}]}],g91=T_A({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:$wQ,routes:ZwQ,templates:{"home-diagram":UwQ},dataSources:[new fkA]});var T91=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],S91=[...T91,"image","site-info","site-content","site-builder"],zwQ=[...S91,"docs","decks"],qwQ=["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.'],m91=QK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:g91,theme:RP,presets:{core:T91,default:S91,full:zwQ},evalDisable:["webserver","mcp","discord"],agentInstructions:qwQ,capabilities:[["prompt",cC,void 0],["note",xC,{}],["link",yC,{}],["image",yx,void 0],["topics",b2A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",s_A,{}],["docs",BkA,void 0],["decks",Km,void 0],["agents",IQA,void 0],["assessment",KQA,void 0],["auth-service",Vy,void 0],["cms",uC,{}],["dashboard",nZ,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:NwQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sm,{definitions:y91}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",_C,{}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({captureUrls:!0})],["a2a",AR,()=>({})],["webserver",ZZ,()=>({})]],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 e5Q}from"fs";import{join as A$Q}from"path";import{execSync as Q$Q}from"child_process";import{parseArgs as LwQ}from"util";var MwQ={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 CW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function A3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function u91(A){let{values:Q,positionals:B}=LwQ({args:A,options:MwQ,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:CW(Q,"model"),domain:CW(Q,"domain"),"content-repo":CW(Q,"content-repo"),backend:CW(Q,"backend"),"push-to":CW(Q,"push-to"),"ai-api-key":CW(Q,"ai-api-key"),"no-interactive":A3(Q,"no-interactive"),preview:A3(Q,"preview"),deploy:A3(Q,"deploy"),regen:A3(Q,"regen"),all:A3(Q,"all"),only:CW(Q,"only"),"dry-run":A3(Q,"dry-run"),"startup-check":A3(Q,"startup-check"),"storage-dir":CW(Q,"storage-dir"),yes:A3(Q,"yes"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Du();import{mkdirSync as p5Q}from"fs";import{join as l5Q}from"path";import{execSync as i5Q}from"child_process";var eQA={name:"@rizom/brain",version:"0.2.0-alpha.72",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","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 B71,writeFileSync as Yu,chmodSync as Xu,existsSync as FkA,readFileSync as KkA}from"fs";import{basename as ZkA,dirname as NkA,join as E8,resolve as $8Q}from"path";import{fileURLToPath as f8Q}from"url";var c91=`ARG BUN_VERSION=1.3.10
|
|
8307
|
+
`,z91=()=>H5("style",{children:cBQ},void 0,!1,void 0,this);import{jsxDEV as Y2,Fragment as pBQ}from"preact/jsx-dev-runtime";var sQA=({title:A,description:Q,children:B,detail:w=!1,footer:$=!1,contentClassName:f=""})=>Y2(pBQ,{children:[Y2(XQ,{title:A,description:Q},void 0,!1,void 0,this),Y2(z91,{},void 0,!1,void 0,this),Y2("div",{className:`docs-handbook${w?" docs-handbook--detail":""}`,children:[Y2(Z91,{},void 0,!1,void 0,this),Y2("div",{className:`${qW.wrap} ${f}`.trim(),children:[B,$&&Y2(N91,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q91=({docsCount:A,sectionsCount:Q,startDoc:B})=>Y2("section",{className:"border-b border-[var(--docs-text)] py-14 md:py-24 md:pb-[72px]",children:[Y2("p",{className:`${qW.label} mb-8`,children:"Handbook \xB7 Brains docs"},void 0,!1,void 0,this),Y2("h1",{className:`${qW.display} m-0 max-w-[16ch] text-5xl leading-[1.05] tracking-[-0.02em] md:text-7xl`,children:["Build, run, and publish"," ",Y2("em",{className:"text-[var(--docs-accent)]",children:"brains."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("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),Y2("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:[Y2("div",{children:[Y2("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),Y2("div",{children:[Y2("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),Y2("div",{children:[Y2("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),Y2("div",{className:"mt-9 flex flex-wrap gap-3.5",children:[B&&Y2("a",{className:qW.primaryButton,href:gP(B),children:"Start reading"},void 0,!1,void 0,this),Y2("a",{className:qW.button,href:"#sections",children:"Browse sections"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C91=({groups:A})=>Y2("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:[Y2("p",{className:"m-0 mb-3.5 font-medium text-[var(--docs-text)]",children:"Sections"},void 0,!1,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.map((Q,B)=>Y2("li",{className:"grid grid-cols-[32px_1fr] gap-2 py-1.5",children:[Y2("span",{className:"docs-font-display text-[var(--docs-text-light)] italic",children:[TP(B),"."]},void 0,!0,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:`#${oQA(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),E91=({group:A,index:Q})=>Y2("article",{className:"mb-16 last:mb-0",id:oQA(Q),children:[Y2("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:[Y2("span",{className:"text-right docs-font-display text-3xl leading-[1.1] text-[var(--docs-accent)] italic md:text-4xl",children:[TP(Q),"."]},void 0,!0,void 0,this),Y2("h2",{className:`${qW.display} m-0 text-3xl leading-[1.1] tracking-[-0.015em] md:text-4xl`,children:A.section},void 0,!1,void 0,this),Y2("span",{className:"docs-chapter__leader"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Y2("ol",{className:"m-0 list-none p-0",children:A.docs.map((B)=>Y2("li",{className:"border-b border-[var(--docs-border-light)] last:border-b-0",children:Y2("a",{className:"group block py-[18px] pl-12 md:pl-[68px]",href:gP(B),children:[Y2("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&&Y2("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),L91=({title:A})=>Y2("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:[Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/",children:"Home"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("a",{className:"text-[var(--docs-text-muted)] hover:text-[var(--docs-accent)]",href:"/docs",children:"Docs"},void 0,!1,void 0,this),Y2("span",{children:"/"},void 0,!1,void 0,this),Y2("span",{children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M91=({groups:A,activeGroupIndex:Q,activeSlug:B})=>Y2("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:Y2("nav",{className:"docs-font-label text-xs tracking-[0.06em] text-[var(--docs-text-light)]",children:[Y2("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),Y2("ol",{className:"m-0 list-none p-0",children:A.map((w,$)=>{let f=$===Q;return Y2("li",{className:f?"mb-[22px]":"mb-3.5",children:[Y2("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#${oQA($)}`,children:[Y2("span",{className:"docs-font-display text-sm text-[var(--docs-accent)] italic",children:[TP($),"."]},void 0,!0,void 0,this)," ",w.section]},void 0,!0,void 0,this),f&&Y2("ol",{className:"mt-0.5 list-none p-0",children:w.docs.map((I)=>{let D=I.metadata.slug===B;return Y2("li",{children:Y2("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:gP(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),V91=({prevDoc:A,nextDoc:Q})=>{if(!A&&!Q)return null;return Y2("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?Y2("a",{className:"group border-t border-[var(--docs-border-light)] pt-[18px] transition-colors duration-150 hover:border-[var(--docs-accent)]",href:gP(A),children:[Y2("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),Y2("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):Y2("span",{},void 0,!1,void 0,this),Q&&Y2("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:gP(Q),children:[Y2("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),Y2("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 SP}from"preact/jsx-dev-runtime";var e_A=({docs:A})=>{let Q=fu(A),B=nQA(Q),$=Q.filter((f)=>f.metadata.slug!=="index")[0]??Q[0];return SP(sQA,{title:"Documentation",description:"Brains documentation",children:[SP(q91,{docsCount:A.length,sectionsCount:B.length,startDoc:$},void 0,!1,void 0,this),SP("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:[SP(C91,{groups:B},void 0,!1,void 0,this),SP("div",{children:B.map((f,I)=>SP(E91,{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 dI}from"preact/jsx-dev-runtime";var AkA=({doc:A,docs:Q,prevDoc:B,nextDoc:w})=>{let $=nQA(Q.length>0?Q:[A]),f=fu(Q.length>0?Q:[A]),I=f.findIndex((H)=>H.metadata.slug===A.metadata.slug),D=Math.max($.findIndex((H)=>H.docs.some((Y)=>Y.metadata.slug===A.metadata.slug)),0);return dI(sQA,{title:A.metadata.title,description:A.metadata.description??A.metadata.section,detail:!0,footer:!0,contentClassName:"pt-16",children:[dI(L91,{title:A.metadata.title},void 0,!1,void 0,this),dI("div",{className:"grid items-start gap-10 py-8 pb-24 md:grid-cols-[240px_minmax(0,1fr)] md:gap-20",children:[dI(M91,{groups:$,activeGroupIndex:D,activeSlug:A.metadata.slug},void 0,!1,void 0,this),dI("article",{className:"min-w-0",children:[dI("header",{className:"mb-10 border-b border-[var(--docs-border)] pb-8",children:[dI("p",{className:`${qW.label} m-0 mb-6 flex items-baseline gap-3`,children:[dI("span",{className:"docs-font-display text-lg leading-none tracking-normal normal-case text-[var(--docs-accent)] italic",children:[TP(D),"."]},void 0,!0,void 0,this)," ",A.metadata.section,I>=0?` \xB7 ${I+1}/${f.length}`:""]},void 0,!0,void 0,this),dI("h1",{className:`${qW.display} m-0 max-w-[18ch] text-4xl leading-[1.05] tracking-[-0.02em] md:text-6xl`,children:A.metadata.title},void 0,!1,void 0,this),A.metadata.description&&dI("p",{className:"mt-6 max-w-[56ch] docs-font-display text-[22px] font-[350] leading-[1.5] text-[var(--docs-text-muted)]",children:A.metadata.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),dI("div",{className:"docs-article__body",children:dI(mI,{markdown:A.body},void 0,!1,void 0,this)},void 0,!1,void 0,this),dI(V91,{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 lBQ=G.object({docs:G.array(FG),pagination:Y9.nullable(),baseUrl:G.string().optional()}),iBQ=G.object({doc:FG,docs:G.array(FG),prevDoc:FG.nullable(),nextDoc:FG.nullable()});function b91(){return{"doc-list":O1({name:"doc-list",description:"Documentation index template",schema:lBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:e_A}}),"doc-detail":O1({name:"doc-detail",description:"Documentation page template",schema:iBQ,dataSourceId:"docs:entities",requiredPermission:"public",layout:{component:AkA}})}}var O91={name:"@brains/doc",private:!0,version:"0.2.0-alpha.73",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 QkA extends KQ{entityType=rQA.entityType;schema=yP;adapter=rQA;constructor(){super("docs",O91,{},void 0)}getTemplates(){return b91()}getDataSources(){return[new dQA(this.logger.child("DocDataSource"))]}}function BkA(){return new QkA}$0();GA();GA();d5();var R91=G.object({label:G.string(),href:G.string()}),P91=G.object({label:G.string(),title:G.string(),detail:G.string()}),dBQ=G.object({eyebrow:G.string(),name:G.string(),sub:G.string()}),nBQ=G.object({tone:G.enum(["capture","synthesis","share"]),title:G.string(),text:G.string()}),wkA=G.object({captures:G.number(),links:G.number(),topics:G.number(),summaries:G.number(),peers:G.number()}),mP=G.object({eyebrow:G.string(),headline:G.string(),intro:G.string(),primaryCta:R91,secondaryCta:R91,inputs:G.array(P91).min(1),outputs:G.array(P91).min(1),core:dBQ,legend:G.array(nBQ).min(1)}),$kA=mP.extend({counts:wkA}),_91={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."}]},k91=new PB(mP,{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 aQA(A){return k91.parse(A)}function j91(A){return k91.format(A)}GA();var oBQ=G.object({query:G.object({routeId:G.string().default("home"),sectionId:G.string().default("diagram")}).default({routeId:"home",sectionId:"diagram"})}).passthrough(),sBQ={captures:"base",links:"link",topics:"topic",summaries:"summary",peers:"agent"};class fkA{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=oBQ.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 _91;return mP.parse(aQA(w.content))}async fetchCounts(A){let Q=await Promise.all(Object.entries(sBQ).map(async([B,w])=>[B,await this.countOrZero(A,w)]));return wkA.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 v91=G.object({label:G.string(),href:G.string()}),aBQ=G.object({eyebrow:G.string(),headline:G.string(),intro:G.string(),primaryCta:v91,secondaryCta:v91,signals:G.array(G.object({label:G.string(),value:G.string(),note:G.string()}))}),tBQ=G.object({eyebrow:G.string(),title:G.string(),intro:G.string(),steps:G.array(G.object({phase:G.string(),title:G.string(),text:G.string()}))}),eBQ=G.object({title:G.string(),intro:G.string(),cards:G.array(G.object({label:G.string(),title:G.string(),text:G.string()}))}),AwQ=G.object({title:G.string(),intro:G.string(),points:G.array(G.string())}),QwQ={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."]},BwQ="font-body text-[15px] text-theme-muted transition-colors hover:text-theme";function x91({href:A,label:Q}){return w1("a",{href:A,className:BwQ,children:Q},void 0,!1,void 0,this)}function wwQ({siteInfo:A,children:Q}){let B=[...A.navigation.primary,...A.navigation.secondary],w=A.cta??{buttonText:"Start here",buttonLink:"/about"};return w1(OP,{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(x91,{...$},`${$.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(x91,{...$},`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 $wQ=({sections:A,siteInfo:Q})=>w1(wwQ,{siteInfo:Q,children:A},void 0,!1,void 0,this);function fwQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,signals:f}){return w1(aZ,{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(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{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 IwQ({eyebrow:A,title:Q,intro:B,steps:w}){return w1(aZ,{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 DwQ({title:A,intro:Q,cards:B}){return w1(aZ,{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 HwQ({title:A,intro:Q,points:B}){return w1(aZ,{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 YwQ=(A)=>{switch(A){case"capture":return"bg-accent";case"synthesis":return"bg-secondary";case"share":return"bg-accent-bright"}},XwQ=(A)=>new Intl.NumberFormat("en",{notation:A>999?"compact":"standard"}).format(A),Iu=(A,Q,B=`${Q}s`)=>`${XwQ(A)} ${A===1?Q:B}`;function WwQ({eyebrow:A,headline:Q,intro:B,primaryCta:w,secondaryCta:$,inputs:f,outputs:I,core:D,legend:H,counts:Y}){let W=[{key:"captures",className:"top-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.captures,"capture")},{key:"topics",className:"top-1/2 right-[-28px] -translate-y-1/2",label:Iu(Y.topics,"topic")},{key:"peers",className:"bottom-[-10px] left-1/2 -translate-x-1/2",label:Iu(Y.peers,"peer brain")},{key:"summaries",className:"top-1/2 left-[-28px] -translate-y-1/2",label:Iu(Y.summaries,"summary","summaries")}];return w1(aZ,{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(iC,{href:w.href,size:"lg",variant:"primary-strong",children:w.label},void 0,!1,void 0,this),w1(iC,{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:[Iu(Y.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:H.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 ${YwQ(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 UwQ=O1({name:"home-diagram",description:"Relay homepage system diagram with live entity counts",schema:$kA,formatter:{parse:(A)=>$kA.parse({...aQA(A),counts:{captures:0,links:0,topics:0,summaries:0,peers:0}}),format:(A)=>j91(mP.parse(A))},dataSourceId:"relay-site:home-counts",requiredPermission:"public",layout:{component:WwQ}}),JwQ=(A)=>fwQ(aBQ.parse(A)),GwQ=(A)=>IwQ(tBQ.parse(A)),FwQ=(A)=>DwQ(eBQ.parse(A)),KwQ=(A)=>HwQ(AwQ.parse(A)),h91={type:"object",label:"CTA",fields:{label:{type:"string",label:"Label"},href:{type:"string",label:"Href"}}},y91={namespace:"relay-site",sections:{"home-hero":{title:"Home hero",description:"Relay homepage hero section",layout:JwQ,fields:{eyebrow:{type:"string",label:"Eyebrow"},headline:{type:"string",label:"Headline"},intro:{type:"string",label:"Intro"},primaryCta:{...h91,label:"Primary CTA"},secondaryCta:{...h91,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:GwQ,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:FwQ,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:KwQ,fields:{title:{type:"string",label:"Title"},intro:{type:"string",label:"Intro"},points:{type:"array",label:"Points",minItems:1,items:{type:"string",label:"Point"}}}}}},ZwQ=[{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:QwQ}]}],g91=T_A({packageName:"@brains/relay/site",contentNamespace:"relay-site",themeProfile:"studio",layout:$wQ,routes:ZwQ,templates:{"home-diagram":UwQ},dataSources:[new fkA]});var T91=["prompt","directory-sync","note","link","topics","conversation-memory","agents","assessment","auth-service","cms","dashboard","mcp","webserver","discord","a2a"],S91=[...T91,"image","site-info","site-content","site-builder"],zwQ=[...S91,"docs","decks"],qwQ=["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.'],m91=QK({name:"relay",version:"0.1.0",model:"gpt-5.4-mini",site:g91,theme:RP,presets:{core:T91,default:S91,full:zwQ},evalDisable:["webserver","mcp","discord"],agentInstructions:qwQ,capabilities:[["prompt",cC,void 0],["note",xC,{}],["link",yC,{}],["image",yx,void 0],["topics",b2A,{includeEntityTypes:["base","link","summary","agent","swot","deck","doc","anchor-profile","brain-character"],extractableStatuses:["published","draft"]}],["conversation-memory",s_A,{}],["docs",BkA,void 0],["decks",Km,void 0],["agents",IQA,void 0],["assessment",KQA,void 0],["auth-service",Vy,void 0],["cms",uC,{}],["dashboard",nZ,void 0],["directory-sync",aq,{seedContent:!0,seedContentPath:NwQ(import.meta.dir,"..","seed-content"),initialSync:!0}],["site-content",sm,{definitions:y91}],["rizom-ecosystem",pC,void 0],["site-info",kC,void 0],["site-builder",_C,{}]],interfaces:[["mcp",hK,()=>({})],["discord",KZ,()=>({captureUrls:!0})],["a2a",AR,()=>({})],["webserver",ZZ,()=>({})]],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 e5Q}from"fs";import{join as A$Q}from"path";import{execSync as Q$Q}from"child_process";import{parseArgs as LwQ}from"util";var MwQ={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 CW(A,Q){let B=A[Q];return typeof B==="string"?B:void 0}function A3(A,Q){let B=A[Q];return typeof B==="boolean"?B:void 0}function u91(A){let{values:Q,positionals:B}=LwQ({args:A,options:MwQ,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:CW(Q,"model"),domain:CW(Q,"domain"),"content-repo":CW(Q,"content-repo"),backend:CW(Q,"backend"),"push-to":CW(Q,"push-to"),"ai-api-key":CW(Q,"ai-api-key"),"no-interactive":A3(Q,"no-interactive"),preview:A3(Q,"preview"),deploy:A3(Q,"deploy"),regen:A3(Q,"regen"),all:A3(Q,"all"),only:CW(Q,"only"),"dry-run":A3(Q,"dry-run"),"startup-check":A3(Q,"startup-check"),"storage-dir":CW(Q,"storage-dir"),yes:A3(Q,"yes"),remote:CW(Q,"remote"),token:CW(Q,"token")}}}Du();import{mkdirSync as p5Q}from"fs";import{join as l5Q}from"path";import{execSync as i5Q}from"child_process";var eQA={name:"@rizom/brain",version:"0.2.0-alpha.73",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","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 B71,writeFileSync as Yu,chmodSync as Xu,existsSync as FkA,readFileSync as KkA}from"fs";import{basename as ZkA,dirname as NkA,join as E8,resolve as $8Q}from"path";import{fileURLToPath as f8Q}from"url";var c91=`ARG BUN_VERSION=1.3.10
|
|
8308
8308
|
FROM oven/bun:\${BUN_VERSION}-slim AS runtime
|
|
8309
8309
|
|
|
8310
8310
|
WORKDIR /app
|